From 497520f1fbb5783937468dea0a537736942ac3ef Mon Sep 17 00:00:00 2001 From: Oleksii Skorobogatko Date: Sun, 15 Dec 2024 18:36:25 +0200 Subject: [PATCH] #4 clipboard top (renderer side) --- src/preload/preload.js | 1 + src/renderer/plugins/plugin-clipboard-top.js | 16 ++++++++++++++++ src/renderer/renderer.js | 13 ++++++++++--- src/renderer/stores/useClipboardStore.js | 18 +++++++++++++++++- 4 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 src/renderer/plugins/plugin-clipboard-top.js diff --git a/src/preload/preload.js b/src/preload/preload.js index bc6021f..7ef7a23 100644 --- a/src/preload/preload.js +++ b/src/preload/preload.js @@ -21,4 +21,5 @@ contextBridge.exposeInMainWorld('electronAPI', { openUrl: (value) => ipcRenderer.send('open:url', value), saveImage: (value) => ipcRenderer.send('save:image', value), saveText: (value) => ipcRenderer.send('save:text', value), + clipboardTop: (clips) => ipcRenderer.send('clipboard:top', clips), }); diff --git a/src/renderer/plugins/plugin-clipboard-top.js b/src/renderer/plugins/plugin-clipboard-top.js new file mode 100644 index 0000000..85098da --- /dev/null +++ b/src/renderer/plugins/plugin-clipboard-top.js @@ -0,0 +1,16 @@ +// This plugin sends 'clipboard:top' ipc event +// after mutating actions on Clipboard store. + +const { electronAPI } = window; +// The list of actions mutate the store. +const mutateActions = ['clear', 'remove', 'moveToTop', 'put']; + +export function pluginClipboardTop({ store }) { + store.$onAction(({ name, store, after }) => { + if (store.$id === 'clips' && mutateActions.indexOf(name) !== -1) { + after(() => { + electronAPI.clipboardTop(store.top()); + }); + } + }); +} diff --git a/src/renderer/renderer.js b/src/renderer/renderer.js index 5bc82b1..3a492fc 100644 --- a/src/renderer/renderer.js +++ b/src/renderer/renderer.js @@ -34,23 +34,30 @@ import App from './components/App.vue'; import { useClipboardStore } from './stores/useClipboardStore'; import { pluginTrimStrings } from './plugins/plugin-trim-strings'; import { pluginLocalStoragePrefs, loadPrefs } from './plugins/plugin-localstorage-prefs'; +import { pluginClipboardTop } from './plugins/plugin-clipboard-top'; import db from './stores/db'; const app = createApp(App); const pinia = createPinia(); +const { electronAPI } = window; app.use(pinia); pinia.use(pluginLocalStoragePrefs); pinia.use(pluginTrimStrings); +pinia.use(pluginClipboardTop); app.mount('#app'); const clipboardStore = useClipboardStore(); -db.open(clipboardStore.getModelsFromDb); -const prefs = loadPrefs(); +db.open(function () { + clipboardStore.getModelsFromDb(function () { + // sends 'clipboard:top' event to initialize clipboard items in tray context menu. + electronAPI.clipboardTop(clipboardStore.top()); + }); +}); -const electronAPI = window.electronAPI; +const prefs = loadPrefs(); electronAPI.onClipboardNew(clipboardStore.put); diff --git a/src/renderer/stores/useClipboardStore.js b/src/renderer/stores/useClipboardStore.js index f84184b..52143a1 100644 --- a/src/renderer/stores/useClipboardStore.js +++ b/src/renderer/stores/useClipboardStore.js @@ -133,7 +133,7 @@ export const useClipboardStore = defineStore('clips', () => { } } - function getModelsFromDb() { + function getModelsFromDb(onAfterLoad) { clear(); /** @type {import("../../models/clip").Model[]} */ @@ -153,6 +153,7 @@ export const useClipboardStore = defineStore('clips', () => { */ (a, b) => b.created - a.created, ); + if (onAfterLoad) onAfterLoad(); }, ); } @@ -167,6 +168,20 @@ export const useClipboardStore = defineStore('clips', () => { return null; } + /** + * Gets n top items. + * + * @param {number} n=5 How many items from the top to get. + * @returns {import("../../models/clip").Model[]} + */ + function top(n = 5) { + if (modelCollection.value.length === 0) { + return []; + } + // TODO: only text items are needed + return modelCollection.value.slice(0, n < 0 ? 10 : n).map(toRaw).reverse(); + } + return { // state clips, @@ -182,5 +197,6 @@ export const useClipboardStore = defineStore('clips', () => { toggleStarred, getModelsFromDb, peekTop, + top, }; });