feat: use monaco instead of vue-prism-editor and support switching color scheme for the editor

This commit is contained in:
Justineo 2021-11-25 15:51:03 +08:00
parent 5226ec968c
commit f5238985a7
No known key found for this signature in database
GPG Key ID: B73F0979CF18A0EA
7 changed files with 315 additions and 61 deletions

View File

@ -36,3 +36,20 @@ export function getLink ({ slug, link, children }) {
}
return `/${slug}`
}
const PREF_KEY = 'veui.preferences'
export function loadPref (key) {
try {
const pref = JSON.parse(localStorage.getItem(PREF_KEY))
return pref[key]
} catch (e) {
return null
}
}
export function savePref (key, value) {
const pref = JSON.parse(localStorage.getItem(PREF_KEY)) || {}
pref[key] = value
localStorage.setItem(PREF_KEY, JSON.stringify(pref))
}

View File

@ -4,42 +4,57 @@
min-size="30"
class="live-editor"
>
<v-live-editor
:code="localCode"
:editor-props="{
lineNumbers: true
<v-monaco-editor
v-model="localCode"
style="height: 100%"
language="html"
:theme="theme"
:options="{
automaticLayout: true,
minimap: {
enabled: false,
},
}"
@change="handleChange"
/>
<div class="editor-toolbar">
<veui-button
v-tooltip="t('@onedemo.playInCodeSandbox')"
ui="s translucent square"
:ui="iconUi"
@click="play('CodeSandbox')"
>
<veui-icon name="one-demo-codesandbox"/>
</veui-button>
<veui-button
v-tooltip="t('@onedemo.playInStackBlitz')"
ui="s translucent square"
:ui="iconUi"
@click="play('StackBlitz')"
>
<veui-icon name="one-demo-stackblitz"/>
</veui-button>
<veui-button
v-tooltip="t('reset')"
ui="s translucent square"
:ui="iconUi"
@click="reset"
>
<veui-icon name="anticlockwise"/>
</veui-button>
<veui-button
v-tooltip="t('copyCode')"
ui="s translucent square"
:ui="iconUi"
@click="copy"
>
<veui-icon name="copy"/>
</veui-button>
<veui-button
v-tooltip="t(colorSchemeLabelKey)"
:ui="iconUi"
@click="switchColorScheme"
>
<veui-icon
:name="colorSchemeIcon"
scale="1.2"
/>
</veui-button>
<div class="editor-live-badge">
<span>Live</span>
</div>
@ -74,9 +89,10 @@
<script>
import Vue from 'vue'
import { VueLiveEditor, VueLivePreview } from 'vue-live'
import 'vue-live/lib/vue-live.esm.css'
import 'prism-theme-night-owl/build/no-italics.css'
import { VueLivePreview } from 'vue-live'
import MonacoEditor from 'vue-monaco'
import { editor } from 'monaco-editor/esm/vs/editor/editor.api'
import NightOwl from 'monaco-themes/themes/Night Owl.json'
import { Button, Icon, Alert } from 'veui'
import * as veui from 'veui'
import lodash from 'lodash'
@ -91,12 +107,42 @@ import 'splitpanes/dist/splitpanes.css'
import { getLocale } from '../common/i18n'
import { play } from '../common/play'
import { transformLessCode } from '../common/transform'
import { loadPref, savePref } from '../common/util'
Vue.use(toast)
editor.defineTheme('night-owl', NightOwl)
Icon.register({
'one-live-color-scheme-auto': {
width: 24,
height: 24,
d:
'M7.5 2c-1.79 1.15-3 3.18-3 5.5s1.21 4.35 3.03 5.5C4.46 13 2 10.54 2 7.5A5.5 5.5 0 0 1 7.5 2m11.57 1.5l1.43 1.43L4.93 20.5L3.5 19.07L19.07 3.5m-6.18 2.43L11.41 5L9.97 6l.42-1.7L9 3.24l1.75-.12l.58-1.65L12 3.1l1.73.03l-1.35 1.13l.51 1.67m-3.3 3.61l-1.16-.73l-1.12.78l.34-1.32l-1.09-.83l1.36-.09l.45-1.29l.51 1.27l1.36.03l-1.05.87l.4 1.31M19 13.5a5.5 5.5 0 0 1-5.5 5.5c-1.22 0-2.35-.4-3.26-1.07l7.69-7.69c.67.91 1.07 2.04 1.07 3.26m-4.4 6.58l2.77-1.15l-.24 3.35l-2.53-2.2m4.33-2.7l1.15-2.77l2.2 2.54l-3.35.23m1.15-4.96l-1.14-2.78l3.34.24l-2.2 2.54M9.63 18.93l2.77 1.15l-2.53 2.19l-.24-3.34z'
},
'one-live-color-scheme-light': {
width: 24,
height: 24,
d:
'M12 9c1.65 0 3 1.35 3 3s-1.35 3-3 3s-3-1.35-3-3s1.35-3 3-3m0-2c-2.76 0-5 2.24-5 5s2.24 5 5 5s5-2.24 5-5s-2.24-5-5-5zM2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1zm18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1zM11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1zm0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1zM5.99 4.58a.996.996 0 0 0-1.41 0a.996.996 0 0 0 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41L5.99 4.58zm12.37 12.37a.996.996 0 0 0-1.41 0a.996.996 0 0 0 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0a.996.996 0 0 0 0-1.41l-1.06-1.06zm1.06-10.96a.996.996 0 0 0 0-1.41a.996.996 0 0 0-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06zM7.05 18.36a.996.996 0 0 0 0-1.41a.996.996 0 0 0-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0l1.06-1.06z'
},
'one-live-color-scheme-dark': {
width: 24,
height: 24,
d:
'M9.37 5.51A7.35 7.35 0 0 0 9.1 7.5c0 4.08 3.32 7.4 7.4 7.4c.68 0 1.35-.09 1.99-.27A7.014 7.014 0 0 1 12 19c-3.86 0-7-3.14-7-7c0-2.93 1.81-5.45 4.37-6.49zM12 3a9 9 0 1 0 9 9c0-.46-.04-.92-.1-1.36a5.389 5.389 0 0 1-4.4 2.26a5.403 5.403 0 0 1-3.14-9.8c-.44-.06-.9-.1-1.36-.1z'
}
})
const iconPackage = 'veui-theme-dls-icons'
const iconNames = Object.keys(Icon.icons).filter(name => !name.startsWith('one-demo-') && Icon.icons[name])
const iconModules = [iconPackage].concat(iconNames.map(name => `${iconPackage}/${name}`))
const iconNames = Object.keys(Icon.icons).filter(
name => !name.startsWith('one-demo-') && Icon.icons[name]
)
const iconModules = [iconPackage].concat(
iconNames.map(name => `${iconPackage}/${name}`)
)
const colorSchemeOptions = ['dark', 'light', 'auto']
export default {
name: 'one-live',
@ -106,7 +152,7 @@ export default {
'veui-alert': Alert,
'v-splitpanes': Splitpanes,
'v-pane': Pane,
'v-live-editor': VueLiveEditor,
'v-monaco-editor': MonacoEditor,
'v-live-preview': VueLivePreview
},
directives: {
@ -132,7 +178,9 @@ export default {
mocks[module] = true
return mocks
}, {})
}
},
colorSchemeOption: loadPref('prefers-color-scheme'),
colorSchemeSystemPref: null
}
},
computed: {
@ -144,6 +192,46 @@ export default {
}
return error.name ? `${error.name}: ${error.message}` : error.message
},
colorScheme () {
if (!this.colorSchemeOption || !this.mql) {
return 'dark'
}
if (this.colorSchemeOption === 'auto') {
return this.colorSchemeSystemPref
}
return this.colorSchemeOption
},
theme () {
return this.colorScheme === 'dark' ? 'night-owl' : 'vs'
},
iconUi () {
const ui = 's square icon'
return this.colorScheme === 'dark' ? `${ui} reverse` : ui
},
colorSchemeIcon () {
if (!this.colorSchemeOption) {
return 'one-live-color-scheme-dark'
}
return {
light: 'one-live-color-scheme-light',
dark: 'one-live-color-scheme-dark',
auto: 'one-live-color-scheme-auto'
}[this.colorSchemeOption]
},
colorSchemeLabelKey () {
if (!this.colorSchemeOption) {
return 'darkMode'
}
return {
light: 'lightMode',
dark: 'darkMode',
auto: 'followSystem'
}[this.colorSchemeOption]
}
},
watch: {
@ -162,6 +250,13 @@ export default {
}
}
},
mounted () {
this.mql = window.matchMedia('(prefers-color-scheme: dark)')
this.mql.addEventListener('change', this.handleColorSchemeChange)
},
beforeDestroy () {
this.mql.removeEventListener('change', this.handleColorSchemeChange)
},
methods: {
play (vendor) {
let locale = getLocale(this.$route.path)
@ -175,6 +270,21 @@ export default {
this.$toast.error(this.t('copyFailed'))
}
},
switchColorScheme () {
if (!this.colorSchemeOption) {
this.colorSchemeOption = 'light'
} else {
this.colorSchemeOption = colorSchemeOptions[
(colorSchemeOptions.indexOf(this.colorSchemeOption) + 1) %
colorSchemeOptions.length
]
}
savePref('prefers-color-scheme', this.colorSchemeOption)
},
handleColorSchemeChange () {
this.colorSchemeSystemPref = this.mql.matches ? 'dark' : 'light'
},
reset () {
this.localCode = this.code
},
@ -208,7 +318,7 @@ export default {
.editor-toolbar
position absolute
top 12px
right 20px
right 28px
display flex
align-items center
@ -224,10 +334,6 @@ export default {
color #fff
height 18px
span
position relative
top -1px
&::before
content ""
position absolute
@ -268,4 +374,14 @@ export default {
100%
transform scale(0.95)
box-shadow 0 0 0 0 rgba(255, 255, 255, 0)
.veui-button[ui~="icon"][ui~="reverse"]
color #ebedf5
&:hover
&[data-focus-visible-added]
color #f6f7fa
&:active
color #fff
</style>

View File

@ -70,6 +70,7 @@ export default {
padding 0 24px
box-shadow 0 0 4px #0006
position relative
z-index 1
h1
flex none
@ -86,30 +87,6 @@ export default {
flex 1 1 auto
height calc(100vh - 48px)
& >>> .prism-editor-wrapper
padding 8px 12px
font-size 12px
color #eee
background-color #0a0b0d
line-height 1.5
font-family Menlo, consolas, monospace
-webkit-font-smoothing auto
&::-webkit-scrollbar
width 8px
background transparent
transition all 0.3s
&-thumb
border-radius 4px
background-color #282c33
&:hover::-webkit-scrollbar-thumb
background-color #545b66
textarea
outline none
& >>> .live-preview
padding 24px 36px

View File

@ -1,4 +1,5 @@
const path = require('path')
const MonacoEditorPlugin = require('monaco-editor-webpack-plugin')
function resolve (p) {
return path.resolve(__dirname, p)
@ -75,6 +76,12 @@ module.exports = {
}
},
plugins: [
new MonacoEditorPlugin({
languages: ['javascript', 'css', 'html', 'typescript']
})
],
extend (config) {
/**
* veui-loader
@ -107,6 +114,7 @@ module.exports = {
config.resolve.alias.vue$ = 'vue/dist/vue.esm.js'
config.resolve.alias['vue-inbrowser-compiler-utils'] = '@justfork/vue-inbrowser-compiler-utils'
config.resolve.alias['vue-monaco'] = '@justfork/vue-monaco'
},
optimization: {

153
package-lock.json generated
View File

@ -14,6 +14,7 @@
"@docsearch/css": "^3.0.0-alpha.39",
"@docsearch/js": "^3.0.0-alpha.39",
"@justfork/vue-inbrowser-compiler-utils": "^4.42.0",
"@justfork/vue-monaco": "^0.3.1",
"@stackblitz/sdk": "^1.5.2",
"babel-eslint": "^10.1.0",
"babel-plugin-lodash": "^3.3.4",
@ -46,12 +47,14 @@
"mdast-util-to-string": "^2.0.0",
"mkdirp": "^0.5.5",
"moment": "^2.22.2",
"monaco-editor": "^0.30.1",
"monaco-editor-webpack-plugin": "^6.0.0",
"monaco-themes": "^0.4.0",
"nuxt": "^2.15.7",
"object-deep-search": "0.0.7",
"preact": "^10.5.14",
"prettier": "^1.16.4",
"prettier-eslint": "^8.8.2",
"prism-theme-night-owl": "^1.4.0",
"raw-loader": "^4.0.2",
"recursive-readdir": "^2.2.2",
"recursive-readdir-sync": "^1.0.6",
@ -4120,6 +4123,18 @@
"node": ">=6"
}
},
"node_modules/@justfork/vue-monaco": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@justfork/vue-monaco/-/vue-monaco-0.3.1.tgz",
"integrity": "sha512-liXmN27hbYc+uJgiJHO8sv2QkCK2ULIJ+4Cv983ZteA76/ykCTFeLQoyJPUPWd5OQK80rQ1i70kAWv0j4z5eEw==",
"dev": true,
"dependencies": {
"nano-assign": "^1.0.0"
},
"peerDependencies": {
"monaco-editor": "^0.30.1"
}
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@ -12310,6 +12325,12 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"node_modules/fast-plist": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/fast-plist/-/fast-plist-0.1.2.tgz",
"integrity": "sha1-pFr/NFGWAG1AbKbNzQX2kFHvNbg=",
"dev": true
},
"node_modules/fastest-levenshtein": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
@ -16369,6 +16390,63 @@
"node": "*"
}
},
"node_modules/monaco-editor": {
"version": "0.30.1",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.30.1.tgz",
"integrity": "sha512-B/y4+b2O5G2gjuxIFtCE2EkM17R2NM7/3F8x0qcPsqy4V83bitJTIO4TIeZpYlzu/xy6INiY/+84BEm6+7Cmzg==",
"dev": true
},
"node_modules/monaco-editor-webpack-plugin": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-6.0.0.tgz",
"integrity": "sha512-vC886Mzpd2AkSM35XLkfQMjH+Ohz6RISVwhAejDUzZDheJAiz6G34lky1vyO8fZ702v7IrcKmsGwL1rRFnwvUA==",
"dev": true,
"dependencies": {
"loader-utils": "^2.0.0"
},
"peerDependencies": {
"monaco-editor": "0.30.x",
"webpack": "^4.5.0 || 5.x"
}
},
"node_modules/monaco-editor-webpack-plugin/node_modules/json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.5"
},
"bin": {
"json5": "lib/cli.js"
},
"engines": {
"node": ">=6"
}
},
"node_modules/monaco-editor-webpack-plugin/node_modules/loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"dev": true,
"dependencies": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
},
"engines": {
"node": ">=8.9.0"
}
},
"node_modules/monaco-themes": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/monaco-themes/-/monaco-themes-0.4.0.tgz",
"integrity": "sha512-AJL7Sk3j1DrQo94RqaYBr+IrGNP/2f5drFkKXKyjNZHYY/j+2Pv+O4+WETYkrTj9m1Zm2K3YRuGP/I3+5rHPxw==",
"dev": true,
"dependencies": {
"fast-plist": "^0.1.2"
}
},
"node_modules/move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz",
@ -19651,12 +19729,6 @@
"node": ">=0.1.90"
}
},
"node_modules/prism-theme-night-owl": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/prism-theme-night-owl/-/prism-theme-night-owl-1.4.0.tgz",
"integrity": "sha512-1N1GVbVorGd5t1Vw76yL/3rhqdiCpDrJg26Is+jGeMV7qiIMZL+bC7Mjx7HMMuVKZoi+2nWSbU5IutBYNy9tiQ==",
"dev": true
},
"node_modules/prismjs": {
"version": "1.25.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.25.0.tgz",
@ -29098,6 +29170,15 @@
}
}
},
"@justfork/vue-monaco": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/@justfork/vue-monaco/-/vue-monaco-0.3.1.tgz",
"integrity": "sha512-liXmN27hbYc+uJgiJHO8sv2QkCK2ULIJ+4Cv983ZteA76/ykCTFeLQoyJPUPWd5OQK80rQ1i70kAWv0j4z5eEw==",
"dev": true,
"requires": {
"nano-assign": "^1.0.0"
}
},
"@nodelib/fs.scandir": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
@ -35620,6 +35701,12 @@
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
"dev": true
},
"fast-plist": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/fast-plist/-/fast-plist-0.1.2.tgz",
"integrity": "sha1-pFr/NFGWAG1AbKbNzQX2kFHvNbg=",
"dev": true
},
"fastest-levenshtein": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
@ -38818,6 +38905,52 @@
"integrity": "sha512-Z5KOjYmnHyd/ukynmFd/WwyXHd7L4J9vTI/nn5Ap9AVUgaAE15VvQ9MOGmJJygEUklupqIrFnor/tjTwRU+tQw==",
"dev": true
},
"monaco-editor": {
"version": "0.30.1",
"resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.30.1.tgz",
"integrity": "sha512-B/y4+b2O5G2gjuxIFtCE2EkM17R2NM7/3F8x0qcPsqy4V83bitJTIO4TIeZpYlzu/xy6INiY/+84BEm6+7Cmzg==",
"dev": true
},
"monaco-editor-webpack-plugin": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/monaco-editor-webpack-plugin/-/monaco-editor-webpack-plugin-6.0.0.tgz",
"integrity": "sha512-vC886Mzpd2AkSM35XLkfQMjH+Ohz6RISVwhAejDUzZDheJAiz6G34lky1vyO8fZ702v7IrcKmsGwL1rRFnwvUA==",
"dev": true,
"requires": {
"loader-utils": "^2.0.0"
},
"dependencies": {
"json5": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz",
"integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
"dev": true,
"requires": {
"minimist": "^1.2.5"
}
},
"loader-utils": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.2.tgz",
"integrity": "sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==",
"dev": true,
"requires": {
"big.js": "^5.2.2",
"emojis-list": "^3.0.0",
"json5": "^2.1.2"
}
}
}
},
"monaco-themes": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/monaco-themes/-/monaco-themes-0.4.0.tgz",
"integrity": "sha512-AJL7Sk3j1DrQo94RqaYBr+IrGNP/2f5drFkKXKyjNZHYY/j+2Pv+O4+WETYkrTj9m1Zm2K3YRuGP/I3+5rHPxw==",
"dev": true,
"requires": {
"fast-plist": "^0.1.2"
}
},
"move-concurrently": {
"version": "1.0.1",
"resolved": "https://registry.npm.taobao.org/move-concurrently/download/move-concurrently-1.0.1.tgz",
@ -41515,12 +41648,6 @@
}
}
},
"prism-theme-night-owl": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/prism-theme-night-owl/-/prism-theme-night-owl-1.4.0.tgz",
"integrity": "sha512-1N1GVbVorGd5t1Vw76yL/3rhqdiCpDrJg26Is+jGeMV7qiIMZL+bC7Mjx7HMMuVKZoi+2nWSbU5IutBYNy9tiQ==",
"dev": true
},
"prismjs": {
"version": "1.25.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.25.0.tgz",

View File

@ -22,6 +22,7 @@
"@docsearch/css": "^3.0.0-alpha.39",
"@docsearch/js": "^3.0.0-alpha.39",
"@justfork/vue-inbrowser-compiler-utils": "^4.42.0",
"@justfork/vue-monaco": "^0.3.1",
"@stackblitz/sdk": "^1.5.2",
"babel-eslint": "^10.1.0",
"babel-plugin-lodash": "^3.3.4",
@ -54,12 +55,14 @@
"mdast-util-to-string": "^2.0.0",
"mkdirp": "^0.5.5",
"moment": "^2.22.2",
"monaco-editor": "^0.30.1",
"monaco-editor-webpack-plugin": "^6.0.0",
"monaco-themes": "^0.4.0",
"nuxt": "^2.15.7",
"object-deep-search": "0.0.7",
"preact": "^10.5.14",
"prettier": "^1.16.4",
"prettier-eslint": "^8.8.2",
"prism-theme-night-owl": "^1.4.0",
"raw-loader": "^4.0.2",
"recursive-readdir": "^2.2.2",
"recursive-readdir-sync": "^1.0.6",

View File

@ -35,7 +35,10 @@ i18n.register(
copySuccess: '复制成功!',
copyFailed: '复制失败!',
reset: '重置',
dismiss: '关闭'
dismiss: '关闭',
darkMode: '暗色模式',
lightMode: '亮色模式',
followSystem: '跟随系统设置'
},
{
ns: 'onelive'
@ -49,7 +52,10 @@ i18n.register(
copySuccess: 'Copy success!',
copyFailed: 'Copy failed!',
reset: 'Reset',
dismiss: 'Dismiss'
dismiss: 'Dismiss',
darkMode: 'Dark mode',
lightMode: 'Light mode',
followSystem: 'Follow system preferences'
},
{
ns: 'onelive'