diff --git a/ImagesModal.tsx b/ImagesModal.tsx index 40e73c7..388be13 100644 --- a/ImagesModal.tsx +++ b/ImagesModal.tsx @@ -20,6 +20,7 @@ interface Props { fetcher: Fetcher; onFetcherChange: (fetcher: Fetcher) => void; settings: PluginSettings; + random: boolean; onSelect: (image: Image) => void; } @@ -27,6 +28,7 @@ const ImagesModal = ({ fetcher: defaultFetcher, onFetcherChange, settings, + random, onSelect, }: Props) => { const [fetcher, setFetcher] = useState(defaultFetcher); @@ -39,9 +41,12 @@ const ImagesModal = ({ const [loading, setLoading] = useState(false); + const filteredImageProviders = random ? [ImageProvider.unsplash] : imageProviders + const fetchImages = async (query: string) => { try { - const images = await fetcher.searchImages(query); + const fetchFunc = random ? fetcher.randomImage : fetcher.searchImages + const images = await fetchFunc(query); setImages(images); setSelectedImage(0); } catch (e) { @@ -127,11 +132,11 @@ const ImagesModal = ({ prev - 1 < 0 ? images.length - 1 : prev - 1, ); } else if (e.ctrlKey && e.key === "u") { - let index = imageProviders.indexOf(fetcher.imageProvider) + 1; - if (index >= imageProviders.length) { + let index = filteredImageProviders.indexOf(fetcher.imageProvider) + 1; + if (index >= filteredImageProviders.length) { index = 0; } - onProviderChange(imageProviders[index]); + onProviderChange(filteredImageProviders[index]); } else if (e.ctrlKey && e.key === "i") { let index = imageSizes.indexOf(fetcher.imageSize) + 1; if (index >= imageSizes.length) { @@ -188,7 +193,7 @@ const ImagesModal = ({ onChange={onProviderSelectorChange} className="selector" > - {imageProviders.map((provider) => ( + {filteredImageProviders.map((provider) => ( diff --git a/ModalWrapper.tsx b/ModalWrapper.tsx index 72174d3..85594ed 100644 --- a/ModalWrapper.tsx +++ b/ModalWrapper.tsx @@ -7,7 +7,7 @@ import { createRoot } from "react-dom/client"; import { getFetcher } from "./fetchers"; import { Fetcher, Image } from "./fetchers/constants"; import { ImagesModal } from "./ImagesModal"; -import { PluginSettings } from "./SettingTab"; +import { ImageProvider, PluginSettings } from "./SettingTab"; export enum InsertPlace { default = "default", @@ -19,12 +19,14 @@ export class ModalWrapper extends Modal { fetcher: ReturnType; settings: PluginSettings; insertPlace: InsertPlace; + random: boolean; constructor( app: App, editor: Editor, settings: PluginSettings, insertPlace: InsertPlace = InsertPlace.default, + random = false, ) { super(app); this.editor = editor; @@ -32,8 +34,9 @@ export class ModalWrapper extends Modal { ...settings, useMarkdownLinks: app.vault.config.useMarkdownLinks, }; - this.fetcher = getFetcher(this.settings, app.vault); + this.fetcher = getFetcher({ ...this.settings, imageProvider: random ? ImageProvider.unsplash : this.settings.imageProvider }, app.vault); this.insertPlace = insertPlace; + this.random = random this.containerEl.addClass("image-inserter-container"); } @@ -51,6 +54,7 @@ export class ModalWrapper extends Modal { fetcher={this.fetcher} onFetcherChange={this.onFetcherChange.bind(this)} settings={this.settings} + random={this.random} onSelect={this.onChooseSuggestion.bind(this)} /> , diff --git a/fetchers/constants.ts b/fetchers/constants.ts index 0b90102..fd73cb0 100644 --- a/fetchers/constants.ts +++ b/fetchers/constants.ts @@ -53,6 +53,7 @@ export interface Fetcher { prevPage: () => void; nextPage: () => void; searchImages: (query: string) => Promise; + randomImage: (query: string) => Promise; touchDownloadLocation?: (url: string) => Promise; downloadImage: (url: string) => Promise; downloadAndInsertImage: ( diff --git a/fetchers/local.ts b/fetchers/local.ts index 02b6a52..f00af96 100644 --- a/fetchers/local.ts +++ b/fetchers/local.ts @@ -51,6 +51,9 @@ export const local = (settings: PluginSettings, vault: Vault) => { }; }); }, + async randomImage(_: string): Promise { + return [] + }, async downloadImage(_: string): Promise { return new ArrayBuffer(0); }, diff --git a/fetchers/pexels.ts b/fetchers/pexels.ts index f3be6f0..50c7758 100644 --- a/fetchers/pexels.ts +++ b/fetchers/pexels.ts @@ -79,6 +79,9 @@ export const pexels = (settings: PluginSettings, vault: Vault) => { }; }); }, + async randomImage(_: string): Promise { + return [] + }, async downloadImage(url: string): Promise { const res = await requestUrl({ url }); return res.arrayBuffer; diff --git a/fetchers/pixabay.ts b/fetchers/pixabay.ts index f4a2bbf..345389f 100644 --- a/fetchers/pixabay.ts +++ b/fetchers/pixabay.ts @@ -85,6 +85,9 @@ export const pixabay = (settings: PluginSettings, vault: Vault) => { }; }); }, + async randomImage(_: string): Promise { + return [] + }, async downloadImage(url: string): Promise { const res = await requestUrl({ url }); return res.arrayBuffer; diff --git a/fetchers/unsplash.ts b/fetchers/unsplash.ts index 99fb8b3..4a6ace1 100644 --- a/fetchers/unsplash.ts +++ b/fetchers/unsplash.ts @@ -82,6 +82,27 @@ export const unsplash = (settings: PluginSettings, vault: Vault) => { }; }); }, + async randomImage(query: string): Promise { + const url = new URL("/photos/random", proxyServer); + url.searchParams.set("query", query); + if (orientation != "not_specified") { + url.searchParams.set("orientation", orientation); + } + const res = await requestUrl({ url: url.toString() }); + const item: Unsplash.Photo = res.json; + return [{ + desc: (item.description || item.alt_description || "").replace( + new RegExp(/\n/g), + " ", + ), + thumb: item.urls.thumb, + url: item.urls[imageSizeMapping[imageSize]], + downloadLocationUrl: item.links.download_location, + pageUrl: item.links.html, + username: item.user.name, + userUrl: `https://unsplash.com/@${item.user.username}?${UTM}`, + }]; + }, async touchDownloadLocation(url: string): Promise { await requestUrl({ url: url.replace("https://api.unsplash.com", proxyServer), diff --git a/main.ts b/main.ts index 5de39ca..ba98757 100644 --- a/main.ts +++ b/main.ts @@ -25,6 +25,22 @@ export default class InsertUnsplashImage extends Plugin { new ModalWrapper(this.app, editor, this.settings, InsertPlace.frontmatter).open(); } }); + + this.addCommand({ + id: 'insert-random', + name: 'Insert random image (only support Unsplash)', + editorCallback: (editor: Editor) => { + new ModalWrapper(this.app, editor, this.settings, InsertPlace.default, true).open(); + } + }); + + this.addCommand({ + id: 'insert-random-in-frontmatter', + name: 'Insert random image in frontmatter (only support Unsplash)', + editorCallback: (editor: Editor) => { + new ModalWrapper(this.app, editor, this.settings, InsertPlace.frontmatter, true).open(); + } + }); } onunload() {}