From 359f937ced211c2b112672766c44a22d19b055c5 Mon Sep 17 00:00:00 2001 From: tanknee Date: Wed, 11 Aug 2021 17:25:57 +0800 Subject: [PATCH 1/2] [feat]: add mind toolbar and theme loader --- package.json | 2 +- share/channels.js | 3 + src-electron/main-process/api.js | 2 +- .../assets/css/Default-Dark.dark.css | 209 +----------------- .../assets/css/Default-Light.light.css | 180 +++++++++++++++ src-electron/main-process/electron-main.js | 3 +- .../main-process/utlis/theme-manager.js | 80 +++++++ .../main-process/utlis/wiz-resource-helper.js | 6 - src/ApiInvoker.js | 15 ++ src/components/ui/MarkMapToolBar.vue | 60 +++++ src/components/ui/NoteItem.vue | 3 +- src/components/ui/dialog/SettingsDialog.vue | 96 ++++---- src/components/ui/editor/MarkMap.vue | 9 +- src/components/ui/editor/Muya.vue | 21 +- src/i18n/en-us/components/Vditor.js | 3 - src/i18n/en-us/components/index.js | 4 +- .../en-us/components/ui/MarkMapToolBar.js | 7 + .../en-us/components/ui/SettingsDialog.js | 6 +- src/i18n/en-us/components/ui/index.js | 4 +- src/i18n/en-us/other.js | 3 +- src/i18n/zh-cn/components/Vditor.js | 3 - src/i18n/zh-cn/components/index.js | 4 +- .../zh-cn/components/ui/MarkMapToolBar.js | 7 + .../zh-cn/components/ui/SettingsDialog.js | 6 +- src/i18n/zh-cn/components/ui/index.js | 4 +- src/i18n/zh-cn/other.js | 3 +- .../render/renderBlock/renderCopyButton.js | 3 +- src/libs/muya/lib/ui/frontMenu/index.css | 4 +- src/store/client/state.js | 5 +- src/store/server/actions.js | 4 + src/utils/theme.js | 20 +- 31 files changed, 453 insertions(+), 326 deletions(-) rename src/utils/themeColor.js => src-electron/main-process/assets/css/Default-Dark.dark.css (60%) create mode 100644 src-electron/main-process/assets/css/Default-Light.light.css create mode 100644 src-electron/main-process/utlis/theme-manager.js create mode 100644 src/components/ui/MarkMapToolBar.vue delete mode 100644 src/i18n/en-us/components/Vditor.js create mode 100644 src/i18n/en-us/components/ui/MarkMapToolBar.js delete mode 100644 src/i18n/zh-cn/components/Vditor.js create mode 100644 src/i18n/zh-cn/components/ui/MarkMapToolBar.js diff --git a/package.json b/package.json index fbb6b03..475d131 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cn.memocast.app", - "version": "2.1.6", + "version": "2.1.7", "description": "An Awesome WizNote Desktop Application", "productName": "Memocast", "author": "tanknee ", diff --git a/share/channels.js b/share/channels.js index 7f371a8..348d6f8 100644 --- a/share/channels.js +++ b/share/channels.js @@ -11,6 +11,9 @@ export default { remoteRequest: 'remote-request', getCacheImage: 'get-cache-image', saveTempImage: 'save-temp-image', + loadTheme: 'load-theme', + openThemeFolder: 'open-theme-folder', + refreshThemeFolder: 'refresh-theme-folder', getLocalFileData: 'get-local-file-data', saveUploadedImage: 'save-uploaded-image' } diff --git a/src-electron/main-process/api.js b/src-electron/main-process/api.js index ee25dd4..fe4f4b2 100644 --- a/src-electron/main-process/api.js +++ b/src-electron/main-process/api.js @@ -24,7 +24,7 @@ const sanitize = require('sanitize-filename') * @param {Function} api 操作函数 * @returns {Promise} */ -async function handleApi (channel, api) { +export async function handleApi (channel, api) { ipcMain.handle(channel, async (event, ...args) => { try { const ret = await api(event, ...args) diff --git a/src/utils/themeColor.js b/src-electron/main-process/assets/css/Default-Dark.dark.css similarity index 60% rename from src/utils/themeColor.js rename to src-electron/main-process/assets/css/Default-Dark.dark.css index 5509cd5..3fcdb4a 100644 --- a/src/utils/themeColor.js +++ b/src-electron/main-process/assets/css/Default-Dark.dark.css @@ -1,8 +1,4 @@ -// import oneDarkTheme from 'src/css/dark.theme.css' -// import oneDarkPrismTheme from 'src/css/prism/dark.theme.css' -// import lightTheme from 'src/css/lights.theme.css' - -const oneDarkTheme = `:root { +:root { --backgroundColor: #35373e; --editorAreaWidth: 90%; --activeItemBgColor: rgb(41, 42, 44); @@ -108,9 +104,8 @@ p:not(.ag-active)[data-role="hr"]::before { figure.ag-active.ag-container-block > div.ag-container-preview { box-shadow: 0 3px 8px 0 var(--floatShadow) !important; } -` -const oneDarkPrismTheme = `/** +/** * prism.js default theme for JavaScript, CSS and HTML * Based on dabblet (http://dabblet.com) * @author Lea Verou @@ -138,10 +133,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - #mind code { - color: inherit; - background: transparent; - } +#mind code { + color: inherit; + background: transparent; +} code[class*="language-"], pre.ag-paragraph { @@ -253,195 +248,3 @@ pre.ag-paragraph { .token.entity { cursor: help; } -` - -const lightTheme = `/* Common CSS use by both light and dark themes */ -:root { - --titleBarHeight: 32px; - --editorAreaWidth: 90%; - --backgroundColor: #ffffff; - --activeItemBgColor: rgb(204, 207, 214); - /*editor*/ - /*Theme color cluster*/ - --themeColor: rgba(25, 118, 210, 1); - --themeColor90: rgba(25, 118, 210, .9); - --themeColor80: rgba(25, 118, 210, .8); - --themeColor70: rgba(25, 118, 210, .7); - --themeColor60: rgba(25, 118, 210, .6); - --themeColor50: rgba(25, 118, 210, .5); - --themeColor40: rgba(25, 118, 210, .4); - --themeColor30: rgba(25, 118, 210, .3); - --themeColor20: rgba(25, 118, 210, .2); - --themeColor10: rgba(25, 118, 210, .1); - - --highlightColor: rgba(25, 118, 210, .4); - --selectionColor: #DAE3E9; - --editorColor: rgba(0, 0, 0, .7); - --editorColor80: rgba(0, 0, 0, .8); - --editorColor60: rgba(0, 0, 0, .6); - --editorColor50: rgba(0, 0, 0, .5); - --editorColor40: rgba(0, 0, 0, .4); - --editorColor30: rgba(0, 0, 0, .3); - --editorColor10: rgba(0, 0, 0, .1); - --editorColor04: rgba(0, 0, 0, .03); - --editorBgColor: rgba(255, 255, 255, 1); - --deleteColor: #ff6969; - --iconColor: #6B737B; - --codeBgColor: #d8d8d869; - --codeBlockBgColor: rgba(0, 0, 0, 0.03); - --inputBgColor: rgba(0, 0, 0, .06); - --buttonBgColor: #ffffff; - --buttonBorderColor: rgba(0, 0, 0, 0.2); - --buttonShadow: rgba(0, 0, 0, 0.12); - --buttonHover: #f2f2f2; - --buttonActive: #e5e5e5; - - --treeNodeColor: rgb(62, 43, 42); - --highlightThemeColor: rgb(100, 203, 154); - - /*marktext*/ - --sideBarColor: rgba(0, 0, 0, .6); - --sideBarTitleColor: rgba(0, 0, 0, 1); - --sideBarTextColor: rgba(0, 0, 0, .4); - --sideBarBgColor: rgba(242, 242, 242, 0.9); - --sideBarItemHoverBgColor: rgba(0, 0, 0, .03); - --itemBgColor: rgba(255, 255, 255, 0.6); - --floatBgColor: #fff; - --floatHoverColor: rgba(0, 0, 0, .04); - --floatBorderColor: rgba(0, 0, 0, .1); - --floatShadow: rgba(15, 15, 15, 0.03) 0px 0px 0px 1px, rgba(15, 15, 15, 0.04) 0px 3px 6px, rgba(15, 15, 15, 0.05) 0px 9px 24px; - --maskColor: rgba(255, 255, 255, .7); - --tableBorderColor: rgb(158, 158, 158); -} -` - -const lightPrismTheme = `/* - * ------------------------------------ - * Prism.js light theme - */ - - #mind code { - color: inherit; - background: transparent; - } - -code[class*="language-"], -pre.ag-paragraph { - color: black; - /*font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;*/ - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - text-shadow: none; - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; - font-family: JetBrains Mono; -} - -/* Code Fence */ -pre.ag-paragraph { - padding: 1em; - margin: 1em 0; -} - -/* Inline Code */ -:not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; - white-space: normal; -} - -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: slategray; -} - -.token.punctuation { - color: #999; -} - -.namespace { - opacity: .7; -} - -.token.property, -.token.tag, -.token.boolean, -.token.number, -.token.constant, -.token.symbol { - color: #905; -} - -.token.selector, -.token.attr-name, -.token.string, -.token.char, -.token.builtin { - color: #690; -} - -.token.inserted { - color: #22863a; - background: #f0fff4; -} - -.token.deleted { - color: #b31d28; - background: #ffeef0; -} - -.token.operator, -.token.entity, -.token.url, -.language-css .token.string, -.style .token.string { - color: #9a6e3a; -} - -.token.atrule, -.token.attr-value, -.token.keyword { - color: #07a; -} - -.token.function, -.token.class-name { - color: #DD4A68; -} - -.token.regex, -.token.important, -.token.variable { - color: #e90; -} - -.token.important, -.token.bold { - font-weight: bold; -} -.token.italic { - font-style: italic; -} - -.token.entity { - cursor: help; -} -` - -export const oneDark = () => { - return oneDarkTheme + '\n' + oneDarkPrismTheme -} - -export const light = () => { - return lightTheme + '\n' + lightPrismTheme -} diff --git a/src-electron/main-process/assets/css/Default-Light.light.css b/src-electron/main-process/assets/css/Default-Light.light.css new file mode 100644 index 0000000..3a64246 --- /dev/null +++ b/src-electron/main-process/assets/css/Default-Light.light.css @@ -0,0 +1,180 @@ +/* Common CSS use by both light and dark themes */ +:root { + --titleBarHeight: 32px; + --editorAreaWidth: 90%; + --backgroundColor: #ffffff; + --activeItemBgColor: rgb(204, 207, 214); + /*editor*/ + /*Theme color cluster*/ + --themeColor: rgba(25, 118, 210, 1); + --themeColor90: rgba(25, 118, 210, .9); + --themeColor80: rgba(25, 118, 210, .8); + --themeColor70: rgba(25, 118, 210, .7); + --themeColor60: rgba(25, 118, 210, .6); + --themeColor50: rgba(25, 118, 210, .5); + --themeColor40: rgba(25, 118, 210, .4); + --themeColor30: rgba(25, 118, 210, .3); + --themeColor20: rgba(25, 118, 210, .2); + --themeColor10: rgba(25, 118, 210, .1); + + --highlightColor: rgba(25, 118, 210, .4); + --selectionColor: #DAE3E9; + --editorColor: rgba(0, 0, 0, .7); + --editorColor80: rgba(0, 0, 0, .8); + --editorColor60: rgba(0, 0, 0, .6); + --editorColor50: rgba(0, 0, 0, .5); + --editorColor40: rgba(0, 0, 0, .4); + --editorColor30: rgba(0, 0, 0, .3); + --editorColor10: rgba(0, 0, 0, .1); + --editorColor04: rgba(0, 0, 0, .03); + --editorBgColor: rgba(255, 255, 255, 1); + --deleteColor: #ff6969; + --iconColor: #6B737B; + --codeBgColor: #d8d8d869; + --codeBlockBgColor: rgba(0, 0, 0, 0.03); + --inputBgColor: rgba(0, 0, 0, .06); + --buttonBgColor: #ffffff; + --buttonBorderColor: rgba(0, 0, 0, 0.2); + --buttonShadow: rgba(0, 0, 0, 0.12); + --buttonHover: #f2f2f2; + --buttonActive: #e5e5e5; + + --treeNodeColor: rgb(62, 43, 42); + --highlightThemeColor: rgb(100, 203, 154); + + /*marktext*/ + --sideBarColor: rgba(0, 0, 0, .6); + --sideBarTitleColor: rgba(0, 0, 0, 1); + --sideBarTextColor: rgba(0, 0, 0, .4); + --sideBarBgColor: rgba(242, 242, 242, 0.9); + --sideBarItemHoverBgColor: rgba(0, 0, 0, .03); + --itemBgColor: rgba(255, 255, 255, 0.6); + --floatBgColor: #fff; + --floatHoverColor: rgba(0, 0, 0, .04); + --floatBorderColor: rgba(0, 0, 0, .1); + --floatShadow: rgba(15, 15, 15, 0.03) 0px 0px 0px 1px, rgba(15, 15, 15, 0.04) 0px 3px 6px, rgba(15, 15, 15, 0.05) 0px 9px 24px; + --maskColor: rgba(255, 255, 255, .7); + --tableBorderColor: rgb(158, 158, 158); +} + +/* + * ------------------------------------ + * Prism.js light theme + */ + +#mind code { + color: inherit; + background: transparent; +} + +code[class*="language-"], +pre.ag-paragraph { + color: black; + /*font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;*/ + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + text-shadow: none; + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; + font-family: JetBrains Mono; +} + +/* Code Fence */ +pre.ag-paragraph { + padding: 1em; + margin: 1em 0; +} + +/* Inline Code */ +:not(pre) > code[class*="language-"] { + padding: .1em; + border-radius: .3em; + white-space: normal; +} + +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata { + color: slategray; +} + +.token.punctuation { + color: #999; +} + +.namespace { + opacity: .7; +} + +.token.property, +.token.tag, +.token.boolean, +.token.number, +.token.constant, +.token.symbol { + color: #905; +} + +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin { + color: #690; +} + +.token.inserted { + color: #22863a; + background: #f0fff4; +} + +.token.deleted { + color: #b31d28; + background: #ffeef0; +} + +.token.operator, +.token.entity, +.token.url, +.language-css .token.string, +.style .token.string { + color: #9a6e3a; +} + +.token.atrule, +.token.attr-value, +.token.keyword { + color: #07a; +} + +.token.function, +.token.class-name { + color: #DD4A68; +} + +.token.regex, +.token.important, +.token.variable { + color: #e90; +} + +.token.important, +.token.bold { + font-weight: bold; +} +.token.italic { + font-style: italic; +} + +.token.entity { + cursor: help; +} diff --git a/src-electron/main-process/electron-main.js b/src-electron/main-process/electron-main.js index 9187f3b..81e8c5c 100644 --- a/src-electron/main-process/electron-main.js +++ b/src-electron/main-process/electron-main.js @@ -9,6 +9,7 @@ import osLocale from 'os-locale' import { openNewGitHubIssue, debugInfo, enforceMacOSAppLocation } from 'electron-util' import KeyBindings from './keyboard/shortcut' import { registerMemocastProtocol } from './utlis/resource-loader' +import ThemeManager from './utlis/theme-manager' import Store from 'electron-store' import i18n from './i18n' @@ -16,7 +17,6 @@ const ClientStorage = new Store({ name: 'ClientFileStorage' }) const { registerApiHandler } = Api -// console.log(await osLocale()) osLocale().then(locale => { const cur = ClientStorage.get('language') @@ -144,6 +144,7 @@ function createWindow () { }) }) registerApiHandler() + global.themeManager = ThemeManager if (isMac) { enforceMacOSAppLocation() } diff --git a/src-electron/main-process/utlis/theme-manager.js b/src-electron/main-process/utlis/theme-manager.js new file mode 100644 index 0000000..35bce71 --- /dev/null +++ b/src-electron/main-process/utlis/theme-manager.js @@ -0,0 +1,80 @@ +import Store from 'electron-store' +import { app, shell } from 'electron' +import path from 'path' +import fs from 'fs' +import _ from 'lodash' +import { handleApi } from '../api' + +const ClientStorage = new Store({ + name: 'ClientFileStorage' +}) + +class ThemeManager { + themePath + themes = [] + constructor () { + this.themePath = path.join(app.getAppPath(), 'themes') + this.validateThemePath() + this.initThemes() + this.registerListener() + ClientStorage.set('themes', this.themes) + } + + initThemes () { + const themeNames = fs + .readdirSync(this.themePath) + .filter(v => _.endsWith(v, '.css')) + themeNames.forEach(tn => { + if (_.endsWith(tn, '.light.css')) { + this.themes.push({ + name: tn.replace('.light.css', ''), + dark: false, + fileName: tn + }) + } else if (_.endsWith(tn, '.dark.css')) { + this.themes.push({ + name: tn.replace('.dark.css', ''), + dark: true, + fileName: tn + }) + } + }) + } + + validateThemePath () { + if (!fs.existsSync(this.themePath)) { + fs.mkdirSync(this.themePath) + fs.copyFileSync( + path.resolve(__dirname, '../assets/css/Default-Dark.dark.css'), + path.join(this.themePath, 'Default-Dark.dark.css') + ) + fs.copyFileSync( + path.resolve(__dirname, '../assets/css/Default-Light.light.css'), + path.join(this.themePath, 'Default-Light.light.css') + ) + } + } + + loadThemeHandler (event, { name }) { + const theme = this.themes.find(t => t.name === name) + return fs.readFileSync(path.join(this.themePath, theme.fileName)).toString('utf-8') + } + + openThemeFolderHandler () { + shell.showItemInFolder(this.themePath) + } + + refreshThemeFolderHandler () { + this.themes = [] + this.initThemes() + return this.themes + } + + registerListener () { + handleApi('load-theme', this.loadThemeHandler.bind(this)).catch(console.error) + handleApi('open-theme-folder', this.openThemeFolderHandler.bind(this)).catch(console.error) + handleApi('refresh-theme-folder', this.refreshThemeFolderHandler.bind(this)).catch(console.error) + } +} + +export default new ThemeManager() diff --git a/src-electron/main-process/utlis/wiz-resource-helper.js b/src-electron/main-process/utlis/wiz-resource-helper.js index 839cdb4..a069cb3 100644 --- a/src-electron/main-process/utlis/wiz-resource-helper.js +++ b/src-electron/main-process/utlis/wiz-resource-helper.js @@ -1,4 +1,3 @@ -import FormData from 'form-data' import fs from 'fs' import request from 'request' import { isBase64, saveBuffer, saveFileInTempPath } from './helper' @@ -18,7 +17,6 @@ export async function uploadImagesByWiz (imagePaths, options) { const results = [] try { for (const image of imagePaths) { - const formData = new FormData() let buffer, filePath if (image instanceof Object && isBase64(image.file)) { @@ -29,10 +27,6 @@ export async function uploadImagesByWiz (imagePaths, options) { filePath = image } - formData.append('data', fs.createReadStream(filePath)) - formData.append('kbGuid', kbGuid) - formData.append('docGuid', docGuid) - const result = await postRequestAsync( `${baseUrl}/ks/resource/upload/${kbGuid}/${docGuid}`, { diff --git a/src/ApiInvoker.js b/src/ApiInvoker.js index 90811c7..379c678 100644 --- a/src/ApiInvoker.js +++ b/src/ApiInvoker.js @@ -78,6 +78,18 @@ async function saveTempImage (bundle) { return ipcRenderer.invoke(channels.saveTempImage, bundle) } +async function loadTheme (name) { + return ipcRenderer.invoke(channels.loadTheme, { name }) +} + +async function openThemeFolder () { + return ipcRenderer.invoke(channels.openThemeFolder) +} + +async function refreshThemeFolder () { + return ipcRenderer.invoke(channels.refreshThemeFolder) +} + async function getLocalFileData (filePath) { return ipcRenderer.invoke(channels.getLocalFileData, filePath) } @@ -99,6 +111,9 @@ export { remoteRequest, getCacheImage, saveTempImage, + loadTheme, + openThemeFolder, + refreshThemeFolder, getLocalFileData, saveUploadedImage } diff --git a/src/components/ui/MarkMapToolBar.vue b/src/components/ui/MarkMapToolBar.vue new file mode 100644 index 0000000..478b625 --- /dev/null +++ b/src/components/ui/MarkMapToolBar.vue @@ -0,0 +1,60 @@ + + + + + diff --git a/src/components/ui/NoteItem.vue b/src/components/ui/NoteItem.vue index 68b96fd..0abf526 100644 --- a/src/components/ui/NoteItem.vue +++ b/src/components/ui/NoteItem.vue @@ -120,7 +120,8 @@ export default { message: this.$t('discardNoteHint') }).onOk(() => this.getNoteContent({ docGuid: this.docGuid })) } else { - this.getNoteContent({ docGuid: this.docGuid }) + console.time('NoteLoadTime') + this.getNoteContent({ docGuid: this.docGuid }).then(() => console.timeEnd('NoteLoadTime')) } }, ...mapServerActions(['getNoteContent', 'updateNoteInfo']) diff --git a/src/components/ui/dialog/SettingsDialog.vue b/src/components/ui/dialog/SettingsDialog.vue index b75039c..d95de21 100644 --- a/src/components/ui/dialog/SettingsDialog.vue +++ b/src/components/ui/dialog/SettingsDialog.vue @@ -64,18 +64,19 @@
- {{ $t('darkMode') }} - + {{ $t('theme') }}
+ + +
@@ -145,31 +146,9 @@ :options='imageUploadServiceOptions' @input='imageUploadServiceChangeHandler' > -
-
-
- {{ $t('flomo') }} - -
-
@@ -189,7 +168,7 @@ import { i18n } from 'boot/i18n' import bus from 'components/bus' import events from 'src/constants/events' import { version } from '../../../../package.json' -import { needUpdate } from 'src/ApiInvoker' +import { needUpdate, openThemeFolder, refreshThemeFolder } from 'src/ApiInvoker' import helper from 'src/utils/helper' const { @@ -209,8 +188,6 @@ export default { splitterModel: 20, imageUploadServiceOptionsPlain: [ 'wizOfficialImageUploadService', - // 'customWebUploadService', - // 'smmsImageUploadService' 'picgoServer', 'none' ], @@ -226,11 +203,12 @@ export default { languageOptions: function () { return i18n.availableLocales.map(l => i18n.t(l)) }, + themeOptions: function () { + return this.themes.map(t => i18n.t(t.name)) + }, imageUploadServiceOptions: function () { return [ this.$t('wizOfficialImageUploadService'), - // this.$t('customWebUploadService'), - // this.$t('smmsImageUploadService') this.$t('picgoServer'), this.$t('none') ] @@ -247,8 +225,9 @@ export default { 'noteListDenseMode', 'markdownOnly', 'imageUploadService', - 'flomoApiUrl', - 'noteOrderType' + 'noteOrderType', + 'theme', + 'themes' ]) }, methods: { @@ -267,6 +246,14 @@ export default { icon: 'info' }) }, + themeChangeHandler: function (theme) { + theme = this.themes.find(t => { + return i18n.t(t.name) === theme + }) + this.updateStateAndStore({ theme: theme.name }) + this.$q.dark.set(theme.dark) + this.toggleChanged({ key: 'darkMode', value: theme.dark }) + }, imageUploadServiceChangeHandler: function (service) { const servicePlain = this.imageUploadServiceOptionsPlain.find( i => this.$t(i) === service @@ -294,6 +281,16 @@ export default { }) }) }, + openThemeFolderHandler: function () { + openThemeFolder() + }, + refreshThemeFolderHandler: async function () { + const themes = await refreshThemeFolder() + this.toggleChanged({ key: 'themes', value: themes }) + }, + themeHelpHandler: function () { + this.$q.electron.shell.openExternal('https://www.tanknee.cn/Memocast/docs/tutorial-development/create-theme') + }, updateAvailableHandler: function (info) { console.log(info) if (this.checkingNotify && this.checkingNotify instanceof Function) { @@ -348,25 +345,6 @@ export default { }) } }, - flomoSettingHandler: async function () { - this.$q.dialog({ - prompt: { - model: this.flomoApiUrl - }, - title: this.$t('flomo'), - ok: { - label: this.$t('submit') - }, - cancel: { - label: this.$t('cancel') - } - }).onOk(data => { - this.updateStateAndStore({ flomoApiUrl: data }) - }) - // this.$q.electron.shell.openExternal( - // 'https://flomoapp.com/mine?source=incoming_webhook' - // ) - }, ...mapActions([ 'toggleChanged', 'updateStateAndStore', diff --git a/src/components/ui/editor/MarkMap.vue b/src/components/ui/editor/MarkMap.vue index 6325d90..22caa27 100644 --- a/src/components/ui/editor/MarkMap.vue +++ b/src/components/ui/editor/MarkMap.vue @@ -1,9 +1,10 @@ @@ -14,6 +15,7 @@ import * as markmap from 'markmap-view' import { showContextMenu as showMarkMapContextMenu } from 'src/contextMenu/markMap' import bus from '../../bus' import events from '../../../constants/events' +import MarkMapToolBar from '../MarkMapToolBar' const transformer = new Transformer() const { Markmap, loadJS } = markmap @@ -24,6 +26,7 @@ const { export default { name: 'MarkMap', + components: { MarkMapToolBar }, props: { data: { type: String, @@ -47,6 +50,10 @@ export default { if (this.markMap) this.markMap.destroy() const svgEl = document.querySelector('#mind') this.markMap = Markmap.create(svgEl, null, root) + + this.$refs.markMapToolBar.setMarkMap(this.markMap) + const containerEl = document.querySelector('#mind-container') + this.$refs.markMapToolBar.setContainer(containerEl) }, contextMenuHandler: function (e) { showMarkMapContextMenu(e) diff --git a/src/components/ui/editor/Muya.vue b/src/components/ui/editor/Muya.vue index 2e1bcf1..9cb6925 100644 --- a/src/components/ui/editor/Muya.vue +++ b/src/components/ui/editor/Muya.vue @@ -68,7 +68,7 @@ export default { }, ...mapServerState(['isCurrentNoteLoading', 'contentsList']), ...mapServerGetters(['currentNote', 'uploadImageUrl', 'currentNoteResources', 'currentNoteResourceUrl']), - ...mapClientState(['darkMode', 'enablePreviewEditor']) + ...mapClientState(['darkMode', 'enablePreviewEditor', 'theme']) }, methods: { getValue: function () { @@ -223,11 +223,12 @@ export default { imageAction: this.uploadImage }) - if (this.darkMode) { - attachThemeColor('one-dark') - } else { - attachThemeColor('light') - } + attachThemeColor(this.theme) + // if (this.darkMode) { + // attachThemeColor('one-dark') + // } else { + // attachThemeColor('light') + // } this.contentEditor.on('muya-click', (event) => { if (event.target.type === 'checkbox') { @@ -321,12 +322,8 @@ export default { debugLogger.Error(e, e.message) } }, - darkMode: function (mode) { - if (mode) { - attachThemeColor('one-dark') - } else { - attachThemeColor('light') - } + theme: function (t) { + attachThemeColor(t) }, enablePreviewEditor: function (val) { document.querySelector('.ag-show-quick-insert-hint').setAttribute('contenteditable', val) diff --git a/src/i18n/en-us/components/Vditor.js b/src/i18n/en-us/components/Vditor.js deleted file mode 100644 index 985fd0f..0000000 --- a/src/i18n/en-us/components/Vditor.js +++ /dev/null @@ -1,3 +0,0 @@ -export default { - showNoteTimeout: 'Show Note Timeout' -} diff --git a/src/i18n/en-us/components/index.js b/src/i18n/en-us/components/index.js index 31a2b06..1a518b1 100644 --- a/src/i18n/en-us/components/index.js +++ b/src/i18n/en-us/components/index.js @@ -1,10 +1,8 @@ import ui from './ui' import Header from 'src/i18n/en-us/components/Header' import NoteList from 'src/i18n/en-us/components/NoteList' -import Vditor from 'src/i18n/en-us/components/Vditor' export default { ...ui, ...Header, - ...NoteList, - ...Vditor + ...NoteList } diff --git a/src/i18n/en-us/components/ui/MarkMapToolBar.js b/src/i18n/en-us/components/ui/MarkMapToolBar.js new file mode 100644 index 0000000..558bf37 --- /dev/null +++ b/src/i18n/en-us/components/ui/MarkMapToolBar.js @@ -0,0 +1,7 @@ +export default { + zoomIn: 'Zoom In', + zoomOut: 'Zoom Out', + fitScreen: 'Fit Screen', + fullscreen: 'Fullscreen', + fullscreenExit: 'Exit Fullscreen' +} diff --git a/src/i18n/en-us/components/ui/SettingsDialog.js b/src/i18n/en-us/components/ui/SettingsDialog.js index 2f2226a..b9f478d 100644 --- a/src/i18n/en-us/components/ui/SettingsDialog.js +++ b/src/i18n/en-us/components/ui/SettingsDialog.js @@ -24,7 +24,7 @@ export default { checking: 'Checking', noNewerVersion: 'This is the latest version!', updateError: 'Fail to update', - codeTheme: 'Code Theme', - lightCodeTheme: 'Light Mode Code Theme', - darkCodeTheme: 'Dark Mode Code Theme' + theme: 'Theme', + 'Default-Dark': 'Default Dark', + 'Default-Light': 'Default Light' } diff --git a/src/i18n/en-us/components/ui/index.js b/src/i18n/en-us/components/ui/index.js index 27a0433..46e9301 100644 --- a/src/i18n/en-us/components/ui/index.js +++ b/src/i18n/en-us/components/ui/index.js @@ -14,6 +14,7 @@ import TableTools from 'src/i18n/en-us/components/ui/TableTools' import RenderToolBar from 'src/i18n/en-us/components/ui/RenderToolBar' import RenderLeafBlock from 'src/i18n/en-us/components/ui/RenderLeafBlock' import UpdateDialog from 'src/i18n/en-us/components/ui/UpdateDialog' +import MarkMapToolBar from 'src/i18n/en-us/components/ui/MarkMapToolBar' export default { ...LoginDialog, ...SettingsDialog, @@ -30,5 +31,6 @@ export default { ...TableTools, ...RenderToolBar, ...RenderLeafBlock, - ...UpdateDialog + ...UpdateDialog, + ...MarkMapToolBar } diff --git a/src/i18n/en-us/other.js b/src/i18n/en-us/other.js index 93564f5..423e182 100644 --- a/src/i18n/en-us/other.js +++ b/src/i18n/en-us/other.js @@ -16,5 +16,6 @@ export default { wordCount: 'Word Count', 'word:': 'Words: {word}', 'paragraph:': 'Paragraph: {paragraph}', - 'character:': 'Characters: {character}' + 'character:': 'Characters: {character}', + copyContent: 'Copy Content' } diff --git a/src/i18n/zh-cn/components/Vditor.js b/src/i18n/zh-cn/components/Vditor.js deleted file mode 100644 index e7317b6..0000000 --- a/src/i18n/zh-cn/components/Vditor.js +++ /dev/null @@ -1,3 +0,0 @@ -export default { - showNoteTimeout: '加载笔记超时' -} diff --git a/src/i18n/zh-cn/components/index.js b/src/i18n/zh-cn/components/index.js index af5dd75..f063358 100644 --- a/src/i18n/zh-cn/components/index.js +++ b/src/i18n/zh-cn/components/index.js @@ -1,10 +1,8 @@ import ui from './ui' import Header from 'src/i18n/zh-cn/components/Header' import NoteList from 'src/i18n/zh-cn/components/NoteList' -import Vditor from 'src/i18n/zh-cn/components/Vditor' export default { ...ui, ...Header, - ...NoteList, - ...Vditor + ...NoteList } diff --git a/src/i18n/zh-cn/components/ui/MarkMapToolBar.js b/src/i18n/zh-cn/components/ui/MarkMapToolBar.js new file mode 100644 index 0000000..a3564f5 --- /dev/null +++ b/src/i18n/zh-cn/components/ui/MarkMapToolBar.js @@ -0,0 +1,7 @@ +export default { + zoomIn: '放大', + zoomOut: '缩小', + fitScreen: '适配屏幕大小', + fullscreen: '全屏', + fullscreenExit: '退出全屏' +} diff --git a/src/i18n/zh-cn/components/ui/SettingsDialog.js b/src/i18n/zh-cn/components/ui/SettingsDialog.js index 2d7ab5b..ee1a56f 100644 --- a/src/i18n/zh-cn/components/ui/SettingsDialog.js +++ b/src/i18n/zh-cn/components/ui/SettingsDialog.js @@ -24,7 +24,7 @@ export default { checking: '检查更新中', noNewerVersion: '当前已是最新版本 !', updateError: '更新失败', - codeTheme: '代码主题', - lightCodeTheme: '日间模式代码主题', - darkCodeTheme: '暗黑模式代码主题' + theme: '主题', + 'Default-Dark': '默认暗色主题', + 'Default-Light': '默认亮色主题' } diff --git a/src/i18n/zh-cn/components/ui/index.js b/src/i18n/zh-cn/components/ui/index.js index cfcff80..c1dd63c 100644 --- a/src/i18n/zh-cn/components/ui/index.js +++ b/src/i18n/zh-cn/components/ui/index.js @@ -14,6 +14,7 @@ import TableTools from 'src/i18n/zh-cn/components/ui/TableTools' import RenderToolBar from 'src/i18n/zh-cn/components/ui/RenderToolBar' import RenderLeafBlock from 'src/i18n/zh-cn/components/ui/RenderLeafBlock' import UpdateDialog from 'src/i18n/zh-cn/components/ui/UpdateDialog' +import MarkMapToolBar from 'src/i18n/zh-cn/components/ui/MarkMapToolBar' export default { ...LoginDialog, ...SettingsDialog, @@ -30,5 +31,6 @@ export default { ...TableTools, ...RenderToolBar, ...RenderLeafBlock, - ...UpdateDialog + ...UpdateDialog, + ...MarkMapToolBar } diff --git a/src/i18n/zh-cn/other.js b/src/i18n/zh-cn/other.js index de3c1e7..c859caa 100644 --- a/src/i18n/zh-cn/other.js +++ b/src/i18n/zh-cn/other.js @@ -16,5 +16,6 @@ export default { wordCount: '字数统计', 'word:': '词: {word}', 'paragraph:': '段落: {paragraph}', - 'character:': '字符: {character}' + 'character:': '字符: {character}', + copyContent: '复制内容' } diff --git a/src/libs/muya/lib/parser/render/renderBlock/renderCopyButton.js b/src/libs/muya/lib/parser/render/renderBlock/renderCopyButton.js index c24e8d5..ee48f6c 100644 --- a/src/libs/muya/lib/parser/render/renderBlock/renderCopyButton.js +++ b/src/libs/muya/lib/parser/render/renderBlock/renderCopyButton.js @@ -1,5 +1,6 @@ import { h } from '../snabbdom' import copyIcon from '../../../assets/pngicon/copy/2.png' +import { i18n } from 'boot/i18n' const renderCopyButton = () => { const selector = 'a.ag-code-copy' @@ -12,7 +13,7 @@ const renderCopyButton = () => { return h(selector, { attrs: { - title: 'Copy content', + title: i18n.t('copyContent'), contenteditable: 'false' } }, iconVnode) diff --git a/src/libs/muya/lib/ui/frontMenu/index.css b/src/libs/muya/lib/ui/frontMenu/index.css index 28b07ae..2ee1da1 100644 --- a/src/libs/muya/lib/ui/frontMenu/index.css +++ b/src/libs/muya/lib/ui/frontMenu/index.css @@ -52,7 +52,7 @@ display: inline-block; width: 100%; height: 100%; - filter: drop-shadow(16px 0 currentColor); + filter: drop-shadow(16px 0 currentColor); position: relative; left: -16px; } @@ -74,7 +74,7 @@ } .ag-front-menu .submenu { - width: 190px; + width: 210px; max-height: 300px; position: absolute; left: calc(100% + 3px); diff --git a/src/store/client/state.js b/src/store/client/state.js index be601d0..e098228 100644 --- a/src/store/client/state.js +++ b/src/store/client/state.js @@ -17,9 +17,10 @@ export default function () { customBody: '', shrinkInTray: false, noteListVisible: true, - flomoApiUrl: '', enablePreviewEditor: true, rightClickNoteItem: {}, - rightClickCategoryItem: '' + rightClickCategoryItem: '', + theme: 'Default-Light', + themes: [] } } diff --git a/src/store/server/actions.js b/src/store/server/actions.js index 83dd197..593e1f5 100644 --- a/src/store/server/actions.js +++ b/src/store/server/actions.js @@ -18,6 +18,7 @@ import html2canvas from 'html2canvas' import debugLogger from 'src/utils/debugLogger' export async function _getContent (kbGuid, docGuid) { + console.time('FetchNote') const { info } = await api.KnowledgeBaseApi.getNoteContent({ kbGuid, docGuid, @@ -25,6 +26,7 @@ export async function _getContent (kbGuid, docGuid) { downloadInfo: 1 } }) + console.timeEnd('FetchNote') const cacheKey = api.KnowledgeBaseApi.getCacheKey(kbGuid, docGuid) const note = ClientFileStorage.getCachedNote(info, cacheKey) let result @@ -246,7 +248,9 @@ export default { // }) const { kbGuid } = state const { docGuid } = payload + console.time('GetContent') const result = await _getContent(kbGuid, docGuid) + console.timeEnd('GetContent') Loading.hide() commit(types.UPDATE_CURRENT_NOTE_LOADING_STATE, false) commit(types.UPDATE_CURRENT_NOTE, result) diff --git a/src/utils/theme.js b/src/utils/theme.js index 5a2b222..834c101 100644 --- a/src/utils/theme.js +++ b/src/utils/theme.js @@ -1,7 +1,7 @@ -import { oneDark, light } from 'src/utils/themeColor' +import { loadTheme } from 'src/ApiInvoker' -export const railscastsThemes = ['dark', 'material-dark'] -export const oneDarkThemes = ['one-dark'] +export const railscastsThemes = ['Default-Dark'] +export const oneDarkThemes = ['Default-Dark'] const patchTheme = css => { return `@media not print {\n${css}\n}` @@ -17,17 +17,9 @@ export function attachThemeColor (theme) { themeStyleEle.id = 'ag-theme' document.head.appendChild(themeStyleEle) } - - switch (theme) { - case 'one-dark': { - themeStyleEle.innerHTML = patchTheme(oneDark()) - break - } - case 'light' : { - themeStyleEle.innerHTML = patchTheme(light()) - break - } - } + loadTheme(theme).then((themeSource) => { + themeStyleEle.innerHTML = patchTheme(themeSource) + }) document.body.classList.remove('dark') if (isDarkTheme) { From d4b53915fdd6e99a46fb912cde1cf33ca7d595e5 Mon Sep 17 00:00:00 2001 From: tanknee Date: Wed, 11 Aug 2021 17:36:45 +0800 Subject: [PATCH 2/2] [readme]: add document address --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e325d9c..5bc12fa 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@
AppIcon

Memocast

- + ![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/TankNee/Neeto-Vue/Neeto-Vue%20Release%20Action/master?label=REALSE%20ACTION&style=for-the-badge) ![GitHub Releases](https://img.shields.io/github/downloads/TankNee/Neeto-Vue/latest/total?style=for-the-badge) ![GitHub All Releases](https://img.shields.io/github/downloads/TankNee/Neeto-Vue/total?style=for-the-badge) ![GitHub Release Date](https://img.shields.io/github/release-date/TankNee/Neeto-Vue?style=for-the-badge) ![GitHub repo size](https://img.shields.io/github/repo-size/TankNee/Neeto-Vue?style=for-the-badge) ![GitHub](https://img.shields.io/github/license/TankNee/Neeto-Vue?style=for-the-badge)
@@ -13,13 +13,19 @@
Memocast - an awesome wiznote client, online note. | Product Hunt
- + ## Download 你可以在 GitHub 的 Release 页面下载最新版本,与此同时,你也可以使用内置的更新按钮获取最新版本,注意 mac 并不支持直接使用内置更新,因为受限于 macOS 的安全策略,所有自动安装的应用应该被有效地签名。 GitHub Release:[Releases · TankNee/Memocast · GitHub](https://github.com/TankNee/Memocast/releases) +## Documentation + +你可以在 Memocast 的文档中找到与软件相关的实用用法与介绍。 + +文档地址:https://www.tanknee.cn/Memocast/ + ## Feature 1. 较为完整的为知服务的支持。