mirror of
https://github.com/heyman/heynote.git
synced 2024-11-26 01:44:05 +01:00
Settings improvements (#88)
* Organize Settings in different tabs * Add setting for turning off/on auto updates. * Remove debug log * Use a better variable name (systemTheme -> themeSetting) * Store theme setting for Heynote webapp in local storage
This commit is contained in:
parent
77ed45cfa2
commit
6022356478
@ -25,6 +25,7 @@ const schema = {
|
|||||||
"emacsMetaKey": { "enum": [null, "alt", "meta"], default: null },
|
"emacsMetaKey": { "enum": [null, "alt", "meta"], default: null },
|
||||||
"showLineNumberGutter": {type: "boolean", default:true},
|
"showLineNumberGutter": {type: "boolean", default:true},
|
||||||
"showFoldGutter": {type: "boolean", default:true},
|
"showFoldGutter": {type: "boolean", default:true},
|
||||||
|
"autoUpdate": {type: "boolean", default: true},
|
||||||
"allowBetaVersions": {type: "boolean", default: false},
|
"allowBetaVersions": {type: "boolean", default: false},
|
||||||
"enableGlobalHotkey": {type: "boolean", default: false},
|
"enableGlobalHotkey": {type: "boolean", default: false},
|
||||||
"globalHotkey": {type: "string", default: "CmdOrCtrl+Shift+H"},
|
"globalHotkey": {type: "string", default: "CmdOrCtrl+Shift+H"},
|
||||||
@ -49,6 +50,7 @@ const defaults = {
|
|||||||
emacsMetaKey: "meta",
|
emacsMetaKey: "meta",
|
||||||
showLineNumberGutter: true,
|
showLineNumberGutter: true,
|
||||||
showFoldGutter: true,
|
showFoldGutter: true,
|
||||||
|
autoUpdate: true,
|
||||||
allowBetaVersions: false,
|
allowBetaVersions: false,
|
||||||
enableGlobalHotkey: false,
|
enableGlobalHotkey: false,
|
||||||
globalHotkey: "CmdOrCtrl+Shift+H",
|
globalHotkey: "CmdOrCtrl+Shift+H",
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
languageAuto: true,
|
languageAuto: true,
|
||||||
theme: window.heynote.themeMode.initial,
|
theme: window.heynote.themeMode.initial,
|
||||||
initialTheme: window.heynote.themeMode.initial,
|
initialTheme: window.heynote.themeMode.initial,
|
||||||
systemTheme: 'system',
|
themeSetting: 'system',
|
||||||
development: window.location.href.indexOf("dev=1") !== -1,
|
development: window.location.href.indexOf("dev=1") !== -1,
|
||||||
showLanguageSelector: false,
|
showLanguageSelector: false,
|
||||||
showSettings: false,
|
showSettings: false,
|
||||||
@ -32,7 +32,7 @@
|
|||||||
mounted() {
|
mounted() {
|
||||||
window.heynote.themeMode.get().then((mode) => {
|
window.heynote.themeMode.get().then((mode) => {
|
||||||
this.theme = mode.computed
|
this.theme = mode.computed
|
||||||
this.systemTheme = mode.theme
|
this.themeSetting = mode.theme
|
||||||
})
|
})
|
||||||
const onThemeChange = (theme) => {
|
const onThemeChange = (theme) => {
|
||||||
this.theme = theme
|
this.theme = theme
|
||||||
@ -69,12 +69,12 @@
|
|||||||
let newTheme
|
let newTheme
|
||||||
// when the "system" theme is used, make sure that the first click always results in amn actual theme change
|
// when the "system" theme is used, make sure that the first click always results in amn actual theme change
|
||||||
if (this.initialTheme === "light") {
|
if (this.initialTheme === "light") {
|
||||||
newTheme = this.systemTheme === "system" ? "dark" : (this.systemTheme === "dark" ? "light" : "system")
|
newTheme = this.themeSetting === "system" ? "dark" : (this.themeSetting === "dark" ? "light" : "system")
|
||||||
} else {
|
} else {
|
||||||
newTheme = this.systemTheme === "system" ? "light" : (this.systemTheme === "light" ? "dark" : "system")
|
newTheme = this.themeSetting === "system" ? "light" : (this.themeSetting === "light" ? "dark" : "system")
|
||||||
}
|
}
|
||||||
window.heynote.themeMode.set(newTheme)
|
window.heynote.themeMode.set(newTheme)
|
||||||
this.systemTheme = newTheme
|
this.themeSetting = newTheme
|
||||||
this.$refs.editor.focus()
|
this.$refs.editor.focus()
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -129,7 +129,8 @@
|
|||||||
:language="language"
|
:language="language"
|
||||||
:languageAuto="languageAuto"
|
:languageAuto="languageAuto"
|
||||||
:theme="theme"
|
:theme="theme"
|
||||||
:systemTheme="systemTheme"
|
:themeSetting="themeSetting"
|
||||||
|
:autoUpdate="settings.autoUpdate"
|
||||||
:allowBetaVersions="settings.allowBetaVersions"
|
:allowBetaVersions="settings.allowBetaVersions"
|
||||||
@toggleTheme="toggleTheme"
|
@toggleTheme="toggleTheme"
|
||||||
@openLanguageSelector="openLanguageSelector"
|
@openLanguageSelector="openLanguageSelector"
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
"language",
|
"language",
|
||||||
"languageAuto",
|
"languageAuto",
|
||||||
"theme",
|
"theme",
|
||||||
"systemTheme",
|
"themeSetting",
|
||||||
|
"autoUpdate",
|
||||||
"allowBetaVersions",
|
"allowBetaVersions",
|
||||||
],
|
],
|
||||||
|
|
||||||
@ -84,9 +85,13 @@
|
|||||||
>
|
>
|
||||||
<span class="icon icon-format"></span>
|
<span class="icon icon-format"></span>
|
||||||
</div>
|
</div>
|
||||||
<UpdateStatusItem v-if="updatesEnabled" :allowBetaVersions="allowBetaVersions" />
|
<UpdateStatusItem
|
||||||
|
v-if="updatesEnabled"
|
||||||
|
:autoUpdate="autoUpdate"
|
||||||
|
:allowBetaVersions="allowBetaVersions"
|
||||||
|
/>
|
||||||
<div class="status-block theme clickable" @click="$emit('toggleTheme')" title="Toggle dark/light mode">
|
<div class="status-block theme clickable" @click="$emit('toggleTheme')" title="Toggle dark/light mode">
|
||||||
<span :class="'icon ' + systemTheme"></span>
|
<span :class="'icon ' + themeSetting"></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: [
|
props: [
|
||||||
|
"autoUpdate",
|
||||||
"allowBetaVersions",
|
"allowBetaVersions",
|
||||||
],
|
],
|
||||||
|
|
||||||
@ -16,7 +17,6 @@
|
|||||||
total: 0.0,
|
total: 0.0,
|
||||||
bytesPerSecond: 0.0,
|
bytesPerSecond: 0.0,
|
||||||
},
|
},
|
||||||
|
|
||||||
checkForUpdateIntervalId: null,
|
checkForUpdateIntervalId: null,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -50,14 +50,6 @@
|
|||||||
this.updateProgress = progress
|
this.updateProgress = progress
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// check for update now
|
|
||||||
this.checkForUpdate()
|
|
||||||
|
|
||||||
// check for updates every 8 hours
|
|
||||||
this.checkForUpdateIntervalId = setInterval(() => {
|
|
||||||
this.checkForUpdate()
|
|
||||||
}, 1000 * 3600 * 8)
|
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
@ -67,11 +59,27 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
allowBetaVersions: {
|
autoUpdate: {
|
||||||
handler: function (newValue) {
|
immediate: true,
|
||||||
|
handler(autoUpdate) {
|
||||||
|
if (this.checkForUpdateIntervalId) {
|
||||||
|
clearInterval(this.checkForUpdateIntervalId)
|
||||||
|
}
|
||||||
|
if (autoUpdate) {
|
||||||
|
// check for update now
|
||||||
|
this.checkForUpdate()
|
||||||
|
|
||||||
|
// check for updates every 8 hours
|
||||||
|
this.checkForUpdateIntervalId = setInterval(() => {
|
||||||
|
this.checkForUpdate()
|
||||||
|
}, 1000 * 3600 * 8)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
allowBetaVersions(newValue) {
|
||||||
this.checkForUpdate()
|
this.checkForUpdate()
|
||||||
},
|
},
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import KeyboardHotkey from "./KeyboardHotkey.vue"
|
import KeyboardHotkey from "./KeyboardHotkey.vue"
|
||||||
|
import TabListItem from "./TabListItem.vue"
|
||||||
|
import TabContent from "./TabContent.vue"
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@ -8,6 +10,8 @@
|
|||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
KeyboardHotkey,
|
KeyboardHotkey,
|
||||||
|
TabListItem,
|
||||||
|
TabContent,
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
@ -24,6 +28,9 @@
|
|||||||
allowBetaVersions: this.initialSettings.allowBetaVersions,
|
allowBetaVersions: this.initialSettings.allowBetaVersions,
|
||||||
enableGlobalHotkey: this.initialSettings.enableGlobalHotkey,
|
enableGlobalHotkey: this.initialSettings.enableGlobalHotkey,
|
||||||
globalHotkey: this.initialSettings.globalHotkey,
|
globalHotkey: this.initialSettings.globalHotkey,
|
||||||
|
autoUpdate: this.initialSettings.autoUpdate,
|
||||||
|
|
||||||
|
activeTab: "general",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -51,8 +58,9 @@
|
|||||||
allowBetaVersions: this.allowBetaVersions,
|
allowBetaVersions: this.allowBetaVersions,
|
||||||
enableGlobalHotkey: this.enableGlobalHotkey,
|
enableGlobalHotkey: this.enableGlobalHotkey,
|
||||||
globalHotkey: this.globalHotkey,
|
globalHotkey: this.globalHotkey,
|
||||||
|
autoUpdate: this.autoUpdate,
|
||||||
})
|
})
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@ -61,7 +69,31 @@
|
|||||||
<div class="settings">
|
<div class="settings">
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
|
<nav class="sidebar">
|
||||||
<h1>Settings</h1>
|
<h1>Settings</h1>
|
||||||
|
<ul>
|
||||||
|
<TabListItem
|
||||||
|
name="General"
|
||||||
|
tab="general"
|
||||||
|
:activeTab="activeTab"
|
||||||
|
@click="activeTab = 'general'"
|
||||||
|
/>
|
||||||
|
<TabListItem
|
||||||
|
name="Appearance"
|
||||||
|
tab="appearance"
|
||||||
|
:activeTab="activeTab"
|
||||||
|
@click="activeTab = 'appearance'"
|
||||||
|
/>
|
||||||
|
<TabListItem
|
||||||
|
name="Updates"
|
||||||
|
tab="updates"
|
||||||
|
:activeTab="activeTab"
|
||||||
|
@click="activeTab = 'updates'"
|
||||||
|
/>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
<div class="settings-content">
|
||||||
|
<TabContent tab="general" :activeTab="activeTab">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<h2>Keymap</h2>
|
<h2>Keymap</h2>
|
||||||
@ -79,6 +111,28 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="entry">
|
||||||
|
<h2>Global Keyboard Shortcut</h2>
|
||||||
|
<label class="keyboard-shortcut-label">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
v-model="enableGlobalHotkey"
|
||||||
|
@change="updateSettings"
|
||||||
|
/>
|
||||||
|
Enable Global Hotkey
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<KeyboardHotkey
|
||||||
|
:disabled="!enableGlobalHotkey"
|
||||||
|
v-model="globalHotkey"
|
||||||
|
@change="updateSettings"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TabContent>
|
||||||
|
|
||||||
|
<TabContent tab="appearance" :activeTab="activeTab">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<h2>Gutters</h2>
|
<h2>Gutters</h2>
|
||||||
@ -101,23 +155,20 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</TabContent>
|
||||||
|
|
||||||
|
<TabContent tab="updates" :activeTab="activeTab">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<h2>Global Keyboard Shortcut</h2>
|
<h2>Auto Update</h2>
|
||||||
<label class="keyboard-shortcut-label">
|
<label>
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
v-model="enableGlobalHotkey"
|
v-model="autoUpdate"
|
||||||
@change="updateSettings"
|
@change="updateSettings"
|
||||||
/>
|
/>
|
||||||
Enable Global Hotkey
|
Periodically check for new updates
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<KeyboardHotkey
|
|
||||||
:disabled="!enableGlobalHotkey"
|
|
||||||
v-model="globalHotkey"
|
|
||||||
@change="updateSettings"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
@ -133,6 +184,8 @@
|
|||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</TabContent>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bottom-bar">
|
<div class="bottom-bar">
|
||||||
@ -190,12 +243,24 @@
|
|||||||
box-shadow: 0 0 25px rgba(0, 0, 0, 0.3)
|
box-shadow: 0 0 25px rgba(0, 0, 0, 0.3)
|
||||||
.dialog-content
|
.dialog-content
|
||||||
flex-grow: 1
|
flex-grow: 1
|
||||||
padding: 40px
|
display: flex
|
||||||
|
.sidebar
|
||||||
|
box-sizing: border-box
|
||||||
|
width: 140px
|
||||||
|
border-right: 1px solid #eee
|
||||||
|
padding-top: 20px
|
||||||
|
+dark-mode
|
||||||
|
border-right: 1px solid #222
|
||||||
h1
|
h1
|
||||||
font-size: 20px
|
font-size: 16px
|
||||||
font-weight: 600
|
font-weight: 700
|
||||||
margin-bottom: 20px
|
margin-bottom: 20px
|
||||||
|
padding: 0 20px
|
||||||
|
margin-bottom: 20px
|
||||||
|
.settings-content
|
||||||
|
flex-grow: 1
|
||||||
|
padding: 40px
|
||||||
|
overflow-y: auto
|
||||||
.row
|
.row
|
||||||
display: flex
|
display: flex
|
||||||
.entry
|
.entry
|
||||||
|
24
src/components/settings/TabContent.vue
Normal file
24
src/components/settings/TabContent.vue
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ["tab", "activeTab"],
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
className() {
|
||||||
|
return "tab-content " + (this.tab === this.activeTab ? "active" : "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div :class="className">
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="sass">
|
||||||
|
.tab-content
|
||||||
|
display: none
|
||||||
|
&.active
|
||||||
|
display: block
|
||||||
|
</style>
|
34
src/components/settings/TabListItem.vue
Normal file
34
src/components/settings/TabListItem.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ["tab", "activeTab", "name"],
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
tabClass() {
|
||||||
|
return this.tab === this.activeTab ? "active" : ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<li :class="tabClass">{{ name }}</li>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped lang="sass">
|
||||||
|
li
|
||||||
|
padding: 9px 20px
|
||||||
|
font-size: 13px
|
||||||
|
user-select: none
|
||||||
|
cursor: pointer
|
||||||
|
&:hover
|
||||||
|
background: #f1f1f1
|
||||||
|
+dark-mode
|
||||||
|
background: #292929
|
||||||
|
&.active
|
||||||
|
background: #48b57e
|
||||||
|
color: #fff
|
||||||
|
cursor: default
|
||||||
|
+dark-mode
|
||||||
|
background: #1b6540
|
||||||
|
|
||||||
|
</style>
|
@ -1,5 +1,3 @@
|
|||||||
=dark-mode()
|
=dark-mode()
|
||||||
@media (prefers-color-scheme: dark)
|
|
||||||
@content
|
|
||||||
body[theme=dark] &
|
body[theme=dark] &
|
||||||
@content
|
@content
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
const mediaMatch = window.matchMedia('(prefers-color-scheme: dark)')
|
const mediaMatch = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
let themeModeChangeListener = null
|
|
||||||
let autoUpdateCallbacks = null
|
|
||||||
let themeCallback = null
|
let themeCallback = null
|
||||||
|
mediaMatch.addEventListener("change", async (event) => {
|
||||||
|
if (themeCallback) {
|
||||||
|
themeCallback((await Heynote.themeMode.get()).computed)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let autoUpdateCallbacks = null
|
||||||
let currencyData = null
|
let currencyData = null
|
||||||
|
|
||||||
export default {
|
const Heynote = {
|
||||||
platform: {
|
platform: {
|
||||||
isMac: true,
|
isMac: true,
|
||||||
isWindows: false,
|
isWindows: false,
|
||||||
@ -41,27 +45,25 @@ export default {
|
|||||||
|
|
||||||
themeMode: {
|
themeMode: {
|
||||||
set: (mode) => {
|
set: (mode) => {
|
||||||
|
localStorage.setItem("theme", mode)
|
||||||
themeCallback(mode)
|
themeCallback(mode)
|
||||||
document.body.setAttribute("theme", mode === "dark" ? "dark" : "light")
|
console.log("set theme to", mode)
|
||||||
},
|
},
|
||||||
get: async () => {
|
get: async () => {
|
||||||
|
const theme = localStorage.getItem("theme") || "system"
|
||||||
|
const systemTheme = mediaMatch.matches ? "dark" : "light"
|
||||||
return {
|
return {
|
||||||
theme: "light",
|
theme: theme,
|
||||||
computed: "light",
|
computed: theme === "system" ? systemTheme : theme,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onChange: (callback) => {
|
onChange: (callback) => {
|
||||||
themeCallback = callback
|
themeCallback = callback
|
||||||
themeModeChangeListener = (event) => {
|
|
||||||
callback(event.matches ? "dark" : "light")
|
|
||||||
}
|
|
||||||
mediaMatch.addEventListener('change', themeModeChangeListener)
|
|
||||||
return mediaMatch
|
|
||||||
},
|
},
|
||||||
removeListener() {
|
removeListener() {
|
||||||
mediaMatch.removeEventListener('change', themeModeChangeListener)
|
themeCallback = null
|
||||||
},
|
},
|
||||||
initial: "light",
|
initial: localStorage.getItem("theme") || "system",
|
||||||
},
|
},
|
||||||
|
|
||||||
settings: {
|
settings: {
|
||||||
@ -77,3 +79,5 @@ export default {
|
|||||||
return currencyData
|
return currencyData
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default Heynote
|
||||||
|
Loading…
Reference in New Issue
Block a user