Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 | 8x 8x 3x 8x 2x 2x 1x 8x 8x 8x 8x 8x 8x 8x 8x 8x 2x 4x 1x 8x 1x 1x 1x 1x 1x 3x 2x 2x 1x | import { invoke } from '@tauri-apps/api/core';
import { getCurrentWindow } from '@tauri-apps/api/window';
import { watchEditorGlass } from '../desktop/EditorGlass';
import { applyTheme, onMac } from '../desktop/Theme';
import type { CaptureMode } from '../lib/Db';
applyTheme();
addEventListener('storage', (event) => {
if (event.key === 'theme' || event.key === null) applyTheme();
});
// Editor windows follow the main window's Window design on macOS.
if (onMac() && isEditorWindow()) watchEditorGlass();
function isEditorWindow() {
try {
return getCurrentWindow().label.startsWith('editor-');
} catch {
return false;
}
}
export const CAPTURE_MODES: CaptureMode[] = ['selection', 'screen', 'window'];
export type Action = 'selection' | 'screen' | 'window' | 'copy-selection';
// Alt is Option on macOS.
export const DEFAULT_SHORTCUTS: Record<Action, string> = {
selection: 'Alt+Shift+S',
window: 'Alt+Shift+W',
screen: 'Alt+Shift+V',
'copy-selection': 'Alt+Shift+C',
};
export const CAPTURE_HINT =
'Use Capture, the Daguerre icon in the menu bar or system tray, or a shortcut.';
export const SHORTCUT_HINTS: [keys: string, label: string][] = [
[DEFAULT_SHORTCUTS.selection, 'Select area'],
[DEFAULT_SHORTCUTS.window, 'Window'],
[DEFAULT_SHORTCUTS.screen, 'Screen'],
];
export const NO_URL_LABEL = '';
export const SAVE_PNG_LABEL = 'Save PNG…';
export const SAVED_TOAST = 'Saved';
export const SEARCH_PLACEHOLDER = 'Search by title';
const bytes = async (blob: Blob) => new Uint8Array(await blob.arrayBuffer());
/** Asks where to save, then writes the file; resolves false if the dialog is cancelled. */
export async function downloadBlob(blob: Blob, name: string) {
return invoke<boolean>('save_file', await bytes(blob), {
// Header values must be ASCII.
headers: { 'x-file-name': name.replace(/[^\x20-\x7e]/g, '_') },
});
}
export async function copyPng(png: Blob | Promise<Blob>) {
await invoke('copy_png', await bytes(await png));
}
export async function copyText(text: Promise<string>) {
await invoke('copy_text', { text: await text });
}
// WKWebView ignores window.print(), so the native webview prints itself.
export const printPage = () => invoke('print');
/** History lives in the main window: bring it forward and close this editor (through its close guard). */
export function leaveToHistory() {
void invoke('show_main', { page: 'history' }).then(() =>
getCurrentWindow().close(),
);
return true;
}
/** Asks before closing a window with unsaved work; returns a cleanup function. */
export function guardClose(
isDirty: () => boolean,
ask: () => Promise<boolean>,
) {
const win = getCurrentWindow();
const off = win.onCloseRequested(async (e) => {
if (!isDirty()) return;
e.preventDefault();
if (await ask()) await win.destroy();
});
return () => void off.then((unlisten) => unlisten());
}
|