From 249d510f23ceb0547ddfed9d00264366abf4d6e4 Mon Sep 17 00:00:00 2001 From: Outrun Colors Date: Sun, 25 Sep 2022 14:52:45 -0500 Subject: [PATCH] Don't allow multiple sets of actions open --- chat/package.json | 4 +- chat/src/features/chat/ChatMessage.css | 18 +++-- chat/src/features/chat/ChatMessage.tsx | 83 +++++++++++++++----- chat/src/features/chat/QuotedMessageLink.tsx | 2 +- chat/yarn.lock | 12 +++ 5 files changed, 89 insertions(+), 30 deletions(-) diff --git a/chat/package.json b/chat/package.json index b83d3f6b6..0e9502ae3 100644 --- a/chat/package.json +++ b/chat/package.json @@ -1,10 +1,11 @@ { "name": "chat", - "version": "0.0.24", + "version": "0.1.0", "main": "./src/index.tsx", "license": "MIT", "dependencies": { "@types/humanize-duration": "^3.27.1", + "@types/lodash.clonedeep": "^4.5.7", "@types/lodash.debounce": "^4.0.7", "@types/lozad": "^1.16.1", "@types/react": "^18.0.20", @@ -15,6 +16,7 @@ "dotenv": "^16.0.2", "esbuild": "^0.15.7", "humanize-duration": "^3.27.3", + "lodash.clonedeep": "^4.5.0", "lodash.debounce": "^4.0.8", "lozad": "^1.16.0", "react": "^18.2.0", diff --git a/chat/src/features/chat/ChatMessage.css b/chat/src/features/chat/ChatMessage.css index d6c445d31..55a112fdb 100644 --- a/chat/src/features/chat/ChatMessage.css +++ b/chat/src/features/chat/ChatMessage.css @@ -18,14 +18,6 @@ margin: 0; } -.ChatMessage__showingUser:not(:first-child) { - margin-top: 2rem; -} - -.ChatMessage:not(.ChatMessage__showingUser) { - padding-bottom: 0; -} - .ChatMessage .btn { border: none !important; } @@ -102,4 +94,14 @@ .ChatMessageList { flex: 1; padding-bottom: 2rem; +} + +.ChatMessageList-group { + margin-bottom: 1rem; + padding: 0.3rem; + border-radius: 8px; +} + +.ChatMessageList-group:nth-child(even) { + background: rgba(255, 255, 255, 0.025); } \ No newline at end of file diff --git a/chat/src/features/chat/ChatMessage.tsx b/chat/src/features/chat/ChatMessage.tsx index b4c667858..135cfda27 100644 --- a/chat/src/features/chat/ChatMessage.tsx +++ b/chat/src/features/chat/ChatMessage.tsx @@ -2,6 +2,7 @@ import React, { useCallback, useEffect, useMemo, useState } from "react"; import cx from "classnames"; import key from "weak-key"; import humanizeDuration from "humanize-duration"; +import cloneDeep from "lodash.clonedeep"; import { Username } from "./Username"; import { useChat, useRootContext } from "../../hooks"; import { QuotedMessageLink } from "./QuotedMessageLink"; @@ -11,6 +12,8 @@ interface ChatMessageProps { message: IChatMessage; timestampUpdates: number; showUser?: boolean; + actionsOpen: boolean; + onToggleActions(messageId: string): void; } const TIMESTAMP_UPDATE_INTERVAL = 20000; @@ -19,6 +22,8 @@ export function ChatMessage({ message, showUser = true, timestampUpdates, + actionsOpen, + onToggleActions }: ChatMessageProps) { const { id, @@ -36,7 +41,6 @@ export function ChatMessage({ const { messageLookup, deleteMessage, quoteMessage } = useChat(); const quotedMessage = messageLookup[quotes]; const content = censored ? text_censored : text_html; - const [showingActions, setShowingActions] = useState(false); const [confirmedDelete, setConfirmedDelete] = useState(false); const timestamp = useMemo( () => formatTimeAgo(time), @@ -49,20 +53,16 @@ export function ChatMessage({ setConfirmedDelete(true); } }, [text, confirmedDelete]); - const toggleMessageActions = useCallback( - () => setShowingActions((prev) => !prev), - [] - ); const handleQuoteMessage = useCallback(() => { quoteMessage(message); - setShowingActions(false); - }, [message]); + onToggleActions(message.id); + }, [message, onToggleActions]); useEffect(() => { - if (!showingActions) { + if (!actionsOpen) { setConfirmedDelete(false); } - }, [showingActions]); + }, [actionsOpen]); return (
- {!showingActions && ( + {!actionsOpen && ( )} - {showingActions && ( + {actionsOpen && (
@@ -136,6 +136,17 @@ export function ChatMessage({ export function ChatMessageList() { const { messages } = useChat(); const [timestampUpdates, setTimestampUpdates] = useState(0); + const groupedMessages = useMemo(() => groupMessages(messages), [messages]); + const [actionsOpenForMessage, setActionsOpenForMessage] = useState< + string | null + >(null); + const handleToggleActionsForMessage = useCallback( + (messageId: string) => + setActionsOpenForMessage( + messageId === actionsOpenForMessage ? null : messageId + ), + [actionsOpenForMessage] + ); useEffect(() => { const updatingTimestamps = setInterval( @@ -150,13 +161,19 @@ export function ChatMessageList() { return (
- {messages.map((message, index) => ( - + {groupedMessages.map((group) => ( +
+ {group.map((message, index) => ( + + ))} +
))}
); @@ -188,3 +205,29 @@ function formatTimeAgo(time: number) { return humanized === "0s ago" ? "just now" : humanized; } + +function groupMessages(messages: IChatMessage[]) { + const grouped: IChatMessage[][] = []; + let lastUsername = ""; + let temp: IChatMessage[] = []; + + for (const message of messages) { + if (!lastUsername) { + lastUsername = message.username; + } + + if (message.username === lastUsername) { + temp.push(message); + } else { + grouped.push(cloneDeep(temp)); + lastUsername = message.username; + temp = [message]; + } + } + + if (temp.length > 0) { + grouped.push(cloneDeep(temp)); + } + + return grouped; +} diff --git a/chat/src/features/chat/QuotedMessageLink.tsx b/chat/src/features/chat/QuotedMessageLink.tsx index 46ee0f546..1e598a436 100644 --- a/chat/src/features/chat/QuotedMessageLink.tsx +++ b/chat/src/features/chat/QuotedMessageLink.tsx @@ -42,7 +42,7 @@ export function QuotedMessageLink({ message }: { message: IChatMessage }) { return ( - Replying to @{message.username}:{" "} + @{message.username}:{" "} "{replyText}" ); diff --git a/chat/yarn.lock b/chat/yarn.lock index 2555ae935..98721ce97 100644 --- a/chat/yarn.lock +++ b/chat/yarn.lock @@ -39,6 +39,13 @@ resolved "https://registry.yarnpkg.com/@types/humanize-duration/-/humanize-duration-3.27.1.tgz#f14740d1f585a0a8e3f46359b62fda8b0eaa31e7" integrity sha512-K3e+NZlpCKd6Bd/EIdqjFJRFHbrq5TzPPLwREk5Iv/YoIjQrs6ljdAUCo+Lb2xFlGNOjGSE0dqsVD19cZL137w== +"@types/lodash.clonedeep@^4.5.7": + version "4.5.7" + resolved "https://registry.yarnpkg.com/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.7.tgz#0e119f582ed6f9e6b373c04a644651763214f197" + integrity sha512-ccNqkPptFIXrpVqUECi60/DFxjNKsfoQxSQsgcBJCX/fuX1wgyQieojkcWH/KpE3xzLoWN/2k+ZeGqIN3paSvw== + dependencies: + "@types/lodash" "*" + "@types/lodash.debounce@^4.0.7": version "4.0.7" resolved "https://registry.yarnpkg.com/@types/lodash.debounce/-/lodash.debounce-4.0.7.tgz#0285879defb7cdb156ae633cecd62d5680eded9f" @@ -390,6 +397,11 @@ inherits@2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== +lodash.clonedeep@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"