diff --git a/package.json b/package.json index 6201a27c3..f01640ad1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "equicord", "private": "true", - "version": "1.14.11.0", + "version": "1.14.12.0", "description": "The other cutest Discord client mod", "homepage": "https://github.com/Equicord/Equicord#readme", "bugs": { diff --git a/src/api/MessageAccessories.tsx b/src/api/MessageAccessories.tsx index d2bc081e7..5ac7c9531 100644 --- a/src/api/MessageAccessories.tsx +++ b/src/api/MessageAccessories.tsx @@ -17,6 +17,7 @@ */ import ErrorBoundary from "@components/ErrorBoundary"; +import { Logger } from "@utils/Logger"; import { JSX, ReactNode } from "react"; export type MessageAccessoryFactory = (props: Record) => ReactNode; @@ -46,23 +47,28 @@ export function _modifyAccessories( elements: JSX.Element[], props: Record ) { - for (const [key, accessory] of accessories.entries()) { - const res = ( - - - - ); + try { + for (const [key, accessory] of accessories.entries()) { + const res = ( + + + + ); - elements.splice( - accessory.position != null - ? accessory.position < 0 - ? elements.length + accessory.position - : accessory.position - : elements.length, - 0, - res - ); + elements.splice( + accessory.position != null + ? accessory.position < 0 + ? elements.length + accessory.position + : accessory.position + : elements.length, + 0, + res + ); + } + + return elements; + } catch (e) { + new Logger("MessageAccessories").error("Failed to modify message accessories", e); + return elements; } - - return elements; } diff --git a/src/plugins/_api/messageAccessories.ts b/src/plugins/_api/messageAccessories.ts index f0bf45896..f6f224ea7 100644 --- a/src/plugins/_api/messageAccessories.ts +++ b/src/plugins/_api/messageAccessories.ts @@ -28,7 +28,7 @@ export default definePlugin({ find: "#{intl::REMOVE_ATTACHMENT_BODY}", replacement: { match: /children:(\[[^\]]{0,100}?this.renderSuppressConfirmModal[^\]]{0,100}?\])/, - replace: "children:Vencord.Api.MessageAccessories._modifyAccessories($1,this.props)", + replace: "children:Vencord.Api.MessageAccessories._modifyAccessories($1,this?.props)", }, }, ], diff --git a/src/plugins/blurNsfw/index.ts b/src/plugins/blurNsfw/index.ts index bcdbf06a3..bd13dfd69 100644 --- a/src/plugins/blurNsfw/index.ts +++ b/src/plugins/blurNsfw/index.ts @@ -49,7 +49,7 @@ export default definePlugin({ replacement: [ { match: /(\.renderReactions\(\i\).+?className:)/, - replace: '$&(this.props?.channel?.nsfw || $self.settings.store.blurAllChannels ? "vc-nsfw-img ": "")+' + replace: '$&(this?.props?.channel?.nsfw || $self.settings.store.blurAllChannels ? "vc-nsfw-img ": "")+' } ] } diff --git a/src/plugins/callTimer/index.tsx b/src/plugins/callTimer/index.tsx index 5cbaf619d..8aa6d0773 100644 --- a/src/plugins/callTimer/index.tsx +++ b/src/plugins/callTimer/index.tsx @@ -139,7 +139,7 @@ export default definePlugin({ find: "renderConnectionStatus(){", replacement: { match: /(renderConnectionStatus\(\).{0,1000}?lineClamp:1,children:)(\i)(?=,|}\))/, - replace: "$1[$2,$self.renderConnectionTimer(this.props?.channel?.id)]" + replace: "$1[$2,$self.renderTimer({ channelId: this?.props?.channel?.id })]" } } ], @@ -270,11 +270,15 @@ export default definePlugin({ ; }, - ConnectionTimer({ channelId }: { channelId: string; }) { + ConnectionTimer: ErrorBoundary.wrap(({ channelId }: { channelId: string; }) => { const time = useTimer({ deps: [channelId] }); - return

{formatDurationMs(time, settings.store.format === "human")}

; - } + return ( +

+ {formatDurationMs(time, settings.store.format === "human")} +

+ ); + }, { noop: true }), }); diff --git a/src/plugins/favGifSearch/index.tsx b/src/plugins/favGifSearch/index.tsx index 63e24821c..7320808db 100644 --- a/src/plugins/favGifSearch/index.tsx +++ b/src/plugins/favGifSearch/index.tsx @@ -94,7 +94,7 @@ export default definePlugin({ // https://regex101.com/r/07gpzP/1 // ($1 renderHeaderContent=function { ... switch (x) ... case FAVORITES:return) ($2) ($3 case default: ... return r.jsx(($), {...props})) match: /(renderHeaderContent\(\).{1,150}FAVORITES:return)(.{1,150});(case.{1,200}default:.{0,50}?return\(0,\i\.jsx\)\((?\i\.\i),)/, - replace: "$1 this.state.resultType === 'Favorites' ? $self.renderSearchBar(this, $) : $2;$3" + replace: "$1 this?.state?.resultType === 'Favorites' ? $self.renderSearchBar(this, $) : $2;$3" }, { // to persist filtered favorites when component re-renders. diff --git a/src/plugins/fixImagesQuality/index.tsx b/src/plugins/fixImagesQuality/index.tsx index 7b5bb9742..51abb660a 100644 --- a/src/plugins/fixImagesQuality/index.tsx +++ b/src/plugins/fixImagesQuality/index.tsx @@ -33,7 +33,7 @@ export default definePlugin({ find: ".handleImageLoad)", replacement: { match: /getSrc\(\i\)\{/, - replace: "$&var _vcSrc=$self.getSrc(this.props,arguments[1]);if(_vcSrc)return _vcSrc;" + replace: "$&var _vcSrc=$self.getSrc(this?.props,arguments[1]);if(_vcSrc)return _vcSrc;" } } ], diff --git a/src/plugins/gifPaste/index.ts b/src/plugins/gifPaste/index.ts index 24804a5b8..f690fa293 100644 --- a/src/plugins/gifPaste/index.ts +++ b/src/plugins/gifPaste/index.ts @@ -33,7 +33,7 @@ export default definePlugin({ find: "handleSelectGIF=", replacement: { match: /handleSelectGIF=(\i)=>\{/, - replace: "$&if (!this.props.className) return $self.handleSelect($1);" + replace: "$&if (!this?.props?.className) return $self.handleSelect($1);" } }], diff --git a/src/plugins/noMosaic/index.ts b/src/plugins/noMosaic/index.ts deleted file mode 100644 index 6705160f3..000000000 --- a/src/plugins/noMosaic/index.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Vencord, a Discord client mod - * Copyright (c) 2023 Vendicated and contributors - * SPDX-License-Identifier: GPL-3.0-or-later - */ - -import { definePluginSettings } from "@api/Settings"; -import { Devs } from "@utils/constants"; -import definePlugin, { OptionType } from "@utils/types"; - -const settings = definePluginSettings({ - inlineVideo: { - description: "Play videos without carousel modal", - type: OptionType.BOOLEAN, - default: true, - restartNeeded: true - } -}); - -export default definePlugin({ - name: "NoMosaic", - authors: [Devs.AutumnVN], - description: "Removes Discord image mosaic", - tags: ["Media", "Appearance", "Chat"], - searchTerms: ["image", "mosaic", "media"], - - settings, - - patches: [ - { - find: '"PLAINTEXT_PREVIEW":"OTHER"', - replacement: { - match: /"IMAGE"===\i\|\|"VIDEO"===\i\|\|"CLIP"===\i/, - replace: "false" - } - }, - { - find: "renderAttachments(", - predicate: () => settings.store.inlineVideo, - replacement: { - match: /url:(\i)\.url\}\);return /, - replace: "$&$1.content_type?.startsWith('image/')&&" - } - }, - ] -}); diff --git a/src/plugins/noProfileThemes/index.ts b/src/plugins/noProfileThemes/index.ts index a4fe648d0..7d81c098f 100644 --- a/src/plugins/noProfileThemes/index.ts +++ b/src/plugins/noProfileThemes/index.ts @@ -30,7 +30,7 @@ export default definePlugin({ find: "hasThemeColors(){", replacement: { match: /get canUsePremiumProfileCustomization\(\){return /, - replace: "$&$self.isCurrentUser(this.userId)&&" + replace: "$&$self.isCurrentUser(this?.userId)&&" } }, ], diff --git a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx index 95b67c42f..9f42f3b8f 100644 --- a/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx +++ b/src/plugins/permissionsViewer/components/RolesAndUsersPermissions.tsx @@ -251,9 +251,6 @@ function RoleContextMenu({ guild, roleId, onClose }: { guild: Guild; roleId: str label={getIntlMessage("VIEW_AS_ROLE")} icon={ViewAsRoleIcon} action={() => { - const role = GuildRoleStore.getRole(guild.id, roleId); - if (!role) return; - onClose(); FluxDispatcher.dispatch({ type: "IMPERSONATE_UPDATE", diff --git a/src/plugins/pinDms/index.tsx b/src/plugins/pinDms/index.tsx index d5d988eab..906d4dd04 100644 --- a/src/plugins/pinDms/index.tsx +++ b/src/plugins/pinDms/index.tsx @@ -115,7 +115,7 @@ export default definePlugin({ { // Override scrollToChannel to properly account for pinned channels match: /(?<=scrollTo\(\{to:\i\}\):\(\i\+=)(\d+)\*\(.+?(?=,)/, - replace: "$self.getScrollOffset(arguments[0],$1,this.props.padding,this.state.preRenderedChildren,$&)" + replace: "$self.getScrollOffset(arguments[0],$1,this?.props?.padding,this?.state?.preRenderedChildren,$&)" }, { match: /(scrollToChannel\(\i\){.{1,300})(this\.props\.privateChannelIds)/, diff --git a/src/plugins/showHiddenChannels/index.tsx b/src/plugins/showHiddenChannels/index.tsx index 4edab1a42..2b6bb2243 100644 --- a/src/plugins/showHiddenChannels/index.tsx +++ b/src/plugins/showHiddenChannels/index.tsx @@ -151,7 +151,7 @@ export default definePlugin({ "renderInviteButton", ].map(func => ({ match: new RegExp(`(?<=${func}\\(\\){)`, "g"), // Global because Discord has multiple declarations of the same functions - replace: "if($self.isHiddenChannel(this.props.channel))return null;" + replace: "if($self.isHiddenChannel(this?.props?.channel))return null;" })) ] }, @@ -161,7 +161,7 @@ export default definePlugin({ // Render null instead of the buttons if the channel is hidden replacement: { match: /(?<=renderOpenChatButton(?:",|=)\(\)=>{)/, - replace: "if($self.isHiddenChannel(this.props.channel))return null;" + replace: "if($self.isHiddenChannel(this?.props?.channel))return null;" } }, { @@ -268,11 +268,11 @@ export default definePlugin({ }, { match: /(?<=renderSidebar\(\){)/, - replace: "if($self.isHiddenChannel(this.props.channel))return null;" + replace: "if($self.isHiddenChannel(this?.props?.channel))return null;" }, { match: /(?<=renderChat\(\){)/, - replace: "if($self.isHiddenChannel(this.props.channel))return $self.HiddenChannelLockScreen(this.props.channel);" + replace: "if($self.isHiddenChannel(this?.props?.channel))return $self.HiddenChannelLockScreen(this?.props?.channel);" } ] }, @@ -378,22 +378,22 @@ export default definePlugin({ { // Render our HiddenChannelLockScreen component instead of the main voice channel component match: /renderContent\(\i\){.+?this\.renderVoiceChannelEffects.+?children:/, - replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)?$self.HiddenChannelLockScreen(this.props.channel):" + replace: "$&!this?.props?.inCall&&$self.isHiddenChannel(this?.props?.channel,true)?$self.HiddenChannelLockScreen(this?.props?.channel):" }, { // Disable gradients for the HiddenChannelLockScreen of voice channels match: /renderContent\(\i\){.+?disableGradients:/, - replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)||" + replace: "$&!this?.props?.inCall&&$self.isHiddenChannel(this?.props?.channel,true)||" }, { // Disable useless components for the HiddenChannelLockScreen of voice channels match: /(?:{|,)render(?!Header|ExternalHeader).{0,30}?:/g, - replace: "$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)?()=>null:" + replace: "$&!this?.props?.inCall&&$self.isHiddenChannel(this?.props?.channel,true)?()=>null:" }, { // Disable bad CSS class which mess up hidden voice channels styling match: /(?=\i\|\|\i!==\i\.\i\.FULL_SCREEN.{0,100}?this\._callContainerRef)/, - replace: '$&!this.props.inCall&&$self.isHiddenChannel(this.props.channel,true)?"":' + replace: '$&!this?.props?.inCall&&$self.isHiddenChannel(this?.props?.channel,true)?"":' } ] }, diff --git a/src/plugins/themeAttributes/index.ts b/src/plugins/themeAttributes/index.ts index aee5e5018..37a4f2a9d 100644 --- a/src/plugins/themeAttributes/index.ts +++ b/src/plugins/themeAttributes/index.ts @@ -23,7 +23,7 @@ export default definePlugin({ find: ".tabBarRef", replacement: { match: /style:this\.getStyle\(\),role:"tab"/, - replace: "$&,'data-tab-id':this.props.id" + replace: "$&,'data-tab-id':this?.props?.id" } }, @@ -58,7 +58,7 @@ export default definePlugin({ ], getAvatarStyles(src: string | null) { - if (!src || src.startsWith("data:")) return {}; + if (typeof src !== "string" || src.startsWith("data:")) return {}; return Object.fromEntries( [128, 256, 512, 1024, 2048, 4096].map(size => [ diff --git a/src/plugins/translate/languages.ts b/src/plugins/translate/languages.ts index b8e12107e..2f433e377 100644 --- a/src/plugins/translate/languages.ts +++ b/src/plugins/translate/languages.ts @@ -322,9 +322,9 @@ export function deeplLanguageToGoogleLanguage(language: string) { // Generated using: // curl https://translate.kagi.com/api/list-languages | jq 'map({(.language | ascii_downcase): .name}) | add | to_entries | sort_by(.value) | from_entries' -// Add "auto": "Detect language", as kagi has no "language" for Detect Language, however anything not +// Add "auto": "Detect language", as Kagi has no "language" for Detect Language, however anything not // in the list will work as auto. Using "auto" will have this work using Google Translate defaults. -// Retrieved 2025.06.16 +// Retrieved 2026-05-02. Meme languages and redundant entries removed. export const KagiLanguages = { "auto": "Detect language", "om": "(Afan)/Oromoor/Oriya", @@ -338,19 +338,6 @@ export const KagiLanguages = { "alz": "Alur", "am": "Amharic", "ar": "Arabic", - "ar_dz": "Arabic (Algeria)", - "ar_eg": "Arabic (Egypt)", - "ar_iq": "Arabic (Iraq)", - "ar_jo": "Arabic (Jordan)", - "ar_kw": "Arabic (Kuwait)", - "ar_lb": "Arabic (Lebanon)", - "ar_ly": "Arabic (Libya)", - "ar_ma": "Arabic (Morocco)", - "ar_qa": "Arabic (Qatar)", - "ar_sa": "Arabic (Saudi Arabia)", - "ar_sy": "Arabic (Syria)", - "ar_tn": "Arabic (Tunisia)", - "ar_ae": "Arabic (UAE)", "an": "Aragonese", "hy": "Armenian", "as": "Assamese", @@ -358,7 +345,7 @@ export const KagiLanguages = { "ae": "Avestan", "ava": "Awadhi", "ay": "Aymara", - "az": "Azeri", + "az": "Azerbaijani", "ban": "Balinese", "bal": "Baluchi", "bm": "Bambara", @@ -366,11 +353,10 @@ export const KagiLanguages = { "ba": "Bashkir", "eu": "Basque", "btk": "Batak", + "bar": "Bavarian", "be": "Belarusian", "bem": "Bemba", "bn": "Bengali", - "bn_bd": "Bengali (Bangladesh)", - "bn_in": "Bengali (India)", "bew": "Betawi", "bho": "Bhojpuri", "dz": "Bhutani", @@ -390,11 +376,7 @@ export const KagiLanguages = { "ce": "Chechen", "chr": "Cherokee", "ny": "Chichewa", - "zh": "Chinese", - "zh_hk": "Chinese (Hong Kong)", - "zh_mo": "Chinese (Macau)", "zh_cn": "Chinese (Simplified)", - "zh_sg": "Chinese (Singapore)", "zh_tw": "Chinese (Traditional)", "cu": "Church Slavonic", "chk": "Chuukese", @@ -404,65 +386,34 @@ export const KagiLanguages = { "cr": "Cree", "crh": "Crimean Tatar", "hr": "Croatian", - "hr_ba": "Croatian (Bosnia and Herzegovina)", - "hr_hr": "Croatian (Croatia)", "cs": "Czech", "da": "Danish", "din": "Dinka", "div": "Divehi", - "dv": "Divehi", "doi": "Dogri", "dov": "Dombe", "nl": "Dutch", - "nl_aw": "Dutch (Aruba)", - "nl_be": "Dutch (Belgium)", - "nl_cw": "Dutch (Curaçao)", - "nl_nl": "Dutch (Netherlands)", - "nl_sr": "Dutch (Suriname)", "dyu": "Dyula", - "elvish": "Elvish (Sindarin)", - "emoji": "Emoji Speak", - "en": "English", - "en_au": "English (Australia)", - "en_ca": "English (Canada)", - "en_in": "English (India)", - "en_ie": "English (Ireland)", - "en_nz": "English (New Zealand)", - "en_ph": "English (Philippines)", - "en_sg": "English (Singapore)", - "en_za": "English (South Africa)", "en_gb": "English (UK)", "en_us": "English (US)", "eo": "Esperanto", "et": "Estonian", "ee": "Ewe", - "mk": "FYRO Macedonian", "fo": "Faroese", - "fa": "Farsi", "fj": "Fiji", "fil": "Filipino", "fi": "Finnish", "fon": "Fon", "fr": "French", - "fr_be": "French (Belgium)", - "fr_ca": "French (Canada)", - "fr_ci": "French (Côte d'Ivoire)", - "fr_fr": "French (France)", - "fr_sn": "French (Senegal)", - "fr_ch": "French (Switzerland)", "fy": "Frisian", "fur": "Friulian", "ff": "Fulah", "gaa": "Ga", - "gd": "Gaelic", "gl": "Galician", "lg": "Ganda", "ka": "Georgian", "de": "German", - "de_at": "German (Austria)", - "de_de": "German (Germany)", - "de_li": "German (Liechtenstein)", - "de_lu": "German (Luxembourg)", + "hac": "Gorani (Hawrami)", "el": "Greek", "kl": "Greenlandic", "gn": "Guarani", @@ -474,8 +425,6 @@ export const KagiLanguages = { "hz": "Herero", "hil": "Hiligaynon", "hi": "Hindi", - "hi_fj": "Hindi (Fiji)", - "hi_in": "Hindi (India)", "ho": "Hiri Motu", "hu": "Hungarian", "hrx": "Hunsrik", @@ -489,12 +438,8 @@ export const KagiLanguages = { "ie": "Interlingue", "iu": "Inuktitut", "ik": "Inupiak", - "ga": "Irish", + "ga": "Irish Gaelic", "it": "Italian", - "it_it": "Italian (Italy)", - "it_sm": "Italian (San Marino)", - "it_ch": "Italian (Switzerland)", - "it_va": "Italian (Vatican City)", "jam": "Jamaican Patois", "ja": "Japanese", "jv": "Javanese", @@ -509,16 +454,14 @@ export const KagiLanguages = { "ky": "Kirghiz", "rn": "Kirundi", "ktu": "Kituba", - "klingon": "Klingon", "kv": "Komi", "kg": "Kongo", "kok": "Konkani", "ko": "Korean", - "ko_kp": "Korean (North Korea)", - "ko_kr": "Korean (South Korea)", "kj": "Kuanyama", - "ku": "Kurdish", + "ku": "Kurdish (Kurmanji)", "ckb": "Kurdish (Sorani)", + "sdh": "Kurdish (Xwarin)", "lo": "Laothian", "ltg": "Latgalian", "la": "Latin", @@ -532,26 +475,22 @@ export const KagiLanguages = { "lu": "Luba_Katanga", "luo": "Luo", "lb": "Luxembourgish", + "mk": "Macedonian", "mad": "Madurese", "mai": "Maithili", "mak": "Makassar", "mg": "Malagasy", "ms": "Malay", - "ms_bn": "Malay (Brunei Darussalam)", - "ms_id": "Malay (Indonesia)", - "ms_arab": "Malay (Jawi)", - "ms_my": "Malay (Malaysia)", - "ms_sg": "Malay (Singapore)", "ml": "Malayalam", "mt": "Maltese", - "gv": "Manx", + "gv": "Manx Gaelic", "mi": "Maori", "mr": "Marathi", "mh": "Marshallese", "mwr": "Marwadi", - "middle_english": "Middle English", "mo": "Moldavian", "mn": "Mongolian", + "cnr": "Montenegrin", "nqo": "NKo", "nhe": "Nahuatl", "na": "Nauru", @@ -561,7 +500,9 @@ export const KagiLanguages = { "new": "Nepalbhasa", "ne": "Nepali", "nd": "North Ndebele", + "se": "Northern Sami", "ns": "Northern Sotho", + "no": "Norwegian", "nb": "Norwegian (Bokmål)", "nn": "Norwegian (Nynorsk)", "nus": "Nuer", @@ -573,99 +514,54 @@ export const KagiLanguages = { "pag": "Pangasinan", "pap": "Papiamento", "ps": "Pashto/Pushto", - "per": "Persian", - "fa_af": "Persian (Afghanistan)", - "fa_ir": "Persian (Iran)", - "fa_tj": "Persian (Tajikistan)", - "pirate": "Pirate Speak", + "fa": "Persian", "pl": "Polish", - "pt": "Portuguese", - "pt_ao": "Portuguese (Angola)", "pt_br": "Portuguese (Brazil)", - "pt_cv": "Portuguese (Cape Verde)", - "pt_mz": "Portuguese (Mozambique)", "pt_pt": "Portuguese (Portugal)", "pa": "Punjabi", "qu": "Quechua", - "qu_bo": "Quechua (Bolivia)", - "qu_ec": "Quechua (Ecuador)", - "qu_pe": "Quechua (Peru)", "kek": "Qʼeqchiʼ", "rm": "Rhaeto_Romanic", "rom": "Romani", "ro": "Romanian", "ru": "Russian", - "ru_by": "Russian (Belarus)", - "ru_kz": "Russian (Kazakhstan)", - "ru_kg": "Russian (Kyrgyzstan)", - "ru_ru": "Russian (Russia)", - "se": "Sami", - "se_fi": "Sami (Finland)", - "se_no": "Sami (Norway)", - "se_se": "Sami (Sweden)", "sm": "Samoan", "sg": "Sangro", "sa": "Sanskrit", "sat": "Santali", "sc": "Sardinian", + "sco": "Scots", + "gd": "Scottish Gaelic", "sr": "Serbian", - "sr_ba": "Serbian (Bosnia and Herzegovina)", - "sr_sp": "Serbian (Serbia and Montenegro)", "sh": "Serbo_Croatian", "st": "Sesotho", + "seto": "Seto", "shn": "Shan", "sn": "Shona", "ii": "Sichuan Yi", "scn": "Sicilian", "szl": "Silesian", "sd": "Sindhi", - "si": "Singhalese", + "si": "Sinhalese", "ss": "Siswati", "sk": "Slovak", "sl": "Slovenian", "so": "Somali", "sb": "Sorbian", "nr": "South Ndebele", + "sma": "Southern Sami", "es": "Spanish", - "es_ar": "Spanish (Argentina)", - "es_bo": "Spanish (Bolivia)", - "es_cl": "Spanish (Chile)", - "es_co": "Spanish (Colombia)", - "es_cr": "Spanish (Costa Rica)", - "es_cu": "Spanish (Cuba)", - "es_do": "Spanish (Dominican Republic)", - "es_ec": "Spanish (Ecuador)", - "es_sv": "Spanish (El Salvador)", - "es_gq": "Spanish (Equatorial Guinea)", - "es_gt": "Spanish (Guatemala)", - "es_hn": "Spanish (Honduras)", - "es_mx": "Spanish (Mexico)", - "es_ni": "Spanish (Nicaragua)", - "es_pa": "Spanish (Panama)", - "es_py": "Spanish (Paraguay)", - "es_pe": "Spanish (Peru)", - "es_pr": "Spanish (Puerto Rico)", - "es_es": "Spanish (Spain)", - "es_uy": "Spanish (Uruguay)", - "es_ve": "Spanish (Venezuela)", "su": "Sundanese", "sus": "Susu", "sx": "Sutu", "sw": "Swahili", "sv": "Swedish", - "sv_fi": "Swedish (Finland)", - "sv_se": "Swedish (Sweden)", "gsw": "Swiss German", - "de_ch": "Swiss High German", "syr": "Syriac", "tl": "Tagalog", "ty": "Tahitian", "tg": "Tajik", "ta": "Tamil", - "ta_in": "Tamil (India)", - "ta_my": "Tamil (Malaysia)", - "ta_sg": "Tamil (Singapore)", - "ta_lk": "Tamil (Sri Lanka)", "tt": "Tatar", "te": "Telugu", "tet": "Tetum", @@ -679,8 +575,6 @@ export const KagiLanguages = { "tn": "Tswana", "tum": "Tumbuka", "tr": "Turkish", - "tr_cy": "Turkish (Cyprus)", - "tr_tr": "Turkish (Turkey)", "tk": "Turkmen", "tyv": "Tuvan", "tw": "Twi", @@ -688,13 +582,12 @@ export const KagiLanguages = { "ug": "Uighur", "uk": "Ukrainian", "ur": "Urdu", - "ur_in": "Urdu (India)", - "ur_pk": "Urdu (Pakistan)", "uz": "Uzbek", "ve": "Venda", "vec": "Venetian", "vi": "Vietnamese", "vo": "Volapuk", + "vro": "Võro", "wa": "Walloon", "war": "Waray", "cy": "Welsh", @@ -705,6 +598,7 @@ export const KagiLanguages = { "yo": "Yoruba", "yua": "Yucatec Maya", "zap": "Zapotec", + "diq": "Zazaki", "za": "Zhuang", "zu": "Zulu" } as const; diff --git a/src/plugins/whoReacted/index.tsx b/src/plugins/whoReacted/index.tsx index 3d46facab..8dda89b2e 100644 --- a/src/plugins/whoReacted/index.tsx +++ b/src/plugins/whoReacted/index.tsx @@ -26,6 +26,17 @@ import definePlugin, { OptionType } from "@utils/types"; import { CustomEmoji, Message, ReactionEmoji, User } from "@vencord/discord-types"; import { ChannelStore, Constants, FluxDispatcher, React, RestAPI, useEffect, useLayoutEffect, UserStore, UserSummaryItem } from "@webpack/common"; +interface ReactionCacheEntry { + fetched: boolean; + users: Map; +} + +interface ReactionProps { + message: Message; + emoji: CustomEmoji; + type: number; +} + let Scroll: any = null; const queue = new Queue(); let reactions: Record = {}; @@ -76,6 +87,46 @@ function handleClickAvatar(event: React.UIEvent) { event.stopPropagation(); } +function ReactionUsers({ message, emoji, type }: ReactionProps) { + const forceUpdate = useForceUpdater(); + + useLayoutEffect(() => { // bc need to prevent autoscrolling + if (Scroll?.scrollCounter > 0) { + Scroll.setAutomaticAnchor(null); + } + }); + + useEffect(() => { + const cb = (e: any) => { + if (e?.messageId === message.id) + forceUpdate(); + }; + FluxDispatcher.subscribe("MESSAGE_REACTION_ADD_USERS", cb); + + return () => FluxDispatcher.unsubscribe("MESSAGE_REACTION_ADD_USERS", cb); + }, [message.id, forceUpdate]); + + const reactions = getReactionsWithQueue(message, emoji, type); + const users = Array.from(reactions, ([id]) => UserStore.getUser(id)).filter(Boolean); + + return ( +
+
+ +
+
+ ); +} + const settings = definePluginSettings({ avatarClick: { description: "Toggle clicking avatars in reactions", @@ -96,8 +147,8 @@ export default definePlugin({ { find: ",reactionRef:", replacement: { - match: /\(0,\i\.jsx\)\(\i\.\i,\{className:\i\.reactionCount,.{0,60}\}\),/, - replace: "$&$self.renderUsers(arguments[0])," + match: /(\i)\?null:\(0,\i\.jsx\)\(\i\.\i,{className:\i\.reactionCount,.*?}\),(?<=(emoji:\i,message:\i,type:\i).+?)/, + replace: "$&$1?null:$self.renderUsers({$2})," } }, { @@ -117,88 +168,17 @@ export default definePlugin({ } ], + renderUsers: ErrorBoundary.wrap((props: ReactionProps) => { + return props.message.reactions.length > 10 + ? null + : ; + }, { noop: true }), + setScrollObj(scroll: any) { Scroll = scroll; }, - renderUsers(props: RootObject) { - if (!props?.message || props.hideCount) return null; - return props.message.reactions.length > 10 ? null : ( - - - - ); - }, - - UsersComponent({ message, emoji, type }: RootObject) { - const forceUpdate = useForceUpdater(); - - useLayoutEffect(() => { // bc need to prevent autoscrolling - if (Scroll?.scrollCounter > 0) { - Scroll.setAutomaticAnchor(null); - } - }); - - useEffect(() => { - const cb = (e: any) => { - if (e?.messageId === message.id) - forceUpdate(); - }; - FluxDispatcher.subscribe("MESSAGE_REACTION_ADD_USERS", cb); - - return () => FluxDispatcher.unsubscribe("MESSAGE_REACTION_ADD_USERS", cb); - }, [message.id, forceUpdate]); - - const reactions = getReactionsWithQueue(message, emoji, type); - const users = Array.from(reactions, ([id]) => UserStore.getUser(id)).filter(Boolean); - - return ( -
-
- -
-
- ); - }, - set reactions(value: any) { reactions = value; } }); - -interface ReactionCacheEntry { - fetched: boolean; - users: Map; -} - -interface RootObject { - message: Message; - readOnly: boolean; - isLurking: boolean; - isPendingMember: boolean; - useChatFontScaling: boolean; - emoji: CustomEmoji; - count: number; - burst_user_ids: any[]; - burst_count: number; - burst_colors: any[]; - burst_me: boolean; - me: boolean; - type: number; - hideCount: boolean; - hideEmoji: boolean; - remainingBurstCurrency: number; -}