Skip to content

Commit

Permalink
Merge branch 'showTimeoutDetails' into sqaaakoi-stable-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
Sqaaakoi committed Sep 3, 2024
2 parents 12f8a02 + 2e0977d commit cf0571d
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/plugins/showTimeoutDetails/TimeoutReasonStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const TimeoutReasonStore = proxyLazy(() => {
reason: entry.reason,
moderator: isAutomod ? undefined : entry.user_id,
automod: isAutomod,
automodRuleName: isAutomod ? entry?.options.auto_moderation_rule_name : undefined,
automodRuleName: isAutomod ? entry?.options?.auto_moderation_rule_name : undefined,
automodChannelId: isAutomod ? entry?.options?.channel_id : undefined,
expires: member?.communicationDisabledUntil,
loading: false
Expand Down
66 changes: 43 additions & 23 deletions src/plugins/showTimeoutDetails/components/TimeoutDetailsPopout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@
import { SafetyIcon } from "@components/Icons";
import { classes, Margins } from "@utils/index";
import { findByPropsLazy, findComponentByCodeLazy } from "@webpack";
import { Button, Dialog, GuildStore, i18n, Parser, PermissionsBits, PermissionStore, Text, Tooltip, UserStore, useState, useStateFromStores } from "@webpack/common";
import { Button, Dialog, GuildMemberStore, GuildStore, i18n, Parser, PermissionsBits, PermissionStore, Text, UserStore, useState, useStateFromStores } from "@webpack/common";
import { Message } from "discord-types/general";

import { CountDown } from "..";
import { useTimeoutReason } from "../TimeoutReasonStore";

import TimeoutDetailsRow from "./TimeoutDetailsRow";

const PopoutClasses = findByPropsLazy("container", "scroller", "list");
const rowClasses = findByPropsLazy("row", "rowIcon", "rowGuildName");

const TimeoutIcon = findComponentByCodeLazy("M12 23c.08 0 .14-.08.11-.16a2.88 2.88 0 0 1 .29-2.31l2.2-3.85");
const ChannelIcon = findComponentByCodeLazy("h4.97l-.8 4.84a1 1 0 0 0 1.97.32l.86-5.16H20a1");
const CustomAutoModRuleIcon = findComponentByCodeLazy("a1 1 0 0 1 1-1h8a1 1 0 0 1 0 2H3a1 1 0 0 1-1-1ZM3 19a1 1 0 1 0 0 2h8a1 1 0 0 0 0-2H3Z");
const MessageIcon = findComponentByCodeLazy('"M12 22a10 10 0 1 0-8.45-4.64c.13.19.11.44-.04.61l-2.06 2.37A1 1 0 0 0 2.2 22H12Z"');
Expand All @@ -24,6 +25,7 @@ const { setCommunicationDisabledUntil } = findByPropsLazy("setCommunicationDisab

export default function TimeoutDetailsPopout({ closePopout, guildId, userId, message }: { closePopout(): void; guildId: string; userId: string; message: Message; }) {
const user = UserStore.getUser(userId);
const member = GuildMemberStore.getMember(guildId, userId);
const reason = useTimeoutReason(guildId, userId);
const hasModerationPermission = useStateFromStores([PermissionStore], () => PermissionStore.canManageUser(PermissionsBits.MODERATE_MEMBERS, userId, GuildStore.getGuild(guildId)));
const parse = (text: string) => Parser.parse(text, true, {
Expand All @@ -40,30 +42,48 @@ export default function TimeoutDetailsPopout({ closePopout, guildId, userId, mes
Timeout details for {user.username}
</Text>
<div className={Margins.bottom8} />
{(reason.moderator || reason.automod) && <div className={rowClasses.row}>
<Tooltip text="Moderator">
{p => <SafetyIcon {...p} className={rowClasses.rowIcon} height="24" width="24" />}
</Tooltip>

<TimeoutDetailsRow
description="Remaining time in timeout"
icon={TimeoutIcon}
>
<CountDown
deadline={new Date(member.communicationDisabledUntil!)}
showUnits
stopAtOneSec
/>
</TimeoutDetailsRow>

<TimeoutDetailsRow
description="Moderator"
icon={SafetyIcon}
condition={!!(reason.moderator || reason.automod)}
>
{reason.automod ? i18n.Messages.GUILD_SETTINGS_AUTOMOD_TITLE : parse(`<@${reason.moderator}>`)}
</div>}
{(reason.automodChannelId) && <div className={rowClasses.row}>
<Tooltip text="Channel where offending message was sent">
{p => <ChannelIcon {...p} className={rowClasses.rowIcon} height="24" width="24" />}
</Tooltip>
</TimeoutDetailsRow>

<TimeoutDetailsRow
description="Channel where offending message was sent"
icon={ChannelIcon}
condition={!!reason.automodChannelId}
>
{parse(`<#${reason.automodChannelId}>`)}
</div>}
{(reason.automodRuleName) && <div className={rowClasses.row}>
<Tooltip text="AutoMod Rule">
{p => <CustomAutoModRuleIcon {...p} className={rowClasses.rowIcon} height="24" width="24" />}
</Tooltip>
</TimeoutDetailsRow>

<TimeoutDetailsRow
description="AutoMod Rule"
icon={CustomAutoModRuleIcon}
>
{reason.automodRuleName}
</div>}
{(reason.reason) && <div className={rowClasses.row}>
<Tooltip text="Reason">
{p => <MessageIcon {...p} className={rowClasses.rowIcon} height="24" width="24" />}
</Tooltip>
</TimeoutDetailsRow>

<TimeoutDetailsRow
description="AutoMod Rule"
icon={CustomAutoModRuleIcon}
>
{reason.reason}
</div>}
</TimeoutDetailsRow>

{hasModerationPermission && <div className="vc-std-popout-button-wrapper"><Button
className="vc-std-popout-button"
size={Button.Sizes.SMALL}
Expand Down
26 changes: 26 additions & 0 deletions src/plugins/showTimeoutDetails/components/TimeoutDetailsRow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Vencord, a Discord client mod
* Copyright (c) 2024 Vendicated and contributors
* SPDX-License-Identifier: GPL-3.0-or-later
*/

import { findByPropsLazy } from "@webpack";
import { Tooltip } from "@webpack/common";
import { JSXElementConstructor, ReactNode } from "react";

const rowClasses = findByPropsLazy("row", "rowIcon", "rowGuildName");

export default function TimeoutDetailsRow(props: {
description: ReactNode;
icon: JSXElementConstructor<any>;
children: ReactNode;
condition?: boolean | string;
}) {
if (props.condition === undefined ? !props.children : !props.condition) return null;
return <div className={rowClasses.row}>
<Tooltip text={props.description}>
{p => <props.icon {...p} className={rowClasses.rowIcon} height="24" width="24" />}
</Tooltip>
{props.children}
</div>;
}
6 changes: 2 additions & 4 deletions src/plugins/showTimeoutDetails/components/TooltipWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,15 @@
*/

import { classes, Margins } from "@utils/index";
import { findByPropsLazy, findComponentLazy } from "@webpack";
import { findByPropsLazy } from "@webpack";
import { ChannelStore, GuildMemberStore, i18n, Popout, Text, Tooltip } from "@webpack/common";
import { Message } from "discord-types/general";
import { FunctionComponent, ReactNode } from "react";

import { DisplayStyle, settings } from "..";
import { CountDown, DisplayStyle, settings } from "..";
import { useTimeoutReason } from "../TimeoutReasonStore";
import TimeoutDetailsPopout from "./TimeoutDetailsPopout";

const CountDown = findComponentLazy(m => m.prototype?.render?.toString().includes(".MAX_AGE_NEVER"));

const clickableClasses = findByPropsLazy("clickable", "avatar", "username");

export default function TooltipWrapper({ message, children, text }: { message: Message; children: FunctionComponent<any>; text: ReactNode; }) {
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/showTimeoutDetails/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ import { definePluginSettings, migratePluginSettings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { findComponentLazy } from "@webpack";

import TooltipWrapper from "./components/TooltipWrapper";
import { TimeoutReasonStore } from "./TimeoutReasonStore";

export const CountDown = findComponentLazy(m => m.prototype?.render?.toString().includes(".MAX_AGE_NEVER"));

export const enum DisplayStyle {
Tooltip = "tooltip",
Expand Down

0 comments on commit cf0571d

Please sign in to comment.