mirror of
https://github.com/heyman/heynote.git
synced 2024-11-21 23:43:22 +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,
|
isWindows,
|
||||||
isLinux,
|
isLinux,
|
||||||
},
|
},
|
||||||
|
isWebApp: false,
|
||||||
|
|
||||||
themeMode: themeMode,
|
themeMode: themeMode,
|
||||||
|
|
||||||
|
@ -135,6 +135,7 @@
|
|||||||
@toggleTheme="toggleTheme"
|
@toggleTheme="toggleTheme"
|
||||||
@openLanguageSelector="openLanguageSelector"
|
@openLanguageSelector="openLanguageSelector"
|
||||||
@formatCurrentBlock="formatCurrentBlock"
|
@formatCurrentBlock="formatCurrentBlock"
|
||||||
|
@openSettings="showSettings = true"
|
||||||
class="status"
|
class="status"
|
||||||
/>
|
/>
|
||||||
<div class="overlay">
|
<div class="overlay">
|
||||||
|
@ -22,6 +22,12 @@
|
|||||||
UpdateStatusItem,
|
UpdateStatusItem,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
showSettingsButton: window.heynote.isWebApp,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
||||||
},
|
},
|
||||||
@ -90,6 +96,14 @@
|
|||||||
:autoUpdate="autoUpdate"
|
:autoUpdate="autoUpdate"
|
||||||
:allowBetaVersions="allowBetaVersions"
|
: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">
|
<div class="status-block theme clickable" @click="$emit('toggleTheme')" title="Toggle dark/light mode">
|
||||||
<span :class="'icon ' + themeSetting"></span>
|
<span :class="'icon ' + themeSetting"></span>
|
||||||
</div>
|
</div>
|
||||||
@ -132,6 +146,12 @@
|
|||||||
cursor: pointer
|
cursor: pointer
|
||||||
&:hover
|
&:hover
|
||||||
background-color: rgba(255,255,255, 0.1)
|
background-color: rgba(255,255,255, 0.1)
|
||||||
|
.icon
|
||||||
|
display: block
|
||||||
|
width: 14px
|
||||||
|
height: 22px
|
||||||
|
+dark-mode
|
||||||
|
opacity: 0.9
|
||||||
.line-number
|
.line-number
|
||||||
color: rgba(255, 255, 255, 0.7)
|
color: rgba(255, 255, 255, 0.7)
|
||||||
.num
|
.num
|
||||||
@ -148,14 +168,9 @@
|
|||||||
padding-top: 0
|
padding-top: 0
|
||||||
padding-bottom: 0
|
padding-bottom: 0
|
||||||
.icon
|
.icon
|
||||||
display: block
|
|
||||||
width: 14px
|
|
||||||
height: 22px
|
|
||||||
background-size: 14px
|
background-size: 14px
|
||||||
background-repeat: no-repeat
|
background-repeat: no-repeat
|
||||||
background-position: center center
|
background-position: center center
|
||||||
+dark-mode
|
|
||||||
opacity: 0.9
|
|
||||||
&.dark
|
&.dark
|
||||||
background-image: url("@/assets/icons/dark-mode.png")
|
background-image: url("@/assets/icons/dark-mode.png")
|
||||||
&.light
|
&.light
|
||||||
@ -167,14 +182,18 @@
|
|||||||
padding-top: 0
|
padding-top: 0
|
||||||
padding-bottom: 0
|
padding-bottom: 0
|
||||||
.icon
|
.icon
|
||||||
display: block
|
|
||||||
width: 14px
|
|
||||||
height: 22px
|
|
||||||
+dark-mode
|
|
||||||
opacity: 0.9
|
|
||||||
background-size: 16px
|
background-size: 16px
|
||||||
background-repeat: no-repeat
|
background-repeat: no-repeat
|
||||||
background-position: center center
|
background-position: center center
|
||||||
background-image: url("@/assets/icons/format.svg")
|
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>
|
</style>
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
autoUpdate: this.initialSettings.autoUpdate,
|
autoUpdate: this.initialSettings.autoUpdate,
|
||||||
|
|
||||||
activeTab: "general",
|
activeTab: "general",
|
||||||
|
isWebApp: window.heynote.isWebApp,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -89,6 +90,7 @@
|
|||||||
@click="activeTab = 'appearance'"
|
@click="activeTab = 'appearance'"
|
||||||
/>
|
/>
|
||||||
<TabListItem
|
<TabListItem
|
||||||
|
v-if="!isWebApp"
|
||||||
name="Updates"
|
name="Updates"
|
||||||
tab="updates"
|
tab="updates"
|
||||||
:activeTab="activeTab"
|
:activeTab="activeTab"
|
||||||
@ -115,7 +117,7 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row" v-if="!isWebApp">
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<h2>Global Keyboard Shortcut</h2>
|
<h2>Global Keyboard Shortcut</h2>
|
||||||
<label class="keyboard-shortcut-label">
|
<label class="keyboard-shortcut-label">
|
||||||
@ -134,7 +136,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row" v-if="!isWebApp">
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<h2>Show In</h2>
|
<h2>Show In</h2>
|
||||||
<label v-if="isMac">
|
<label v-if="isMac">
|
||||||
@ -183,7 +185,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</TabContent>
|
</TabContent>
|
||||||
|
|
||||||
<TabContent tab="updates" :activeTab="activeTab">
|
<TabContent tab="updates" :activeTab="activeTab" v-if="!isWebApp">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="entry">
|
<div class="entry">
|
||||||
<h2>Auto Update</h2>
|
<h2>Auto Update</h2>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
className() {
|
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: {
|
computed: {
|
||||||
tabClass() {
|
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
|
let heynotePage
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
console.log("beforeEach")
|
|
||||||
heynotePage = new HeynotePage(page)
|
heynotePage = new HeynotePage(page)
|
||||||
await heynotePage.goto()
|
await heynotePage.goto()
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,6 @@ import { HeynotePage } from "./test-utils.js";
|
|||||||
let heynotePage
|
let heynotePage
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
console.log("beforeEach")
|
|
||||||
heynotePage = new HeynotePage(page)
|
heynotePage = new HeynotePage(page)
|
||||||
await heynotePage.goto()
|
await heynotePage.goto()
|
||||||
})
|
})
|
||||||
|
@ -4,7 +4,6 @@ import { HeynotePage } from "./test-utils.js";
|
|||||||
let heynotePage
|
let heynotePage
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
console.log("beforeEach")
|
|
||||||
heynotePage = new HeynotePage(page)
|
heynotePage = new HeynotePage(page)
|
||||||
await heynotePage.goto()
|
await heynotePage.goto()
|
||||||
})
|
})
|
||||||
|
@ -4,7 +4,6 @@ import { HeynotePage } from "./test-utils.js";
|
|||||||
let heynotePage
|
let heynotePage
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
console.log("beforeEach")
|
|
||||||
heynotePage = new HeynotePage(page)
|
heynotePage = new HeynotePage(page)
|
||||||
await heynotePage.goto()
|
await heynotePage.goto()
|
||||||
});
|
});
|
||||||
|
@ -4,7 +4,6 @@ import { HeynotePage } from "./test-utils.js";
|
|||||||
let heynotePage
|
let heynotePage
|
||||||
|
|
||||||
test.beforeEach(async ({ page }) => {
|
test.beforeEach(async ({ page }) => {
|
||||||
console.log("beforeEach")
|
|
||||||
heynotePage = new HeynotePage(page)
|
heynotePage = new HeynotePage(page)
|
||||||
await heynotePage.goto()
|
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]
|
const block = blocks[blockIndex]
|
||||||
return content.slice(block.content.from, block.content.to)
|
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)')
|
const mediaMatch = window.matchMedia('(prefers-color-scheme: dark)')
|
||||||
let themeCallback = null
|
let themeCallback = null
|
||||||
mediaMatch.addEventListener("change", async (event) => {
|
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 = {
|
const Heynote = {
|
||||||
platform: platform,
|
platform: platform,
|
||||||
|
isWebApp: true,
|
||||||
|
|
||||||
buffer: {
|
buffer: {
|
||||||
async load() {
|
async load() {
|
||||||
@ -57,12 +97,19 @@ const Heynote = {
|
|||||||
//ipcRenderer.on(WINDOW_CLOSE_EVENT, callback)
|
//ipcRenderer.on(WINDOW_CLOSE_EVENT, callback)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
settings: initialSettings,
|
||||||
|
|
||||||
onOpenSettings(callback) {
|
onOpenSettings(callback) {
|
||||||
//ipcRenderer.on(OPEN_SETTINGS_EVENT, callback)
|
ipcRenderer.on(OPEN_SETTINGS_EVENT, callback)
|
||||||
},
|
},
|
||||||
|
|
||||||
onSettingsChange(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: {
|
themeMode: {
|
||||||
@ -88,10 +135,6 @@ const Heynote = {
|
|||||||
initial: localStorage.getItem("theme") || "system",
|
initial: localStorage.getItem("theme") || "system",
|
||||||
},
|
},
|
||||||
|
|
||||||
settings: {
|
|
||||||
keymap: "default",
|
|
||||||
},
|
|
||||||
|
|
||||||
getCurrencyData: async () => {
|
getCurrencyData: async () => {
|
||||||
if (currencyData !== null) {
|
if (currencyData !== null) {
|
||||||
return currencyData
|
return currencyData
|
||||||
@ -102,4 +145,4 @@ const Heynote = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Heynote
|
export { Heynote, ipcRenderer}
|
||||||
|
@ -11,8 +11,9 @@
|
|||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
|
||||||
<script type="module">
|
<script type="module">
|
||||||
import heynote from "./bridge.js";
|
import { Heynote, ipcRenderer } from "./bridge.js";
|
||||||
window.heynote = heynote;
|
window.ipcRenderer = ipcRenderer;
|
||||||
|
window.heynote = Heynote;
|
||||||
</script>
|
</script>
|
||||||
<script type="module" src="main.js"></script>
|
<script type="module" src="main.js"></script>
|
||||||
<script src="./math.js"></script>
|
<script src="./math.js"></script>
|
||||||
|
Loading…
Reference in New Issue
Block a user