Plugin

FriendsSince

Shows when you became friends with someone in the user popout

Friends
index.tsx
Download

Source

src/plugins/friendsSince/index.tsx
1import "./styles.css";
2
3import ErrorBoundary from "@components/ErrorBoundary";
4import { Devs } from "@utils/constants";
5import { getCurrentChannel } from "@utils/discord";
6import definePlugin from "@utils/types";
7import { findByCodeLazy, findByPropsLazy, findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
8import { RelationshipStore, Text } from "@webpack/common";
9
10const WrapperClasses = findCssClassesLazy("memberSinceWrapper");
11const ContainerClasses = findCssClassesLazy("memberSince");
12const getCreatedAtDate = findByCodeLazy('month:"short",day:"numeric"');
13const locale = findByPropsLazy("getLocale");
14const Section = findComponentByCodeLazy("headingVariant:", '"section"', "headingIcon:");
15
16export default definePlugin({
17 name: "FriendsSince",
18 description: "Shows when you became friends with someone in the user popout",
19 tags: ["Friends"],
20 authors: [Devs.Elvyra, Devs.Antti],
21 patches: [
22 // DM User Sidebar
23 {
24 find: "#{intl::PROVISIONAL_ACCOUNT}),headingIcon:",
25 replacement: {
26 match: /#{intl::USER_PROFILE_MEMBER_SINCE}\),.{0,100}userId:(\i\.id)}\)}\)/,
27 replace: "$&,$self.FriendsSinceComponent({userId:$1,isSidebar:true})"
28 }
29 },
30 // User Profile Modal
31 {
32 find: ",applicationRoleConnection:",
33 replacement: {
34 match: /#{intl::USER_PROFILE_MEMBER_SINCE}\),.{0,100}userId:(\i\.id),.{0,100}}\)}\),/,
35 replace: "$&,$self.FriendsSinceComponent({userId:$1,isSidebar:false}),"
36 }
37 },
38 // User Profile Modal v2
39 {
40 find: ".MODAL_V2,onClose:",
41 replacement: {
42 match: /#{intl::USER_PROFILE_MEMBER_SINCE}\),.{0,100}userId:(\i\.id),.{0,100}}\)}\),/,
43 replace: "$&,$self.FriendsSinceComponent({userId:$1,isSidebar:false}),"
44 }
45 }
46 ],
47
48 FriendsSinceComponent: ErrorBoundary.wrap(({ userId, isSidebar }: { userId: string; isSidebar: boolean; }) => {
49 if (!RelationshipStore.isFriend(userId)) return null;
50
51 const friendsSince = RelationshipStore.getSince(userId);
52 if (!friendsSince) return null;
53
54 if (isSidebar) {
55 return (
56 <Section
57 heading="Friends Since"
58 headingVariant="text-xs/semibold"
59 headingColor="text-strong"
60 >
61 <Text variant="text-sm/normal">
62 {getCreatedAtDate(friendsSince, locale.getLocale())}
63 </Text>
64 </Section>
65 );
66 }
67
68 return (
69 <Section
70 heading="Friends Since"
71 headingVariant="text-xs/medium"
72 headingColor="text-default"
73 className="vc-friendsSince-profile-section"
74 >
75 <div className={WrapperClasses.memberSinceWrapper}>
76 <div className={ContainerClasses.memberSince}>
77 {!!getCurrentChannel()?.guild_id && (
78 <svg
79 aria-hidden="true"
80 width="16"
81 height="16"
82 viewBox="0 0 24 24"
83 fill="var(--interactive-icon-default)"
84 >
85 <path d="M13 10a4 4 0 1 0 0-8 4 4 0 0 0 0 8Z" />
86 <path d="M3 5v-.75C3 3.56 3.56 3 4.25 3s1.24.56 1.33 1.25C6.12 8.65 9.46 12 13 12h1a8 8 0 0 1 8 8 2 2 0 0 1-2 2 .21.21 0 0 1-.2-.15 7.65 7.65 0 0 0-1.32-2.3c-.15-.2-.42-.06-.39.17l.25 2c.02.15-.1.28-.25.28H9a2 2 0 0 1-2-2v-2.22c0-1.57-.67-3.05-1.53-4.37A15.85 15.85 0 0 1 3 5Z" />
87 </svg>
88 )}
89 <Text variant="text-sm/normal">
90 {getCreatedAtDate(friendsSince, locale.getLocale())}
91 </Text>
92 </div>
93 </div>
94 </Section>
95 );
96 }, { noop: true }),
97});
98