From 8df8e350ca90b8e88a36450f2d533cf9f63fd4b7 Mon Sep 17 00:00:00 2001 From: Oleksii Skorobogatko Date: Mon, 16 Dec 2024 20:44:53 +0200 Subject: [PATCH] #4 describe electronAPI type --- src/preload/preload.js | 51 +++++++++++++++++-- src/renderer/components/ClipboardItem.vue | 10 ++-- .../components/pages/ItemViewerPage.vue | 8 +-- .../components/pages/PreferencesPage.vue | 6 ++- src/renderer/plugins/plugin-clipboard-top.js | 1 + src/renderer/plugins/plugin-trim-strings.js | 11 ++-- src/renderer/renderer.js | 1 + 7 files changed, 70 insertions(+), 18 deletions(-) diff --git a/src/preload/preload.js b/src/preload/preload.js index 7ef7a23..88f703d 100644 --- a/src/preload/preload.js +++ b/src/preload/preload.js @@ -10,6 +10,49 @@ contextBridge.exposeInMainWorld('versions', { electron: () => process.versions.electron, }); +/** + * @callback onClipboardNew + * + * @callback removeClipModel + * @param {string} clipModelId + * + * @callback selectClipModel + * @param {import('../models/clip').Model} clipModel + * + * @callback clearList + * + * @callback willShowWindow + * + * @callback willHideWindow + * + * @callback changeStartAtLogin + * @param {boolean} openAtLogin + * + * @callback openUrl + * @param {string} url + * + * @callback saveImage + * @param {string} data + * + * @callback saveText + * @param {string} text + * + * @callback clipboardTop + * @param {import('../models/clip').Model[]} clips + * + * @typedef {Object} electronAPI + * @property {onClipboardNew} onClipboardNew + * @property {removeClipModel} removeClipModel + * @property {selectClipModel} selectClipModel + * @property {clearList} clearList + * @property {willShowWindow} willShowWindow + * @property {willHideWindow} willHideWindow + * @property {changeStartAtLogin} changeStartAtLogin + * @property {openUrl} openUrl + * @property {saveImage} saveImage + * @property {saveText} saveText + * @property {clipboardTop} clipboardTop + */ contextBridge.exposeInMainWorld('electronAPI', { onClipboardNew: (callback) => ipcRenderer.on('clipboard:new', (_event, clipModel) => callback(clipModel)), removeClipModel: (clipModelId) => ipcRenderer.send('clip:remove', clipModelId), @@ -17,9 +60,9 @@ contextBridge.exposeInMainWorld('electronAPI', { clearList: () => ipcRenderer.send('clear:list'), willShowWindow: () => ipcRenderer.send('will-show-window'), willHideWindow: () => ipcRenderer.send('will-hide-window'), - changeStartAtLogin: (value) => ipcRenderer.send('pref:startAtLogin', value), - openUrl: (value) => ipcRenderer.send('open:url', value), - saveImage: (value) => ipcRenderer.send('save:image', value), - saveText: (value) => ipcRenderer.send('save:text', value), + changeStartAtLogin: (openAtLogin) => ipcRenderer.send('pref:startAtLogin', openAtLogin), + openUrl: (url) => ipcRenderer.send('open:url', url), + saveImage: (data) => ipcRenderer.send('save:image', data), + saveText: (text) => ipcRenderer.send('save:text', text), clipboardTop: (clips) => ipcRenderer.send('clipboard:top', clips), }); diff --git a/src/renderer/components/ClipboardItem.vue b/src/renderer/components/ClipboardItem.vue index 005f3c3..2527a8b 100644 --- a/src/renderer/components/ClipboardItem.vue +++ b/src/renderer/components/ClipboardItem.vue @@ -17,6 +17,8 @@ const props = defineProps({ const emit = defineEmits(['peek-item', 'qr-item']); +/** @type {{electronAPI: import('../../preload/preload').electronAPI}} */ +const { electronAPI } = window; const isCopied = ref(false); const clipboardStore = useClipboardStore(); const context = shallowRef(ClipboardItemView); @@ -44,7 +46,7 @@ function onCopyItem() { setTimeout(() => { isCopied.value = false; }, 800); - window.electronAPI.selectClipModel(toRaw(props.clip)); + electronAPI.selectClipModel(toRaw(props.clip)); setViewContext(); } @@ -58,7 +60,7 @@ function onRemoveItem() { || (props.clip.starred && confirm('Are you sure you want to remove ?'))) { clipboardStore.remove(props.clip.id); // FIXME: there should be original object, vue proxied object cannot be cloned by ipc - window.electronAPI.removeClipModel(props.clip.id); + electronAPI.removeClipModel(props.clip.id); } } @@ -73,12 +75,12 @@ function onQrItem() { } function onOpenUrl() { - window.electronAPI.openUrl(props.clip.data); + electronAPI.openUrl(props.clip.data); } function onSaveItem() { const method = props.clip.image ? 'saveImage' : 'saveText'; - window.electronAPI[method](props.clip.data); + electronAPI[method](props.clip.data); } diff --git a/src/renderer/components/pages/ItemViewerPage.vue b/src/renderer/components/pages/ItemViewerPage.vue index 2955977..642b6bc 100644 --- a/src/renderer/components/pages/ItemViewerPage.vue +++ b/src/renderer/components/pages/ItemViewerPage.vue @@ -22,6 +22,8 @@ const props = defineProps({ }, }); +/** @type {{electronAPI: import('../../../preload/preload').electronAPI}} */ +const { electronAPI } = window; const emit = defineEmits(['open-page', 'close-page']); const clipboard = useClipboardStore(); @@ -36,14 +38,14 @@ function closePage() { } function copyClip() { - window.electronAPI.selectClipModel(toRaw(props.clip)); + electronAPI.selectClipModel(toRaw(props.clip)); closePage(); } function removeClip() { if (confirm('Are you sure you want to remove ?')) { clipboard.remove(props.clip.id); - window.electronAPI.removeClipModel(props.clip.id); + electronAPI.removeClipModel(props.clip.id); closePage(); } } @@ -54,7 +56,7 @@ function toggleStarred() { function saveClip() { const method = props.clip.image ? 'saveImage' : 'saveText'; - window.electronAPI[method](props.clip.data); + electronAPI[method](props.clip.data); } /** diff --git a/src/renderer/components/pages/PreferencesPage.vue b/src/renderer/components/pages/PreferencesPage.vue index f798bab..118baa3 100644 --- a/src/renderer/components/pages/PreferencesPage.vue +++ b/src/renderer/components/pages/PreferencesPage.vue @@ -11,6 +11,8 @@ import { version as appVersion, homepage } from '../../../../package.json'; const emit = defineEmits(['close-page']); +/** @type {{electronAPI: import('../../../preload/preload').electronAPI}} */ +const { electronAPI } = window; const prefs = usePreferencesStore(); function closePage() { @@ -21,7 +23,7 @@ function closePage() { * @param {string} url */ function openUrl(url) { - window.electronAPI.openUrl(url); + electronAPI.openUrl(url); } onMounted(() => { @@ -29,7 +31,7 @@ onMounted(() => { }); onUnmounted(() => { - window.electronAPI.changeStartAtLogin(prefs.startAtLogin); + electronAPI.changeStartAtLogin(prefs.startAtLogin); }); diff --git a/src/renderer/plugins/plugin-clipboard-top.js b/src/renderer/plugins/plugin-clipboard-top.js index 85098da..8f7e21d 100644 --- a/src/renderer/plugins/plugin-clipboard-top.js +++ b/src/renderer/plugins/plugin-clipboard-top.js @@ -1,6 +1,7 @@ // This plugin sends 'clipboard:top' ipc event // after mutating actions on Clipboard store. +/** @type {{electronAPI: import("../../preload/preload").electronAPI}} */ const { electronAPI } = window; // The list of actions mutate the store. const mutateActions = ['clear', 'remove', 'moveToTop', 'put']; diff --git a/src/renderer/plugins/plugin-trim-strings.js b/src/renderer/plugins/plugin-trim-strings.js index 9e7f703..2db1f76 100644 --- a/src/renderer/plugins/plugin-trim-strings.js +++ b/src/renderer/plugins/plugin-trim-strings.js @@ -4,7 +4,8 @@ import { usePreferencesStore } from '../stores/usePreferencesStore'; import { useClipboardStore } from '../stores/useClipboardStore'; import Clip from '../../models/clip'; -const electron = window.electronAPI; +/** @type {{electronAPI: import('../../preload/preload').electronAPI}} */ +const { electronAPI } = window; /** * @param {import("../../models/clip").Model} model @@ -18,8 +19,8 @@ function trimStrings(model) { // eslint-disable-next-line no-param-reassign model.data = trimmed.data; - electron.removeClipModel(model.id); - electron.selectClipModel(model); + electronAPI.removeClipModel(model.id); + electronAPI.selectClipModel(model); } /** @@ -29,13 +30,13 @@ function trimStrings(model) { */ function ignoreEmptyStrings(model) { if (!model.image && model.data.trim().length === 0) { - electron.removeClipModel(model.id); + electronAPI.removeClipModel(model.id); const clipboardStore = useClipboardStore(); const top = clipboardStore.peekTop(); if (top) { - electron.selectClipModel(toRaw(top)); + electronAPI.selectClipModel(toRaw(top)); } throw new Error('plugin info: ignore empty string'); diff --git a/src/renderer/renderer.js b/src/renderer/renderer.js index 3a492fc..c0b8d72 100644 --- a/src/renderer/renderer.js +++ b/src/renderer/renderer.js @@ -39,6 +39,7 @@ import db from './stores/db'; const app = createApp(App); const pinia = createPinia(); +/** @type {{electronAPI: import('../preload/preload').electronAPI}} */ const { electronAPI } = window; app.use(pinia);