Some fixes

This commit is contained in:
snipd-min 2026-05-13 13:22:14 +02:00
parent 21411e69f3
commit 5aaaa4dade
7 changed files with 46 additions and 39 deletions

View file

@ -14,6 +14,11 @@ export default defineConfig([
languageOptions: {
parser: tsparser,
parserOptions: { project: "./tsconfig.json" },
globals: {
activeWindow: "readonly",
activeDocument: "readonly",
console: "readonly",
},
},
// Optional project overrides

20
package-lock.json generated
View file

@ -679,6 +679,7 @@
"integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
@ -771,7 +772,6 @@
"integrity": "sha512-KWiFQpSAqEIyrTXko3hFNLeQvSK8zXlJQzhhxsyVn58WFRYXST99b3Nqnu+ttOtjds2Pl2grUHGpe2NzhPynuQ==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"engines": {
"node": ">=18"
}
@ -795,8 +795,7 @@
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz",
"integrity": "sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/@microsoft/eslint-plugin-sdl": {
"version": "1.1.0",
@ -979,6 +978,7 @@
"integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.33.1",
"@typescript-eslint/types": "8.33.1",
@ -1220,6 +1220,7 @@
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
"dev": true,
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -1602,8 +1603,7 @@
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/cross-spawn": {
"version": "7.0.6",
@ -2021,6 +2021,7 @@
"integrity": "sha512-BhHmn2yNOFA9H9JmmIVKJmd288g9hrVRDkdoIgRCRuSySRUHH7r/DI6aAXW9T1WwUuY3DFgrcaqB+deURBLR5g==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@ -4804,8 +4805,7 @@
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz",
"integrity": "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/supports-color": {
"version": "7.2.0",
@ -5488,6 +5488,7 @@
"integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -5502,6 +5503,7 @@
"integrity": "sha512-KALyxkpYV5Ix7UhvjTwJXZv76VWsHG+NjNlt/z+a17SOQSiOcBdUXdbJdyXi7RPxrBFECtFOiPwUJQusJuCqrg==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.46.4",
"@typescript-eslint/parser": "8.46.4",
@ -5556,6 +5558,7 @@
"integrity": "sha512-tK3GPFWbirvNgsNKto+UmB/cRtn6TZfyw0D6IKrW55n6Vbs7KJoZtI//kpTKzE/DUmmnAFD8/Ca46s7Obs92/w==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@typescript-eslint/scope-manager": "8.46.4",
"@typescript-eslint/types": "8.46.4",
@ -5796,8 +5799,7 @@
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
"dev": true,
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/which": {
"version": "2.0.2",

View file

@ -87,7 +87,7 @@ export class FormattingConfigModal extends Modal {
varSpan.addEventListener('click', () => {
void (async () => {
try {
await globalThis.navigator.clipboard.writeText(varName);
await activeWindow.navigator.clipboard.writeText(varName);
new Notice(`Copied ${varName} to clipboard`);
} catch {
new Notice(`Failed to copy ${varName} to clipboard`);
@ -133,7 +133,7 @@ export class FormattingConfigModal extends Modal {
varSpan.addEventListener('click', () => {
void (async () => {
try {
await globalThis.navigator.clipboard.writeText(varName);
await activeWindow.navigator.clipboard.writeText(varName);
new Notice(`Copied ${varName} to clipboard`);
} catch {
new Notice(`Failed to copy ${varName} to clipboard`);
@ -179,7 +179,7 @@ export class FormattingConfigModal extends Modal {
varSpan.addEventListener('click', () => {
void (async () => {
try {
await globalThis.navigator.clipboard.writeText(varName);
await activeWindow.navigator.clipboard.writeText(varName);
new Notice(`Copied ${varName} to clipboard`);
} catch {
new Notice(`Failed to copy ${varName} to clipboard`);
@ -213,7 +213,7 @@ export class FormattingConfigModal extends Modal {
varSpan.addEventListener('click', () => {
void (async () => {
try {
await globalThis.navigator.clipboard.writeText(varName);
await activeWindow.navigator.clipboard.writeText(varName);
new Notice(`Copied ${varName} to clipboard`);
} catch {
new Notice(`Failed to copy ${varName} to clipboard`);

View file

@ -184,7 +184,7 @@ export default class SnipdPlugin extends Plugin {
private clearStatusBarPersistentMessageAfterDelay(delayMs: number): void {
this.registerInterval(
globalThis.window.setTimeout(() => {
activeWindow.setTimeout(() => {
this.clearStatusBarPersistentMessage();
}, delayMs)
);
@ -1239,13 +1239,13 @@ export default class SnipdPlugin extends Plugin {
const milliseconds = minutes * 60 * 1000;
debugLog('Snipd plugin: setting interval to ', milliseconds, 'milliseconds');
if (this.scheduleInterval !== null) {
globalThis.window.clearInterval(this.scheduleInterval);
activeWindow.clearInterval(this.scheduleInterval);
this.scheduleInterval = null;
}
if (!milliseconds) {
return;
}
this.scheduleInterval = globalThis.window.setInterval(() => {
this.scheduleInterval = activeWindow.setInterval(() => {
void this.syncSnipd();
}, milliseconds);
this.registerInterval(this.scheduleInterval);
@ -1304,7 +1304,7 @@ export default class SnipdPlugin extends Plugin {
if (!this.app.isMobile) {
this.statusBar = new StatusBar(this.addStatusBarItem());
this.registerInterval(
globalThis.window.setInterval(() => {
activeWindow.setInterval(() => {
this.statusBar.display();
}, 1000)
);

View file

@ -5,7 +5,7 @@ export class SecureStorage {
private static async deriveKey(vaultPath: string): Promise<CryptoKey> {
const encoder = new TextEncoder();
const keyMaterial = await globalThis.crypto.subtle.importKey(
const keyMaterial = await activeWindow.crypto.subtle.importKey(
'raw',
encoder.encode(vaultPath + this.SERVICE_NAME),
'PBKDF2',
@ -15,7 +15,7 @@ export class SecureStorage {
const salt = encoder.encode('snipd-secure-storage-salt-v1');
return globalThis.crypto.subtle.deriveKey(
return activeWindow.crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: salt,
@ -39,9 +39,9 @@ export class SecureStorage {
const encoder = new TextEncoder();
const data = encoder.encode(apiKey);
const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));
const iv = activeWindow.crypto.getRandomValues(new Uint8Array(12));
const encryptedData = await globalThis.crypto.subtle.encrypt(
const encryptedData = await activeWindow.crypto.subtle.encrypt(
{
name: this.ALGORITHM,
iv: iv
@ -55,7 +55,7 @@ export class SecureStorage {
combined.set(iv);
combined.set(encryptedArray, iv.length);
return globalThis.btoa(String.fromCharCode(...combined));
return activeWindow.btoa(String.fromCharCode(...combined));
} catch {
throw new Error('Failed to encrypt API key');
}
@ -69,12 +69,12 @@ export class SecureStorage {
try {
const key = await this.deriveKey(vaultPath);
const combined = Uint8Array.from(globalThis.atob(encryptedApiKey), c => c.charCodeAt(0));
const combined = Uint8Array.from(activeWindow.atob(encryptedApiKey), c => c.charCodeAt(0));
const iv = combined.slice(0, 12);
const encryptedData = combined.slice(12);
const decryptedData = await globalThis.crypto.subtle.decrypt(
const decryptedData = await activeWindow.crypto.subtle.decrypt(
{
name: this.ALGORITHM,
iv: iv

View file

@ -16,7 +16,7 @@ export class SnipdSettingModal extends PluginSettingTab {
hide() {
if (this.refreshInterval !== null) {
globalThis.window.clearInterval(this.refreshInterval);
activeWindow.clearInterval(this.refreshInterval);
this.refreshInterval = null;
}
this.plugin.settingsTab = null;
@ -32,7 +32,7 @@ export class SnipdSettingModal extends PluginSettingTab {
// Cannot use electron API in Obsidian
openExternal(url: string) {
globalThis.window.open(url);
activeWindow.open(url);
}
async connectToSnipd(button: HTMLElement, container: HTMLElement, uuid?: string): Promise<void> {
@ -105,7 +105,7 @@ export class SnipdSettingModal extends PluginSettingTab {
if (!this.plugin.settings.apiKey) {
const authSection = containerEl.createDiv({ cls: 'snipd-auth-section' });
authSection.createEl('div', { text: 'Connect Obsidian to Snipd', cls: 'snipd-auth-heading' });
authSection.createDiv({ text: 'Connect Obsidian to Snipd', cls: 'snipd-auth-heading' });
const subtitleRow = authSection.createDiv({ cls: 'snipd-auth-subtitle-row' });
@ -129,7 +129,7 @@ export class SnipdSettingModal extends PluginSettingTab {
const syncStatusContainer = containerEl.createDiv({ cls: 'snipd-sync-status' });
const syncStatusHeader = syncStatusContainer.createDiv({ cls: 'snipd-sync-status-header' });
syncStatusHeader.createEl('div', { text: 'Sync status', cls: 'snipd-sync-status-title' });
syncStatusHeader.createDiv({ text: 'Sync status', cls: 'snipd-sync-status-title' });
if (this.plugin.settings.isSyncing) {
const stopButton = syncStatusHeader.createEl('button', {
@ -162,24 +162,24 @@ export class SnipdSettingModal extends PluginSettingTab {
const episodeCount = this.plugin.settings.current_batch_episode_count;
const snipCount = this.plugin.settings.current_batch_snip_count;
syncStatusBody.createEl('div', {
syncStatusBody.createDiv({
text: `Syncing: Batch ${displayBatch} of ${totalBatches} (${remainingBatches} remaining)`,
cls: 'snipd-sync-status-text'
});
if (episodeCount > 0 || snipCount > 0) {
syncStatusBody.createEl('div', {
syncStatusBody.createDiv({
text: `Current batch: ${episodeCount} episode${episodeCount !== 1 ? 's' : ''}, ${snipCount} snip${snipCount !== 1 ? 's' : ''}`,
cls: 'snipd-sync-status-text'
});
}
syncStatusBody.createEl('div', {
syncStatusBody.createDiv({
text: `Progress: ${progressPercent}%`,
cls: 'snipd-sync-status-text'
});
} else {
syncStatusBody.createEl('div', {
syncStatusBody.createDiv({
text: 'Preparing sync...',
cls: 'snipd-sync-status-text'
});
@ -188,19 +188,19 @@ export class SnipdSettingModal extends PluginSettingTab {
const lastSyncDate = new Date(this.plugin.settings.lastSyncTimestamp);
const formattedDate = lastSyncDate.toLocaleString();
syncStatusBody.createEl('div', {
syncStatusBody.createDiv({
text: `Last sync: ${formattedDate}`,
cls: 'snipd-sync-status-text'
});
if (this.plugin.settings.lastSyncEpisodeCount > 0 || this.plugin.settings.lastSyncSnipCount > 0) {
syncStatusBody.createEl('div', {
syncStatusBody.createDiv({
text: `Last synced: ${this.plugin.settings.lastSyncEpisodeCount} episodes, ${this.plugin.settings.lastSyncSnipCount} snips`,
cls: 'snipd-sync-status-text'
});
}
} else {
syncStatusBody.createEl('div', {
syncStatusBody.createDiv({
text: 'No sync performed yet',
cls: 'snipd-sync-status-text'
});
@ -304,7 +304,7 @@ export class SnipdSettingModal extends PluginSettingTab {
button.setButtonText(isBusy ? "Syncing..." : "Reset & sync");
button.setDisabled(isBusy);
button.onClick(() => {
const confirmed = globalThis.window.confirm(
const confirmed = activeWindow.confirm(
"This will remove all synced Snipd data from your vault and start a fresh sync. Continue?"
);
if (!confirmed) {
@ -320,12 +320,12 @@ export class SnipdSettingModal extends PluginSettingTab {
});
if (this.refreshInterval !== null) {
globalThis.window.clearInterval(this.refreshInterval);
activeWindow.clearInterval(this.refreshInterval);
this.refreshInterval = null;
}
if (this.plugin.settings.isSyncing || this.plugin.settings.isTestSyncing) {
this.refreshInterval = globalThis.window.setInterval(() => {
this.refreshInterval = activeWindow.setInterval(() => {
this.display();
}, 1000);
}

View file

@ -8,7 +8,7 @@ export const isDev = (): boolean => {
export const debugLog = (...args: unknown[]): void => {
if (isDev()) {
globalThis.console.log('[Snipd]', ...args);
console.debug('[Snipd]', ...args);
}
};