Move Attach Media button

This commit is contained in:
Abdo 2025-06-18 23:16:23 +03:00
parent 70a69cfdbe
commit e48a2a5b6a
3 changed files with 19 additions and 31 deletions

View file

@ -6,7 +6,6 @@ from __future__ import annotations
import base64 import base64
import functools import functools
import html import html
import itertools
import json import json
import mimetypes import mimetypes
import os import os
@ -18,7 +17,7 @@ import warnings
from collections.abc import Callable from collections.abc import Callable
from enum import Enum from enum import Enum
from random import randrange from random import randrange
from typing import Any, Iterable, Match, cast from typing import Any, Iterable, Match
import bs4 import bs4
import requests import requests
@ -38,7 +37,7 @@ from aqt import AnkiQt, gui_hooks
from aqt.operations.notetype import update_notetype_legacy from aqt.operations.notetype import update_notetype_legacy
from aqt.qt import * from aqt.qt import *
from aqt.sound import av_player 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 from aqt.webview import AnkiWebView, AnkiWebViewKind
pics = ("jpg", "jpeg", "png", "gif", "svg", "webp", "ico", "avif") 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 # 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: 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. """Legacy routine used by add-ons to add a media file and update the current field.
canDelete is ignored.""" canDelete is ignored."""
@ -905,7 +883,6 @@ require("anki/ui").loaded.then(() => require("anki/NoteEditor").instances[0].too
self._links: dict[str, Callable] = dict( self._links: dict[str, Callable] = dict(
fields=Editor.onFields, fields=Editor.onFields,
cards=Editor.onCardLayout, cards=Editor.onCardLayout,
attach=Editor.onAddMedia,
record=Editor.onRecSound, record=Editor.onRecSound,
paste=Editor.onPaste, paste=Editor.onPaste,
cut=Editor.onCut, cut=Editor.onCut,

View file

@ -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 type { RichTextInputAPI } from "../rich-text-input";
import { editingInputIsRichText } from "../rich-text-input"; import { editingInputIsRichText } from "../rich-text-input";
import LatexButton from "./LatexButton.svelte"; import LatexButton from "./LatexButton.svelte";
import { filenameToLink, openFilePickerForMedia } from "../rich-text-input/data-transfer";
import { addMediaFromPath } from "@generated/backend";
const { focusedInput } = context.get(); const { focusedInput } = context.get();
@ -38,7 +40,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
resolve?.(media); resolve?.(media);
} }
function attachMediaOnFocus(): void { async function attachMediaOnFocus(): Promise<void> {
if (disabled) { if (disabled) {
return; return;
} }
@ -48,8 +50,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
async () => setFormat("inserthtml", await mediaPromise), async () => setFormat("inserthtml", await mediaPromise),
{ once: true }, { once: true },
); );
let file = await openFilePickerForMedia();
bridgeCommand("attach"); file = (await addMediaFromPath({ path: file })).val;
resolveMedia(filenameToLink(file));
} }
registerPackage("anki/TemplateButtons", { registerPackage("anki/TemplateButtons", {

View file

@ -391,16 +391,24 @@ export function handleCutOrCopy(event: ClipboardEvent) {
const FILE_PICKER_MEDIA_KEY = "media"; const FILE_PICKER_MEDIA_KEY = "media";
export async function openFilePickerForImageOcclusion(): Promise<string> { export async function openFilePickerForSuffixes(suffixes: string[]): Promise<string> {
const filename = (await openFilePicker({ const filename = (await openFilePicker({
title: tr.editingAddMedia(), title: tr.editingMedia(),
filterDescription: tr.editingMedia(), filterDescription: tr.editingMedia(),
extensions: imageSuffixes, extensions: suffixes,
key: FILE_PICKER_MEDIA_KEY, key: FILE_PICKER_MEDIA_KEY,
})).val; })).val;
return filename; return filename;
} }
export async function openFilePickerForImageOcclusion(): Promise<string> {
return await openFilePickerForSuffixes(imageSuffixes);
}
export async function openFilePickerForMedia(): Promise<string> {
return await openFilePickerForSuffixes(mediaSuffixes);
}
export async function extractImagePathFromHtml(html: string): Promise<string | null> { export async function extractImagePathFromHtml(html: string): Promise<string | null> {
const images = (await extractMediaFiles({ val: html })).vals; const images = (await extractMediaFiles({ val: html })).vals;
if (images.length === 0) { if (images.length === 0) {