From 8bda3123dadf280643cf79bcec2caed6b641b4b9 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 15 Jan 2022 12:52:11 +0000 Subject: [PATCH 1/6] fix(unreads): allow dynamic unread changes --- src/lib/eventEmitter.ts | 1 + src/pages/channels/Channel.tsx | 32 +++++++++++++++++++++++--------- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/lib/eventEmitter.ts b/src/lib/eventEmitter.ts index b4f86958..1ad13148 100644 --- a/src/lib/eventEmitter.ts +++ b/src/lib/eventEmitter.ts @@ -30,3 +30,4 @@ export function internalEmit(ns: string, event: string, ...args: unknown[]) { // - Modal/close // - PWA/update // - NewMessages/hide +// - NewMessages/mark diff --git a/src/pages/channels/Channel.tsx b/src/pages/channels/Channel.tsx index ea1f5a5c..cd550257 100644 --- a/src/pages/channels/Channel.tsx +++ b/src/pages/channels/Channel.tsx @@ -7,9 +7,10 @@ import { Channel as ChannelI } from "revolt.js/dist/maps/Channels"; import styled from "styled-components/macro"; import { Text } from "preact-i18n"; -import { useEffect, useMemo } from "preact/hooks"; +import { useEffect, useState } from "preact/hooks"; import ErrorBoundary from "../../lib/ErrorBoundary"; +import { internalSubscribe } from "../../lib/eventEmitter"; import { isTouchscreenDevice } from "../../lib/isTouchscreenDevice"; import { useApplicationState } from "../../mobx/State"; @@ -123,17 +124,30 @@ export function Channel({ id, server_id }: { id: string; server_id: string }) { const TextChannel = observer(({ channel }: { channel: ChannelI }) => { const layout = useApplicationState().layout; - // Cache the unread location. - const last_id = useMemo( + // Store unread location. + const [lastId, setLastId] = useState(undefined); + + useEffect( () => - (channel.unread - ? channel.client.unreads?.getUnread(channel._id)?.last_id - : undefined) ?? undefined, - [channel], + internalSubscribe("NewMessages", "hide", () => + setLastId(undefined), + ), + [], + ); + + useEffect( + () => internalSubscribe("NewMessages", "mark", setLastId as any), + [], ); // Mark channel as read. useEffect(() => { + setLastId( + channel.unread + ? channel.client.unreads?.getUnread(channel._id)?.last_id + : undefined ?? undefined, + ); + const checkUnread = () => channel.unread && channel.client.unreads!.markRead( @@ -165,8 +179,8 @@ const TextChannel = observer(({ channel }: { channel: ChannelI }) => { - - + + From 7e4f4cf001bac46140539096a0cfdd828da093d2 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 15 Jan 2022 12:52:31 +0000 Subject: [PATCH 2/6] fix(messaging): hide overlay on mobile --- src/components/common/messaging/Message.tsx | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index 68517fd3..801985e8 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -6,6 +6,7 @@ import { memo } from "preact/compat"; import { useState } from "preact/hooks"; import { internalEmit } from "../../../lib/eventEmitter"; +import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice"; import { QueuedMessage } from "../../../mobx/stores/MessageQueue"; @@ -175,12 +176,14 @@ const Message = observer( {message.embeds?.map((embed, index) => ( ))} - {mouseHovering && !replacement && ( - - )} + {mouseHovering && + !replacement && + !isTouchscreenDevice && ( + + )} From 2c8bbe7d1f78a766ca5b650a65a5960ac0d09e36 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 15 Jan 2022 12:52:50 +0000 Subject: [PATCH 3/6] feat(messaging): add message overlay logic --- .../messaging/bars/MessageOverlayBar.tsx | 119 +++++++++++------- src/lib/modifiers.ts | 18 +++ 2 files changed, 93 insertions(+), 44 deletions(-) create mode 100644 src/lib/modifiers.ts diff --git a/src/components/common/messaging/bars/MessageOverlayBar.tsx b/src/components/common/messaging/bars/MessageOverlayBar.tsx index 4eec2bd2..d47ac6d6 100644 --- a/src/components/common/messaging/bars/MessageOverlayBar.tsx +++ b/src/components/common/messaging/bars/MessageOverlayBar.tsx @@ -12,8 +12,11 @@ import { Message as MessageObject } from "revolt.js/dist/maps/Messages"; import styled from "styled-components"; import { openContextMenu } from "preact-context-menu"; +import { useEffect, useState } from "preact/hooks"; import { internalEmit } from "../../../../lib/eventEmitter"; +import { shiftKeyPressed } from "../../../../lib/modifiers"; +import { getRenderer } from "../../../../lib/renderer/Singleton"; import { QueuedMessage } from "../../../../mobx/stores/MessageQueue"; @@ -89,9 +92,24 @@ const Divider = styled.div` export const MessageOverlayBar = observer(({ message, queued }: Props) => { const client = useClient(); - const { openScreen } = useIntermediate(); + const { openScreen, writeClipboard } = useIntermediate(); const isAuthor = message.author_id === client.user!._id; + const [copied, setCopied] = useState<"link" | "id">(null!); + const [extraActions, setExtra] = useState(shiftKeyPressed); + + useEffect(() => { + const handler = (ev: KeyboardEvent) => setExtra(ev.shiftKey); + + document.addEventListener("keyup", handler); + document.addEventListener("keydown", handler); + + return () => { + document.removeEventListener("keyup", handler); + document.removeEventListener("keydown", handler); + }; + }); + return ( @@ -120,12 +138,14 @@ export const MessageOverlayBar = observer(({ message, queued }: Props) => { ChannelPermission.ManageMessages) ? ( - openScreen({ - id: "special_prompt", - type: "delete_message", - target: message, - } as unknown as Screen) + onClick={(e) => + e.shiftKey + ? message.delete() + : openScreen({ + id: "special_prompt", + type: "delete_message", + target: message, + } as unknown as Screen) }> @@ -143,43 +163,54 @@ export const MessageOverlayBar = observer(({ message, queued }: Props) => { - - - - openContextMenu("Menu", { - message, - contextualChannel: message.channel_id, - queued, - }) - }> - - - - - - openContextMenu("Menu", { - message, - contextualChannel: message.channel_id, - queued, - }) - }> - - - - - - openContextMenu("Menu", { - message, - contextualChannel: message.channel_id, - queued, - }) - }> - - - + {extraActions && ( + <> + + + { + const messages = getRenderer( + message.channel!, + ).messages; + const index = messages.findIndex( + (x) => x._id === message._id, + ); + + let unread_id = message._id; + if (index > 0) { + unread_id = messages[index - 1]._id; + } + + internalEmit("NewMessages", "mark", unread_id); + message.channel?.ack(unread_id, true); + }}> + + + + + { + setCopied("link"); + writeClipboard(message.url); + }}> + + + + + { + setCopied("id"); + writeClipboard(message._id); + }}> + + + + + )} ); }); diff --git a/src/lib/modifiers.ts b/src/lib/modifiers.ts new file mode 100644 index 00000000..105f81c0 --- /dev/null +++ b/src/lib/modifiers.ts @@ -0,0 +1,18 @@ +/** + * Utility file for detecting whether the + * shift key is currently pressed or not. + */ + +export let shiftKeyPressed = false; + +if (typeof window !== "undefined") { + document.addEventListener("keydown", (ev) => { + if (ev.shiftKey) shiftKeyPressed = true; + else shiftKeyPressed = false; + }); + + document.addEventListener("keyup", (ev) => { + if (ev.shiftKey) shiftKeyPressed = true; + else shiftKeyPressed = false; + }); +} From ba40da2a15138b82b90727549b4d9f936ef6f9ed Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 15 Jan 2022 12:53:06 +0000 Subject: [PATCH 4/6] fix: don't show unread indicator on active channel --- src/components/navigation/items/ButtonItem.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/navigation/items/ButtonItem.tsx b/src/components/navigation/items/ButtonItem.tsx index 1a0cced6..a9a7a895 100644 --- a/src/components/navigation/items/ButtonItem.tsx +++ b/src/components/navigation/items/ButtonItem.tsx @@ -153,12 +153,13 @@ export const ChannelButton = observer((props: ChannelProps) => { } const { openScreen } = useIntermediate(); + const alerting = alert && !muted && !active; return (
{ )}
- {alert && !muted && ( + {alerting && (
{alertCount}
From bb5f940ad14a3b990241d28f3d17c9a89a115553 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 15 Jan 2022 12:53:13 +0000 Subject: [PATCH 5/6] chore: bump revolt.js --- package.json | 4 ++-- yarn.lock | 23 +++++++++-------------- 2 files changed, 11 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index daf995c6..a7ee8868 100644 --- a/package.json +++ b/package.json @@ -145,8 +145,8 @@ "react-scroll": "^1.8.2", "react-virtualized-auto-sizer": "^1.0.5", "react-virtuoso": "^1.10.4", - "revolt-api": "0.5.3-alpha.10", - "revolt.js": "5.2.5", + "revolt-api": "0.5.3-alpha.12", + "revolt.js": "5.2.7", "rimraf": "^3.0.2", "sass": "^1.35.1", "shade-blend-color": "^1.0.0", diff --git a/yarn.lock b/yarn.lock index 09f7b985..80ba7071 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4203,20 +4203,15 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -revolt-api@0.5.3-alpha.10: - version "0.5.3-alpha.10" - resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.3-alpha.10.tgz#973f7d63dbce5ddb0c5ec17c7e89a0474770d66f" - integrity sha512-v+eSPLWpiqmfHafPDeCF1nvd4Ff43ktyvVgGHt7aQN2v9Qm1BFrmpWHWoDPeZpXlW6mtpo+1t74nLK6VCsZ+VA== +revolt-api@0.5.3-alpha.12: + version "0.5.3-alpha.12" + resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.3-alpha.12.tgz#78f25b567b840c1fd072595526592a422cb01f25" + integrity sha512-MM42oI5+5JJMnAs3JiOwSQOy/SUYzYs3M8YRC5QI4G6HU7CfyB2HNWh5jFsyRlcLdSi13dGazHm31FUPHsxOzw== -revolt-api@^0.5.3-alpha.9: - version "0.5.3-alpha.9" - resolved "https://registry.yarnpkg.com/revolt-api/-/revolt-api-0.5.3-alpha.9.tgz#46e75b7d8f9c6702df39039b829dddbb7897f237" - integrity sha512-L8K9uPV3ME8bLdtWm8L9iPQvFM0GghA+5LzmWFjd6Gbn56u22ZYub2lABi4iHrWgeA2X41dGSsuSBgHSlts9Og== - -revolt.js@5.2.5: - version "5.2.5" - resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-5.2.5.tgz#ffd2b759a807f3430f6018459acdf57e95f842a5" - integrity sha512-rS6FOc7XPfe/BuGnuCvM1N/CEGMtR/bHy4le5154MF9bbpebLw205niq7rq5TMsXT/f7J4qlOI7xX0rvKprn6w== +revolt.js@5.2.7: + version "5.2.7" + resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-5.2.7.tgz#7b887329913494a2caf02c9828685d63551890db" + integrity sha512-KNoQqLrdd/B8zryu2fhWim9rO5OEkouhCZj4nU+upwrekz30DjxqWgZCup/apKXE8PSmrhSgWdKT8SHCBXOxFQ== dependencies: "@insertish/exponential-backoff" "3.1.0-patch.0" "@insertish/isomorphic-ws" "^4.0.1" @@ -4226,7 +4221,7 @@ revolt.js@5.2.5: lodash.flatten "^4.4.0" lodash.isequal "^4.5.0" mobx "^6.3.2" - revolt-api "^0.5.3-alpha.9" + revolt-api "0.5.3-alpha.12" ulid "^2.3.0" ws "^8.2.2" From e67f8f95cd306424cb83ade0eb03440072cf50c0 Mon Sep 17 00:00:00 2001 From: Paul Makles Date: Sat, 15 Jan 2022 13:00:27 +0000 Subject: [PATCH 6/6] fix(messaging): prevent message overlay from sticking after finishing edit --- src/components/common/messaging/Message.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index 801985e8..b3ead6b3 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -3,7 +3,7 @@ import { Message as MessageObject } from "revolt.js/dist/maps/Messages"; import { attachContextMenu } from "preact-context-menu"; import { memo } from "preact/compat"; -import { useState } from "preact/hooks"; +import { useEffect, useState } from "preact/hooks"; import { internalEmit } from "../../../lib/eventEmitter"; import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice"; @@ -89,6 +89,7 @@ const Message = observer( // ! FIXME(?): animate on hover const [mouseHovering, setAnimate] = useState(false); + useEffect(() => setAnimate(false), [replacement]); return (