From 8ad470aaf5434005db4c59106dcbcf4cbc8cf49b Mon Sep 17 00:00:00 2001 From: sowgro Date: Tue, 3 Dec 2024 00:02:21 -0500 Subject: Push drag and drop code so far --- extension/src/assets/create_folder.svg | 1 + extension/src/components/Body.tsx | 15 ++- extension/src/components/Bookmark-backup.txt | 161 --------------------------- extension/src/components/Bookmark.tsx | 92 ++++++++++++++- extension/src/index.css | 17 ++- 5 files changed, 116 insertions(+), 170 deletions(-) create mode 100644 extension/src/assets/create_folder.svg delete mode 100644 extension/src/components/Bookmark-backup.txt (limited to 'extension') diff --git a/extension/src/assets/create_folder.svg b/extension/src/assets/create_folder.svg new file mode 100644 index 0000000..3e94c9c --- /dev/null +++ b/extension/src/assets/create_folder.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/extension/src/components/Body.tsx b/extension/src/components/Body.tsx index e575d89..07b0259 100644 --- a/extension/src/components/Body.tsx +++ b/extension/src/components/Body.tsx @@ -9,9 +9,15 @@ import {getBrowser} from "../main.tsx"; export const Settings = React.createContext<[ISettings, (arg0: ISettings) => void]>([ - defaultSettings, - () => {} -]); + defaultSettings, + () => {} + ]); + +export const ActiveDrag = + React.createContext<[boolean, (arg0: boolean) => void]>([ + false, + () => {} + ]) /** * A component for the full body of the application @@ -22,6 +28,7 @@ function Body() { const [settings, setSettings] = useState(defaultSettings); const [selectedBookmarkTree, setSelectedBookmarkTree] = useState([]) const [fullBookmarkTree, setFullBookmarkTree] = useState([]) + const [activeDrag, setActiveDrag] = useState(false); useEffect(() => { loadSettings().then(r => { @@ -47,6 +54,7 @@ function Body() { return ( + {(() => {switch (settings.backgroundMode) { case "color": return () case "image": return () @@ -63,6 +71,7 @@ function Body() { {selectedBookmarkTree[0] && ()} + ) } diff --git a/extension/src/components/Bookmark-backup.txt b/extension/src/components/Bookmark-backup.txt deleted file mode 100644 index 4d1eb60..0000000 --- a/extension/src/components/Bookmark-backup.txt +++ /dev/null @@ -1,161 +0,0 @@ -import BookmarkTreeNode = browser.bookmarks.BookmarkTreeNode; -import React, {SyntheticEvent, useEffect} from "react"; -import {getBrowser} from "../main.tsx"; -import {Settings} from "./Body.tsx"; -import react from "@vitejs/plugin-react"; - -/** - * A component for a single bookmark - * - * @param props.data The BookmarkTreeNode with the data for the bookmark - */ -function Bookmark(props: {data: BookmarkTreeNode}) { - let [favicon, setFavicon] = React.useState(null); - let [iconMode, setIconMode] = React.useState<"large" | "small" | "letter">("letter"); - let [settings, setSettings] = React.useContext(Settings); - let [bgColor, setBgColor] = React.useState<[number, number, number] | null>(null) - // let [dropRight, setDropRight] = React.useState(false); - // let [dropLeft, setDropLeft] = React.useState(false); - // let [dropCenter, setDropCenter] = React.useState(false); - - useEffect(() => { - setBgColor([255, 0, 0]) - // faviconURL(props.data.url).then(o => o && setFavicon(o)) - faviconURL(props.data).then(r => { - if (r) { - setFavicon(r) - setIconMode("small"); - } - }) - }, []); - - // useEffect(() => { - // console.log("signal received", dropCenter) - // }, [dropCenter]); - - function handleImageLoad(e: SyntheticEvent) { - if (e.currentTarget.naturalWidth >= 75 || favicon!.startsWith("data:image/svg+xml")) { - setIconMode("large") - } - } - - return( -
- { - // console.log("dragStart") - // e.dataTransfer.dropEffect = "move"; - // e.dataTransfer.setData("bm-id", props.data.id); - // }} - > -
- {favicon ? ( - Bookmark icon - ) : ( - {new URL(props.data.url!).hostname.charAt(0)} - )} - -
- {props.data.title} -
- {/*
*/} - {/* setDropLeft(true)}*/} - {/* onDragLeave={_ => setDropRight(false)}*/} - {/* onDrop={e => getBrowser().bookmarks.move(e.dataTransfer.getData("bm-id"), {parentId: props.data.parentId, index: props.data.index})}*/} - {/* style={dropLeft ? undefined : {visibility: "hidden"}}*/} - {/* // hidden={!dropLeft}*/} - {/* >*/} - {/*
*/} - {/*
*/} - {/* setDropLeft(true)}*/} - {/* onDragLeave={_ => setDropRight(false)}*/} - {/* onDrop={e => getBrowser().bookmarks.move(e.dataTransfer.getData("bm-id"), {parentId: props.data.parentId, index: (props.data.index! + 1)})}*/} - {/* style={dropRight ? undefined : {visibility: "hidden"}}*/} - {/* // hidden={!dropRight}*/} - {/* >*/} - {/*
*/} - {/*
*/} - {/* {*/} - {/* e.preventDefault()*/} - {/* // console.log("dropped")*/} - {/* }}*/} - {/* onDragEnter={e => {*/} - {/* e.preventDefault()*/} - {/* setDropCenter(true)*/} - {/* console.log("enter")*/} - {/* }}*/} - {/* onDragLeave={_ => {*/} - {/* setDropCenter(false)*/} - {/* console.log("exit")*/} - {/* }}*/} - {/* onDrop={e => {*/} - {/* e.preventDefault();*/} - {/* console.log("dropped")*/} - {/* }}*/} - {/* style={dropCenter ? undefined : {visibility: "hidden"}}*/} - {/* // hidden={!dropCenter}*/} - {/* >*/} - {/* +*/} - {/*
*/} - {/*
*/} - - ); -} - -/** - * Gets the icon for a bookmark - * - * @param data The URL of the link - * @return The URL of the icon - */ -async function faviconURL(data: BookmarkTreeNode) { - let i = (await getBrowser().storage.local.get("icon-cache-"+data.id))["icon-cache-"+data.id]; - if (i) return i - - const url = new URL('https://www.google.com/s2/favicons'); - url.searchParams.set("sz", "256"); - url.searchParams.set("domain_url", data.url!); - let resp = await fetch(url) - let imgData = resp.ok ? await toDataURL(url.toString()) : null; - getBrowser().storage.local.set({["icon-cache-"+data.id]: imgData}); - return imgData; -} - -function toDataURL(url:string):string { - // @ts-ignore - return fetch(url) - .then(response => response.blob()) - .then(blob => new Promise((resolve, reject) => { - const reader = new FileReader() - reader.onloadend = () => resolve(reader.result) - reader.onerror = reject - reader.readAsDataURL(blob) - })) -} - -// function hashColor(url:string) { -// hashCode(String) -// } -// -// function hashCode(str: string) { -// let hash = 0; -// for (let i = 0, len = str.length; i < len; i++) { -// let chr = str.charCodeAt(i); -// hash = (hash << 5) - hash + chr; -// hash |= 0; // Convert to 32bit integer -// } -// return hash; -// } - -export default Bookmark; \ No newline at end of file diff --git a/extension/src/components/Bookmark.tsx b/extension/src/components/Bookmark.tsx index d1c1756..fc73387 100644 --- a/extension/src/components/Bookmark.tsx +++ b/extension/src/components/Bookmark.tsx @@ -1,8 +1,9 @@ import BookmarkTreeNode = browser.bookmarks.BookmarkTreeNode; import React, {SyntheticEvent, useEffect} from "react"; import {getBrowser} from "../main.tsx"; -import {Settings} from "./Body.tsx"; +import {ActiveDrag, Settings} from "./Body.tsx"; import ColorThief from 'colorthief' +import CreateFolderIcon from "../assets/create_folder.svg?react" import react from "@vitejs/plugin-react"; /** @@ -15,6 +16,10 @@ function Bookmark(props: {data: BookmarkTreeNode}) { let [iconMode, setIconMode] = React.useState<"large" | "small" | "letter">("letter"); let [settings, setSettings] = React.useContext(Settings); let [bgColor, setBgColor] = React.useState<[number, number, number] | null>(null) + let [activeDrag, setActiveDrag] = React.useContext(ActiveDrag); + let [dropRight, setDropRight] = React.useState(false); + let [dropLeft, setDropLeft] = React.useState(false); + let [dropCenter, setDropCenter] = React.useState(false); useEffect(() => { faviconURL(props.data).then(r => { @@ -33,9 +38,15 @@ function Bookmark(props: {data: BookmarkTreeNode}) { } } + function handleDrag(e: React.DragEvent) { + e.dataTransfer.dropEffect = "move"; + e.dataTransfer.setData("bm-id", props.data.id); + setActiveDrag(true); + } + return(
- + setActiveDrag(false)}>
{(() => { switch (iconMode) { case "letter": { @@ -55,6 +66,83 @@ function Bookmark(props: {data: BookmarkTreeNode}) {
{props.data.title}
+ {activeDrag && ( +
+
{ + e.preventDefault() + setDropLeft(true) + }} + onDragEnter={e =>{ + e.preventDefault() + }} + onDragLeave={_ => { + setDropLeft(false) + }} + onDrop={e => { + getBrowser().bookmarks.move(e.dataTransfer.getData("bm-id"), { + parentId: props.data.parentId, + index: props.data.index + }) + console.log("dropped") + }} + style={dropLeft ? undefined : {opacity: 0}} + // hidden={!dropLeft} + > +
+
+
{ + e.preventDefault(); + setDropRight(true); + }} + onDragEnter={e => { + e.preventDefault(); + }} + onDragLeave={_ => { + setDropRight(false) + }} + onDrop={e => { + getBrowser().bookmarks.move(e.dataTransfer.getData("bm-id"), { + parentId: props.data.parentId, + index: (props.data.index! + 1) + }) + e.preventDefault() + console.log("dropped right", e.dataTransfer.getData("bm-id")) + }} + style={dropRight ? undefined : {opacity: 0}} + // hidden={!dropRight} + > +
+
+
{ + e.preventDefault() + setDropCenter(true) + // console.log("dropped") + }} + onDragEnter={e => { + e.preventDefault() + // console.log("enter") + }} + onDragLeave={_ => { + setDropCenter(false) + // console.log("exit") + }} + onDrop={e => { + e.preventDefault(); + console.log("dropped") + }} + style={dropCenter ? undefined : {opacity: 0}} + // hidden={!dropCenter} + > + +
+
+ )}
); } diff --git a/extension/src/index.css b/extension/src/index.css index a85aeaf..a14e0d6 100644 --- a/extension/src/index.css +++ b/extension/src/index.css @@ -191,7 +191,7 @@ a { /* Drop targets */ .drop-targets { - pointer-events: none; + /*pointer-events: none;*/ position: absolute; top: 0; /* bottom: 0; */ @@ -215,7 +215,7 @@ a { align-items: center; > div { - background-color: aqua; + background-color: white; height: 50%; width: 4px; } @@ -231,7 +231,7 @@ a { align-items: center; > div { - background-color: aqua; + background-color: white; width: 4px; height: 50%; } @@ -248,13 +248,22 @@ a { align-items: center; > span { - color: aqua; + /*color: aqua;*/ font-size: 100px; /* background-color: aqua; */ /* aspect-ratio: 1 / 1; */ /* height: 100px; */ font-family: monospace; } + + > svg { + background-color: #000000ba; + width: 65px; + height: 65px; + border-radius: 10px; + padding: 10px; + margin-bottom: 14px; + } } -- cgit v1.2.3