From 2d25e518c82bf5fa4a054816420f594721a525c2 Mon Sep 17 00:00:00 2001 From: Ahmed-Elgendy25 Date: Wed, 1 Apr 2026 10:44:27 +0200 Subject: [PATCH] resolving conflicts: color picker functionality and enhance memo components with color customization options --- .hintrc | 18 ++ memos_prod.db-shm | Bin 32768 -> 32768 bytes .../MemoActionMenu/MemoActionMenu.tsx | 4 - web/src/components/MemoContent/index.tsx | 135 ------------ .../MemoReactionListView/ReactionView.tsx | 4 - web/src/components/MemoView/MemoView.tsx | 92 -------- .../components/MemoCustomizeColor.tsx | 199 ----------------- .../MemoView/components/MemoHeader.tsx | 32 --- web/src/components/MemoView/types.ts | 13 -- .../PagedMemoList/PagedMemoList.tsx | 4 - web/src/hooks/useMemoQueries.ts | 10 - web/src/utils/markdown-manipulation.ts | 206 +----------------- 12 files changed, 19 insertions(+), 698 deletions(-) create mode 100644 .hintrc diff --git a/.hintrc b/.hintrc new file mode 100644 index 000000000..a16619cbd --- /dev/null +++ b/.hintrc @@ -0,0 +1,18 @@ +{ + "extends": [ + "development" + ], + "hints": { + "compat-api/html": [ + "default", + { + "ignore": [ + "meta[name=theme-color]" + ] + } + ], + "meta-viewport": "off", + "axe/name-role-value": "off", + "axe/forms": "off" + } +} \ No newline at end of file diff --git a/memos_prod.db-shm b/memos_prod.db-shm index 62d7f1546f0ef0f0fdd0c6887eed1d50998c7b4a..63e3d695358f6a2cdb7c82a5451ed217755f14af 100644 GIT binary patch delta 86 zcmZo@U}|V!;*@x#%K!!wIpqbfrkW+L%kf!^ET{<+geYTRI0$6?M*?v1jg9s707Fe3 AVgLXD delta 86 zcmZo@U}|V!;*@x#%K!qt6FKDt_hp(T{x9-bj4Y@L69g**5(j~}4v7Cl0Zcq^V`F_i E055MEvj6}9 diff --git a/web/src/components/MemoActionMenu/MemoActionMenu.tsx b/web/src/components/MemoActionMenu/MemoActionMenu.tsx index 8b5ac4b9d..1f2739db2 100644 --- a/web/src/components/MemoActionMenu/MemoActionMenu.tsx +++ b/web/src/components/MemoActionMenu/MemoActionMenu.tsx @@ -57,11 +57,7 @@ const MemoActionMenu = (props: MemoActionMenuProps) => { diff --git a/web/src/components/MemoContent/index.tsx b/web/src/components/MemoContent/index.tsx index a32f9d636..3e7b121eb 100644 --- a/web/src/components/MemoContent/index.tsx +++ b/web/src/components/MemoContent/index.tsx @@ -1,4 +1,3 @@ -<<<<<<< HEAD import type { Element } from "hast"; import { ChevronDown, ChevronUp } from "lucide-react"; import { memo } from "react"; @@ -131,137 +130,3 @@ const MemoContent = (props: MemoContentProps) => { }; export default memo(MemoContent); -======= -import type { Element } from "hast"; -import { ChevronDown, ChevronUp } from "lucide-react"; -import { memo } from "react"; -import ReactMarkdown from "react-markdown"; -import rehypeKatex from "rehype-katex"; -import rehypeRaw from "rehype-raw"; -import rehypeSanitize from "rehype-sanitize"; -import remarkBreaks from "remark-breaks"; -import remarkGfm from "remark-gfm"; -import remarkMath from "remark-math"; -import { cn } from "@/lib/utils"; -import { useTranslate } from "@/utils/i18n"; -import { remarkDisableSetext } from "@/utils/remark-plugins/remark-disable-setext"; -import { remarkPreserveType } from "@/utils/remark-plugins/remark-preserve-type"; -import { remarkTag } from "@/utils/remark-plugins/remark-tag"; -import { CodeBlock } from "./CodeBlock"; -import { isTagNode, isTaskListItemNode } from "./ConditionalComponent"; -import { COMPACT_MODE_CONFIG, SANITIZE_SCHEMA } from "./constants"; -import { useCompactLabel, useCompactMode } from "./hooks"; -import { Blockquote, Heading, HorizontalRule, Image, InlineCode, Link, List, ListItem, Paragraph } from "./markdown"; -import { Table, TableBody, TableCell, TableHead, TableHeaderCell, TableRow } from "./Table"; -import { Tag } from "./Tag"; -import { TaskListItem } from "./TaskListItem"; -import type { MemoContentProps } from "./types"; - -const MemoContent = (props: MemoContentProps) => { - const { className, contentClassName, content, onClick, onDoubleClick } = props; - const t = useTranslate(); - const { - containerRef: memoContentContainerRef, - mode: showCompactMode, - toggle: toggleCompactMode, - } = useCompactMode(Boolean(props.compact)); - - const compactLabel = useCompactLabel(showCompactMode, t as (key: string) => string); - - return ( -
-
*:last-child]:mb-0", - showCompactMode === "ALL" && "overflow-hidden", - contentClassName, - )} - style={showCompactMode === "ALL" ? { maxHeight: `${COMPACT_MODE_CONFIG.maxHeightVh}vh` } : undefined} - onMouseUp={onClick} - onDoubleClick={onDoubleClick} - > - & { node?: Element }) => { - if (inputProps.node && isTaskListItemNode(inputProps.node)) { - return ; - } - return ; - }) as React.ComponentType>, - span: ((spanProps: React.ComponentProps<"span"> & { node?: Element }) => { - const { node, ...rest } = spanProps; - if (node && isTagNode(node)) { - return ; - } - return ; - }) as React.ComponentType>, - // Headings - h1: ({ children }) => {children}, - h2: ({ children }) => {children}, - h3: ({ children }) => {children}, - h4: ({ children }) => {children}, - h5: ({ children }) => {children}, - h6: ({ children }) => {children}, - // Block elements - p: ({ children }) => {children}, - blockquote: ({ children }) =>
{children}
, - hr: () => , - // Lists - ul: ({ children, ...props }) => {children}, - ol: ({ children, ...props }) => ( - - {children} - - ), - li: ({ children, ...props }) => {children}, - // Inline elements - a: ({ children, ...props }) => {children}, - code: ({ children }) => {children}, - img: ({ ...props }) => , - // Code blocks - pre: CodeBlock, - // Tables - table: ({ children }) => {children}
, - thead: ({ children }) => {children}, - tbody: ({ children }) => {children}, - tr: ({ children }) => {children}, - th: ({ children, ...props }) => {children}, - td: ({ children, ...props }) => {children}, - }} - > - {content} -
- {showCompactMode === "ALL" && ( -
- )} -
- {showCompactMode !== undefined && ( -
- -
- )} -
- ); -}; - -export default memo(MemoContent); ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) diff --git a/web/src/components/MemoReactionListView/ReactionView.tsx b/web/src/components/MemoReactionListView/ReactionView.tsx index 4b21f8bfc..c0beae916 100644 --- a/web/src/components/MemoReactionListView/ReactionView.tsx +++ b/web/src/components/MemoReactionListView/ReactionView.tsx @@ -35,11 +35,7 @@ const ReactionView = (props: Props) => { type="button" className={cn( "h-7 border px-2 py-0.5 rounded-full flex flex-row justify-center items-center gap-1", -<<<<<<< HEAD - "text-sm", -======= "text-sm text-muted-foreground", ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) isClickable && "cursor-pointer", !isClickable && "cursor-default", hasReaction && "bg-accent border-border", diff --git a/web/src/components/MemoView/MemoView.tsx b/web/src/components/MemoView/MemoView.tsx index 9d3c37ba5..174e7f9c0 100644 --- a/web/src/components/MemoView/MemoView.tsx +++ b/web/src/components/MemoView/MemoView.tsx @@ -1,8 +1,4 @@ -<<<<<<< HEAD -import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react"; -======= import { memo, useCallback, useMemo, useRef, useState } from "react"; ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) import { useLocation } from "react-router-dom"; import useCurrentUser from "@/hooks/useCurrentUser"; import { useUser } from "@/hooks/useUserQueries"; @@ -19,20 +15,7 @@ import type { MemoViewProps } from "./types"; import MemoFooter from "./components/MemoFooter"; const MemoView: React.FC = (props: MemoViewProps) => { -<<<<<<< HEAD - const { - memo: memoData, - className, - parentPage: parentPageProp, - compact, - showCreator, - showVisibility, - showPinned, - colorKey, - } = props; -======= const { memo: memoData, className, parentPage: parentPageProp, compact, showCreator, showVisibility, showPinned } = props; ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) const cardRef = useRef(null); const [showEditor, setShowEditor] = useState(false); @@ -56,64 +39,6 @@ const MemoView: React.FC = (props: MemoViewProps) => { const isInMemoDetailPage = location.pathname.startsWith(`/${memoData.name}`); const showCommentPreview = !isInMemoDetailPage && computeCommentAmount(memoData) > 0; -<<<<<<< HEAD - const [customColors, setCustomColors] = useState<{ bgColor?: string; textColor?: string } | null>(null); - - useEffect(() => { - if (typeof window === "undefined") { - return; - } - - const storageKey = colorKey || memoData.name; - - try { - const stored = window.localStorage.getItem(storageKey); - if (!stored) { - return; - } - - const parsed = JSON.parse(stored) as { bgColor?: string; textColor?: string }; - setCustomColors({ - bgColor: parsed.bgColor, - textColor: parsed.textColor, - }); - } catch { - // Ignore malformed values - } - }, [colorKey, memoData.name]); - - useEffect(() => { - if (typeof window === "undefined") { - return; - } - - const storageKey = colorKey || memoData.name; - - const handleColorChange = (event: Event) => { - const customEvent = event as CustomEvent<{ - key: string; - colors: { bgColor?: string; textColor?: string }; - }>; - - if (!customEvent.detail || customEvent.detail.key !== storageKey) { - return; - } - - setCustomColors({ - bgColor: customEvent.detail.colors.bgColor, - textColor: customEvent.detail.colors.textColor, - }); - }; - - window.addEventListener("memo-colors-changed", handleColorChange as EventListener); - - return () => { - window.removeEventListener("memo-colors-changed", handleColorChange as EventListener); - }; - }, [colorKey, memoData.name]); - -======= ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) const contextValue = useMemo( () => ({ memo: memoData, @@ -161,25 +86,8 @@ const MemoView: React.FC = (props: MemoViewProps) => { className={cn(MEMO_CARD_BASE_CLASSES, showCommentPreview ? "mb-0 rounded-b-none" : "mb-2", className)} ref={cardRef} tabIndex={readonly ? -1 : 0} -<<<<<<< HEAD - style={ - customColors?.bgColor || customColors?.textColor - ? { backgroundColor: customColors?.bgColor, color: customColors?.textColor } - : undefined - } - > - setCustomColors(colors)} - /> -======= > ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) diff --git a/web/src/components/MemoView/components/MemoCustomizeColor.tsx b/web/src/components/MemoView/components/MemoCustomizeColor.tsx index 7b9b45c0e..21596d88d 100644 --- a/web/src/components/MemoView/components/MemoCustomizeColor.tsx +++ b/web/src/components/MemoView/components/MemoCustomizeColor.tsx @@ -1,72 +1,3 @@ -<<<<<<< HEAD -import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover"; -import { cn } from "@/lib/utils"; -import { AlertCircle, Brush } from "lucide-react"; -import { useEffect, useState } from "react"; -import { HexColorPicker } from "react-colorful"; - -interface Props { - name:string; - className?: string; - onOpenChange?: (open: boolean) => void; - onSavePreferences?: (colors: { bgColor: string; textColor: string }) => Promise | void; -} -const MIN_CONTRAST_RATIO = 4.5; - -const parseHexColor = (hex: string) => { - const normalized = hex.trim().replace("#", ""); - if (normalized.length !== 6) { - return null; - } - - const r = Number.parseInt(normalized.slice(0, 2), 16); - const g = Number.parseInt(normalized.slice(2, 4), 16); - const b = Number.parseInt(normalized.slice(4, 6), 16); - - if (Number.isNaN(r) || Number.isNaN(g) || Number.isNaN(b)) { - return null; - } - - return { r, g, b }; -}; - -const relativeLuminance = (hex: string) => { - const rgb = parseHexColor(hex); - if (!rgb) { - return null; - } - - const transform = (channel: number) => { - const sRgb = channel / 255; - return sRgb <= 0.03928 ? sRgb / 12.92 : Math.pow((sRgb + 0.055) / 1.055, 2.4); - }; - - const r = transform(rgb.r); - const g = transform(rgb.g); - const b = transform(rgb.b); - - return 0.2126 * r + 0.7152 * g + 0.0722 * b; -}; - -const getContrastRatio = (foreground: string, background: string) => { - const l1 = relativeLuminance(foreground); - const l2 = relativeLuminance(background); - - if (l1 == null || l2 == null) { - return null; - } - - const light = Math.max(l1, l2); - const dark = Math.min(l1, l2); - - return (light + 0.05) / (dark + 0.05); -}; - -function MemoCustomizeColor(props: Props) { - const { className, onOpenChange, onSavePreferences,name } = props; - const [open, setOpen] = useState(false); - const [bgColor, setBgColor] = useState("#121212"); -======= import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover" import { cn } from "@/lib/utils"; import { Brush } from "lucide-react" @@ -83,42 +14,10 @@ function MemoCustomizeColor(props:Props) { const {className,onOpenChange} = props; const [open, setOpen] = useState(false); const [bgColor, setBgColor] = useState("#121212"); ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) const [textColor, setTextColor] = useState("#FFFFFF"); const [showBgPicker, setShowBgPicker] = useState(false); const [showTextPicker, setShowTextPicker] = useState(false); -<<<<<<< HEAD - useEffect(() => { - if (typeof window === "undefined") { - return; - } - - try { - const stored = window.localStorage.getItem(name); - if (!stored) { - return; - } - - const parsed = JSON.parse(stored) as { - bgColor?: string; - textColor?: string; - }; - - if (parsed.bgColor) { - setBgColor(parsed.bgColor); - } - if (parsed.textColor) { - setTextColor(parsed.textColor); - } - } catch (error) { - // eslint-disable-next-line no-console - console.error("Failed to load memo color preferences", error); - } - }, [name]); - -======= ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) const bgPresets = ["#121212", "#2c2f33", "#1d3557", "#2d6a4f", "#601010", "#000000"]; const textPresets = ["#FFFFFF", "#E1E8ED", "#89CFF0", "#C7F9CC", "#FEFAE0", "#FAD2E1"]; @@ -126,72 +25,6 @@ const [open, setOpen] = useState(false); setOpen(newOpen); onOpenChange?.(newOpen); }; -<<<<<<< HEAD - - const handleCancel = () => { - handleOpenChange(false); - }; - - const handleSave = async () => { - try { - if (typeof window !== "undefined") { - try { - window.localStorage.setItem( - name, - JSON.stringify({ - bgColor, - textColor, - }), - ); - - window.dispatchEvent( - new CustomEvent("memo-colors-changed", { - detail: { - key: name, - colors: { - bgColor, - textColor, - }, - }, - }), - ); - } catch { - // Ignore write errors - } - } - - if (onSavePreferences) { - await onSavePreferences({ - bgColor, - textColor, - }); - } - handleOpenChange(false); - } catch (error) { - console.error("Failed to save memo color preferences", error); - } - }; - - const contrastRatio = getContrastRatio(textColor, bgColor); - return ( - - - - - - - - -======= return ( @@ -212,7 +45,6 @@ const [open, setOpen] = useState(false);
->>>>>>> 89d43a2e (Developed Color Picker Feature for memos)
{/* Header */}
@@ -230,25 +62,12 @@ const [open, setOpen] = useState(false);
🎨 ⚙️ ︙

-<<<<<<< HEAD - Content Should be here... -======= EL DONIA DH BTA3TIIIIIIIIII ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos)

👍 1 ❤️ 1
-<<<<<<< HEAD - {contrastRatio != null && contrastRatio < MIN_CONTRAST_RATIO && ( -
- - Low contrast may affect readability. -
- )} -======= ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos)
{/* Background Color Section */} @@ -310,31 +129,13 @@ const [open, setOpen] = useState(false); {/* Footer Actions */}
-<<<<<<< HEAD - -
-<<<<<<< HEAD -=======
->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) diff --git a/web/src/components/MemoView/components/MemoHeader.tsx b/web/src/components/MemoView/components/MemoHeader.tsx index 6c5dc9b85..4e9746e91 100644 --- a/web/src/components/MemoView/components/MemoHeader.tsx +++ b/web/src/components/MemoView/components/MemoHeader.tsx @@ -19,16 +19,10 @@ import { useMemoViewContext, useMemoViewDerived } from "../MemoViewContext"; import type { MemoHeaderProps } from "../types"; import MemoCustomizeColor from "./MemoCustomizeColor"; -<<<<<<< HEAD -const MemoHeader: React.FC = ({ name, showCreator, showVisibility, showPinned, onColorPreferencesChange, showColorCustomizer = true }) => { - const t = useTranslate(); - const [reactionSelectorOpen, setReactionSelectorOpen] = useState(false); -======= const MemoHeader: React.FC = ({ showCreator, showVisibility, showPinned }) => { const t = useTranslate(); const [reactionSelectorOpen, setReactionSelectorOpen] = useState(false); const [customizeColorToggle,setCustomizeColorToggle]= useState(false); ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) const { memo, creator, currentUser, parentPage, isArchived, readonly, openEditor } = useMemoViewContext(); const { relativeTimeFormat } = useMemoViewDerived(); @@ -67,20 +61,10 @@ const MemoHeader: React.FC = ({ showCreator, showVisibility, sh onOpenChange={setReactionSelectorOpen} /> )} -<<<<<<< HEAD - {showColorCustomizer && ( - - )} -======= ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) {showVisibility && memo.visibility !== Visibility.PRIVATE && ( @@ -99,11 +83,7 @@ const MemoHeader: React.FC = ({ showCreator, showVisibility, sh -<<<<<<< HEAD - -======= ->>>>>>> 89d43a2e (Developed Color Picker Feature for memos) @@ -132,11 +112,7 @@ const CreatorDisplay: React.FC = ({ creator, displayTime, o
>>>>>> 89d43a2e (Developed Color Picker Feature for memos) to={`/u/${encodeURIComponent(creator.username)}`} viewTransition > @@ -144,11 +120,7 @@ const CreatorDisplay: React.FC = ({ creator, displayTime, o