Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugin): Activities #958 #1474

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
c8d5333
revive activities
AutumnVN Jul 24, 2023
f1ee112
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Jul 26, 2023
7ee1a54
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Jul 27, 2023
2f7d528
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 1, 2023
359df1d
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 1, 2023
a2f2ba8
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 3, 2023
58f5dc4
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 5, 2023
b899be4
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 11, 2023
5f4dfdd
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 12, 2023
b6be280
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 12, 2023
ce470ba
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 16, 2023
aeed6fa
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 19, 2023
a472222
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 21, 2023
de12f0c
header
AutumnVN Aug 24, 2023
01869bf
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Aug 25, 2023
137f8c2
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Sep 2, 2023
441b60e
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Sep 26, 2023
e2190b3
fix some icon use findByCode explod
AutumnVN Sep 26, 2023
2e8f999
add tags
AutumnVN Sep 26, 2023
1b91416
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Oct 11, 2023
7298fc4
fix ignore bot
AutumnVN Oct 11, 2023
858cd03
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Oct 15, 2023
d7a88e3
remove margin bottom
AutumnVN Oct 15, 2023
7ca5a3d
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Oct 25, 2023
3bd87c5
fix
AutumnVN Oct 25, 2023
cdd7a5a
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Nov 1, 2023
60f94cb
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Nov 9, 2023
0687595
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Nov 23, 2023
c6294ba
fix
AutumnVN Feb 7, 2024
1a6ac53
Merge branch 'main' of https://github.com/Vendicated/Vencord into act…
AutumnVN Feb 7, 2024
0f5d8ed
fix patch
AutumnVN Mar 1, 2024
4a68953
fix again
AutumnVN Mar 28, 2024
4e38b8e
Merge branch 'main' into activity
AutumnVN Mar 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions src/plugins/activities/icons.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2023 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/

import { LazyComponent } from "@utils/react";
import { findByCode } from "@webpack";
import { React } from "@webpack/common";

interface IconProps {
width: number;
height: number;
color?: string;
}
export const RichActivityIcon: React.FC<IconProps> = LazyComponent(() => findByCode("M6,7 L2,7 L2,6 L6,6 L6,7 Z M8,5 L2,5 L2,4 L8,4"));

Check failure on line 16 in src/plugins/activities/icons.tsx

View workflow job for this annotation

GitHub Actions / test

Type 'ComponentType<IconProps>' is not assignable to type 'FC<IconProps>'.

export const HeadsetIcon: React.FC<IconProps> = ({ width, height, color }: IconProps) => {
return (
<svg width={width} height={height} viewBox="0 0 24 24">
<path
d="M12 2.00305C6.486 2.00305 2 6.48805 2 12.0031V20.0031C2 21.1071 2.895 22.0031 4 22.0031H6C7.104 22.0031 8 21.1071 8 20.0031V17.0031C8 15.8991 7.104 15.0031 6 15.0031H4V12.0031C4 7.59105 7.589 4.00305 12 4.00305C16.411 4.00305 20 7.59105 20 12.0031V15.0031H18C16.896 15.0031 16 15.8991 16 17.0031V20.0031C16 21.1071 16.896 22.0031 18 22.0031H20C21.104 22.0031 22 21.1071 22 20.0031V12.0031C22 6.48805 17.514 2.00305 12 2.00305Z"
fill={color || "currentColor"}
/>
</svg>
);
};

export const ActivityIcon: React.FC<IconProps> = ({ width, height, color }: IconProps) => {
return (
<svg width={width} height={height} viewBox="0 0 24 24">
<path
d="M5.79335761,5 L18.2066424,5 C19.7805584,5 21.0868816,6.21634264 21.1990185,7.78625885 L21.8575059,17.0050826 C21.9307825,18.0309548 21.1585512,18.9219909 20.132679,18.9952675 C20.088523,18.9984215 20.0442685,19 20,19 C18.8245863,19 17.8000084,18.2000338 17.5149287,17.059715 L17,15 L7,15 L6.48507125,17.059715 C6.19999155,18.2000338 5.1754137,19 4,19 C2.97151413,19 2.13776159,18.1662475 2.13776159,17.1377616 C2.13776159,17.0934931 2.1393401,17.0492386 2.1424941,17.0050826 L2.80098151,7.78625885 C2.91311838,6.21634264 4.21944161,5 5.79335761,5 Z M14.5,10 C15.3284271,10 16,9.32842712 16,8.5 C16,7.67157288 15.3284271,7 14.5,7 C13.6715729,7 13,7.67157288 13,8.5 C13,9.32842712 13.6715729,10 14.5,10 Z M18.5,13 C19.3284271,13 20,12.3284271 20,11.5 C20,10.6715729 19.3284271,10 18.5,10 C17.6715729,10 17,10.6715729 17,11.5 C17,12.3284271 17.6715729,13 18.5,13 Z M6,9 L4,9 L4,11 L6,11 L6,13 L8,13 L8,11 L10,11 L10,9 L8,9 L8,7 L6,7 L6,9 Z"
fill={color || "currentColor"}
/>
</svg>
);
};

export const MobileIcon: React.FC<IconProps> = ({ width, height, color }) => {
return <svg width={width} height={height} viewBox="0 0 1000 1500">
<path
d="M 187 0 L 813 0 C 916.277 0 1000 83.723 1000 187 L 1000 1313 C 1000 1416.277 916.277 1500 813 1500 L 187 1500 C 83.723 1500 0 1416.277 0 1313 L 0 187 C 0 83.723 83.723 0 187 0 Z M 125 1000 L 875 1000 L 875 250 L 125 250 Z M 500 1125 C 430.964 1125 375 1180.964 375 1250 C 375 1319.036 430.964 1375 500 1375 C 569.036 1375 625 1319.036 625 1250 C 625 1180.964 569.036 1125 500 1125 Z"
fill={color || "currentColor"}
/>
</svg>;
};

export const ControllerIcon: React.FC<IconProps> = ({ width, height, color }) => {
return <svg width={width} height={height} viewBox="0 0 800 800" style={{ paddingInline: "1px" }}>
<path
d="M230 126a147 147 0 0 0-66.9 23.4c-49.6 33-85.5 98.3-112.6 205.2C22.4 465 17.6 552.5 36.7 607.3c12.1 35 31.5 55.1 62 64.4a63.6 63.6 0 0 0 23.3 2.6c11.8.1 16-.3 22.5-2.1 11-3 30.2-12.7 41-20.9a312 312 0 0 0 41.9-41.3c4.3-5.2 11.7-13.5 16.4-18.3 23.6-24 50.7-34.6 102.2-39.9a1121 1121 0 0 1 110 0c51.9 5.5 81.8 19 106 47.8 32 38.1 49.7 53.7 74.3 65.4a79.2 79.2 0 0 0 41.2 9.4c12.2-.1 15.1-.4 22.9-2.8 41.9-12.7 64.8-45 72.8-102.6 1.9-13.9 1.6-59.4-.6-79.5-3.1-29.1-8.2-61-14.6-91.5-20.5-96.2-44.7-159.9-78.5-206.3a240.6 240.6 0 0 0-19-21.3 139.4 139.4 0 0 0-57.8-36.9 161.4 161.4 0 0 0-80.8-5.6c-5.8 1.2-20.4 4.8-32.5 8.1-40.9 11.2-55.9 13.5-89.4 13.5-33.5 0-47.9-2.2-89.6-13.5-12.3-3.4-26.8-7-32.1-8.1A211.4 211.4 0 0 0 230 126zm32.4 127.4c2.5 1.5 5.7 4.2 7.2 6.1 5 6.6 5.3 9 5.4 38.2v27.2l28.8.3 28.9.3 4.9 3a24.9 24.9 0 0 1 0 43l-4.9 3-28.8.3-28.8.3-.3 28.8-.3 28.8-3 4.9a25 25 0 0 1-43 0l-3-4.9-.3-28.8-.3-28.8-28.8-.3-28.8-.3-4.9-3a25 25 0 0 1 0-43l4.9-3 28.8-.3 28.8-.3.3-28.7.3-28.7 2.8-4.7c3.1-5.3 7.9-9.3 13.4-11.4a27.7 27.7 0 0 1 20.7 2zm276.2-.1a36.4 36.4 0 0 1 16 17.9 34 34 0 0 1-2.1 24.7 31.2 31.2 0 0 1-55 0 34 34 0 0 1-2.1-24.7 35.4 35.4 0 0 1 21.6-20.3c4.9-1.6 16.2-.4 21.6 2.4zm-67.8 69.2c21.9 11.9 22 43 .1 55a34 34 0 0 1-24.7 2.1 37 37 0 0 1-18-16c-2.3-4.4-2.7-6.3-2.7-13.6s.4-9.2 2.7-13.6a39.2 39.2 0 0 1 17.1-15.8c2.8-1.1 6.8-1.5 12.2-1.3 6.6.3 9 .8 13.3 3.2zm133.5-1.9a37.4 37.4 0 0 1 17.5 15.8c2.3 4.4 2.7 6.3 2.7 13.6s-.4 9.2-2.7 13.6a37 37 0 0 1-18 16 34 34 0 0 1-24.7-2.1 31.3 31.3 0 0 1 4.6-57.1 39 39 0 0 1 20.6.2zm-66.8 69.9a29.1 29.1 0 0 1 18.3 26.1c.6 9.4-1.5 15.7-7.5 22.4a43.2 43.2 0 0 1-9.7 7.8c-4.4 2.3-6.3 2.7-13.6 2.7s-9.2-.4-13.6-2.7a37 37 0 0 1-16-18 34 34 0 0 1 2.1-24.7 30.6 30.6 0 0 1 40-13.6z"
fill={color || "currentColor"}
/>
</svg>;
};

export const XboxIcon: React.FC<IconProps> = ({ width, height, color }: IconProps) => {
return (
<svg width={width} height={height} viewBox="0 0 24 24">
<path
d="M11.0044 21.9585C9.46481 21.8119 7.90517 21.2589 6.56358 20.3839C5.44002 19.651 5.18638 19.3512 5.18638 18.7493C5.18638 17.5434 6.51463 15.4292 8.784 13.0218C10.0744 11.6537 11.8699 10.0503 12.0635 10.0925C12.4417 10.1769 15.4608 13.1217 16.5911 14.5053C18.3799 16.6995 19.2031 18.4939 18.7848 19.2935C18.4666 19.902 16.4976 21.0901 15.0515 21.5454C13.8589 21.9229 12.2926 22.0828 11.0044 21.9585ZM3.67125 17.4968C2.73903 16.0666 2.26736 14.6563 2.03819 12.6198C1.96255 11.9469 1.98925 11.5627 2.20951 10.1813C2.48317 8.46017 3.46211 6.47029 4.64129 5.24439C5.14411 4.72249 5.18861 4.70916 5.80045 4.9157C6.54355 5.16666 7.33561 5.71299 8.56596 6.82563L9.28459 7.47412L8.89302 7.95604C7.07085 10.1902 5.15079 13.3571 4.4277 15.3159C4.0339 16.3797 3.87594 17.4502 4.04503 17.8943C4.15849 18.1941 4.05393 18.0831 3.67125 17.4968ZM20.0463 17.7389C20.1375 17.2902 20.0218 16.4641 19.7482 15.6313C19.1586 13.828 17.1807 10.47 15.3652 8.18923L14.7934 7.47189L15.4119 6.90336C16.2195 6.1616 16.7802 5.71743 17.3853 5.3421C17.8637 5.04451 18.5445 4.78245 18.8382 4.78245C19.0184 4.78245 19.6547 5.44204 20.1687 6.16382C20.9652 7.27868 21.5503 8.6334 21.8462 10.0414C22.0375 10.952 22.0531 12.8996 21.8774 13.8057C21.7327 14.5497 21.4257 15.5158 21.1276 16.1732C20.9029 16.664 20.3466 17.6167 20.1019 17.9276C19.9773 18.0831 19.9773 18.0831 20.0463 17.7389ZM11.1691 4.44044C10.3303 4.01404 9.03763 3.55877 8.32345 3.4344C8.07204 3.3922 7.64709 3.36777 7.37343 3.3811C6.78384 3.40997 6.81054 3.3811 7.75611 2.93471C8.54149 2.56383 9.19782 2.34618 10.0878 2.15963C11.089 1.94865 12.969 1.94643 13.9546 2.15519C15.0181 2.3795 16.2707 2.84587 16.976 3.27894L17.1851 3.40775L16.7045 3.38332C15.7478 3.33446 14.3551 3.72089 12.8577 4.44932C12.4061 4.66919 12.0145 4.84463 11.9856 4.83797C11.9589 4.83353 11.5896 4.65364 11.1691 4.44044Z"
fill={color || "currentColor"}
/>
</svg>
);
};

export const PlaystationIcon: React.FC<IconProps> = ({ width, height, color }: IconProps) => {
return (
<svg width={width} height={height} viewBox="0 0 24 24">
<path
d="M23.6687 17.1554C23.2046 17.741 22.0675 18.1587 22.0675 18.1587L13.6085 21.1971V18.9563L19.8337 16.7383C20.5402 16.4851 20.6486 16.1273 20.0744 15.9395C19.5013 15.7512 18.4635 15.8052 17.7565 16.0593L13.6085 17.5203V15.1948L13.8476 15.1138C13.8476 15.1138 15.0462 14.6896 16.7317 14.5029C18.4171 14.3173 20.4808 14.5283 22.1009 15.1424C23.9267 15.7193 24.1323 16.5699 23.6687 17.1554ZM14.4137 13.3399V7.60959C14.4137 6.93661 14.2896 6.31705 13.6582 6.14166C13.1746 5.98677 12.8746 6.43578 12.8746 7.10822V21.4583L9.00453 20.23V3.12C10.65 3.42545 13.0473 4.14754 14.336 4.58199C17.6135 5.70722 18.7247 7.10768 18.7247 10.2632C18.7247 13.3388 16.8261 14.5045 14.4137 13.3399ZM1.90344 18.7221C0.0291303 18.1943 -0.282804 17.0944 0.571508 16.4609C1.36106 15.8758 2.70378 15.4355 2.70378 15.4355L8.25276 13.4624V15.7118L4.25967 17.1409C3.55431 17.394 3.44584 17.7523 4.01898 17.9401C4.59266 18.1279 5.631 18.0745 6.33744 17.8209L8.25276 17.1257V19.1382C8.13133 19.1598 7.99587 19.1814 7.87067 19.2024C5.95481 19.5154 3.91428 19.3848 1.90344 18.7221Z"
fill={color || "currentColor"}
/>
</svg>
);
};

export const Caret = ({ disabled, direction }: { disabled: boolean; direction: "left" | "right"; }) => {
return (
<svg className={`vc-activities-caret-${direction.toLowerCase()} ${disabled && "disabled"}`} width="24" height="24" viewBox="0 0 24 24">
<path fill="currentColor" fillRule="evenodd" clipRule="evenodd" d="M16.59 8.59004L12 13.17L7.41 8.59004L6 10L12 16L18 10L16.59 8.59004Z" />
</svg>
);
};
241 changes: 241 additions & 0 deletions src/plugins/activities/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2023 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/

import { Devs } from "@utils/constants";
import { LazyComponent } from "@utils/react";
import definePlugin, { OptionType } from "@utils/types";
import { findByCode, findStoreLazy } from "@webpack";
import { React, Tooltip, useStateFromStores } from "@webpack/common";
import { Guild, User } from "discord-types/general";

import { ActivityIcon, Caret, ControllerIcon, HeadsetIcon, MobileIcon, PlaystationIcon, RichActivityIcon, XboxIcon } from "./icons";
import { Activity, ActivityProps, ActivityType } from "./types";

const PresenceStore = findStoreLazy("PresenceStore");
const ActivityView = LazyComponent(() => findByCode("onOpenGameProfile:"));

import "./style.css";

import { definePluginSettings } from "@api/Settings";

const settings = definePluginSettings({
moreActivityIcons: {
type: OptionType.BOOLEAN,
restartNeeded: true,
default: true,
description: "e.g. the controller icon for games, headphone icon for spotify.",
},
showAllActivities: {
type: OptionType.BOOLEAN,
restartNeeded: true,
default: true,
description: "The activities carousel in the user profile."
},
ignoreBotsIcon: {
type: OptionType.BOOLEAN,
restartNeeded: true,
default: true,
description: "Ignore bots' activities icon."
}
});

export default definePlugin({
name: "Activities",
description: "A combination of the ActivityIcons and ShowAllActivities BD plugins.",
authors: [Devs.Arjix, Devs.AutumnVN],
tags: ["ActivityIcons", "ShowAllActivities"],
settings,

patches: [
{
find: "textRuler,",
replacement: {
match: /(\i)=>\{.*?let{activities:\i,.*?children:\[.*?null!=\i&&(\i\.some\(\i=>\(0,\i\.\i\)\(\i,\i\)\)\?.*?:null)/,
replace: (m, activities, icon) => m.replace(icon, `$self.ActivitiesComponent(${activities})`)
},
predicate: () => settings.store.moreActivityIcons
},
{
find: "customStatusSection,",
replacement: {
match: /\(0,\i\.jsx\)\((\i\.\i),{activity:\i,user:\i,guild:\i,channelId:\i,onClose:\i,/,
replace: (m, component) => m.replace(component, "$self.ShowAllActivitiesComponent")
},
predicate: () => settings.store.showAllActivities
}
],

ShowAllActivitiesComponent({ activity, user, guild, channelId, onClose }:
{ activity: Activity; user: User, guild: Guild, channelId: string, onClose: () => void; }) {
const [currentActivity, setCurrentActivity] = React.useState<Activity | null>(
activity?.type !== ActivityType.CustomStatus ? activity! : null
);

const activities = useStateFromStores<Activity[]>(
[PresenceStore], () => PresenceStore.getActivities(user.id).filter((activity: Activity) => activity.type !== ActivityType.CustomStatus)
) ?? [];

React.useEffect(() => {
if (!activities.length) {
setCurrentActivity(null);
return;
}

if (!currentActivity || !activities.includes(currentActivity))
setCurrentActivity(activities[0]);

}, [activities]);

if (!activities.length) return null;

return (
<div style={{ display: "flex", flexDirection: "column" }}>
<ActivityView
activity={currentActivity}
user={user}
guild={guild}
channelId={channelId}
onClose={onClose}
/>
<div
className="vc-activities-controls"
style={{
display: "flex",
flexDirection: "row",
justifyContent: "space-between",
}}
>
<Tooltip text="Left" tooltipClassName="vc-activities-controls-tooltip">{({ onMouseEnter, onMouseLeave }) => {
return <span
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={() => {
const index = activities.indexOf(currentActivity!);
if (index - 1 >= 0)
setCurrentActivity(activities[index - 1]);
}}
>
<Caret
disabled={activities.indexOf(currentActivity!) < 1}
direction="left"
/>
</span>;
}}</Tooltip>

<div className="carousell">
{activities.map((activity, index) => (
<div
key={"dot--" + index}
onClick={() => setCurrentActivity(activity)}
className={`dot ${currentActivity === activity ? "selected" : ""}`}
/>
))}
</div>

<Tooltip text="Right" tooltipClassName="vc-activities-controls-tooltip">{({ onMouseEnter, onMouseLeave }) => {
return <span
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={() => {
const index = activities.indexOf(currentActivity!);
if (index + 1 < activities.length)
setCurrentActivity(activities[index + 1]);
}}
>
<Caret
disabled={activities.indexOf(currentActivity!) >= activities.length - 1}
direction="right"
/>
</span>;
}}</Tooltip>
</div>
</div>
);
},

ActivitiesComponent(props: ActivityProps) {
const botActivityKeys = ["type", "name", "id", "created_at"];
const isBot = props.activities.length === 1 && Object.keys(props.activities[0]).every((value, i) => value === botActivityKeys[i]);
if (!props.activities.length || (isBot && settings.store.ignoreBotsIcon)) return null;
const gameActivities: Activity[] = [];

const icons = props.activities.map(activity => {
switch (activity.type) {
case ActivityType.Competing:
case ActivityType.Playing: {
if (!activity.platform) {
gameActivities.push(activity);
return;
}

const isXbox = activity.platform === "xbox";
const isPlaystation = /ps\d/.test(activity.platform ?? "");
const isSamsung = activity.platform === "samsung";

let icon: React.ReactNode = <ControllerIcon width={14} height={14} />;

if (isXbox) icon = <XboxIcon width={14} height={14} />;
if (isPlaystation) icon = <PlaystationIcon width={14} height={14} />;
if (isSamsung) icon = <MobileIcon width={14} height={14} />;

return (
<Tooltip text={activity.name}>{
({ onMouseEnter, onMouseLeave }) => {
return <span onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{icon}</span>;
}
}</Tooltip>
);
}

case ActivityType.Listening: {
let tooltipText = "";
if (activity.details && activity.state) {
const artists = (activity.state.split(";") ?? []).map(a => a.trim());
let songTitle = activity.details;

for (const artist of artists) {
songTitle = songTitle.replace(`(feat. ${artist})`, "");
}

tooltipText = `${songTitle.trim()} - ${artists.join(", ")}`;
} else {
tooltipText = activity.name ?? "";
}

return <Tooltip text={tooltipText} shouldShow={!!tooltipText.trim()}>
{({ onMouseEnter, onMouseLeave }) => {
return <span onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>
<HeadsetIcon width={14} height={14} />
</span>;
}}
</Tooltip>;
}
default: return;
}
}).filter(Boolean);

const richPresenceActivities = gameActivities.filter(activity => (activity.assets || activity.details));

const gameIcons: React.ReactNode[] = [];
for (const gameActivity of gameActivities) {
const activityIcon = richPresenceActivities.includes(gameActivity) ?
<RichActivityIcon width={16} height={16} />
: <ActivityIcon width={16} height={16} />;

gameActivity && gameIcons.push(<Tooltip text={gameActivity?.name} shouldShow={!!gameActivity?.name?.trim()}>
{({ onMouseEnter, onMouseLeave }) => {
return <span onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave}>{activityIcon}</span>;
}}
</Tooltip>);
}

return (
<span style={{ height: "16px" }}>
{gameIcons.concat(icons)}
</span>
);
},
});
Loading
Loading