use composables.

This commit is contained in:
2023-01-13 23:20:36 +08:00
parent d45783334d
commit d3caa5438d
15 changed files with 2360 additions and 72 deletions

1147
public/dark.json Normal file

File diff suppressed because it is too large Load Diff

1144
public/light.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ import Md from "./step-1/index.md"
import Monaco from "../shared/monaco/index.vue"
const route = useRoute()
console.log(route.params.step)
// console.log(route.params.step)
const code = ref("")
@@ -19,6 +19,7 @@ function change(value: string) {
<Md />
{{ code }}
</el-col>
<!-- TODO: 这里有BUG -->
<el-col :span="8">
<Monaco :value="code" @change="change" />
</el-col>

View File

@@ -1,6 +1,7 @@
import { createRouter, createWebHistory } from "vue-router"
import { createPinia } from "pinia"
import "normalize.css"
import "element-plus/theme-chalk/dark/css-vars.css"
import loader from "@monaco-editor/loader"
import storage from "utils/storage"
@@ -9,7 +10,7 @@ import { STORAGE_KEY } from "utils/constants"
import { routes } from "./routes"
import App from "./App.vue"
import { useLoginStore } from "~/shared/store/login"
import { toggleLogin } from "./shared/composables/modal"
const router = createRouter({
history: createWebHistory(),
@@ -19,8 +20,7 @@ const router = createRouter({
router.beforeEach((to, from, next) => {
if (to.matched.some((record) => record.meta.requiresAuth)) {
if (!storage.get(STORAGE_KEY.AUTHED)) {
const login = useLoginStore()
login.show()
toggleLogin(true)
next("/")
} else {
next()
@@ -32,9 +32,14 @@ router.beforeEach((to, from, next) => {
const pinia = createPinia()
Promise.all([loader.init(), fetch("/dracula.json")]).then(([monaco, dark]) => {
loader.init().then((monaco) => {
window.monaco = monaco
dark.json().then((data) => monaco.editor.defineTheme("dark", data))
fetch("/dark.json").then((data) =>
data.json().then((theme) => monaco.editor.defineTheme("dark", theme))
)
fetch("/light.json").then((data) =>
data.json().then((theme) => monaco.editor.defineTheme("light", theme))
)
})
loader.config({

View File

@@ -1,10 +1,10 @@
<script lang="ts" setup>
import { TabsPaneContext } from "element-plus"
import { SOURCES } from "utils/constants"
import { Problem } from "utils/types"
import Monaco from "~/shared/Monaco/index.vue"
import { useCodeStore } from "oj/store/code"
import { submissionExists } from "oj/api"
import { TabsPaneContext } from "element-plus"
import SubmitPanel from "./SubmitPanel.vue"
import TestcasePanel from "./TestcasePanel.vue"
@@ -68,8 +68,8 @@ function onTab(pane: TabsPaneContext) {
class="editor"
:language="code.language"
:value="code.value"
height="calc(100vh - 621px)"
@change="change"
height="calc(100vh - 621px)"
/>
<el-tabs type="border-card" @tab-click="onTab" v-model="tab">
<TestcasePanel />

View File

@@ -13,6 +13,7 @@ export const routes = [
{
path: "status",
component: () => import("oj/status/list.vue"),
meta: { requiresAuth: true },
},
{
path: "status/:statusID",
@@ -44,7 +45,7 @@ export const routes = [
{
path: "/learn",
component: () => import("~/shared/layout/default.vue"),
children: [{ path: ":step*", component: () => import("learn/index.vue") }],
children: [{ path: "", component: () => import("learn/index.vue") }],
},
{
path: "/admin",

View File

@@ -1,11 +1,10 @@
<script setup lang="ts">
import { useLoginStore } from "../store/login"
import { useSignupStore } from "~/shared/store/signup"
import { Sunny, Moon } from "@element-plus/icons-vue"
import { logout } from "../api"
import { useUserStore } from "../store/user"
import { isDark, toggleDark } from "~/shared/composables/dark"
import { toggleLogin, toggleSignup } from "~/shared/composables/modal"
const loginStore = useLoginStore()
const signupStore = useSignupStore()
const userStore = useUserStore()
const router = useRouter()
@@ -34,11 +33,17 @@ onMounted(userStore.getMyProfile)
<el-menu-item index="/status">提交</el-menu-item>
<el-menu-item index="/rank">排名</el-menu-item>
</el-menu>
<div v-if="userStore.isFinished && !userStore.isAuthed" class="actions">
<el-button @click="loginStore.show">登录</el-button>
<el-button @click="signupStore.show">注册</el-button>
<el-space class="actions">
<el-button
circle
:icon="isDark ? Sunny : Moon"
@click="toggleDark()"
></el-button>
<div v-if="userStore.isFinished && !userStore.isAuthed">
<el-button @click="toggleLogin(true)">登录</el-button>
<el-button @click="toggleSignup(true)">注册</el-button>
</div>
<div v-if="userStore.isFinished && userStore.isAuthed" class="actions">
<div v-if="userStore.isFinished && userStore.isAuthed">
<el-dropdown @command="handleDropdown">
<el-button>{{ userStore.user.username }}</el-button>
<template #dropdown>
@@ -54,6 +59,7 @@ onMounted(userStore.getMyProfile)
</template>
</el-dropdown>
</div>
</el-space>
</template>
<style scoped>

View File

@@ -1,12 +1,9 @@
<script setup lang="ts">
import { FormInstance } from "element-plus"
import { useSignupStore } from "~/shared/store/signup"
import { login } from "../api"
import { useLoginStore } from "../store/login"
import { loginModal, toggleLogin, toggleSignup } from "../composables/modal"
import { useUserStore } from "../store/user"
const loginStore = useLoginStore()
const signupStore = useSignupStore()
const userStore = useUserStore()
const loginRef = ref<FormInstance>()
const form = reactive({
@@ -29,15 +26,15 @@ async function submit() {
if (valid) {
await execute()
if (!error.value) {
loginStore.hide()
toggleLogin(false)
userStore.getMyProfile()
}
}
}
function goSignup() {
loginStore.hide()
signupStore.show()
toggleLogin(false)
toggleSignup(true)
}
</script>
@@ -46,7 +43,7 @@ function goSignup() {
style="max-width: 400px"
:close-on-click-modal="false"
:close-on-press-escape="false"
v-model="loginStore.visible"
v-model="loginModal"
title="登录"
>
<el-form

View File

@@ -3,6 +3,7 @@ import type * as Monaco from "monaco-editor"
import { LANGUAGE_VALUE } from "utils/constants"
import { LANGUAGE } from "utils/types"
import { isMobile } from "utils/breakpoints"
import { isDark } from "../composables/dark"
interface Props {
value: string
@@ -35,7 +36,7 @@ onMounted(function () {
editor = window.monaco.editor.create(monacoEditorRef.value, {
model,
theme: "dark", // 官方自带三种主题vs, hc-black, or vs-dark
theme: isDark.value ? "dark" : "light", // 官方自带三种主题vs, hc-black, or vs-dark
minimap: {
enabled: false,
},
@@ -78,6 +79,10 @@ onMounted(function () {
model.setValue(props.value)
}
})
watchEffect(() => {
window.monaco.editor.setTheme(isDark.value ? "dark" : "light")
})
})
onUnmounted(() => {

View File

@@ -1,13 +1,12 @@
<script setup lang="ts">
import { useSignupStore } from "../store/signup"
const store = useSignupStore()
import { signupModal } from "../composables/modal"
</script>
<template>
<el-dialog
:close-on-click-modal="false"
:close-on-press-escape="false"
v-model="store.visible"
v-model="signupModal"
title="注册"
>
</el-dialog>

View File

@@ -0,0 +1,2 @@
export const isDark = useDark({ storageKey: "theme-appearance" })
export const toggleDark = useToggle(isDark)

View File

@@ -0,0 +1,2 @@
export const [loginModal, toggleLogin] = useToggle()
export const [signupModal, toggleSignup] = useToggle()

View File

@@ -3,6 +3,7 @@ import type * as Monaco from "monaco-editor"
import { LANGUAGE_VALUE } from "utils/constants"
import { LANGUAGE } from "utils/types"
import { isMobile } from "utils/breakpoints"
import { isDark } from "../composables/dark"
interface Props {
value: string
@@ -35,7 +36,7 @@ onMounted(function () {
editor = window.monaco.editor.create(monacoEditorRef.value, {
model,
theme: "dark", // 官方自带三种主题vs, hc-black, or vs-dark
theme: isDark.value ? "dark" : "light", // 官方自带三种主题vs, hc-black, or vs-dark
minimap: {
enabled: false,
},
@@ -78,6 +79,10 @@ onMounted(function () {
model.setValue(props.value)
}
})
watchEffect(() => {
window.monaco.editor.setTheme(isDark.value ? "dark" : "light")
})
})
onUnmounted(() => {

View File

@@ -1,13 +0,0 @@
export const useLoginStore = defineStore("login", () => {
const [visible] = useToggle()
function show() {
visible.value = true
}
function hide() {
visible.value = false
}
return { visible, show, hide }
})

View File

@@ -1,13 +0,0 @@
export const useSignupStore = defineStore("signup", () => {
const [visible] = useToggle()
function show() {
visible.value = true
}
function hide() {
visible.value = false
}
return { visible, show, hide }
})