aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsowgro <tpoke.ferrari@gmail.com>2025-01-18 15:16:12 -0500
committersowgro <tpoke.ferrari@gmail.com>2025-01-18 15:16:12 -0500
commit279e8c7ea4f7e48ee68844e4347a67e5875faaa2 (patch)
tree518b4c7dd2c5b1c626645ba17423e788c0ef426a
parentef013458cc29c6948603e32a001019fe6c52b743 (diff)
downloadbookmarks-home-279e8c7ea4f7e48ee68844e4347a67e5875faaa2.tar.gz
bookmarks-home-279e8c7ea4f7e48ee68844e4347a67e5875faaa2.tar.bz2
bookmarks-home-279e8c7ea4f7e48ee68844e4347a67e5875faaa2.zip
Icon picker working (barely, refresh after)
-rw-r--r--extension/src/Icons.ts4
-rw-r--r--extension/src/assets/check.svg1
-rw-r--r--extension/src/components/BMEditor.tsx33
-rw-r--r--extension/src/components/Body.tsx8
-rw-r--r--extension/src/components/Bookmark.tsx2
-rw-r--r--extension/src/components/FolderBody.tsx2
-rw-r--r--extension/src/components/FolderButton.tsx2
-rw-r--r--extension/src/components/IconPicker.tsx89
-rw-r--r--extension/src/components/SettingsEditor.tsx16
-rw-r--r--extension/src/index.css23
10 files changed, 132 insertions, 48 deletions
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 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px" fill="currentColor"><path d="M382-240 154-468l57-57 171 171 367-367 57 57-424 424Z"/></svg>
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<string[]>([]);
- const [gIcon, setGIcon] = useState<string | undefined>(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() {
</>)}
<h3>Icon</h3>
- <h4>Found on the site</h4>
- <div className={"icon-selector"}>
- { iconOptions &&
- // <RadioButtonGroup value={undefined} children={
- iconOptions.map(s =>
- <BMIcon imgSrc={s}/>
- )
- // />
- }
- </div>
- <h4>From Google</h4>
- <div className={"icon-selector"}>
- <BMIcon imgSrc={gIcon}/>
- </div>
- <h4>Custom</h4>
- <button className={"default"}>Upload</button>
+ <IconPicker bmData={activeEdit}/>
+
</>)}
</div>
);
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() {
}})()}
<style>{"body > .folderBody, a {color: " + settings.foregroundColor + "; }"}</style>
<div id={"action-area"}>
- {settings.editMode && <span>Edit mode: Drag bookmarks to change order</span>}
- <button onClick={_ => setSettings({...settings, editMode: !settings.editMode})}>
- {settings.editMode ? <EditIcon/> : <EditOffIcon/>}
- </button>
+ {/*{settings.editMode && <span>Edit mode: Drag bookmarks to change order</span>}*/}
+ {/*<button onClick={_ => setSettings({...settings, editMode: !settings.editMode})}>*/}
+ {/* {settings.editMode ? <EditIcon/> : <EditOffIcon/>}*/}
+ {/*</button>*/}
<button onClick={_ => setSettingsOpen(!settingsOpen)}>
<SettingsIcon/>
</button>
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(
- <div className={"bookmark"}>
+ <div className={"bookmark"} id={bmData.id}>
<a href={bmData.url} draggable={settings.editMode} onDrag={handleDrag} onDragEnd={handleDragEnd}>
<IconPre bmData={bmData}/>
<span>{bmData.title}</span>
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 (
<div className={"folderBody"}>
{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(
<>
- <div className={"bookmark"}>
+ <div className={"bookmark"} id={bmData.id}>
<a onClick={() => setFolderOpen(!folderOpen)} draggable={settings.editMode} onDrag={handleDrag}
onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
<div className="icon-box">
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<IIconOption[]>([]);
+ const [iconCache, setIconCache] = useState<IconCacheEntry | undefined>(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<HTMLInputElement>) {
+ 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 (<>
+ <div className={"icon-selector"}>
+ {iconOptions &&
+ iconOptions.map(i => <IconOption ico={i} isSelected={iconCache?.url == i.url} isSelectedAuto={false} id={props.bmData.id} />)
+ }
+ </div>
+ <h4>Custom</h4>
+ <input type={"file"} accept={"image/*"} className={"default"} name={"Upload"} onChange={handleImageUpload}/>
+ </>)
+}
+
+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 (
+ <div className={"icon-option"} onClick={handleClick}>
+ <BMIcon imgSrc={props.ico.url}/>
+ {props.isSelected && <div className={"selected"}>
+ <Check/>
+ </div>}
+ </div>
+ )
+}
+
+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.Dispatch<React.SetState
<h3>Icon Cache</h3>
<button className={"default"} onClick={_ => getBrowser().storage.local.clear()}>Clear Icon Cache</button>
- {/*<h3>Editing</h3>*/}
- {/*<label>*/}
- {/* <input type={"checkbox"}*/}
- {/* checked={!settings.editMode}*/}
- {/* onChange={e => setSettings({...settings, editMode: !e.target.checked})}*/}
- {/* />*/}
- {/* Prevent editing of bookmarks*/}
- {/*</label>*/}
+ <h3>Editing</h3>
+ <label>
+ <input type={"checkbox"}
+ checked={!settings.editMode}
+ onChange={e => setSettings({...settings, editMode: !e.target.checked})}
+ />
+ Prevent editing of bookmarks
+ </label>
<h3>Open Folders</h3>
<label>
diff --git a/extension/src/index.css b/extension/src/index.css
index 48710d0..b88c8c0 100644
--- a/extension/src/index.css
+++ b/extension/src/index.css
@@ -59,9 +59,9 @@ body {
margin: 5px;
padding: 10px;
flex-wrap: wrap;
- /*position: fixed;*/
+ /*position: absolute;*/
/*bottom: 0;*/
- animation: slideDown 0.2s ease;
+ animation: slideDown 0.1s ease;
overflow: hidden;
white-space: nowrap;
}
@@ -358,6 +358,21 @@ button:hover:not(.default) {
margin: 15px;
}
+.selected {
+ position: absolute;
+ top: 0;
+ left: 0;
+ background-color: #000000c4;
+ display: flex
+;
+ right: 0;
+ bottom: 0;
+ align-content: center;
+ justify-content: center;
+ align-items: center;
+ /* fill: black; */
+}
-
-
+.icon-option {
+ position: relative;
+}