mirror of
https://github.com/heyman/heynote.git
synced 2024-11-21 15:33:14 +01:00
Add Settings to web app (#125)
* Add support for opening settings dialog in the webapp * Add tests for settings dialog * Hide stand-alone app specific settings in web app * Remove debug log
This commit is contained in:
parent
0ba5820cf4
commit
acb7ddf189
1
assets/icons/settings.svg
Normal file
1
assets/icons/settings.svg
Normal file
@ -0,0 +1 @@
|
||||
<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="M262.29 192.31a64 64 0 1 0 57.4 57.4 64.13 64.13 0 0 0-57.4-57.4ZM416.39 256a154.34 154.34 0 0 1-1.53 20.79l45.21 35.46a10.81 10.81 0 0 1 2.45 13.75l-42.77 74a10.81 10.81 0 0 1-13.14 4.59l-44.9-18.08a16.11 16.11 0 0 0-15.17 1.75A164.48 164.48 0 0 1 325 400.8a15.94 15.94 0 0 0-8.82 12.14l-6.73 47.89a11.08 11.08 0 0 1-10.68 9.17h-85.54a11.11 11.11 0 0 1-10.69-8.87l-6.72-47.82a16.07 16.07 0 0 0-9-12.22 155.3 155.3 0 0 1-21.46-12.57 16 16 0 0 0-15.11-1.71l-44.89 18.07a10.81 10.81 0 0 1-13.14-4.58l-42.77-74a10.8 10.8 0 0 1 2.45-13.75l38.21-30a16.05 16.05 0 0 0 6-14.08c-.36-4.17-.58-8.33-.58-12.5s.21-8.27.58-12.35a16 16 0 0 0-6.07-13.94l-38.19-30A10.81 10.81 0 0 1 49.48 186l42.77-74a10.81 10.81 0 0 1 13.14-4.59l44.9 18.08a16.11 16.11 0 0 0 15.17-1.75A164.48 164.48 0 0 1 187 111.2a15.94 15.94 0 0 0 8.82-12.14l6.73-47.89A11.08 11.08 0 0 1 213.23 42h85.54a11.11 11.11 0 0 1 10.69 8.87l6.72 47.82a16.07 16.07 0 0 0 9 12.22 155.3 155.3 0 0 1 21.46 12.57 16 16 0 0 0 15.11 1.71l44.89-18.07a10.81 10.81 0 0 1 13.14 4.58l42.77 74a10.8 10.8 0 0 1-2.45 13.75l-38.21 30a16.05 16.05 0 0 0-6.05 14.08c.33 4.14.55 8.3.55 12.47Z" fill="none" stroke="#ffffff" stroke-linecap="round" stroke-linejoin="round" stroke-width="32px" class="stroke-000000"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
@ -25,6 +25,7 @@ contextBridge.exposeInMainWorld("heynote", {
|
||||
isWindows,
|
||||
isLinux,
|
||||
},
|
||||
isWebApp: false,
|
||||
|
||||
themeMode: themeMode,
|
||||
|
||||
|
@ -135,6 +135,7 @@
|
||||
@toggleTheme="toggleTheme"
|
||||
@openLanguageSelector="openLanguageSelector"
|
||||
@formatCurrentBlock="formatCurrentBlock"
|
||||
@openSettings="showSettings = true"
|
||||
class="status"
|
||||
/>
|
||||
<div class="overlay">
|
||||
|
@ -22,6 +22,12 @@
|
||||
UpdateStatusItem,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
showSettingsButton: window.heynote.isWebApp,
|
||||
}
|
||||
},
|
||||
|
||||
mounted() {
|
||||
|
||||
},
|
||||
@ -90,6 +96,14 @@
|
||||
:autoUpdate="autoUpdate"
|
||||
:allowBetaVersions="allowBetaVersions"
|
||||
/>
|
||||
<div
|
||||
v-if="showSettingsButton"
|
||||
@click="$emit('openSettings')"
|
||||
class="status-block settings clickable"
|
||||
title="Settings"
|
||||
>
|
||||
<span class="icon icon-format"></span>
|
||||
</div>
|
||||
<div class="status-block theme clickable" @click="$emit('toggleTheme')" title="Toggle dark/light mode">
|
||||
<span :class="'icon ' + themeSetting"></span>
|
||||
</div>
|
||||
@ -132,6 +146,12 @@
|
||||
cursor: pointer
|
||||
&:hover
|
||||
background-color: rgba(255,255,255, 0.1)
|
||||
.icon
|
||||
display: block
|
||||
width: 14px
|
||||
height: 22px
|
||||
+dark-mode
|
||||
opacity: 0.9
|
||||
.line-number
|
||||
color: rgba(255, 255, 255, 0.7)
|
||||
.num
|
||||
@ -148,14 +168,9 @@
|
||||
padding-top: 0
|
||||
padding-bottom: 0
|
||||
.icon
|
||||
display: block
|
||||
width: 14px
|
||||
height: 22px
|
||||
background-size: 14px
|
||||
background-repeat: no-repeat
|
||||
background-position: center center
|
||||
+dark-mode
|
||||
opacity: 0.9
|
||||
&.dark
|
||||
background-image: url("@/assets/icons/dark-mode.png")
|
||||
&.light
|
||||
@ -167,14 +182,18 @@
|
||||
padding-top: 0
|
||||
padding-bottom: 0
|
||||
.icon
|
||||
display: block
|
||||
width: 14px
|
||||
height: 22px
|
||||
+dark-mode
|
||||
opacity: 0.9
|
||||
background-size: 16px
|
||||
background-repeat: no-repeat
|
||||
background-position: center center
|
||||
background-image: url("@/assets/icons/format.svg")
|
||||
|
||||
.settings
|
||||
padding-top: 0
|
||||
padding-bottom: 0
|
||||
.icon
|
||||
background-size: 13px
|
||||
background-repeat: no-repeat
|
||||
background-position: center center
|
||||
background-image: url("@/assets/icons/settings.svg")
|
||||
|
||||
</style>
|
||||
|
@ -33,6 +33,7 @@
|
||||
autoUpdate: this.initialSettings.autoUpdate,
|
||||
|
||||
activeTab: "general",
|
||||
isWebApp: window.heynote.isWebApp,
|
||||
}
|
||||
},
|
||||
|
||||
@ -89,6 +90,7 @@
|
||||
@click="activeTab = 'appearance'"
|
||||
/>
|
||||
<TabListItem
|
||||
v-if="!isWebApp"
|
||||
name="Updates"
|
||||
tab="updates"
|
||||
:activeTab="activeTab"
|
||||
@ -115,7 +117,7 @@
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row" v-if="!isWebApp">
|
||||
<div class="entry">
|
||||
<h2>Global Keyboard Shortcut</h2>
|
||||
<label class="keyboard-shortcut-label">
|
||||
@ -134,7 +136,7 @@
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row" v-if="!isWebApp">
|
||||
<div class="entry">
|
||||
<h2>Show In</h2>
|
||||
<label v-if="isMac">
|
||||
@ -183,7 +185,7 @@
|
||||
</div>
|
||||
</TabContent>
|
||||
|
||||
<TabContent tab="updates" :activeTab="activeTab">
|
||||
<TabContent tab="updates" :activeTab="activeTab" v-if="!isWebApp">
|
||||
<div class="row">
|
||||
<div class="entry">
|
||||
<h2>Auto Update</h2>
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
computed: {
|
||||
className() {
|
||||
return "tab-content " + (this.tab === this.activeTab ? "active" : "")
|
||||
return "tab-content tab-" + this.tab + " " + (this.tab === this.activeTab ? "active" : "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
computed: {
|
||||
tabClass() {
|
||||
return this.tab === this.activeTab ? "active" : ""
|
||||
return "tab-" + this.tab + " " + (this.tab === this.activeTab ? "active" : "")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,6 @@ import { HeynotePage } from "./test-utils.js";
|
||||
let heynotePage
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
console.log("beforeEach")
|
||||
heynotePage = new HeynotePage(page)
|
||||
await heynotePage.goto()
|
||||
});
|
||||
|
@ -4,7 +4,6 @@ import { HeynotePage } from "./test-utils.js";
|
||||
let heynotePage
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
console.log("beforeEach")
|
||||
heynotePage = new HeynotePage(page)
|
||||
await heynotePage.goto()
|
||||
})
|
||||
|
@ -4,7 +4,6 @@ import { HeynotePage } from "./test-utils.js";
|
||||
let heynotePage
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
console.log("beforeEach")
|
||||
heynotePage = new HeynotePage(page)
|
||||
await heynotePage.goto()
|
||||
})
|
||||
|
@ -4,7 +4,6 @@ import { HeynotePage } from "./test-utils.js";
|
||||
let heynotePage
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
console.log("beforeEach")
|
||||
heynotePage = new HeynotePage(page)
|
||||
await heynotePage.goto()
|
||||
});
|
||||
|
@ -4,7 +4,6 @@ import { HeynotePage } from "./test-utils.js";
|
||||
let heynotePage
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
console.log("beforeEach")
|
||||
heynotePage = new HeynotePage(page)
|
||||
await heynotePage.goto()
|
||||
});
|
||||
|
40
tests/settings.spec.js
Normal file
40
tests/settings.spec.js
Normal file
@ -0,0 +1,40 @@
|
||||
import { test, expect } from "@playwright/test";
|
||||
import { HeynotePage } from "./test-utils.js";
|
||||
|
||||
let heynotePage
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
heynotePage = new HeynotePage(page)
|
||||
await heynotePage.goto()
|
||||
});
|
||||
|
||||
|
||||
test("test open settings dialog", async ({ page }) => {
|
||||
await page.locator("css=.status-block.settings").click()
|
||||
await expect(page.locator("css=.overlay .settings .dialog")).toBeVisible()
|
||||
})
|
||||
|
||||
test("test close settings dialog", async ({ page }) => {
|
||||
await page.locator("css=.status-block.settings").click()
|
||||
await page.locator("css=.overlay .settings .dialog .bottom-bar .close").click()
|
||||
await expect(page.locator("css=.overlay .settings .dialog")).not.toBeVisible()
|
||||
})
|
||||
|
||||
test("test close settings dialog with escape", async ({ page }) => {
|
||||
await page.locator("css=.status-block.settings").click()
|
||||
await page.locator("body").press("Escape")
|
||||
await expect(page.locator("css=.overlay .settings .dialog")).not.toBeVisible()
|
||||
})
|
||||
|
||||
test("test change line gutter setting", async ({ page }) => {
|
||||
await expect(page.locator("css=.cm-lineNumbers")).toBeVisible()
|
||||
await page.locator("css=.status-block.settings").click()
|
||||
await page.locator("css=.overlay .settings .dialog .sidebar li.tab-appearance").click()
|
||||
await expect(page.locator("css=.settings .tab-content.tab-appearance")).toBeVisible()
|
||||
await page.getByLabel("Show line numbers").click()
|
||||
await expect(page.locator("css=.cm-lineNumbers")).toBeHidden()
|
||||
expect((await heynotePage.getStoredSettings()).showLineNumberGutter).toBe(false)
|
||||
await page.getByLabel("Show line numbers").click()
|
||||
await expect(page.locator("css=.cm-lineNumbers")).toBeVisible()
|
||||
expect((await heynotePage.getStoredSettings()).showLineNumberGutter).toBe(true)
|
||||
})
|
@ -42,4 +42,8 @@ export class HeynotePage {
|
||||
const block = blocks[blockIndex]
|
||||
return content.slice(block.content.from, block.content.to)
|
||||
}
|
||||
|
||||
async getStoredSettings() {
|
||||
return await this.page.evaluate(() => JSON.parse(window.localStorage.getItem("settings")))
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
import { SETTINGS_CHANGE_EVENT, OPEN_SETTINGS_EVENT } from "../electron/constants";
|
||||
|
||||
const mediaMatch = window.matchMedia('(prefers-color-scheme: dark)')
|
||||
let themeCallback = null
|
||||
mediaMatch.addEventListener("change", async (event) => {
|
||||
@ -31,8 +33,46 @@ if (uaPlatform.indexOf("Win") !== -1) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class IpcRenderer {
|
||||
constructor() {
|
||||
this.callbacks = {}
|
||||
}
|
||||
|
||||
on(event, callback) {
|
||||
if (!this.callbacks[event]) {
|
||||
this.callbacks[event] = []
|
||||
}
|
||||
this.callbacks[event].push(callback)
|
||||
}
|
||||
|
||||
send(event, ...args) {
|
||||
if (this.callbacks[event]) {
|
||||
for (const callback of this.callbacks[event]) {
|
||||
callback(null, ...args)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const ipcRenderer = new IpcRenderer()
|
||||
|
||||
// get initial settings
|
||||
let settingsData = localStorage.getItem("settings")
|
||||
let initialSettings = {
|
||||
keymap: "default",
|
||||
emacsMetaKey: "meta",
|
||||
showLineNumberGutter: true,
|
||||
showFoldGutter: true,
|
||||
}
|
||||
if (settingsData !== null) {
|
||||
initialSettings = Object.assign(initialSettings, JSON.parse(settingsData))
|
||||
}
|
||||
|
||||
|
||||
const Heynote = {
|
||||
platform: platform,
|
||||
isWebApp: true,
|
||||
|
||||
buffer: {
|
||||
async load() {
|
||||
@ -57,12 +97,19 @@ const Heynote = {
|
||||
//ipcRenderer.on(WINDOW_CLOSE_EVENT, callback)
|
||||
},
|
||||
|
||||
settings: initialSettings,
|
||||
|
||||
onOpenSettings(callback) {
|
||||
//ipcRenderer.on(OPEN_SETTINGS_EVENT, callback)
|
||||
ipcRenderer.on(OPEN_SETTINGS_EVENT, callback)
|
||||
},
|
||||
|
||||
onSettingsChange(callback) {
|
||||
//ipcRenderer.on(SETTINGS_CHANGE_EVENT, (event, settings) => callback(settings))
|
||||
ipcRenderer.on(SETTINGS_CHANGE_EVENT, (event, settings) => callback(settings))
|
||||
},
|
||||
|
||||
setSettings(settings) {
|
||||
localStorage.setItem("settings", JSON.stringify(settings))
|
||||
ipcRenderer.send(SETTINGS_CHANGE_EVENT, settings)
|
||||
},
|
||||
|
||||
themeMode: {
|
||||
@ -88,10 +135,6 @@ const Heynote = {
|
||||
initial: localStorage.getItem("theme") || "system",
|
||||
},
|
||||
|
||||
settings: {
|
||||
keymap: "default",
|
||||
},
|
||||
|
||||
getCurrencyData: async () => {
|
||||
if (currencyData !== null) {
|
||||
return currencyData
|
||||
@ -102,4 +145,4 @@ const Heynote = {
|
||||
},
|
||||
}
|
||||
|
||||
export default Heynote
|
||||
export { Heynote, ipcRenderer}
|
||||
|
@ -11,8 +11,9 @@
|
||||
<div id="app"></div>
|
||||
|
||||
<script type="module">
|
||||
import heynote from "./bridge.js";
|
||||
window.heynote = heynote;
|
||||
import { Heynote, ipcRenderer } from "./bridge.js";
|
||||
window.ipcRenderer = ipcRenderer;
|
||||
window.heynote = Heynote;
|
||||
</script>
|
||||
<script type="module" src="main.js"></script>
|
||||
<script src="./math.js"></script>
|
||||
|
Loading…
Reference in New Issue
Block a user