From 16e3457ec85ff91e57a11085c1a45be959a32f3d Mon Sep 17 00:00:00 2001 From: Bill Date: Thu, 18 Aug 2022 01:31:11 -0400 Subject: [PATCH] Card size/position is now stored in LocalStorage --- src/api/utils/GetLocalStorage.ts | 1 + src/api/utils/SetLocalStorage.ts | 1 + src/api/utils/WindowSaveOptions.ts | 5 +++ src/api/utils/index.ts | 3 ++ src/common/card/NitroCardView.tsx | 36 +++++++++++++++++-- .../draggable-window/DraggableWindow.tsx | 34 +++++++++++------- src/hooks/useLocalStorage.ts | 7 ++-- 7 files changed, 69 insertions(+), 18 deletions(-) create mode 100644 src/api/utils/GetLocalStorage.ts create mode 100644 src/api/utils/SetLocalStorage.ts create mode 100644 src/api/utils/WindowSaveOptions.ts diff --git a/src/api/utils/GetLocalStorage.ts b/src/api/utils/GetLocalStorage.ts new file mode 100644 index 00000000..e8ba878d --- /dev/null +++ b/src/api/utils/GetLocalStorage.ts @@ -0,0 +1 @@ +export const GetLocalStorage = (key: string) => JSON.parse(window.localStorage.getItem(key)) as T ?? null; diff --git a/src/api/utils/SetLocalStorage.ts b/src/api/utils/SetLocalStorage.ts new file mode 100644 index 00000000..02aa8f3d --- /dev/null +++ b/src/api/utils/SetLocalStorage.ts @@ -0,0 +1 @@ +export const SetLocalStorage = (key: string, value: T) => window.localStorage.setItem(key, JSON.stringify(value)); diff --git a/src/api/utils/WindowSaveOptions.ts b/src/api/utils/WindowSaveOptions.ts new file mode 100644 index 00000000..9aa84563 --- /dev/null +++ b/src/api/utils/WindowSaveOptions.ts @@ -0,0 +1,5 @@ +export interface WindowSaveOptions +{ + offset: { x: number, y: number }; + size: { width: number, height: number }; +} diff --git a/src/api/utils/index.ts b/src/api/utils/index.ts index c2f1d4b1..0c51fc49 100644 --- a/src/api/utils/index.ts +++ b/src/api/utils/index.ts @@ -1,6 +1,7 @@ export * from './CloneObject'; export * from './ColorUtils'; export * from './ConvertSeconds'; +export * from './GetLocalStorage'; export * from './LocalizeBadgeDescription'; export * from './LocalizeBageName'; export * from './LocalizeFormattedNumber'; @@ -11,4 +12,6 @@ export * from './PlaySound'; export * from './ProductImageUtility'; export * from './Randomizer'; export * from './RoomChatFormatter'; +export * from './SetLocalStorage'; export * from './SoundNames'; +export * from './WindowSaveOptions'; diff --git a/src/common/card/NitroCardView.tsx b/src/common/card/NitroCardView.tsx index 329d3615..236f615f 100644 --- a/src/common/card/NitroCardView.tsx +++ b/src/common/card/NitroCardView.tsx @@ -1,5 +1,6 @@ -import { FC, useMemo } from 'react'; +import { FC, useEffect, useMemo, useRef } from 'react'; import { Column, ColumnProps } from '..'; +import { GetLocalStorage, SetLocalStorage, WindowSaveOptions } from '../../api'; import { DraggableWindow, DraggableWindowPosition, DraggableWindowProps } from '../draggable-window'; import { NitroCardContextProvider } from './NitroCardContext'; @@ -11,6 +12,7 @@ export interface NitroCardViewProps extends DraggableWindowProps, ColumnProps export const NitroCardView: FC = props => { const { theme = 'primary', uniqueKey = null, handleSelector = '.drag-handler', windowPosition = DraggableWindowPosition.CENTER, disableDrag = false, overflow = 'hidden', position = 'relative', gap = 0, classNames = [], ...rest } = props; + const elementRef = useRef(); const getClassNames = useMemo(() => { @@ -23,10 +25,40 @@ export const NitroCardView: FC = props => return newClassNames; }, [ theme, classNames ]); + useEffect(() => + { + if(!uniqueKey || !elementRef || !elementRef.current) return; + + const localStorage = GetLocalStorage(`nitro.windows.${ uniqueKey }`); + const element = elementRef.current; + + if(localStorage && localStorage.size) + { + element.style.width = `${ localStorage.size.width }px`; + element.style.height = `${ localStorage.size.height }px`; + } + + const observer = new ResizeObserver(event => + { + const newStorage = { ...GetLocalStorage>(`nitro.windows.${ uniqueKey }`) } as WindowSaveOptions; + + newStorage.size = { width: element.offsetWidth, height: element.offsetHeight }; + + SetLocalStorage(`nitro.windows.${ uniqueKey }`, newStorage); + }); + + observer.observe(element); + + return () => + { + observer.disconnect(); + } + }, [ uniqueKey ]); + return ( - + ); diff --git a/src/common/draggable-window/DraggableWindow.tsx b/src/common/draggable-window/DraggableWindow.tsx index 05813e42..286d51d1 100644 --- a/src/common/draggable-window/DraggableWindow.tsx +++ b/src/common/draggable-window/DraggableWindow.tsx @@ -2,10 +2,10 @@ import { MouseEventType, TouchEventType } from '@nitrots/nitro-renderer'; import { CSSProperties, FC, Key, MouseEvent as ReactMouseEvent, ReactNode, TouchEvent as ReactTouchEvent, useCallback, useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { Base } from '..'; +import { GetLocalStorage, SetLocalStorage, WindowSaveOptions } from '../../api'; import { DraggableWindowPosition } from './DraggableWindowPosition'; const CURRENT_WINDOWS: HTMLElement[] = []; -const POS_MEMORY: Map = new Map(); const BOUNDS_THRESHOLD_TOP: number = 0; const BOUNDS_THRESHOLD_LEFT: number = 0; @@ -138,7 +138,14 @@ export const DraggableWindow: FC = props => setOffset({ x: offsetX, y: offsetY }); setIsDragging(false); - if(uniqueKey !== null) POS_MEMORY.set(uniqueKey, { x: offsetX, y: offsetY }); + if(uniqueKey !== null) + { + const newStorage = { ...GetLocalStorage(`nitro.windows.${ uniqueKey }`) } as WindowSaveOptions; + + newStorage.offset = { x: offsetX, y: offsetY }; + + SetLocalStorage(`nitro.windows.${ uniqueKey }`, newStorage); + } }, [ dragHandler, delta, offset, uniqueKey ]); const onDragMouseUp = useCallback((event: MouseEvent) => @@ -187,17 +194,6 @@ export const DraggableWindow: FC = props => break; } - if(uniqueKey !== null) - { - const memory = POS_MEMORY.get(uniqueKey); - - if(memory) - { - offsetX = memory.x; - offsetY = memory.y; - } - } - setDelta({ x: 0, y: 0 }); setOffset({ x: offsetX, y: offsetY }); @@ -253,6 +249,18 @@ export const DraggableWindow: FC = props => } }, [ isDragging, onDragMouseUp, onDragMouseMove, onDragTouchUp, onDragTouchMove ]); + useEffect(() => + { + if(!uniqueKey) return; + + const localStorage = GetLocalStorage(`nitro.windows.${ uniqueKey }`); + + if(!localStorage || !localStorage.offset) return; + + setDelta({ x: 0, y: 0 }); + if(localStorage.offset) setOffset(localStorage.offset); + }, [ uniqueKey ]); + return ( createPortal( diff --git a/src/hooks/useLocalStorage.ts b/src/hooks/useLocalStorage.ts index f0cc26cb..1e55fb93 100644 --- a/src/hooks/useLocalStorage.ts +++ b/src/hooks/useLocalStorage.ts @@ -1,5 +1,6 @@ import { NitroLogger } from '@nitrots/nitro-renderer'; import { Dispatch, SetStateAction, useState } from 'react'; +import { GetLocalStorage, SetLocalStorage } from '../api'; const useLocalStorageState = (key: string, initialValue: T): [ T, Dispatch>] => { @@ -9,9 +10,9 @@ const useLocalStorageState = (key: string, initialValue: T): [ T, Dispatch(key); - return item ? JSON.parse(item) : initialValue; + return item ?? initialValue; } catch(error) @@ -28,7 +29,7 @@ const useLocalStorageState = (key: string, initialValue: T): [ T, Dispatch