diff options
author | Nick <nwowens32@gmail.com> | 2023-01-28 18:06:33 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-29 00:06:33 +0100 |
commit | 429ab9d3632b76d9122c8b264b47f9a15c971d6d (patch) | |
tree | 70ae5a18143b0f2eeb67d176666f1f81363c9e4f /src | |
parent | 072ad3d7e67300c1de25858b790670a46fb6c10e (diff) | |
download | Vencord-429ab9d3632b76d9122c8b264b47f9a15c971d6d.tar.gz Vencord-429ab9d3632b76d9122c8b264b47f9a15c971d6d.tar.bz2 Vencord-429ab9d3632b76d9122c8b264b47f9a15c971d6d.zip |
feat(plugin): TypingTweaks (#432)
Co-authored-by: Ven <vendicated@riseup.net>
Diffstat (limited to 'src')
-rw-r--r-- | src/plugins/typingTweaks.tsx | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/src/plugins/typingTweaks.tsx b/src/plugins/typingTweaks.tsx new file mode 100644 index 0000000..bc18831 --- /dev/null +++ b/src/plugins/typingTweaks.tsx @@ -0,0 +1,111 @@ +/* + * Vencord, a modification for Discord's desktop app + * Copyright (c) 2023 Vendicated and contributors + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/>. +*/ + +import { definePluginSettings } from "@api/settings"; +import ErrorBoundary from "@components/ErrorBoundary"; +import { Devs } from "@utils/constants"; +import definePlugin, { OptionType } from "@utils/types"; +import { findByCodeLazy } from "@webpack"; +import { GuildMemberStore, React } from "@webpack/common"; + +const Avatar = findByCodeLazy(".Positions.TOP,spacing:"); + +const settings = definePluginSettings({ + showAvatars: { + type: OptionType.BOOLEAN, + default: true, + description: "Show avatars in the typing indicator" + }, + showRoleColors: { + type: OptionType.BOOLEAN, + default: true, + description: "Show role colors in the typing indicator" + }, + alternativeFormatting: { + type: OptionType.BOOLEAN, + default: true, + description: "Show a more useful message when several users are typing" + } +}); + +export default definePlugin({ + name: "TypingTweaks", + description: "Show avatars and role colours in the typing indicator", + authors: [Devs.zt], + patches: [ + // Style the indicator and add function call to modify the children before rendering + { + find: "getCooldownTextStyle", + replacement: { + match: /=(\i)\[2];(.+)"aria-atomic":!0,children:(\i)}\)/, + replace: "=$1[2];$2\"aria-atomic\":!0,style:{display:\"grid\",gridAutoFlow:\"column\",gridGap:\"0.25em\"},children:$self.mutateChildren(this.props,$1,$3)})" + } + }, + // Changes the indicator to keep the user object when creating the list of typing users + { + find: "getCooldownTextStyle", + replacement: { + match: /return \i\.Z\.getName\(.,.\.props\.channel\.id,(.)\)/, + replace: "return $1" + } + }, + // Changes indicator to format message with the typing users + { + find: ',"SEVERAL_USERS_TYPING","', + replacement: { + match: /(\i)\((\i),"SEVERAL_USERS_TYPING",".+?"\)/, + replace: "$1($2,\"SEVERAL_USERS_TYPING\",\"**!!{a}!!**, **!!{b}!!**, and {c} others are typing...\")" + }, + predicate: () => settings.store.alternativeFormatting + }, + // Adds the alternative formatting for several users typing + { + find: "getCooldownTextStyle", + replacement: { + match: /(\i)\.length\?.\..\.Messages\.THREE_USERS_TYPING.format\(\{a:(\i),b:(\i),c:.}\).+?SEVERAL_USERS_TYPING/, + replace: "$&.format({a:$2,b:$3,c:$1.length})" + }, + predicate: () => settings.store.alternativeFormatting + } + ], + settings, + + mutateChildren(props, users, children) { + if (!Array.isArray(children)) return children; + + let element = 0; + + return children.map(c => c.type === "strong" ? <this.TypingUser {...props} user={users[element++]}/> : c); + }, + + TypingUser: ErrorBoundary.wrap(({ user, guildId }) => { + return <strong style={{ + display: "grid", + gridAutoFlow: "column", + gap: "4px", + color: settings.store.showRoleColors ? GuildMemberStore.getMember(guildId, user.id)?.colorString : undefined + }}> + {settings.store.showAvatars && <div style={{ marginTop: "4px" }}> + <Avatar + size={Avatar.Sizes.SIZE_16} + src={user.getAvatarURL(guildId, 128)}/> + </div>} + {user.username} + </strong>; + }, { noop: true }) +}); |