mirror of
https://github.com/marktext/marktext.git
synced 2025-05-04 03:32:36 +08:00
feat: add dark theme and light theme
This commit is contained in:
parent
590f49cf24
commit
12c22ce588
@ -6,6 +6,8 @@
|
|||||||
|
|
||||||
- Add Focus Mode, the current paragraph's will be focused.
|
- Add Focus Mode, the current paragraph's will be focused.
|
||||||
|
|
||||||
|
- Add Dark theme, Light theme.
|
||||||
|
|
||||||
**Optimization**
|
**Optimization**
|
||||||
|
|
||||||
- Optimize the display of path name and file name in title bar.
|
- Optimize the display of path name and file name in title bar.
|
||||||
|
@ -47,6 +47,7 @@ export const LOWERCASE_TAGS = generateKeyHash([
|
|||||||
|
|
||||||
export const CLASS_OR_ID = genUpper2LowerKeyHash([
|
export const CLASS_OR_ID = genUpper2LowerKeyHash([
|
||||||
'mousetrap',
|
'mousetrap',
|
||||||
|
'AG_THEME_ID',
|
||||||
'AG_GRAY',
|
'AG_GRAY',
|
||||||
'AG_HIDE',
|
'AG_HIDE',
|
||||||
'AG_WARN',
|
'AG_WARN',
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import ContentState from './contentState'
|
import ContentState from './contentState'
|
||||||
import selection from './selection'
|
import selection from './selection'
|
||||||
import EventCenter from './event'
|
import EventCenter from './event'
|
||||||
import { LOWERCASE_TAGS, EVENT_KEYS, CLASS_OR_ID } from './config'
|
import { LOWERCASE_TAGS, EVENT_KEYS, CLASS_OR_ID, codeMirrorConfig } from './config'
|
||||||
import { throttle, debounce } from './utils'
|
import { throttle, debounce } from './utils'
|
||||||
import { search } from './codeMirror'
|
import { search } from './codeMirror'
|
||||||
import { checkEditLanguage } from './codeMirror/language'
|
import { checkEditLanguage } from './codeMirror/language'
|
||||||
@ -429,6 +429,23 @@ class Aganippe {
|
|||||||
this.focusMode = bool
|
this.focusMode = bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTheme (name, css) {
|
||||||
|
if (name === 'dark') {
|
||||||
|
codeMirrorConfig.theme = 'railscasts'
|
||||||
|
} else {
|
||||||
|
delete codeMirrorConfig.theme
|
||||||
|
}
|
||||||
|
const themeStyleId = CLASS_OR_ID['AG_THEME_ID']
|
||||||
|
let styleEle = document.querySelector(`#${themeStyleId}`)
|
||||||
|
if (!styleEle) {
|
||||||
|
styleEle = document.createElement('style')
|
||||||
|
styleEle.id = themeStyleId
|
||||||
|
document.querySelector('head').appendChild(styleEle)
|
||||||
|
}
|
||||||
|
styleEle.innerHTML = css
|
||||||
|
this.contentState.render()
|
||||||
|
}
|
||||||
|
|
||||||
updateParagraph (type) {
|
updateParagraph (type) {
|
||||||
this.contentState.updateParagraph(type)
|
this.contentState.updateParagraph(type)
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,6 @@
|
|||||||
.ag-table-picker .footer button {
|
.ag-table-picker .footer button {
|
||||||
outline: none;
|
outline: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
vertical-align: text-bottom;
|
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
line-height: 12px;
|
line-height: 12px;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -5,37 +5,8 @@
|
|||||||
|
|
||||||
@include-when-export url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);
|
@include-when-export url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
src: local('Open Sans Regular'), url('./github/400.woff') format('woff')
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans';
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: normal;
|
|
||||||
src: local('Open Sans Italic'), url('./github/400i.woff') format('woff')
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: bold;
|
|
||||||
src: local('Open Sans Bold'), url('./github/700.woff') format('woff')
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans';
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: bold;
|
|
||||||
src: local('Open Sans Bold Italic'), url('./github/700i.woff') format('woff')
|
|
||||||
}
|
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
background: rgb(43, 43, 43);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@ -62,11 +33,44 @@ body {
|
|||||||
margin-top: 30px;
|
margin-top: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ag-float-box {
|
||||||
|
background: #303133;
|
||||||
|
border: 1px solid #303133;
|
||||||
|
}
|
||||||
|
.ag-float-item {
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-float-item-active {
|
||||||
|
background: #606266;
|
||||||
|
color: #C0C4CC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-table-picker {
|
||||||
|
background: #606266;
|
||||||
|
border: 1px solid #606266;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ag-table-picker::before {
|
||||||
|
background: #606266;
|
||||||
|
border: 1px solid #606266;
|
||||||
|
border-right: none;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
.ag-gray {
|
.ag-gray {
|
||||||
color: #909399;
|
color: #909399;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.el-dialog {
|
||||||
|
background: rgb(43, 43, 43);
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-modal {
|
||||||
|
background: rgba(0, 0, 0, .9);
|
||||||
|
}
|
||||||
|
|
||||||
body>*:first-child {
|
body>*:first-child {
|
||||||
margin-top: 0 !important;
|
margin-top: 0 !important;
|
||||||
}
|
}
|
||||||
|
@ -5,34 +5,6 @@
|
|||||||
|
|
||||||
@include-when-export url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);
|
@include-when-export url(http://fonts.googleapis.com/css?family=Open+Sans:400italic,700italic,700,400&subset=latin,latin-ext);
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: normal;
|
|
||||||
src: local('Open Sans Regular'), url('./github/400.woff') format('woff')
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans';
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: normal;
|
|
||||||
src: local('Open Sans Italic'), url('./github/400i.woff') format('woff')
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans';
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: bold;
|
|
||||||
src: local('Open Sans Bold'), url('./github/700.woff') format('woff')
|
|
||||||
}
|
|
||||||
|
|
||||||
@font-face {
|
|
||||||
font-family: 'Open Sans';
|
|
||||||
font-style: italic;
|
|
||||||
font-weight: bold;
|
|
||||||
src: local('Open Sans Bold Italic'), url('./github/700i.woff') format('woff')
|
|
||||||
}
|
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
background: rgb(252, 252, 252);
|
background: rgb(252, 252, 252);
|
||||||
@ -40,7 +12,7 @@ html, body {
|
|||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
font-family: "Open Sans", "Clear Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||||
color: #606266;
|
color: #303133;
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +39,11 @@ body {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.v-modal {
|
||||||
|
background: #fff;
|
||||||
|
opacity: .8;
|
||||||
|
}
|
||||||
|
|
||||||
body>*:first-child {
|
body>*:first-child {
|
||||||
margin-top: 0 !important;
|
margin-top: 0 !important;
|
||||||
}
|
}
|
||||||
|
45
src/main/actions/theme.js
Normal file
45
src/main/actions/theme.js
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import { ipcMain, BrowserWindow } from 'electron'
|
||||||
|
import { getMenuItem } from '../utils'
|
||||||
|
|
||||||
|
const THEME_PATH = path.resolve(__dirname, '../../editor/themes')
|
||||||
|
const themeCSS = {}
|
||||||
|
|
||||||
|
export const selectTheme = (win, theme, themeCSS) => {
|
||||||
|
win.webContents.send('AGANI::theme', { theme, themeCSS })
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSelectTheme = () => {
|
||||||
|
const themeMenu = getMenuItem('Theme')
|
||||||
|
return themeMenu.submenu.items.find(item => item.checked)
|
||||||
|
}
|
||||||
|
|
||||||
|
ipcMain.on('AGANI::ask-for-theme', e => {
|
||||||
|
const win = BrowserWindow.fromWebContents(e.sender)
|
||||||
|
if (!Object.keys(themeCSS).length) {
|
||||||
|
const promises = ['dark', 'light'].map(theme => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
fs.readFile(`${THEME_PATH}/${theme}.css`, 'utf-8', (err, data) => {
|
||||||
|
if (err) reject(err)
|
||||||
|
resolve({ theme, data })
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Promise.all(promises)
|
||||||
|
.then(themes => {
|
||||||
|
themes.forEach(t => {
|
||||||
|
console.log(t)
|
||||||
|
const { theme, data } = t
|
||||||
|
themeCSS[theme] = data
|
||||||
|
})
|
||||||
|
const selectedTheme = getSelectTheme().label.toLowerCase()
|
||||||
|
console.log(selectedTheme)
|
||||||
|
console.log(themeCSS)
|
||||||
|
selectTheme(win, selectedTheme, themeCSS)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
const selectedTheme = getSelectTheme().label.toLowerCase()
|
||||||
|
selectTheme(win, selectedTheme, themeCSS)
|
||||||
|
}
|
||||||
|
})
|
@ -17,6 +17,8 @@ export const EXTENSION_HASN = {
|
|||||||
pdf: '.pdf'
|
pdf: '.pdf'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const DEFAULT_THEME = 'dark'
|
||||||
|
|
||||||
export const VIEW_MENU_ITEM = {
|
export const VIEW_MENU_ITEM = {
|
||||||
'Source Code Mode': false,
|
'Source Code Mode': false,
|
||||||
'Typewriter Mode': false,
|
'Typewriter Mode': false,
|
||||||
|
@ -6,6 +6,7 @@ import view from './view'
|
|||||||
import windowMenu from './windowMenu'
|
import windowMenu from './windowMenu'
|
||||||
import paragraph from './paragraph'
|
import paragraph from './paragraph'
|
||||||
import format from './format'
|
import format from './format'
|
||||||
|
import theme from './theme'
|
||||||
|
|
||||||
export dockMenu from './dock'
|
export dockMenu from './dock'
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ export default function configureMenu ({ app }) {
|
|||||||
paragraph,
|
paragraph,
|
||||||
format,
|
format,
|
||||||
windowMenu,
|
windowMenu,
|
||||||
|
theme,
|
||||||
view,
|
view,
|
||||||
help
|
help
|
||||||
]
|
]
|
||||||
|
20
src/main/menus/theme.js
Normal file
20
src/main/menus/theme.js
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import * as actions from '../actions/theme'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
label: 'Theme',
|
||||||
|
submenu: [{
|
||||||
|
label: 'Dark',
|
||||||
|
type: 'radio',
|
||||||
|
checked: true,
|
||||||
|
click (menuItem, browserWindow) {
|
||||||
|
actions.selectTheme(browserWindow, 'dark')
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
label: 'Light',
|
||||||
|
type: 'radio',
|
||||||
|
checked: false,
|
||||||
|
click (menuItem, browserWindow) {
|
||||||
|
actions.selectTheme(browserWindow, 'light')
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
@ -2,5 +2,6 @@ import { Menu } from 'electron'
|
|||||||
|
|
||||||
export const getMenuItem = menuName => {
|
export const getMenuItem = menuName => {
|
||||||
const menus = Menu.getApplicationMenu()
|
const menus = Menu.getApplicationMenu()
|
||||||
|
console.log(typeof menus.append)
|
||||||
return menus.items.find(menu => menu.label === menuName)
|
return menus.items.find(menu => menu.label === menuName)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
:filename="filename"
|
:filename="filename"
|
||||||
:active="windowActive"
|
:active="windowActive"
|
||||||
:word-count="wordCount"
|
:word-count="wordCount"
|
||||||
|
:theme="theme"
|
||||||
></title-bar>
|
></title-bar>
|
||||||
<editor
|
<editor
|
||||||
:typewriter="typewriter"
|
:typewriter="typewriter"
|
||||||
@ -13,14 +14,18 @@
|
|||||||
:markdown="markdown"
|
:markdown="markdown"
|
||||||
:cursor="cursor"
|
:cursor="cursor"
|
||||||
v-if="!sourceCode"
|
v-if="!sourceCode"
|
||||||
|
:theme="theme"
|
||||||
|
:theme-css="themeCSS"
|
||||||
></editor>
|
></editor>
|
||||||
<source-code
|
<source-code
|
||||||
v-else
|
v-else
|
||||||
:markdown="markdown"
|
:markdown="markdown"
|
||||||
:cursor="cursor"
|
:cursor="cursor"
|
||||||
|
:theme="theme"
|
||||||
></source-code>
|
></source-code>
|
||||||
<search
|
<search
|
||||||
v-if="!sourceCode"
|
v-if="!sourceCode"
|
||||||
|
:theme="theme"
|
||||||
></search>
|
></search>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -46,12 +51,14 @@
|
|||||||
computed: {
|
computed: {
|
||||||
...mapState([
|
...mapState([
|
||||||
'pathname', 'filename', 'windowActive', 'wordCount',
|
'pathname', 'filename', 'windowActive', 'wordCount',
|
||||||
'typewriter', 'focus', 'sourceCode', 'markdown', 'cursor'
|
'typewriter', 'focus', 'sourceCode', 'markdown', 'cursor',
|
||||||
|
'theme', 'themeCSS'
|
||||||
])
|
])
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
const { dispatch } = this.$store
|
const { dispatch } = this.$store
|
||||||
|
|
||||||
|
dispatch('ASK_FOR_THEME')
|
||||||
dispatch('ASK_FOR_MODE')
|
dispatch('ASK_FOR_MODE')
|
||||||
dispatch('LISTEN_FOR_CLOSE')
|
dispatch('LISTEN_FOR_CLOSE')
|
||||||
dispatch('LISTEN_FOR_SAVE_AS')
|
dispatch('LISTEN_FOR_SAVE_AS')
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="editor-wrapper"
|
class="editor-wrapper"
|
||||||
:class="{ 'typewriter': typewriter, 'focus': focus, 'source': sourceCode }"
|
:class="[{ 'typewriter': typewriter, 'focus': focus, 'source': sourceCode }, theme]"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
ref="editor"
|
ref="editor"
|
||||||
@ -83,7 +83,9 @@
|
|||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
markdown: String,
|
markdown: String,
|
||||||
cursor: Object
|
cursor: Object,
|
||||||
|
theme: String,
|
||||||
|
themeCss: Object
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@ -106,6 +108,12 @@
|
|||||||
},
|
},
|
||||||
focus: function (value) {
|
focus: function (value) {
|
||||||
this.editor.setFocusMode(value)
|
this.editor.setFocusMode(value)
|
||||||
|
},
|
||||||
|
theme: function (value, oldValue) {
|
||||||
|
const { editor, themeCss } = this
|
||||||
|
if (value !== oldValue && editor) {
|
||||||
|
editor.setTheme(value, themeCss[value])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created () {
|
created () {
|
||||||
@ -113,7 +121,7 @@
|
|||||||
const ele = this.$refs.editor
|
const ele = this.$refs.editor
|
||||||
this.editor = new Aganippe(ele)
|
this.editor = new Aganippe(ele)
|
||||||
const { container } = this.editor
|
const { container } = this.editor
|
||||||
const { markdown } = this
|
const { markdown, theme, themeCss } = this
|
||||||
// init set markdown and edit mode(typewriter mode and focus mode)
|
// init set markdown and edit mode(typewriter mode and focus mode)
|
||||||
if (markdown.trim()) {
|
if (markdown.trim()) {
|
||||||
this.setMarkdownToEditor(markdown)
|
this.setMarkdownToEditor(markdown)
|
||||||
@ -123,6 +131,10 @@
|
|||||||
this.editor.setFocusMode(this.focus)
|
this.editor.setFocusMode(this.focus)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (theme) {
|
||||||
|
this.editor.setTheme(theme, themeCss[theme])
|
||||||
|
}
|
||||||
|
|
||||||
bus.$on('file-loaded', this.setMarkdownToEditor)
|
bus.$on('file-loaded', this.setMarkdownToEditor)
|
||||||
bus.$on('undo', () => this.editor.undo())
|
bus.$on('undo', () => this.editor.undo())
|
||||||
bus.$on('redo', () => this.editor.redo())
|
bus.$on('redo', () => this.editor.redo())
|
||||||
@ -247,7 +259,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@import '../../editor/themes/light.css';
|
/* @import '../../editor/themes/dark.css';*/
|
||||||
@import '../../editor/index.css';
|
@import '../../editor/index.css';
|
||||||
.editor-wrapper {
|
.editor-wrapper {
|
||||||
height: calc(100vh - 22px);
|
height: calc(100vh - 22px);
|
||||||
@ -267,15 +279,17 @@
|
|||||||
padding-top: calc(50vh - 136px);
|
padding-top: calc(50vh - 136px);
|
||||||
padding-bottom: calc(50vh - 54px);
|
padding-bottom: calc(50vh - 54px);
|
||||||
}
|
}
|
||||||
.v-modal {
|
|
||||||
background: #fff;
|
|
||||||
opacity: .8;
|
|
||||||
}
|
|
||||||
.ag-dialog-table {
|
.ag-dialog-table {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ag-dialog-table .dialog-title svg {
|
.ag-dialog-table .dialog-title svg {
|
||||||
width: 1.5em;
|
width: 1.5em;
|
||||||
height: 1.5em;
|
height: 1.5em;
|
||||||
}
|
}
|
||||||
|
/* for dark theme */
|
||||||
|
.dark.editor-wrapper {
|
||||||
|
background: rgb(43, 43, 43);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="search-bar"
|
<div class="search-bar"
|
||||||
|
:class="theme"
|
||||||
@click.stop="noop"
|
@click.stop="noop"
|
||||||
v-show="showSearch"
|
v-show="showSearch"
|
||||||
>
|
>
|
||||||
@ -100,6 +101,9 @@
|
|||||||
import { mapState } from 'vuex'
|
import { mapState } from 'vuex'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
props: {
|
||||||
|
theme: String
|
||||||
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
showSearch: false,
|
showSearch: false,
|
||||||
@ -258,6 +262,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
margin-right: 5px;
|
||||||
}
|
}
|
||||||
.input-wrapper .search-result {
|
.input-wrapper .search-result {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -276,4 +281,21 @@
|
|||||||
color: #606266;
|
color: #606266;
|
||||||
padding: 0 8px;
|
padding: 0 8px;
|
||||||
}
|
}
|
||||||
|
/* css for dark theme*/
|
||||||
|
.dark {
|
||||||
|
caret-color: #efefef;
|
||||||
|
background: rgb(43, 43, 43);
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
.dark input {
|
||||||
|
background: rgb(54, 55, 49);
|
||||||
|
color: #C0C4CC;
|
||||||
|
}
|
||||||
|
.dark .button:hover {
|
||||||
|
background: rgb(71, 72, 66);
|
||||||
|
color: #C0C4CC;
|
||||||
|
}
|
||||||
|
.dark .button:active {
|
||||||
|
background: #303133;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="source-code" ref="sourceCode">
|
<div class="source-code" ref="sourceCode" :class="[theme]">
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -11,7 +11,8 @@
|
|||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
markdown: String,
|
markdown: String,
|
||||||
cursor: Object
|
cursor: Object,
|
||||||
|
theme: String
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
@ -19,14 +20,28 @@
|
|||||||
editor: null
|
editor: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
watch: {
|
||||||
|
theme: function (value, oldValue) {
|
||||||
|
const cm = this.$refs.sourceCode.querySelector('.CodeMirror')
|
||||||
|
if (value !== oldValue) {
|
||||||
|
if (value === 'dark') {
|
||||||
|
cm.classList.remove('cm-s-default')
|
||||||
|
cm.classList.add('cm-s-railscasts')
|
||||||
|
} else {
|
||||||
|
cm.classList.add('cm-s-default')
|
||||||
|
cm.classList.remove('cm-s-railscasts')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
created () {
|
created () {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
const { markdown = '' } = this
|
const { markdown = '', theme } = this
|
||||||
this.contentState = new ContentState()
|
this.contentState = new ContentState()
|
||||||
const container = this.$refs.sourceCode
|
const container = this.$refs.sourceCode
|
||||||
const editor = this.editor = codeMirror(container, {
|
const codeMirrorConfig = {
|
||||||
// theme: 'railscasts',
|
// theme: 'railscasts',
|
||||||
value: markdown,
|
value: '',
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
autofocus: true,
|
autofocus: true,
|
||||||
lineWrapping: true,
|
lineWrapping: true,
|
||||||
@ -38,9 +53,22 @@
|
|||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
if (theme === 'dark') codeMirrorConfig.theme = 'railscasts'
|
||||||
|
this.editor = codeMirror(container, codeMirrorConfig)
|
||||||
bus.$on('file-loaded', this.setMarkdown)
|
bus.$on('file-loaded', this.setMarkdown)
|
||||||
|
|
||||||
|
this.listenChange()
|
||||||
|
|
||||||
|
this.setMarkdown(markdown)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestory () {
|
||||||
|
bus.$off('file-loaded', this.setMarkdown)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
listenChange () {
|
||||||
|
const { editor } = this
|
||||||
editor.on('cursorActivity', (cm, event) => {
|
editor.on('cursorActivity', (cm, event) => {
|
||||||
const cursor = cm.getCursor()
|
const cursor = cm.getCursor()
|
||||||
const markdown = cm.getValue()
|
const markdown = cm.getValue()
|
||||||
@ -51,13 +79,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
setMode(editor, 'markdown')
|
setMode(editor, 'markdown')
|
||||||
this.setMarkdown(markdown)
|
|
||||||
})
|
|
||||||
},
|
},
|
||||||
beforeDestory () {
|
|
||||||
bus.$off('file-loaded', this.setMarkdown)
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
setMarkdown (markdown) {
|
setMarkdown (markdown) {
|
||||||
const { editor, cursor } = this
|
const { editor, cursor } = this
|
||||||
this.editor.setValue(markdown)
|
this.editor.setValue(markdown)
|
||||||
@ -89,4 +111,11 @@
|
|||||||
.source-code .CodeMirror-activeline-gutter {
|
.source-code .CodeMirror-activeline-gutter {
|
||||||
background: #F2F6FC;
|
background: #F2F6FC;
|
||||||
}
|
}
|
||||||
|
.dark {
|
||||||
|
background: rgb(43, 43, 43);
|
||||||
|
}
|
||||||
|
.dark.source-code .CodeMirror-activeline-background,
|
||||||
|
.dark.source-code .CodeMirror-activeline-gutter {
|
||||||
|
background: #333;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="title-bar"
|
<div class="title-bar"
|
||||||
:class="{ 'active': active }"
|
:class="[{ 'active': active }, theme]"
|
||||||
>
|
>
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<span v-for="(path, index) of paths" :key="index">
|
<span v-for="(path, index) of paths" :key="index">
|
||||||
@ -37,7 +37,8 @@
|
|||||||
filename: String,
|
filename: String,
|
||||||
pathname: String,
|
pathname: String,
|
||||||
active: Boolean,
|
active: Boolean,
|
||||||
wordCount: Object
|
wordCount: Object,
|
||||||
|
theme: String
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
paths () {
|
paths () {
|
||||||
@ -122,4 +123,16 @@
|
|||||||
background: #F2F6FC;
|
background: #F2F6FC;
|
||||||
color: #606266;
|
color: #606266;
|
||||||
}
|
}
|
||||||
|
/* css for dark theme */
|
||||||
|
.dark {
|
||||||
|
background: rgb(43, 43, 43);
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
.dark .title:hover {
|
||||||
|
color: #F2F6FC;
|
||||||
|
}
|
||||||
|
.dark .word-count:hover {
|
||||||
|
background: rgb(71, 72, 66);
|
||||||
|
color: #C0C4CC;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -9,6 +9,8 @@ const state = {
|
|||||||
matches: [],
|
matches: [],
|
||||||
value: ''
|
value: ''
|
||||||
},
|
},
|
||||||
|
theme: '',
|
||||||
|
themeCSS: null,
|
||||||
typewriter: false, // typewriter mode
|
typewriter: false, // typewriter mode
|
||||||
focus: false, // focus mode
|
focus: false, // focus mode
|
||||||
sourceCode: false, // source code mode
|
sourceCode: false, // source code mode
|
||||||
@ -26,6 +28,12 @@ const state = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mutations = {
|
const mutations = {
|
||||||
|
SET_THEME (state, { theme, themeCSS }) {
|
||||||
|
state.theme = theme
|
||||||
|
if (themeCSS) {
|
||||||
|
state.themeCSS = themeCSS
|
||||||
|
}
|
||||||
|
},
|
||||||
SET_MODE (state, { type, checked }) {
|
SET_MODE (state, { type, checked }) {
|
||||||
state[type] = checked
|
state[type] = checked
|
||||||
},
|
},
|
||||||
@ -57,6 +65,13 @@ const mutations = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const actions = {
|
const actions = {
|
||||||
|
ASK_FOR_THEME ({ commit }) {
|
||||||
|
ipcRenderer.send('AGANI::ask-for-theme')
|
||||||
|
ipcRenderer.on('AGANI::theme', (e, themes) => {
|
||||||
|
console.log(themes)
|
||||||
|
commit('SET_THEME', themes)
|
||||||
|
})
|
||||||
|
},
|
||||||
SEARCH ({ commit }, value) {
|
SEARCH ({ commit }, value) {
|
||||||
commit('SET_SEARCH', value)
|
commit('SET_SEARCH', value)
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user