From c3649962298db1600947413527db8b5f05ebc7ab Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Sun, 6 Oct 2024 12:42:36 -0400 Subject: [PATCH 01/13] (feat): make text appear on screen and minimap --- src/components/InfinateCanvas.tsx | 12 ++- src/components/MiniMap.tsx | 30 ++++++ src/components/TextItem.tsx | 108 +++++++++++++++++++++ src/components/cardSelector/TextButton.tsx | 37 +++++++ src/signals/index.ts | 1 + src/signals/texts.ts | 46 +++++++++ src/types/Card.ts | 2 +- src/utils/localStorage.ts | 4 +- 8 files changed, 237 insertions(+), 3 deletions(-) create mode 100644 src/components/TextItem.tsx create mode 100644 src/signals/texts.ts diff --git a/src/components/InfinateCanvas.tsx b/src/components/InfinateCanvas.tsx index 5a7eb0c..d465552 100644 --- a/src/components/InfinateCanvas.tsx +++ b/src/components/InfinateCanvas.tsx @@ -1,5 +1,5 @@ import { useRef, useEffect } from "kaioken" -import { ImagesSignal, NotesSigal, canvasDimentsion } from "../signals" +import { ImagesSignal, NotesSigal, TextSignal, canvasDimentsion } from "../signals" import { NoteCard } from "./NoteCard" import notes from "../signals/notes" import { MiniMap } from "./MiniMap" @@ -8,6 +8,8 @@ import images from "../signals/images" import { CardSelector } from "./cardSelector/CardSelector" import { Logo } from "./Logo" import { useThemeDetector } from "../utils/useThemeDetector" +import { isTheme } from "../utils/isTheme" +import { TextItem } from "./TextItem" export default function InfiniteCanvas() { const containerRef = useRef(null) @@ -74,6 +76,14 @@ export default function InfiniteCanvas() { ) })} + + {Object.keys(TextSignal.default.texts.value).map((itemKey: string) => { + const item = TextSignal.default.texts.value[itemKey] + return ( + + ) + })} + diff --git a/src/components/MiniMap.tsx b/src/components/MiniMap.tsx index 24e524a..01b48bb 100644 --- a/src/components/MiniMap.tsx +++ b/src/components/MiniMap.tsx @@ -3,6 +3,7 @@ import notes, { NoteCardType } from "../signals/notes" import { canvasDimentsion } from "../signals" import { LayerEnum } from "../utils/enums" import images, { ImageCardType } from "../signals/images" +import texts from "../signals/texts" const _MAP_OFFSET = 20 const _MAP_SCALE_FACTOR = 10 @@ -111,6 +112,35 @@ export function MiniMap() { ) })} + {Object.keys(texts.texts.value).map((textKey: textCardType['id']) => { + const text = texts.texts.value[textKey] + const el = useRef(null) + + function _handleItemClick(_e: MouseEvent) { + window.scrollTo({ + left: text.position.x - ((viewportWidth / 2) - (text.dimensions.w / 2)), + top: text.position.y - ((viewportHeight / 2) - (text.dimensions.h / 2)), + behavior: 'smooth' + }) + } + + return ( +
+ ) + })} +
{ + localStorage.setItem("texts", JSON.stringify(texts.texts.value)) + }, time) + } + + function _handleMouseMove(e: MouseEvent) { + e.preventDefault() + if (!pressed.value) return + + newX.current = e.pageX - offsetX.current + newY.current = e.pageY - offsetY.current + const newPos = { x: newX.current, y: newY.current } + + TextSignal.default.updateTextProperty(itemKey, 'position', newPos) + updateLocalStorage() + } + + function _handleMouseUp(e: MouseEvent) { + e.preventDefault() + pressed.value = false + window.removeEventListener('mousemove', _handleMouseMove) + window.removeEventListener('mouseup', _handleMouseUp) + } + + function _handleMouseDown(e: MouseEvent) { + e.preventDefault() + offsetX.current = e.offsetX + offsetY.current = e.offsetY + pressed.value = true + window.addEventListener('mousemove', _handleMouseMove) + window.addEventListener('mouseup', _handleMouseUp) + } + + function _handleResizeMove(e: MouseEvent) { + const { pageX, pageY } = e + const [newX, newY] = [initialResizeX.current - pageX, initialResizeY.current - pageY] + + const newW = -newX + item.dimensions.w + const newH = -newY + item.dimensions.h + const newDim = { w: newW, h: newH } + + TextSignal.default.updateTextProperty(itemKey, 'dimensions', newDim) + TextSignal.default.texts.notify() + } + + + function _handleResizeMouseDown(e: MouseEvent) { + initialResizeX.current = e.pageX + initialResizeY.current = e.pageY + pressed.value = true + window.addEventListener('mousemove', _handleResizeMove) + window.addEventListener('mouseup', _handleResizeMouseUp) + } + + function _handleResizeMouseUp() { + pressed.value = false + updateLocalStorage() + window.removeEventListener('mousemove', _handleResizeMove) + window.removeEventListener('mouseup', _handleResizeMouseUp) + } + + return ( +
focusedItem.value = itemKey} + className="select-none transition flex flex-col justify-stretch shadow-lg rounded border border-[#3c3c3c] absolute border-dashed" + style={{ + zIndex: `${focusedItem.value == itemKey ? LayerEnum.CARD_ELEVATED : LayerEnum.CARD}`, + width: `${item.dimensions.w}px`, + height: `${item.dimensions.h}px`, + top: `${item.position.y}px`, + left: `${item.position.x}px`, + }} + > + + {item.contents} + + +
+ + ) +} + diff --git a/src/components/cardSelector/TextButton.tsx b/src/components/cardSelector/TextButton.tsx index 0abe079..948d1a4 100644 --- a/src/components/cardSelector/TextButton.tsx +++ b/src/components/cardSelector/TextButton.tsx @@ -1,8 +1,28 @@ import { Tooltip } from "./Tooltip"; +import { TextSignal } from "../../signals"; +import texts from "../../signals/texts"; +import { updateLocalStorage } from "../../utils/localStorage"; import { defaultClassName } from "./utils"; export function TextButton() { + function _handleClick(e: MouseEvent) { + TextSignal.default.addText({ + type: "text", + title: "New Note", + contents: "todo: fill me", + position: { + x: e.pageX - 100, + y: e.pageY + (window.innerHeight / 2) - 100 + }, + dimensions: { + w: 200, + h: 100 + } + }) + updateLocalStorage("text", texts.texts.value) + } + return ( + + + + + ) } diff --git a/src/signals/index.ts b/src/signals/index.ts index 21dfeb8..09d8b5e 100644 --- a/src/signals/index.ts +++ b/src/signals/index.ts @@ -6,3 +6,4 @@ export const canvasDimentsion = signal({ width: 3000, height: 3000 }) export * as NotesSigal from "./notes" export * as ImagesSignal from "./images" +export * as TextSignal from "./texts" diff --git a/src/signals/texts.ts b/src/signals/texts.ts new file mode 100644 index 0000000..5f02e7f --- /dev/null +++ b/src/signals/texts.ts @@ -0,0 +1,46 @@ +import { signal } from "kaioken" +import { Card } from "../types" +import { focusedItem } from "." + +export type TextCardType = Card<"text"> + +const texts = signal>({}) + +function loadLocalStorage() { + texts.value = JSON.parse(localStorage.getItem("texts") ?? "{}") +} + +function addText(data: Omit) { + const newCard = { + ...data, + id: crypto.randomUUID(), + } + texts.value[newCard.id] = newCard + texts.notify() + focusedItem.value = newCard.id +} + +function removeText(id: TextCardType["id"]) { + delete texts.value[id] + texts.notify() +} +function updateTextProperty( + id: TextCardType["id"], + property: K, + data: TextCardType[K] +) { + const newData = { + ...texts.value[id], + [property]: data, + } + texts.value[id] = newData + texts.notify() +} + +export default { + texts, + addText, + removeText, + updateTextProperty, + loadLocalStorage, +} diff --git a/src/types/Card.ts b/src/types/Card.ts index cd5ae2c..e810a38 100644 --- a/src/types/Card.ts +++ b/src/types/Card.ts @@ -1,4 +1,4 @@ -export type CardTypes = "note" | "image" +export type CardTypes = "note" | "image" | "text" export type positionCoords = { x: number; y: number } export type dimensionCoords = { w: number; h: number } diff --git a/src/utils/localStorage.ts b/src/utils/localStorage.ts index 57316bf..fcd9549 100644 --- a/src/utils/localStorage.ts +++ b/src/utils/localStorage.ts @@ -1,5 +1,7 @@ +import { CardTypes } from "../types" + export function updateLocalStorage( - location: "notes" | "images", + location: CardTypes, collection: unknown[] | Record ) { localStorage.setItem(location, JSON.stringify(collection)) From 3d61f28aa0af46fd567fdb5debcc6fbf008da338 Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Mon, 7 Oct 2024 00:28:54 -0400 Subject: [PATCH 02/13] working on some text logic playing with ideas --- src/components/InfinateCanvas.tsx | 2 ++ src/components/TextItem.tsx | 14 +++++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/InfinateCanvas.tsx b/src/components/InfinateCanvas.tsx index d465552..58b7452 100644 --- a/src/components/InfinateCanvas.tsx +++ b/src/components/InfinateCanvas.tsx @@ -10,6 +10,7 @@ import { Logo } from "./Logo" import { useThemeDetector } from "../utils/useThemeDetector" import { isTheme } from "../utils/isTheme" import { TextItem } from "./TextItem" +import texts from "../signals/texts" export default function InfiniteCanvas() { const containerRef = useRef(null) @@ -38,6 +39,7 @@ export default function InfiniteCanvas() { window.addEventListener("scrollend", _updatePosition) notes.loadLocalStorage() images.loadLocalStorage() + texts.loadLocalStorage() return () => { window.removeEventListener("resize", _updateDimensions) diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index e7a834b..7e1775a 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -3,6 +3,7 @@ import { TextSignal, focusedItem } from "../signals" import { useDebounce } from "../utils/useDebounce" import texts, { TextCardType } from "../signals/texts" import { LayerEnum } from "../utils/enums" +import { isTheme } from "../utils/isTheme" namespace TextItem { export interface TextCardProps { @@ -87,20 +88,19 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { return (
focusedItem.value = itemKey} - className="select-none transition flex flex-col justify-stretch shadow-lg rounded border border-[#3c3c3c] absolute border-dashed" + onmousedown={_handleMouseDown} + className="select-none transition flex flex-col justify-stretch rounded border border-[#3c3c3c] absolute border-dashed" style={{ zIndex: `${focusedItem.value == itemKey ? LayerEnum.CARD_ELEVATED : LayerEnum.CARD}`, width: `${item.dimensions.w}px`, - height: `${item.dimensions.h}px`, + height: `${item.dimensions.h + 100}px`, top: `${item.position.y}px`, left: `${item.position.x}px`, }} > - - {item.contents} - - +
+

{item.contents}

+
) From cd44e6f570864fe63e2d79d9e906305025009949 Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Thu, 10 Oct 2024 08:23:30 -0400 Subject: [PATCH 03/13] fix broken code --- src/components/TextItem.tsx | 2 -- src/components/cardSelector/TextButton.tsx | 17 ----------------- 2 files changed, 19 deletions(-) diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index 7e1775a..1455343 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -3,7 +3,6 @@ import { TextSignal, focusedItem } from "../signals" import { useDebounce } from "../utils/useDebounce" import texts, { TextCardType } from "../signals/texts" import { LayerEnum } from "../utils/enums" -import { isTheme } from "../utils/isTheme" namespace TextItem { export interface TextCardProps { @@ -13,7 +12,6 @@ namespace TextItem { } export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { - const saved = signal(true) const pressed = signal(false) const newX = useRef(0) const newY = useRef(0) diff --git a/src/components/cardSelector/TextButton.tsx b/src/components/cardSelector/TextButton.tsx index 948d1a4..2b1d925 100644 --- a/src/components/cardSelector/TextButton.tsx +++ b/src/components/cardSelector/TextButton.tsx @@ -42,22 +42,5 @@ export function TextButton() { - - - - - ) } From 09e6c1c9a98be463c2a661c56c5bb89d0268e1be Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Thu, 10 Oct 2024 12:58:34 -0400 Subject: [PATCH 04/13] feat(text): make text insert work with move and resize functionality --- src/components/MiniMap.tsx | 9 ++--- src/components/TextItem.tsx | 39 ++++++++++++++------ src/components/cardSelector/ImportButton.tsx | 6 +-- src/components/cardSelector/TextButton.tsx | 5 ++- src/signals/images.ts | 2 +- src/signals/notes.ts | 2 +- src/signals/texts.ts | 2 +- src/types/Card.ts | 2 +- 8 files changed, 42 insertions(+), 25 deletions(-) diff --git a/src/components/MiniMap.tsx b/src/components/MiniMap.tsx index 01b48bb..986b17d 100644 --- a/src/components/MiniMap.tsx +++ b/src/components/MiniMap.tsx @@ -3,7 +3,7 @@ import notes, { NoteCardType } from "../signals/notes" import { canvasDimentsion } from "../signals" import { LayerEnum } from "../utils/enums" import images, { ImageCardType } from "../signals/images" -import texts from "../signals/texts" +import texts, { TextCardType } from "../signals/texts" const _MAP_OFFSET = 20 const _MAP_SCALE_FACTOR = 10 @@ -112,7 +112,7 @@ export function MiniMap() { ) })} - {Object.keys(texts.texts.value).map((textKey: textCardType['id']) => { + {Object.keys(texts.texts.value).map((textKey: TextCardType['id']) => { const text = texts.texts.value[textKey] const el = useRef(null) @@ -129,12 +129,11 @@ export function MiniMap() { onclick={_handleItemClick} style={{ position: 'absolute', - width: `${text.dimensions.w / _MAP_SCALE_FACTOR}px`, - height: `${text.dimensions.h / _MAP_SCALE_FACTOR}px`, + width: `${300 / _MAP_SCALE_FACTOR}px`, + height: `${100 / _MAP_SCALE_FACTOR}px`, top: `${(text.position.y / _MAP_SCALE_FACTOR)}px`, left: `${(text.position.x / _MAP_SCALE_FACTOR)}px`, border: '1px solid #222', - borderRadius: '2px', zIndex: `${LayerEnum.MINIMAP + 1}` }} >
diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index 1455343..1b198de 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -18,7 +18,6 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { const offsetX = useRef(0) const offsetY = useRef(0) const initialResizeX = useRef(0) - const initialResizeY = useRef(0) const { debounce } = useDebounce() @@ -49,6 +48,7 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { function _handleMouseDown(e: MouseEvent) { e.preventDefault() + focusedItem.value = itemKey offsetX.current = e.offsetX offsetY.current = e.offsetY pressed.value = true @@ -57,12 +57,11 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { } function _handleResizeMove(e: MouseEvent) { - const { pageX, pageY } = e - const [newX, newY] = [initialResizeX.current - pageX, initialResizeY.current - pageY] + const { pageX } = e + const newX = initialResizeX.current - pageX const newW = -newX + item.dimensions.w - const newH = -newY + item.dimensions.h - const newDim = { w: newW, h: newH } + const newDim = { w: newW, h: 0 } TextSignal.default.updateTextProperty(itemKey, 'dimensions', newDim) TextSignal.default.texts.notify() @@ -71,7 +70,6 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { function _handleResizeMouseDown(e: MouseEvent) { initialResizeX.current = e.pageX - initialResizeY.current = e.pageY pressed.value = true window.addEventListener('mousemove', _handleResizeMove) window.addEventListener('mouseup', _handleResizeMouseUp) @@ -87,18 +85,37 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { return (
-
-

{item.contents}

+
+ {item.contents}
+ + + +
) diff --git a/src/components/cardSelector/ImportButton.tsx b/src/components/cardSelector/ImportButton.tsx index 5a41c7d..7226b8c 100644 --- a/src/components/cardSelector/ImportButton.tsx +++ b/src/components/cardSelector/ImportButton.tsx @@ -21,15 +21,15 @@ export function ImportButton() { let content = readerEvent.target?.result; // get only the base64 parts and not any identifiers content = (content as string).split(',')[1] - const data: Record | Card<'image'>> = convertBase64ToJson(content) + const data: Record | Card<'images'>> = convertBase64ToJson(content) for (let key in data) { const item = data[key] - if (item.type == 'image') { + if (item.type == 'images') { const { id, ...rest } = item images.addImage(rest) } - if (item.type == 'note') { + if (item.type == 'notes') { const { id, ...rest } = item notes.addNote(rest) } diff --git a/src/components/cardSelector/TextButton.tsx b/src/components/cardSelector/TextButton.tsx index 2b1d925..d253ddc 100644 --- a/src/components/cardSelector/TextButton.tsx +++ b/src/components/cardSelector/TextButton.tsx @@ -8,7 +8,7 @@ export function TextButton() { function _handleClick(e: MouseEvent) { TextSignal.default.addText({ - type: "text", + type: "texts", title: "New Note", contents: "todo: fill me", position: { @@ -20,12 +20,13 @@ export function TextButton() { h: 100 } }) - updateLocalStorage("text", texts.texts.value) + updateLocalStorage("texts", texts.texts.value) } return ( +export type ImageCardType = Card<"images"> const images = signal>({}) diff --git a/src/signals/notes.ts b/src/signals/notes.ts index 755fb69..71be04a 100644 --- a/src/signals/notes.ts +++ b/src/signals/notes.ts @@ -2,7 +2,7 @@ import { signal } from "kaioken" import { Card } from "../types" import { focusedItem } from "." -export type NoteCardType = Card<"note"> +export type NoteCardType = Card<"notes"> const notes = signal>({}) diff --git a/src/signals/texts.ts b/src/signals/texts.ts index 5f02e7f..72b5e5a 100644 --- a/src/signals/texts.ts +++ b/src/signals/texts.ts @@ -2,7 +2,7 @@ import { signal } from "kaioken" import { Card } from "../types" import { focusedItem } from "." -export type TextCardType = Card<"text"> +export type TextCardType = Card<"texts"> const texts = signal>({}) diff --git a/src/types/Card.ts b/src/types/Card.ts index e810a38..c2dad2e 100644 --- a/src/types/Card.ts +++ b/src/types/Card.ts @@ -1,4 +1,4 @@ -export type CardTypes = "note" | "image" | "text" +export type CardTypes = "notes" | "images" | "texts" export type positionCoords = { x: number; y: number } export type dimensionCoords = { w: number; h: number } From 2fdb9e8d6eadd30ca5766117729751ce48679cd4 Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Thu, 10 Oct 2024 13:00:55 -0400 Subject: [PATCH 05/13] feat(text): update border radius of text mini map item --- src/components/MiniMap.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/MiniMap.tsx b/src/components/MiniMap.tsx index 986b17d..fe618ac 100644 --- a/src/components/MiniMap.tsx +++ b/src/components/MiniMap.tsx @@ -125,7 +125,7 @@ export function MiniMap() { } return ( -
Date: Thu, 10 Oct 2024 21:56:48 -0400 Subject: [PATCH 06/13] feat(text): add text drop shadow and change shade of notes cards --- src/components/NoteCard.tsx | 2 +- src/components/TextItem.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/NoteCard.tsx b/src/components/NoteCard.tsx index 590e8ad..1e1c82d 100644 --- a/src/components/NoteCard.tsx +++ b/src/components/NoteCard.tsx @@ -129,7 +129,7 @@ export function NoteCard({ key: itemKey, data: item }: NoteCard.NoteCardProps) {
{/* Header Bar */} diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index 1b198de..8a61688 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -94,7 +94,7 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { left: `${item.position.x}px`, }} > -
+
{item.contents}
From d6504ce0ce3069c9e9a2e0d42d3bb35f55d817fd Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Thu, 10 Oct 2024 23:08:47 -0400 Subject: [PATCH 07/13] feat(text): fix bug trying to resize text moving element --- src/components/ImageCard.tsx | 14 ++++++--- src/components/TextItem.tsx | 59 ++++++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 28 deletions(-) diff --git a/src/components/ImageCard.tsx b/src/components/ImageCard.tsx index 1f750ff..3601c73 100644 --- a/src/components/ImageCard.tsx +++ b/src/components/ImageCard.tsx @@ -88,6 +88,12 @@ export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps window.removeEventListener('mouseup', _handleResizeMouseUp) } + function _handleClose(_e: Event) { + ImagesSignal.default.removeImage(item.id) + ImagesSignal.default.images.notify() + debounceLSUpdate() + } + return (
- +
diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index 8a61688..a12bc49 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -47,8 +47,9 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { } function _handleMouseDown(e: MouseEvent) { - e.preventDefault() focusedItem.value = itemKey + e.preventDefault() + e.stopPropagation() offsetX.current = e.offsetX offsetY.current = e.offsetY pressed.value = true @@ -69,23 +70,24 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { function _handleResizeMouseDown(e: MouseEvent) { + e.stopPropagation() initialResizeX.current = e.pageX pressed.value = true window.addEventListener('mousemove', _handleResizeMove) window.addEventListener('mouseup', _handleResizeMouseUp) } - function _handleResizeMouseUp() { + function _handleResizeMouseUp(_e: MouseEvent) { pressed.value = false - updateLocalStorage() window.removeEventListener('mousemove', _handleResizeMove) window.removeEventListener('mouseup', _handleResizeMouseUp) + updateLocalStorage() } return (
-
+
{item.contents}
- - - + + +
) } +function ExpandIcon({ cb, item }: { + cb: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null | undefined, + item: TextSignal.TextCardType +}) { + + return ( + + + + ) +} From 3f199cf43fde30fa5a0d47256520dadc76461590 Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Thu, 10 Oct 2024 23:32:55 -0400 Subject: [PATCH 08/13] feat(text): change logic to properly use fontsize and update minimap previously the minimap was hardcoded and thus wouldnt update the size of the text relative to its real size. Im using a useEffect, which im not happy with. IMO you should not use state to set state, but at the moment i dont really know what else to do, thus ithis is the solution. --- src/components/MiniMap.tsx | 4 ++-- src/components/TextItem.tsx | 21 +++++++++++++++------ src/components/cardSelector/TextButton.tsx | 1 + src/signals/texts.ts | 4 +++- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/components/MiniMap.tsx b/src/components/MiniMap.tsx index fe618ac..c9c60bc 100644 --- a/src/components/MiniMap.tsx +++ b/src/components/MiniMap.tsx @@ -129,8 +129,8 @@ export function MiniMap() { onclick={_handleItemClick} style={{ position: 'absolute', - width: `${300 / _MAP_SCALE_FACTOR}px`, - height: `${100 / _MAP_SCALE_FACTOR}px`, + width: `${text.dimensions.w / _MAP_SCALE_FACTOR}px`, + height: `${text.dimensions.h / _MAP_SCALE_FACTOR}px`, top: `${(text.position.y / _MAP_SCALE_FACTOR)}px`, left: `${(text.position.x / _MAP_SCALE_FACTOR)}px`, border: '1px solid #222', diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index a12bc49..ef5afac 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -1,8 +1,9 @@ -import { signal, useRef } from "kaioken" +import { signal, useEffect, useRef } from "kaioken" import { TextSignal, focusedItem } from "../signals" import { useDebounce } from "../utils/useDebounce" import texts, { TextCardType } from "../signals/texts" import { LayerEnum } from "../utils/enums" +import { Card } from "../types" namespace TextItem { export interface TextCardProps { @@ -18,6 +19,7 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { const offsetX = useRef(0) const offsetY = useRef(0) const initialResizeX = useRef(0) + const elRef = useRef(null) const { debounce } = useDebounce() @@ -60,14 +62,20 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { function _handleResizeMove(e: MouseEvent) { const { pageX } = e const newX = initialResizeX.current - pageX + const newFontSize = Math.floor(-newX + item.fontSize) - const newW = -newX + item.dimensions.w - const newDim = { w: newW, h: 0 } - - TextSignal.default.updateTextProperty(itemKey, 'dimensions', newDim) + TextSignal.default.updateTextProperty(itemKey, 'fontSize', newFontSize) TextSignal.default.texts.notify() } + useEffect(() => { + const elDems = elRef.current?.getBoundingClientRect() + const elW = elDems?.width ?? 100 + const elH = elDems?.height ?? 100 + const newDems: Card<'texts'>['dimensions'] = { w: elW, h: elH } + TextSignal.default.updateTextProperty(itemKey, 'dimensions', newDems) + TextSignal.default.texts.notify() + }, [elRef.current, item.fontSize]) function _handleResizeMouseDown(e: MouseEvent) { e.stopPropagation() @@ -86,11 +94,12 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { return (
+export type TextCardType = Card<"texts"> & { + fontSize: number +} const texts = signal>({}) From a31ac3c3f1f2dc6e4cc894bf0bd6eba7a15a1c4c Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Thu, 10 Oct 2024 23:35:55 -0400 Subject: [PATCH 09/13] feat(text): set initial fontsize higher --- src/components/cardSelector/TextButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/cardSelector/TextButton.tsx b/src/components/cardSelector/TextButton.tsx index 5b197c2..bcc28c9 100644 --- a/src/components/cardSelector/TextButton.tsx +++ b/src/components/cardSelector/TextButton.tsx @@ -8,7 +8,7 @@ export function TextButton() { function _handleClick(e: MouseEvent) { TextSignal.default.addText({ - fontSize: 10, + fontSize: 84, type: "texts", title: "New Note", contents: "todo: fill me", From 937d3a3a153580fdd920c0a3c121239eaa9a8546 Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Thu, 10 Oct 2024 23:55:30 -0400 Subject: [PATCH 10/13] feat(text): give ability to delete text item --- src/components/ImageCard.tsx | 1 - src/components/TextItem.tsx | 54 ++++++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/components/ImageCard.tsx b/src/components/ImageCard.tsx index 3601c73..bbecaaa 100644 --- a/src/components/ImageCard.tsx +++ b/src/components/ImageCard.tsx @@ -91,7 +91,6 @@ export function ImageCard({ key: itemKey, data: item }: ImageCard.ImageCardProps function _handleClose(_e: Event) { ImagesSignal.default.removeImage(item.id) ImagesSignal.default.images.notify() - debounceLSUpdate() } return ( diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index ef5afac..3c0b9e9 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -4,6 +4,7 @@ import { useDebounce } from "../utils/useDebounce" import texts, { TextCardType } from "../signals/texts" import { LayerEnum } from "../utils/enums" import { Card } from "../types" +import { useThemeDetector } from "../utils/useThemeDetector" namespace TextItem { export interface TextCardProps { @@ -92,6 +93,12 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { updateLocalStorage() } + function _handleClose(e: MouseEvent) { + e.stopPropagation() + TextSignal.default.removeText(item.id) + TextSignal.default.texts.notify() + } + return (
) } -function ExpandIcon({ cb, item }: { - cb: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null | undefined, - item: TextSignal.TextCardType -}) { +namespace CloseIcon { + export interface Props { + cb: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null | undefined, + item: TextSignal.TextCardType + } +} +function CloseIcon({ item, cb }: CloseIcon.Props) { + const isDark = useThemeDetector() + return ( + + + + + + ) +} + +namespace ExpandIcon { + export interface Props { + cb: ((this: GlobalEventHandlers, ev: MouseEvent) => any) | null | undefined, + item: TextSignal.TextCardType + } +} +function ExpandIcon({ cb, item }: ExpandIcon.Props) { + const isDark = useThemeDetector() return ( Date: Fri, 11 Oct 2024 07:49:42 -0400 Subject: [PATCH 11/13] make text typing work and save --- src/components/TextItem.tsx | 49 +++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index 3c0b9e9..ca9b46a 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -1,4 +1,4 @@ -import { signal, useEffect, useRef } from "kaioken" +import { signal, useEffect, useLayoutEffect, useRef } from "kaioken" import { TextSignal, focusedItem } from "../signals" import { useDebounce } from "../utils/useDebounce" import texts, { TextCardType } from "../signals/texts" @@ -14,6 +14,7 @@ namespace TextItem { } export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { + const { debounce } = useDebounce() const pressed = signal(false) const newX = useRef(0) const newY = useRef(0) @@ -21,8 +22,18 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { const offsetY = useRef(0) const initialResizeX = useRef(0) const elRef = useRef(null) + const pRef = useRef(null) + + useEffect(() => { + const elDems = elRef.current?.getBoundingClientRect() + const elW = elDems?.width ?? 100 + const elH = elDems?.height ?? 100 + const newDems: Card<'texts'>['dimensions'] = { w: elW, h: elH } + TextSignal.default.updateTextProperty(itemKey, 'dimensions', newDems) + TextSignal.default.texts.notify() + }, [elRef.current, item.fontSize]) + - const { debounce } = useDebounce() function updateLocalStorage(time?: number) { debounce(() => { @@ -51,8 +62,6 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { function _handleMouseDown(e: MouseEvent) { focusedItem.value = itemKey - e.preventDefault() - e.stopPropagation() offsetX.current = e.offsetX offsetY.current = e.offsetY pressed.value = true @@ -67,17 +76,9 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { TextSignal.default.updateTextProperty(itemKey, 'fontSize', newFontSize) TextSignal.default.texts.notify() + updateLocalStorage() } - useEffect(() => { - const elDems = elRef.current?.getBoundingClientRect() - const elW = elDems?.width ?? 100 - const elH = elDems?.height ?? 100 - const newDems: Card<'texts'>['dimensions'] = { w: elW, h: elH } - TextSignal.default.updateTextProperty(itemKey, 'dimensions', newDems) - TextSignal.default.texts.notify() - }, [elRef.current, item.fontSize]) - function _handleResizeMouseDown(e: MouseEvent) { e.stopPropagation() initialResizeX.current = e.pageX @@ -99,11 +100,22 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { TextSignal.default.texts.notify() } + function _handleContentInput(e: InputEvent) { + console.log("event: ", e) + texts.updateTextProperty(itemKey, 'contents', (e.target as any).textContent) + updateLocalStorage() + } + + useLayoutEffect(() => { + if (!pRef.current) return + pRef.current.textContent = item.contents + }, []) + return (
-
- {item.contents} +
+

- -
From 0cc0d388b4c9aef942b53af0288d8241ade85297 Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Fri, 11 Oct 2024 13:56:45 -0400 Subject: [PATCH 12/13] feat(text): fix text focus and text wrap previously the text elements werent relieving their focus up until actually clicking another element on the page. This now allows cilcking anywhere on the page regardless of element, relieving the focus and shifting focus to another text element if one is clicked. This also fixes the persistant text wrapping, replacing the
tags with chars and wrapping the text wth a pre tag to maintain all new lines --- src/components/TextItem.tsx | 55 +++++++++++++++++++++++++++++-------- src/styles.css | 3 ++ 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/src/components/TextItem.tsx b/src/components/TextItem.tsx index ca9b46a..a7078d4 100644 --- a/src/components/TextItem.tsx +++ b/src/components/TextItem.tsx @@ -101,8 +101,9 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { } function _handleContentInput(e: InputEvent) { - console.log("event: ", e) - texts.updateTextProperty(itemKey, 'contents', (e.target as any).textContent) + const el = e.target as HTMLParagraphElement & Pick + const val = el.innerHTML.split('
').join('\n') + texts.updateTextProperty(itemKey, 'contents', val) updateLocalStorage() } @@ -111,25 +112,57 @@ export function TextItem({ key: itemKey, data: item }: TextItem.TextCardProps) { pRef.current.textContent = item.contents }, []) + useEffect(() => { + function _handleClick(e: MouseEvent) { + const target = e.target as HTMLElement + + if (target === elRef.current) return + if (elRef.current?.contains(target)) return + + const classes = '.text-container, .text-p, .text-pre, .text-close' + if (target.closest(classes)) return + if (target.matches(classes)) return + + focusedItem.value = null + document.removeEventListener('mousedown', _handleClick) + } + + if (focusedItem.value !== itemKey) return + document.addEventListener('mousedown', _handleClick) + return () => { + document.removeEventListener('mousedown', _handleClick) + } + }, [focusedItem.value]) + + const outline = `${focusedItem.value === item.id ? '1px solid' : ''}` + const fontSize = `${item.fontSize / 6}px` + const zIndex = `${focusedItem.value == itemKey ? LayerEnum.CARD_ELEVATED : LayerEnum.CARD}` + return (
-
+
         

-
+ //@ts-expect-error + oninput={_handleContentInput} + contentEditable + className={'text-p inline-block px-2 w-full select-none drop-shadow relative'}> +

+ @@ -158,7 +191,7 @@ function CloseIcon({ item, cb }: CloseIcon.Props) { stroke-width="2" stroke-linecap="round" stroke-linejoin="round" - className="cursor-pointer w-4 h-4 absolute top-[-8px] right-[-8px]" + className="text-close cursor-pointer w-4 h-4 absolute top-[-8px] right-[-8px]" style={{ display: focusedItem.value === item.id ? 'unset' : 'none' }} diff --git a/src/styles.css b/src/styles.css index ef9368e..6373614 100644 --- a/src/styles.css +++ b/src/styles.css @@ -11,6 +11,9 @@ margin: 0; padding: 0; box-sizing: border-box; + :focus { + outline: none; + } } html { From f497bfda085bfecbbc022b94aa6eda6e90520f99 Mon Sep 17 00:00:00 2001 From: Triston Armstrong Date: Sat, 12 Oct 2024 07:16:58 -0400 Subject: [PATCH 13/13] feat(text): memo infinite canvas so the toasty isnt constantly updating it --- src/App.tsx | 5 ++++- src/components/InfinateCanvas.tsx | 1 - src/styles.css | 7 ++++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 46d4d53..4189a94 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,3 +1,4 @@ +import { memo } from "kaioken" import InfiniteCanvas from "./components/InfinateCanvas" import { ToastContextProvider } from "./components/Toast" import { useThemeDetector } from "./utils/useThemeDetector" @@ -7,7 +8,9 @@ export function App() { return ( - + ) } + +const MemoInfyCanvas = memo(InfiniteCanvas) diff --git a/src/components/InfinateCanvas.tsx b/src/components/InfinateCanvas.tsx index 58b7452..b7976c1 100644 --- a/src/components/InfinateCanvas.tsx +++ b/src/components/InfinateCanvas.tsx @@ -8,7 +8,6 @@ import images from "../signals/images" import { CardSelector } from "./cardSelector/CardSelector" import { Logo } from "./Logo" import { useThemeDetector } from "../utils/useThemeDetector" -import { isTheme } from "../utils/isTheme" import { TextItem } from "./TextItem" import texts from "../signals/texts" diff --git a/src/styles.css b/src/styles.css index 6373614..b41f51d 100644 --- a/src/styles.css +++ b/src/styles.css @@ -11,9 +11,10 @@ margin: 0; padding: 0; box-sizing: border-box; - :focus { - outline: none; - } +} + +*:focus { + outline: none; } html {