///
///
///
///
import { scrapbox } from "jsr:@cosense/types@0.10/userscript";
import { getImages, type Image } from "jsr:@takker/gyazo@0.4";
import type { React } from "./react-event.ts";
export type { Image, React };
export interface AddGyazoMenuInit {
/** Gyazo Access token */
accessToken: string;
/** Max is `100`
* Note that free users cannot get more than 10 images.
*
* @default {10}
*/
maxCount?: number;
onClick?: (image: Image, event: React.MouseEvent) => void;
}
interface UnsafeWindow {
GM_fetch?: (typeof globalThis.fetch);
}
const id = "Gyazo Viewer";
export const addGyazoMenu = (init: AddGyazoMenuInit):void => {
let job: Promise = Promise.resolve();
const GM_fetch = (globalThis as unknown as UnsafeWindow).GM_fetch;
scrapbox.PageMenu.addMenu({
title: !GM_fetch ? "Open Gyazo" : id,
icon: "kamon kamon-gyazo",
onClick: !GM_fetch
? ()=> globalThis.open("https://gyazo.com/captures")
: () => {
job = job.then(
() => loadImages({
per: init.maxCount ?? 10,
accessToken: init.accessToken,
fetch: GM_fetch,
onClick: init.onClick,
})
);
},
});
};
interface LoadImagesInit {
per: number;
accessToken: string;
fetch?: typeof fetch;
onClick?: (image: Image, event: React.MouseEvent) => void;
}
const loadImages = async (init: LoadImagesInit): Promise => {
let timer: number | undefined;
try {
const promise = getImages({ page: 0, ...init });
// 読み込みに時間がかかるようであれば、読み込み中の表示を出す
timer = setTimeout(() => {
scrapbox.PageMenu(id).addItem({
title: "Loading...",
icon: "fas fa-spinner",
onClick: () => {},
})
}, 100);
const res = await promise;
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
const images = await res.json();
clearTimeout(timer);
scrapbox.PageMenu(id).removeAllItems();
for (const image of images) {
if (!image.image_id) continue;
scrapbox.PageMenu(id).addItem({
title: image.metadata?.title || "Untitled",
image: image.url,
onClick: (event) => init.onClick?.(image, event) ?? navigator
?.clipboard
?.writeText?.(image.permalink_url)
?.catch?.((e) => { alert(`${e}`); console.error(e); }),
});
}
} catch(e) {
clearTimeout(timer);
scrapbox.PageMenu(id).removeAllItems();
scrapbox.PageMenu(id).addItem({
title: "Failed to load the image list.",
icon: "fas fa-exclamation-triangle",
onClick: () => {},
});
console.error("Failed to load the image list", e);
}
};