From 279e8c7ea4f7e48ee68844e4347a67e5875faaa2 Mon Sep 17 00:00:00 2001 From: sowgro Date: Sat, 18 Jan 2025 15:16:12 -0500 Subject: Icon picker working (barely, refresh after) --- extension/src/Icons.ts | 4 +- extension/src/assets/check.svg | 1 + extension/src/components/BMEditor.tsx | 33 ++--------- extension/src/components/Body.tsx | 8 +-- extension/src/components/Bookmark.tsx | 2 +- extension/src/components/FolderBody.tsx | 2 + extension/src/components/FolderButton.tsx | 2 +- extension/src/components/IconPicker.tsx | 89 +++++++++++++++++++++++++++++ extension/src/components/SettingsEditor.tsx | 16 +++--- extension/src/index.css | 23 ++++++-- 10 files changed, 132 insertions(+), 48 deletions(-) create mode 100644 extension/src/assets/check.svg create mode 100644 extension/src/components/IconPicker.tsx diff --git a/extension/src/Icons.ts b/extension/src/Icons.ts index 39fee23..7c2288a 100644 --- a/extension/src/Icons.ts +++ b/extension/src/Icons.ts @@ -32,7 +32,7 @@ async function getIcon(bmData: BookmarkTreeNode, setIcon: (icon: string) => void async function iconFromGoogle(bmData: BookmarkTreeNode, setIcon: (icon: string) => void) { const url = new URL('https://www.google.com/s2/favicons'); url.searchParams.set("sz", "256"); - url.searchParams.set("domain_url", bmData.url!); + url.searchParams.set("domain_url", new URL(bmData.url!).origin); let resp = await fetch(url) if (!resp.ok) { return Promise.reject(); @@ -77,4 +77,4 @@ async function toDataURL(url: string) { }); } -export {type IconCacheEntry, getIcon} \ No newline at end of file +export {type IconCacheEntry, getIcon, toDataURL} \ No newline at end of file diff --git a/extension/src/assets/check.svg b/extension/src/assets/check.svg new file mode 100644 index 0000000..de480f6 --- /dev/null +++ b/extension/src/assets/check.svg @@ -0,0 +1 @@ + diff --git a/extension/src/components/BMEditor.tsx b/extension/src/components/BMEditor.tsx index b97d21f..eb84246 100644 --- a/extension/src/components/BMEditor.tsx +++ b/extension/src/components/BMEditor.tsx @@ -4,25 +4,16 @@ import {ActiveEdit} from "./Body.tsx"; import {getBrowser} from "../main.tsx"; import RadioButtonGroup from "./RadioButtonGroup.tsx"; import BMIcon from "./BMIcon.tsx"; +import IconPicker from "./IconPicker.tsx"; + + function BMEditor() { const [activeEdit, setActiveEdit] = useContext(ActiveEdit); - const [iconOptions, setIconOptions] = useState([]); - const [gIcon, setGIcon] = useState(undefined); - useEffect(() => { if (!activeEdit) return; - - const gURL = new URL('https://www.google.com/s2/favicons'); - gURL.searchParams.set("sz", "256"); - gURL.searchParams.set("domain_url", activeEdit.url!); - setGIcon(gURL.toString()); - - getBrowser().storage.local.get("icon-aval-"+activeEdit.id).then( r => { - setIconOptions(r["icon-aval-" + activeEdit.id]); - }); }, [activeEdit]); let isFolder = activeEdit && activeEdit.children && activeEdit.children.length > 0; @@ -48,22 +39,8 @@ function BMEditor() { )}

Icon

-

Found on the site

-
- { iconOptions && - // - - ) - // /> - } -
-

From Google

-
- -
-

Custom

- + + )} ); diff --git a/extension/src/components/Body.tsx b/extension/src/components/Body.tsx index e4c371b..59553da 100644 --- a/extension/src/components/Body.tsx +++ b/extension/src/components/Body.tsx @@ -61,10 +61,10 @@ function Body() { }})()}
- {settings.editMode && Edit mode: Drag bookmarks to change order} - + {/*{settings.editMode && Edit mode: Drag bookmarks to change order}*/} + {/**/} diff --git a/extension/src/components/Bookmark.tsx b/extension/src/components/Bookmark.tsx index cbd8af6..05d0430 100644 --- a/extension/src/components/Bookmark.tsx +++ b/extension/src/components/Bookmark.tsx @@ -83,7 +83,7 @@ function Bookmark(props: {id: string}) { }; return( -
+
{bmData.title} diff --git a/extension/src/components/FolderBody.tsx b/extension/src/components/FolderBody.tsx index 71dad4a..9b7c5f4 100644 --- a/extension/src/components/FolderBody.tsx +++ b/extension/src/components/FolderBody.tsx @@ -37,6 +37,8 @@ function FolderBody (props: {id: string}) { updateBookmarks(); }, [settings]); + if (children.length <= 0) return; + return (
{children.map(child => diff --git a/extension/src/components/FolderButton.tsx b/extension/src/components/FolderButton.tsx index 244760d..8d64ffd 100644 --- a/extension/src/components/FolderButton.tsx +++ b/extension/src/components/FolderButton.tsx @@ -91,7 +91,7 @@ function FolderButton(props: {id: string}) { return( <> -
+
setFolderOpen(!folderOpen)} draggable={settings.editMode} onDrag={handleDrag} onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
diff --git a/extension/src/components/IconPicker.tsx b/extension/src/components/IconPicker.tsx new file mode 100644 index 0000000..ce2488b --- /dev/null +++ b/extension/src/components/IconPicker.tsx @@ -0,0 +1,89 @@ +import BookmarkTreeNode = browser.bookmarks.BookmarkTreeNode; +import React, {useEffect, useState} from "react"; +import {getBrowser} from "../main.tsx"; +import BMIcon from "./BMIcon.tsx"; +import Check from "../assets/check.svg?react" +import {IconCacheEntry, toDataURL} from "../Icons.ts"; + +interface IIconOption { + url: string, + source: "google" | "site" | "custom" +} + +function IconPicker(props: {bmData: BookmarkTreeNode}) { + const [iconOptions, setIconOptions] = useState([]); + const [iconCache, setIconCache] = useState(undefined); + + useEffect(() => { + getBrowser().storage.local.get("icon-cache-"+props.bmData.id).then(r => { + setIconCache(r["icon-cache-"+props.bmData.id]); + }); + + (async ()=>{ + let iconOptions2: IIconOption[] = []; + + const gURL = new URL('https://www.google.com/s2/favicons'); + gURL.searchParams.set("sz", "256"); + gURL.searchParams.set("domain_url", new URL(props.bmData.url!).origin); + let gResponse = await fetch(gURL) + if (gResponse) { + iconOptions2.push({ + url: gURL.toString(), + source: "google" + }) + } + + let siteIcons: string[] = (await getBrowser().storage.local.get("icon-aval-"+props.bmData.id))["icon-aval-" + props.bmData.id] + if (siteIcons) { + iconOptions2.push(...siteIcons.map(ic => ({url: ic, source: "site"} as IIconOption))) + } + + setIconOptions(iconOptions2); + })() + }, []); + + function handleImageUpload(e: React.ChangeEvent) { + if (!e.target.files || e.target.files.length <= 0) { + return; + } + let file = e.target.files[0]; + + let reader = new FileReader(); + reader.readAsDataURL(file); + reader.onload = () => { + setIconOptions([...iconOptions, {url: reader.result, source: "custom"} as IIconOption]) + } + } + + return (<> +
+ {iconOptions && + iconOptions.map(i => ) + } +
+

Custom

+ + ) +} + +function IconOption(props: {ico: IIconOption, isSelected: boolean, isSelectedAuto: boolean, id: string}) { + + async function handleClick() { + await getBrowser().storage.local.set({["icon-cache-"+props.id]: { + ...props.ico, + data: await toDataURL(props.ico.url), + setByUser: true + } as IconCacheEntry}) + } + + return ( +
+ + {props.isSelected &&
+ +
} +
+ ) +} + +export default IconPicker; \ No newline at end of file diff --git a/extension/src/components/SettingsEditor.tsx b/extension/src/components/SettingsEditor.tsx index 2ad5104..362e774 100644 --- a/extension/src/components/SettingsEditor.tsx +++ b/extension/src/components/SettingsEditor.tsx @@ -89,14 +89,14 @@ function SettingsEditor(props: {isOpen: [boolean, React.DispatchIcon Cache - {/*

Editing

*/} - {/**/} +

Editing

+

Open Folders