From e48a2a5b6ae043cc4590c83fd8c7dda541dcb037 Mon Sep 17 00:00:00 2001 From: Abdo Date: Wed, 18 Jun 2025 23:16:23 +0300 Subject: [PATCH] Move Attach Media button --- qt/aqt/editor.py | 27 ++----------------- .../editor-toolbar/TemplateButtons.svelte | 9 ++++--- .../editor/rich-text-input/data-transfer.ts | 14 +++++++--- 3 files changed, 19 insertions(+), 31 deletions(-) diff --git a/qt/aqt/editor.py b/qt/aqt/editor.py index ee135ec93..99f648686 100644 --- a/qt/aqt/editor.py +++ b/qt/aqt/editor.py @@ -6,7 +6,6 @@ from __future__ import annotations import base64 import functools import html -import itertools import json import mimetypes import os @@ -18,7 +17,7 @@ import warnings from collections.abc import Callable from enum import Enum from random import randrange -from typing import Any, Iterable, Match, cast +from typing import Any, Iterable, Match import bs4 import requests @@ -38,7 +37,7 @@ from aqt import AnkiQt, gui_hooks from aqt.operations.notetype import update_notetype_legacy from aqt.qt import * from aqt.sound import av_player -from aqt.utils import KeyboardModifiersPressed, getFile, shortcut, showWarning, tr +from aqt.utils import KeyboardModifiersPressed, shortcut, showWarning, tr from aqt.webview import AnkiWebView, AnkiWebViewKind pics = ("jpg", "jpeg", "png", "gif", "svg", "webp", "ico", "avif") @@ -567,27 +566,6 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too # Audio/video/images ###################################################################### - def onAddMedia(self) -> None: - """Show a file selection screen, then add the selected media. - This expects initial setup to have been done by TemplateButtons.svelte.""" - extension_filter = " ".join( - f"*.{extension}" for extension in sorted(itertools.chain(pics, audio)) - ) - filter = f"{tr.editing_media()} ({extension_filter})" - - def accept(file: str) -> None: - self.resolve_media(file) - - file = getFile( - parent=self.widget, - title=tr.editing_add_media(), - cb=cast(Callable[[Any], None], accept), - filter=filter, - key="media", - ) - - self.parentWindow.activateWindow() - def addMedia(self, path: str, canDelete: bool = False) -> None: """Legacy routine used by add-ons to add a media file and update the current field. canDelete is ignored.""" @@ -905,7 +883,6 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too self._links: dict[str, Callable] = dict( fields=Editor.onFields, cards=Editor.onCardLayout, - attach=Editor.onAddMedia, record=Editor.onRecSound, paste=Editor.onPaste, cut=Editor.onCut, diff --git a/ts/routes/editor/editor-toolbar/TemplateButtons.svelte b/ts/routes/editor/editor-toolbar/TemplateButtons.svelte index 13795f418..8102a7f1f 100644 --- a/ts/routes/editor/editor-toolbar/TemplateButtons.svelte +++ b/ts/routes/editor/editor-toolbar/TemplateButtons.svelte @@ -26,6 +26,8 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html import type { RichTextInputAPI } from "../rich-text-input"; import { editingInputIsRichText } from "../rich-text-input"; import LatexButton from "./LatexButton.svelte"; + import { filenameToLink, openFilePickerForMedia } from "../rich-text-input/data-transfer"; + import { addMediaFromPath } from "@generated/backend"; const { focusedInput } = context.get(); @@ -38,7 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html resolve?.(media); } - function attachMediaOnFocus(): void { + async function attachMediaOnFocus(): Promise { if (disabled) { return; } @@ -48,8 +50,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html async () => setFormat("inserthtml", await mediaPromise), { once: true }, ); - - bridgeCommand("attach"); + let file = await openFilePickerForMedia(); + file = (await addMediaFromPath({ path: file })).val; + resolveMedia(filenameToLink(file)); } registerPackage("anki/TemplateButtons", { diff --git a/ts/routes/editor/rich-text-input/data-transfer.ts b/ts/routes/editor/rich-text-input/data-transfer.ts index 993348b1d..76cab078c 100644 --- a/ts/routes/editor/rich-text-input/data-transfer.ts +++ b/ts/routes/editor/rich-text-input/data-transfer.ts @@ -391,16 +391,24 @@ export function handleCutOrCopy(event: ClipboardEvent) { const FILE_PICKER_MEDIA_KEY = "media"; -export async function openFilePickerForImageOcclusion(): Promise { +export async function openFilePickerForSuffixes(suffixes: string[]): Promise { const filename = (await openFilePicker({ - title: tr.editingAddMedia(), + title: tr.editingMedia(), filterDescription: tr.editingMedia(), - extensions: imageSuffixes, + extensions: suffixes, key: FILE_PICKER_MEDIA_KEY, })).val; return filename; } +export async function openFilePickerForImageOcclusion(): Promise { + return await openFilePickerForSuffixes(imageSuffixes); +} + +export async function openFilePickerForMedia(): Promise { + return await openFilePickerForSuffixes(mediaSuffixes); +} + export async function extractImagePathFromHtml(html: string): Promise { const images = (await extractMediaFiles({ val: html })).vals; if (images.length === 0) {