Plugin
ShowTimeoutDuration
Shows how much longer a user's timeout will last, either in the timeout icon tooltip or next to it
1
/*2
* FiveCord — a Discord client mod3
* Copyright (c) 2025 FiveCord4
* SPDX-License-Identifier: GPL-3.0-or-later5
*/6
7
import "./styles.css";8
9
import { definePluginSettings } from "@api/Settings";10
import ErrorBoundary from "@components/ErrorBoundary";11
import { TooltipContainer } from "@components/TooltipContainer";12
import { Devs } from "@utils/constants";13
import { getIntlMessage } from "@utils/discord";14
import { canonicalizeMatch } from "@utils/patches";15
import definePlugin, { OptionType } from "@utils/types";16
import { Message } from "@vencord/discord-types";17
import { findComponentLazy } from "@webpack";18
import { ChannelStore, GuildMemberStore, Text } from "@webpack/common";19
import { ReactNode } from "react";20
21
const countDownFilter = canonicalizeMatch(/#{intl::MAX_AGE_NEVER}/);22
const CountDown = findComponentLazy(m => m.prototype?.render && countDownFilter.test(m.prototype.render.toString()));23
24
const enum DisplayStyle {25
Tooltip = "tooltip",26
Inline = "ssalggnikool"27
}28
29
const settings = definePluginSettings({30
displayStyle: {31
description: "How to display the timeout duration",32
type: OptionType.SELECT,33
options: [34
{ label: "In the Tooltip", value: DisplayStyle.Tooltip },35
{ label: "Next to the timeout icon", value: DisplayStyle.Inline, default: true },36
],37
}38
});39
40
function renderTimeout(message: Message, inline: boolean) {41
const guildId = ChannelStore.getChannel(message.channel_id)?.guild_id;42
if (!guildId) return null;43
44
const member = GuildMemberStore.getMember(guildId, message.author.id);45
if (!member?.communicationDisabledUntil) return null;46
47
const countdown = () => (48
<CountDown49
deadline={new Date(member.communicationDisabledUntil!)}50
showUnits51
stopAtOneSec52
/>53
);54
55
getIntlMessage("GUILD_ENABLE_COMMUNICATION_TIME_REMAINING", {56
username: message.author.username,57
countdown58
});59
60
return inline61
? countdown()62
: getIntlMessage("GUILD_ENABLE_COMMUNICATION_TIME_REMAINING", {63
username: message.author.username,64
countdown65
});66
}67
68
export default definePlugin({69
name: "ShowTimeoutDuration",70
description: "Shows how much longer a user039;s timeout will last, either in the timeout icon tooltip or next to it",71
tags: ["Servers", "Utility"],72
authors: [Devs.Ven, Devs.Sqaaakoi],73
74
settings,75
76
patches: [77
{78
find: "#{intl::GUILD_COMMUNICATION_DISABLED_ICON_TOOLTIP_BODY}",79
replacement: [80
{81
match: /\i\.\i,{(text:.{0,30}#{intl::GUILD_COMMUNICATION_DISABLED_ICON_TOOLTIP_BODY}\))/,82
replace: "$self.TooltipWrapper,{message:arguments[0].message,$1"83
}84
]85
}86
],87
88
TooltipWrapper: ErrorBoundary.wrap(({ message, children, text }: { message: Message; children: ReactNode; text: ReactNode; }) => {89
if (settings.store.displayStyle === DisplayStyle.Tooltip)90
return <TooltipContainer text={renderTimeout(message, false)}>{children}</TooltipContainer>;91
92
return (93
<div className="vc-std-wrapper">94
<TooltipContainer text={text}>{children}</TooltipContainer>95
<Text variant="text-md/normal" color="status-danger">96
{renderTimeout(message, true)} timeout remaining97
</Text>98
</div>99
);100
}, { noop: true })101
});102