From 4e430c42527556c8ddebd5bc327cee99c88828bc Mon Sep 17 00:00:00 2001 From: D3SOX Date: Mon, 6 May 2024 19:04:17 +0200 Subject: [PATCH] feat(betterActivities): rename and add show all activities functionality --- src/plugins/betterActivities/README.md | 6 + .../betterActivities/components/Caret.tsx | 13 ++ .../components/SpotifyIcon.tsx | 0 .../components/TwitchIcon.tsx | 0 .../index.tsx | 170 +++++++++++++++--- src/plugins/betterActivities/popout.png | Bin 0 -> 11607 bytes .../screenshot.png | Bin src/plugins/betterActivities/styles.css | 131 ++++++++++++++ .../types.ts | 6 +- src/plugins/memberListActivities/README.md | 5 - src/plugins/memberListActivities/styles.css | 60 ------- 11 files changed, 304 insertions(+), 87 deletions(-) create mode 100644 src/plugins/betterActivities/README.md create mode 100644 src/plugins/betterActivities/components/Caret.tsx rename src/plugins/{memberListActivities => betterActivities}/components/SpotifyIcon.tsx (100%) rename src/plugins/{memberListActivities => betterActivities}/components/TwitchIcon.tsx (100%) rename src/plugins/{memberListActivities => betterActivities}/index.tsx (66%) create mode 100644 src/plugins/betterActivities/popout.png rename src/plugins/{memberListActivities => betterActivities}/screenshot.png (100%) create mode 100644 src/plugins/betterActivities/styles.css rename src/plugins/{memberListActivities => betterActivities}/types.ts (90%) delete mode 100644 src/plugins/memberListActivities/README.md delete mode 100644 src/plugins/memberListActivities/styles.css diff --git a/src/plugins/betterActivities/README.md b/src/plugins/betterActivities/README.md new file mode 100644 index 000000000..b40385675 --- /dev/null +++ b/src/plugins/betterActivities/README.md @@ -0,0 +1,6 @@ +# BetterActivities + +Shows activity icons in the member list and allows showing all activities + +![Screenshot](screenshot.png) +![Popout](popout.png) diff --git a/src/plugins/betterActivities/components/Caret.tsx b/src/plugins/betterActivities/components/Caret.tsx new file mode 100644 index 000000000..b948d4358 --- /dev/null +++ b/src/plugins/betterActivities/components/Caret.tsx @@ -0,0 +1,13 @@ +/* + * Vencord, a Discord client mod + * Copyright (c) 2024 Vendicated and contributors + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +export function Caret({ disabled, direction }: { disabled: boolean; direction: "left" | "right"; }) { + return ( + + + + ); +} diff --git a/src/plugins/memberListActivities/components/SpotifyIcon.tsx b/src/plugins/betterActivities/components/SpotifyIcon.tsx similarity index 100% rename from src/plugins/memberListActivities/components/SpotifyIcon.tsx rename to src/plugins/betterActivities/components/SpotifyIcon.tsx diff --git a/src/plugins/memberListActivities/components/TwitchIcon.tsx b/src/plugins/betterActivities/components/TwitchIcon.tsx similarity index 100% rename from src/plugins/memberListActivities/components/TwitchIcon.tsx rename to src/plugins/betterActivities/components/TwitchIcon.tsx diff --git a/src/plugins/memberListActivities/index.tsx b/src/plugins/betterActivities/index.tsx similarity index 66% rename from src/plugins/memberListActivities/index.tsx rename to src/plugins/betterActivities/index.tsx index ec45fa2e0..23ae64daa 100644 --- a/src/plugins/memberListActivities/index.tsx +++ b/src/plugins/betterActivities/index.tsx @@ -23,15 +23,34 @@ import { classNameFactory } from "@api/Styles"; import ErrorBoundary from "@components/ErrorBoundary"; import { Devs } from "@utils/constants"; import definePlugin, { OptionType } from "@utils/types"; -import { findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; -import { moment, React, Tooltip, useMemo } from "@webpack/common"; -import { User } from "discord-types/general"; +import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy, findStoreLazy } from "@webpack"; +import { moment, PresenceStore, React, Tooltip, useMemo, useStateFromStores } from "@webpack/common"; +import { Guild, User } from "discord-types/general"; +import { Caret } from "./components/Caret"; import { SpotifyIcon } from "./components/SpotifyIcon"; import { TwitchIcon } from "./components/TwitchIcon"; -import { Activity, ActivityListIcon, Application, ApplicationIcon, Timestamp } from "./types"; +import { Activity, ActivityListIcon, Application, ApplicationIcon, IconCSSProperties, Timestamp } from "./types"; const settings = definePluginSettings({ + memberList: { + type: OptionType.BOOLEAN, + description: "Show activity icons in the member list", + default: true, + restartNeeded: true, + }, + profileSidebar: { + type: OptionType.BOOLEAN, + description: "Show all activities in the profile sidebar", + default: true, + restartNeeded: true, + }, + userPopout: { + type: OptionType.BOOLEAN, + description: "Show all activities in the user popout", + default: true, + restartNeeded: true, + }, iconSize: { type: OptionType.SLIDER, description: "Size of the activity icons", @@ -47,7 +66,7 @@ const settings = definePluginSettings({ }, }); -const cl = classNameFactory("vc-mla-"); +const cl = classNameFactory("vc-bactivities-"); const ApplicationStore: { getApplication: (id: string) => Application | null; @@ -57,12 +76,14 @@ const { fetchApplication }: { fetchApplication: (id: string) => Promise; } = findByPropsLazy("fetchApplication"); -const TimeBar: React.ComponentType> = findComponentByCodeLazy("isSingleLine"); +}>("isSingleLine"); + +const ActivityView = findByCodeLazy("onOpenGameProfile:"); // if discord one day decides to change their icon this needs to be updated const DefaultActivityIcon = findComponentByCodeLazy("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4 L8,5 Z M8,3 L2,3 L2,2 L8,2 L8,3 Z M8.88888889,0 L1.11111111,0 C0.494444444,0 0,0.494444444 0,1.11111111 L0,8.88888889 C0,9.50253861 0.497461389,10 1.11111111,10 L8.88888889,10 C9.50253861,10 10,9.50253861 10,8.88888889 L10,1.11111111 C10,0.494444444 9.5,0 8.88888889,0 Z"); @@ -117,7 +138,7 @@ function formatElapsedTime(startTime: moment.Moment, endTime: moment.Moment): st return `${customFormat(moment.utc(duration.asMilliseconds()))} elapsed`; } -const ActivityTooltip = ({ activity, application }: Readonly<{ activity: Activity, application?: Application }>) => { +const ActivityTooltip = ({ activity, application, user }: Readonly<{ activity: Activity, application?: Application, user: User; }>) => { const image = useMemo(() => { const activityImage = getActivityImage(activity, application); if (activityImage) { @@ -145,7 +166,7 @@ const ActivityTooltip = ({ activity, application }: Readonly<{ activity: Activit } - {timestamps && } + {timestamps && } ); @@ -240,28 +261,28 @@ function getApplicationIcons(activities: Activity[], preferSmall = false) { } export default definePlugin({ - name: "MemberListActivities", - description: "Shows activity icons in the member list", - authors: [Devs.D3SOX], + name: "BetterActivities", + description: "Shows activity icons in the member list and allows showing all activities", + authors: [Devs.D3SOX, Devs.Arjix, Devs.AutumnVN], tags: ["activity"], settings, - patchActivityList: ({ activities, user }: { activities: Activity[], user: User }): JSX.Element | null => { + patchActivityList: ({ activities, user }: { activities: Activity[], user: User; }): JSX.Element | null => { const icons: ActivityListIcon[] = []; const spotifyActivity = activities.find(({ name }) => name === "Spotify"); if (spotifyActivity) { icons.push({ iconElement: , - tooltip: + tooltip: }); } const twitchActivity = activities.find(({ name }) => name === "Twitch"); if (twitchActivity) { icons.push({ iconElement: , - tooltip: + tooltip: }); } @@ -276,19 +297,20 @@ export default definePlugin({ for (const appIcon of uniqueIcons) { icons.push({ iconElement: , - tooltip: + tooltip: }); } } if (icons.length) { + const iconStyle: IconCSSProperties = { + "--icon-size": `${settings.store.iconSize}px`, + }; + return
{icons.map(({ iconElement, tooltip }, i) => ( -
+
{tooltip ? {({ onMouseEnter, onMouseLeave }) => (
void; }) { + const [currentActivity, setCurrentActivity] = React.useState( + activity?.type !== 4 ? activity! : null + ); + + const activities = useStateFromStores( + [PresenceStore], () => PresenceStore.getActivities(user.id).filter((activity: Activity) => activity.type !== 4) + ) ?? []; + + React.useEffect(() => { + if (!activities.length) { + setCurrentActivity(null); + return; + } + + if (!currentActivity || !activities.includes(currentActivity)) + setCurrentActivity(activities[0]); + + }, [activities]); + + if (!activities.length) return null; + + return ( +
+ +
+ {({ onMouseEnter, onMouseLeave }) => { + return { + const index = activities.indexOf(currentActivity!); + if (index - 1 >= 0) + setCurrentActivity(activities[index - 1]); + }} + > + + ; + }} + +
+ {activities.map((activity, index) => ( +
setCurrentActivity(activity)} + className={`dot ${currentActivity === activity ? "selected" : ""}`} + /> + ))} +
+ + {({ onMouseEnter, onMouseLeave }) => { + return { + const index = activities.indexOf(currentActivity!); + if (index + 1 < activities.length) + setCurrentActivity(activities[index + 1]); + }} + > + = activities.length - 1} + direction="right" + /> + ; + }} +
+
+ ); + }, + patches: [ { // Patch activity icons @@ -321,7 +430,26 @@ export default definePlugin({ replacement: { match: /null!=(\i)&&\i.some\(\i=>\(0,\i.default\)\(\i,\i\)\)\?/, replace: "$self.patchActivityList(e),false?" - } + }, + predicate: () => settings.store.memberList, }, + { + // Show all activities in the profile panel + find: "Profile Panel: user cannot be undefined", + replacement: { + match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{activity:.+?,user:\i,channelId:\i.id,)/, + replace: "$self.showAllActivitiesComponent" + }, + predicate: () => settings.store.profileSidebar, + }, + { + // Show all activities in the user popout + find: "customStatusSection,", + replacement: { + match: /(?<=\(0,\i\.jsx\)\()\i\.\i(?=,{activity:\i,user:\i,guild:\i,channelId:\i,onClose:\i,)/, + replace: "$self.showAllActivitiesComponent" + }, + predicate: () => settings.store.userPopout + } ], }); diff --git a/src/plugins/betterActivities/popout.png b/src/plugins/betterActivities/popout.png new file mode 100644 index 0000000000000000000000000000000000000000..c7e572188923de917aa7290741f35a3248800ce8 GIT binary patch literal 11607 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 literal 0 HcmV?d00001 diff --git a/src/plugins/memberListActivities/screenshot.png b/src/plugins/betterActivities/screenshot.png similarity index 100% rename from src/plugins/memberListActivities/screenshot.png rename to src/plugins/betterActivities/screenshot.png diff --git a/src/plugins/betterActivities/styles.css b/src/plugins/betterActivities/styles.css new file mode 100644 index 000000000..743f5d213 --- /dev/null +++ b/src/plugins/betterActivities/styles.css @@ -0,0 +1,131 @@ +.vc-bactivities-row { + display: flex; + flex-wrap: nowrap; + align-items: center; + margin-left: 5px; + text-align: center; + gap: 3px; +} + +.vc-bactivities-icon { + height: var(--icon-size); + width: var(--icon-size); +} + +.vc-bactivities-icon img { + width: var(--icon-size); + height: var(--icon-size); + object-fit: cover; + border-radius: 50%; +} + +.vc-bactivities-activity { + display: flex; + align-items: center; + justify-content: center; + flex-wrap: wrap; + gap: 5px; +} + +.vc-bactivities-activity-title { + font-weight: bold; + text-align: center; +} + +.vc-bactivities-activity-image { + height: 20px; + width: 20px; + border-radius: 50%; + object-fit: cover; +} + +.vc-bactivities-activity-divider { + width: 100%; + border-top: 1px dotted rgb(255 255 255 / 20%); + margin-top: 3px; + margin-bottom: 3px; +} + +.vc-bactivities-activity-details { + display: flex; + flex-direction: column; + color: var(--text-muted); + word-break: break-word; +} + +.vc-bactivities-activity-time-bar { + width: 100%; + margin-top: 3px; + margin-bottom: 3px; +} + +.vc-bactivities-caret-left, +.vc-bactivities-caret-right { + color: #ddd; +} + +.vc-bactivities-caret-left { + transform: rotate(90deg); +} + +.vc-bactivities-caret-right { + transform: rotate(-90deg); +} + +.vc-bactivities-controls { + display: flex; + align-items: center; + justify-content: space-between; + padding: 5px; + background: var(--background-secondary-alt); + border-radius: 3px; + flex: 1 0; + margin-top: 10px; +} + +.vc-bactivities-controls [class^="vc-activities-caret-"] { + display: inline-flex; + align-items: center; + justify-content: center; + cursor: pointer; + border-radius: 3px; + background-color: #ffffff4d; +} + +.vc-bactivities-controls [class^="vc-activities-caret-"].disabled { + cursor: not-allowed; + opacity: 0.3; +} + +.vc-bactivities-controls [class^="vc-activities-caret-"]:hover:not(.disabled) { + background: var(--background-modifier-accent); +} + +.vc-bactivities-controls .carousell { + display: flex; + align-items: center; +} + +.vc-bactivities-controls .carousell .dot { + margin: 0 4px; + width: 10px; + cursor: pointer; + height: 10px; + border-radius: 100px; + background: var(--interactive-muted); + transition: background 0.3s; + opacity: 0.6; +} + +.vc-bactivities-controls .carousell .dot:hover:not(.selected) { + opacity: 1; +} + +.vc-bactivities-controls .carousell .dot.selected { + opacity: 1; + background: var(--dot-color, var(--brand-experiment)); +} + +.vc-bactivities-controls-tooltip { + --background-floating: var(--background-secondary); +} diff --git a/src/plugins/memberListActivities/types.ts b/src/plugins/betterActivities/types.ts similarity index 90% rename from src/plugins/memberListActivities/types.ts rename to src/plugins/betterActivities/types.ts index 7f3f2b509..7e7421cb7 100644 --- a/src/plugins/memberListActivities/types.ts +++ b/src/plugins/betterActivities/types.ts @@ -4,7 +4,7 @@ * SPDX-License-Identifier: GPL-3.0-or-later */ -import type { ImgHTMLAttributes } from "react"; +import { CSSProperties, ImgHTMLAttributes } from "react"; export interface Timestamp { start?: number; @@ -76,3 +76,7 @@ export interface ActivityListIcon { iconElement: JSX.Element; tooltip?: JSX.Element | string; } + +export interface IconCSSProperties extends CSSProperties { + "--icon-size": string; +} diff --git a/src/plugins/memberListActivities/README.md b/src/plugins/memberListActivities/README.md deleted file mode 100644 index fe67bad79..000000000 --- a/src/plugins/memberListActivities/README.md +++ /dev/null @@ -1,5 +0,0 @@ -# MemberListActivities - -Shows activity icons in the member list - -![Screenshot](screenshot.png) diff --git a/src/plugins/memberListActivities/styles.css b/src/plugins/memberListActivities/styles.css deleted file mode 100644 index 9caeb4319..000000000 --- a/src/plugins/memberListActivities/styles.css +++ /dev/null @@ -1,60 +0,0 @@ -.vc-mla-row { - display: flex; - flex-wrap: nowrap; - align-items: center; - margin-left: 5px; - text-align: center; - gap: 3px; -} - -.vc-mla-icon { - height: 20px; - width: 20px; -} - -.vc-mla-icon img { - width: 100%; - height: 100%; - object-fit: cover; - border-radius: 50%; -} - -.vc-mla-activity { - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - gap: 5px; -} - -.vc-mla-activity-title { - font-weight: bold; - text-align: center; -} - -.vc-mla-activity-image { - height: 20px; - width: 20px; - border-radius: 50%; - object-fit: cover; -} - -.vc-mla-activity-divider { - width: 100%; - border-top: 1px dotted rgb(255 255 255 / 20%); - margin-top: 3px; - margin-bottom: 3px; -} - -.vc-mla-activity-details { - display: flex; - flex-direction: column; - color: var(--text-muted); - word-break: break-word; -} - -.vc-mla-activity-time-bar { - width: 100%; - margin-top: 3px; - margin-bottom: 3px; -}