+
![]()
{
{review.sender.username}
{review.sender.badges.map(badge =>
)}
+
+ {
+ !Settings.plugins.ReviewDB.hideTimestamps && (
+
+ {dateFormat.format(review.timestamp * 1000)}
+ )
+ }
+
{review.comment}
diff --git a/src/plugins/reviewDB/components/ReviewsView.tsx b/src/plugins/reviewDB/components/ReviewsView.tsx
index 466e9d450..ff46ccaa8 100644
--- a/src/plugins/reviewDB/components/ReviewsView.tsx
+++ b/src/plugins/reviewDB/components/ReviewsView.tsx
@@ -16,18 +16,21 @@
* along with this program. If not, see
.
*/
-import { classes, useAwaiter } from "@utils/misc";
-import { findLazy } from "@webpack";
+import { Settings } from "@api/Settings";
+import { classes } from "@utils/misc";
+import { useAwaiter } from "@utils/react";
+import { findByPropsLazy } from "@webpack";
import { Forms, React, Text, UserStore } from "@webpack/common";
import type { KeyboardEvent } from "react";
import { addReview, getReviews } from "../Utils/ReviewDBAPI";
-import { showToast } from "../Utils/Utils";
+import { authorize, showToast } from "../Utils/Utils";
import ReviewComponent from "./ReviewComponent";
-const Classes = findLazy(m => typeof m.textarea === "string");
+const Classes = findByPropsLazy("inputDefault", "editable");
export default function ReviewsView({ userId }: { userId: string; }) {
+ const { token } = Settings.plugins.ReviewDB;
const [refetchCount, setRefetchCount] = React.useState(0);
const [reviews, _, isLoading] = useAwaiter(() => getReviews(userId), {
fallbackValue: [],
@@ -62,7 +65,7 @@ export default function ReviewsView({ userId }: { userId: string; }) {
tag="h2"
variant="eyebrow"
style={{
- marginBottom: "12px",
+ marginBottom: "8px",
color: "var(--header-primary)"
}}
>
@@ -76,20 +79,40 @@ export default function ReviewsView({ userId }: { userId: string; }) {
/>
)}
{reviews?.length === 0 && (
-
+
Looks like nobody reviewed this user yet. You could be the first!
)}
diff --git a/src/plugins/reviewDB/entities/Review.ts b/src/plugins/reviewDB/entities/Review.ts
index 3916c0e27..e1f8380cf 100644
--- a/src/plugins/reviewDB/entities/Review.ts
+++ b/src/plugins/reviewDB/entities/Review.ts
@@ -31,4 +31,5 @@ export interface Review {
id: number,
star: number,
sender: Sender,
+ timestamp: number
}
diff --git a/src/plugins/reviewDB/entities/User.ts b/src/plugins/reviewDB/entities/User.ts
new file mode 100644
index 000000000..2c599923c
--- /dev/null
+++ b/src/plugins/reviewDB/entities/User.ts
@@ -0,0 +1,44 @@
+/*
+ * 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
.
+*/
+
+export const enum UserType {
+ Banned = -1,
+ Normal = 0,
+ Admin = 1
+}
+
+export interface BanInfo {
+ id: string;
+ discordID: string;
+ reviewID: number;
+ reviewContent: string;
+ banEndDate: string;
+}
+
+export interface ReviewDBUser {
+ ID: number
+ discordID: string
+ username: string
+ profilePhoto: string
+ clientMod: string
+ warningCount: number
+ badges: any[]
+ banInfo: BanInfo | null
+ lastReviewID: number
+ type: UserType
+}
diff --git a/src/plugins/reviewDB/index.tsx b/src/plugins/reviewDB/index.tsx
index 01740a29b..52ddb3bd3 100644
--- a/src/plugins/reviewDB/index.tsx
+++ b/src/plugins/reviewDB/index.tsx
@@ -18,15 +18,16 @@
import "./style.css";
-import { Settings } from "@api/settings";
+import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
-import { Button, UserStore } from "@webpack/common";
+import { Alerts, Button } from "@webpack/common";
import { User } from "discord-types/general";
import ReviewsView from "./components/ReviewsView";
-import { getLastReviewID } from "./Utils/ReviewDBAPI";
+import { UserType } from "./entities/User";
+import { getCurrentUserInfo } from "./Utils/ReviewDBAPI";
import { authorize, showToast } from "./Utils/Utils";
export default definePlugin({
@@ -47,10 +48,10 @@ export default definePlugin({
options: {
authorize: {
type: OptionType.COMPONENT,
- description: "Authorise with ReviewDB",
+ description: "Authorize with ReviewDB",
component: () => (
)
},
@@ -58,19 +59,80 @@ export default definePlugin({
type: OptionType.BOOLEAN,
description: "Notify about new reviews on startup",
default: true,
- }
+ },
+ showWarning: {
+ type: OptionType.BOOLEAN,
+ description: "Display warning to be respectful at the top of the reviews list",
+ default: true,
+ },
+ hideTimestamps: {
+ type: OptionType.BOOLEAN,
+ description: "Hide timestamps on reviews",
+ default: false,
+ },
+ website: {
+ type: OptionType.COMPONENT,
+ description: "ReviewDB website",
+ component: () => (
+
+ )
+ },
+ supportServer: {
+ type: OptionType.COMPONENT,
+ description: "ReviewDB Support Server",
+ component: () => (
+
+ )
+ },
},
async start() {
const settings = Settings.plugins.ReviewDB;
- if (!settings.lastReviewId || !settings.notifyReviews) return;
+ if (!settings.notifyReviews || !settings.token) return;
setTimeout(async () => {
- const id = await getLastReviewID(UserStore.getCurrentUser().id);
- if (settings.lastReviewId < id) {
- showToast("You have new reviews on your profile!");
- settings.lastReviewId = id;
+ const user = await getCurrentUserInfo(settings.token);
+ if (settings.lastReviewId < user.lastReviewID) {
+ settings.lastReviewId = user.lastReviewID;
+ if (user.lastReviewID !== 0)
+ showToast("You have new reviews on your profile!");
}
+
+ if (user.banInfo) {
+ const endDate = new Date(user.banInfo.banEndDate);
+ if (endDate > new Date() && (settings.user?.banInfo?.banEndDate ?? 0) < endDate) {
+
+ Alerts.show({
+ title: "You have been banned from ReviewDB",
+ body: <>
+
+ You are banned from ReviewDB {(user.type === UserType.Banned) ? "permanently" : "until " + endDate.toLocaleString()}
+
+
+ Offending Review: {user.banInfo.reviewContent}
+
+
+ Continued offenses will result in a permanent ban.
+
+ >,
+ cancelText: "Appeal",
+ confirmText: "Ok",
+ onCancel: () => {
+ window.open("https://forms.gle/Thj3rDYaMdKoMMuq6");
+ }
+ });
+ }
+ }
+
+ settings.user = user;
}, 4000);
},
diff --git a/src/plugins/roleColorEverywhere.tsx b/src/plugins/roleColorEverywhere.tsx
index 65a1cc060..8b256f40c 100644
--- a/src/plugins/roleColorEverywhere.tsx
+++ b/src/plugins/roleColorEverywhere.tsx
@@ -16,7 +16,7 @@
* along with this program. If not, see
.
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants";
import definePlugin, { OptionType } from "@utils/types";
import { ChannelStore, GuildMemberStore, GuildStore } from "@webpack/common";
@@ -53,7 +53,7 @@ export default definePlugin({
replacement: [
{
match: /user:(\i),channel:(\i).{0,300}?"@"\.concat\(.+?\)/,
- replace: "$&,color:$self.getUserColor($1.id,{channelId:$2?.id})"
+ replace: "$&,color:$self.getUserColor($1?.id,{channelId:$2?.id})"
}
],
predicate: () => settings.store.chatMentions,
@@ -99,10 +99,12 @@ export default definePlugin({
if (!(guildId ??= ChannelStore.getChannel(channelId!)?.guild_id)) return null;
return GuildMemberStore.getMember(guildId, userId)?.colorString ?? null;
},
+
getUserColor(userId: string, ids: { channelId?: string; guildId?: string; }) {
const colorString = this.getColor(userId, ids);
return colorString && parseInt(colorString.slice(1), 16);
},
+
roleGroupColor({ id, count, title, guildId }: { id: string; count: number; title: string; guildId: string; }) {
const guild = GuildStore.getGuild(guildId);
const role = guild?.roles[id];
@@ -113,6 +115,7 @@ export default definePlugin({
letterSpacing: ".05em"
}}>{title} — {count};
},
+
getVoiceProps({ user: { id: userId }, guildId }: { user: { id: string; }; guildId: string; }) {
return {
style: {
diff --git a/src/plugins/searchReply.tsx b/src/plugins/searchReply.tsx
index cb09f5b69..9e5343644 100644
--- a/src/plugins/searchReply.tsx
+++ b/src/plugins/searchReply.tsx
@@ -18,7 +18,7 @@
import { addContextMenuPatch, findGroupChildrenByChildId, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
import { Devs } from "@utils/constants";
-import { LazyComponent } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import definePlugin from "@utils/types";
import { findByCode, findByCodeLazy } from "@webpack";
import { ChannelStore, i18n, Menu, SelectedChannelStore } from "@webpack/common";
@@ -38,7 +38,7 @@ const messageContextMenuPatch: NavContextMenuPatchCallback = (children, { messag
// dms and group chats
const dmGroup = findGroupChildrenByChildId("pin", children);
if (dmGroup && !dmGroup.some(child => child?.props?.id === "reply")) {
- const pinIndex = dmGroup.findIndex(c => c.props.id === "pin");
+ const pinIndex = dmGroup.findIndex(c => c?.props.id === "pin");
return dmGroup.splice(pinIndex + 1, 0, (
require("../components/VencordSettings").default);
-
export default definePlugin({
name: "Settings",
description: "Adds Settings UI and debug info",
@@ -95,37 +91,37 @@ export default definePlugin({
{
section: "VencordSettings",
label: "Vencord",
- element: () =>
+ element: require("@components/VencordSettings/VencordTab").default
},
{
section: "VencordPlugins",
label: "Plugins",
- element: () => ,
+ element: require("@components/VencordSettings/PluginsTab").default,
},
{
section: "VencordThemes",
label: "Themes",
- element: () => ,
+ element: require("@components/VencordSettings/ThemesTab").default,
},
!IS_WEB && {
section: "VencordUpdater",
label: "Updater",
- element: () => ,
+ element: require("@components/VencordSettings/UpdaterTab").default,
},
{
section: "VencordCloud",
label: "Cloud",
- element: () => ,
+ element: require("@components/VencordSettings/CloudTab").default,
},
{
section: "VencordSettingsSync",
label: "Backup & Restore",
- element: () => ,
+ element: require("@components/VencordSettings/BackupAndRestoreTab").default,
},
IS_DEV && {
section: "VencordPatchHelper",
label: "Patch Helper",
- element: PatchHelper!,
+ element: require("@components/VencordSettings/PatchHelperTab").default,
},
IS_VENCORD_DESKTOP && {
section: "VencordDesktop",
@@ -155,12 +151,12 @@ export default definePlugin({
},
get electronVersion() {
- return VencordNative.getVersions().electron || window.armcord?.electron || null;
+ return VencordNative.native.getVersions().electron || window.armcord?.electron || null;
},
get chromiumVersion() {
try {
- return VencordNative.getVersions().chrome
+ return VencordNative.native.getVersions().chrome
// @ts-ignore Typescript will add userAgentData IMMEDIATELY
|| navigator.userAgentData?.brands?.find(b => b.brand === "Chromium" || b.brand === "Google Chrome")?.version
|| null;
diff --git a/src/plugins/shikiCodeblocks/components/Highlighter.tsx b/src/plugins/shikiCodeblocks/components/Highlighter.tsx
index badb3c8f6..dd1401939 100644
--- a/src/plugins/shikiCodeblocks/components/Highlighter.tsx
+++ b/src/plugins/shikiCodeblocks/components/Highlighter.tsx
@@ -17,8 +17,7 @@
*/
import ErrorBoundary from "@components/ErrorBoundary";
-import { useAwaiter } from "@utils/misc";
-import { useIntersection } from "@utils/react";
+import { useAwaiter, useIntersection } from "@utils/react";
import { hljs, React } from "@webpack/common";
import { resolveLang } from "../api/languages";
diff --git a/src/plugins/shikiCodeblocks/settings.ts b/src/plugins/shikiCodeblocks/settings.ts
index ff5afc2e7..f9fd3cc0f 100644
--- a/src/plugins/shikiCodeblocks/settings.ts
+++ b/src/plugins/shikiCodeblocks/settings.ts
@@ -16,7 +16,7 @@
* along with this program. If not, see .
*/
-import { definePluginSettings } from "@api/settings";
+import { definePluginSettings } from "@api/Settings";
import { disableStyle, enableStyle } from "@api/Styles";
import { parseUrl } from "@utils/misc";
import { wordsFromPascal, wordsToTitle } from "@utils/text";
diff --git a/src/plugins/shikiCodeblocks/shiki.css b/src/plugins/shikiCodeblocks/shiki.css
index 32ef992a6..8674147e5 100644
--- a/src/plugins/shikiCodeblocks/shiki.css
+++ b/src/plugins/shikiCodeblocks/shiki.css
@@ -61,10 +61,7 @@
display: flex;
position: absolute;
justify-content: center;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
+ inset: 0;
}
.shiki-preview {
diff --git a/src/plugins/fxTwitter.ts b/src/plugins/showAllMessageButtons.ts
similarity index 57%
rename from src/plugins/fxTwitter.ts
rename to src/plugins/showAllMessageButtons.ts
index efe1ebc7f..32e8ee552 100644
--- a/src/plugins/fxTwitter.ts
+++ b/src/plugins/showAllMessageButtons.ts
@@ -1,6 +1,6 @@
/*
* Vencord, a modification for Discord's desktop app
- * Copyright (c) 2022 Samu
+ * 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
@@ -16,27 +16,22 @@
* along with this program. If not, see .
*/
-import { addPreSendListener, MessageObject, removePreSendListener } from "@api/MessageEvents";
import { Devs } from "@utils/constants";
import definePlugin from "@utils/types";
-const re = /https?:\/\/twitter\.com(?=\/\w+?\/status\/)/g;
-
export default definePlugin({
- name: "FxTwitter",
- description: "Uses FxTwitter to improve embeds from twitter on send",
- authors: [Devs.Samu],
- dependencies: ["MessageEventsAPI"],
+ name: "ShowAllMessageButtons",
+ description: "Always show all message buttons no matter if you are holding the shift key or not.",
+ authors: [Devs.Nuckyz],
- addPrefix(msg: MessageObject) {
- msg.content = msg.content.replace(re, "https://fxtwitter.com");
- },
-
- start() {
- this.preSend = addPreSendListener((_, msg) => this.addPrefix(msg));
- },
-
- stop() {
- removePreSendListener(this.preSend);
- }
+ patches: [
+ {
+ find: ".Messages.MESSAGE_UTILITIES_A11Y_LABEL",
+ replacement: {
+ // isExpanded: V, (?<=,V = shiftKeyDown && !H...;)
+ match: /isExpanded:(\i),(?<=,\1=\i&&(!.+);.+?)/,
+ replace: "isExpanded:$2,"
+ }
+ }
+ ]
});
diff --git a/src/plugins/showConnections/VerifiedIcon.tsx b/src/plugins/showConnections/VerifiedIcon.tsx
new file mode 100644
index 000000000..79e27c455
--- /dev/null
+++ b/src/plugins/showConnections/VerifiedIcon.tsx
@@ -0,0 +1,38 @@
+/*
+ * 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 .
+*/
+
+import { LazyComponent } from "@utils/react";
+import { findByCode, findLazy } from "@webpack";
+import { i18n, useToken } from "@webpack/common";
+
+const ColorMap = findLazy(m => m.colors?.INTERACTIVE_MUTED?.css);
+const VerifiedIconComponent = LazyComponent(() => findByCode(".CONNECTIONS_ROLE_OFFICIAL_ICON_TOOLTIP"));
+
+export function VerifiedIcon() {
+ const color = useToken(ColorMap.colors.INTERACTIVE_MUTED).hex();
+ const forcedIconColor = useToken(ColorMap.colors.INTERACTIVE_ACTIVE).hex();
+
+ return (
+
+ );
+}
diff --git a/src/plugins/showConnections/index.tsx b/src/plugins/showConnections/index.tsx
new file mode 100644
index 000000000..50fcfe10b
--- /dev/null
+++ b/src/plugins/showConnections/index.tsx
@@ -0,0 +1,190 @@
+/*
+ * 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 .
+*/
+
+import "./styles.css";
+
+import { definePluginSettings } from "@api/Settings";
+import ErrorBoundary from "@components/ErrorBoundary";
+import { Flex } from "@components/Flex";
+import { CopyIcon, LinkIcon } from "@components/Icons";
+import { Devs } from "@utils/constants";
+import { copyWithToast } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
+import definePlugin, { OptionType } from "@utils/types";
+import { findByCode, findByCodeLazy, findByPropsLazy, findStoreLazy } from "@webpack";
+import { Text, Tooltip } from "@webpack/common";
+import { User } from "discord-types/general";
+
+import { VerifiedIcon } from "./VerifiedIcon";
+
+const Section = LazyComponent(() => findByCode("().lastSection"));
+const UserProfileStore = findStoreLazy("UserProfileStore");
+const ThemeStore = findStoreLazy("ThemeStore");
+const platforms: { get(type: string): ConnectionPlatform; } = findByPropsLazy("isSupported", "getByUrl");
+const getTheme: (user: User, displayProfile: any) => any = findByCodeLazy(',"--profile-gradient-primary-color"');
+
+const enum Spacing {
+ COMPACT,
+ COZY,
+ ROOMY
+}
+const getSpacingPx = (spacing: Spacing | undefined) => (spacing ?? Spacing.COMPACT) * 2 + 4;
+
+const settings = definePluginSettings({
+ iconSize: {
+ type: OptionType.NUMBER,
+ description: "Icon size (px)",
+ default: 32
+ },
+ iconSpacing: {
+ type: OptionType.SELECT,
+ description: "Icon margin",
+ default: Spacing.COZY,
+ options: [
+ { label: "Compact", value: Spacing.COMPACT },
+ { label: "Cozy", value: Spacing.COZY }, // US Spelling :/
+ { label: "Roomy", value: Spacing.ROOMY }
+ ]
+ }
+});
+
+interface Connection {
+ type: string;
+ id: string;
+ name: string;
+ verified: boolean;
+}
+
+interface ConnectionPlatform {
+ getPlatformUserUrl(connection: Connection): string;
+ icon: { lightSVG: string, darkSVG: string; };
+}
+
+const profilePopoutComponent = ErrorBoundary.wrap(e =>
+
+);
+
+const profilePanelComponent = ErrorBoundary.wrap(e =>
+
+);
+
+function ConnectionsComponent({ id, theme }: { id: string, theme: string; }) {
+ const profile = UserProfileStore.getUserProfile(id);
+ if (!profile)
+ return null;
+
+ const connections: Connection[] = profile.connectedAccounts;
+ if (!connections?.length)
+ return null;
+
+ return (
+
+
+ Connections
+
+
+ {connections.map(connection => )}
+
+
+ );
+}
+
+function CompactConnectionComponent({ connection, theme }: { connection: Connection, theme: string; }) {
+ const platform = platforms.get(connection.type);
+ const url = platform.getPlatformUserUrl?.(connection);
+
+ const img = (
+
+ );
+
+ const TooltipIcon = url ? LinkIcon : CopyIcon;
+
+ return (
+
+ {connection.name}
+ {connection.verified && }
+
+
+ }
+ key={connection.id}
+ >
+ {tooltipProps =>
+ url
+ ?
+ {img}
+
+ :
+
+ }
+
+ );
+}
+
+export default definePlugin({
+ name: "ShowConnections",
+ description: "Show connected accounts in user popouts",
+ authors: [Devs.TheKodeToad],
+ patches: [
+ {
+ find: ".Messages.BOT_PROFILE_SLASH_COMMANDS",
+ replacement: {
+ match: /,theme:\i\}\)(?=,.{0,100}setNote:)/,
+ replace: "$&,$self.profilePopoutComponent(arguments[0])"
+ }
+ },
+ {
+ find: "\"Profile Panel: user cannot be undefined\"",
+ replacement: {
+ // createElement(Divider, {}), createElement(NoteComponent)
+ match: /\(0,\i\.jsx\)\(\i\.\i,\{\}\).{0,100}setNote:/,
+ replace: "$self.profilePanelComponent(arguments[0]),$&"
+ }
+ }
+ ],
+ settings,
+ profilePopoutComponent,
+ profilePanelComponent
+});
diff --git a/src/plugins/showConnections/styles.css b/src/plugins/showConnections/styles.css
new file mode 100644
index 000000000..383593c11
--- /dev/null
+++ b/src/plugins/showConnections/styles.css
@@ -0,0 +1,11 @@
+.vc-user-connection {
+ all: unset;
+ display: inline-block;
+ cursor: pointer;
+}
+
+.vc-sc-tooltip {
+ display: inline-flex;
+ gap: 0.25em;
+ align-items: center;
+}
diff --git a/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
index 932491b21..506fbe7b6 100644
--- a/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
+++ b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
@@ -16,15 +16,17 @@
* along with this program. If not, see .
*/
+import { Settings } from "@api/Settings";
import ErrorBoundary from "@components/ErrorBoundary";
-import { LazyComponent } from "@utils/misc";
+import { LazyComponent } from "@utils/react";
import { formatDuration } from "@utils/text";
-import { find, findByPropsLazy, findStoreLazy } from "@webpack";
-import { FluxDispatcher, GuildMemberStore, GuildStore, moment, Parser, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip } from "@webpack/common";
+import { find, findByPropsLazy } from "@webpack";
+import { EmojiStore, FluxDispatcher, GuildMemberStore, GuildStore, moment, Parser, PermissionStore, SnowflakeUtils, Text, Timestamp, Tooltip, useEffect, useState } from "@webpack/common";
import type { Channel } from "discord-types/general";
import type { ComponentType } from "react";
-import { VIEW_CHANNEL } from "..";
+import openRolesAndUsersPermissionsModal, { PermissionType, RoleOrUserPermission } from "../../permissionsViewer/components/RolesAndUsersPermissions";
+import { settings, VIEW_CHANNEL } from "..";
enum SortOrderTypes {
LATEST_ACTIVITY = 0,
@@ -92,7 +94,6 @@ const TagComponent = LazyComponent(() => find(m => {
return code.includes(".Messages.FORUM_TAG_A11Y_FILTER_BY_TAG") && !code.includes("increasedActivityPill");
}));
-const EmojiStore = findStoreLazy("EmojiStore");
const EmojiParser = findByPropsLazy("convertSurrogateToName");
const EmojiUtils = findByPropsLazy("getURL", "buildEmojiReactionColorsPlatformed");
@@ -124,6 +125,9 @@ const VideoQualityModesToNames = {
const HiddenChannelLogo = "/assets/433e3ec4319a9d11b0cbe39342614982.svg";
function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
+ const [viewAllowedUsersAndRoles, setViewAllowedUsersAndRoles] = useState(settings.store.defaultAllowedUsersAndRolesDropdownState);
+ const [permissions, setPermissions] = useState([]);
+
const {
type,
topic,
@@ -140,27 +144,39 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
bitrate,
rtcRegion,
videoQualityMode,
- permissionOverwrites
+ permissionOverwrites,
+ guild_id
} = channel;
- const membersToFetch: Array = [];
+ useEffect(() => {
+ const membersToFetch: Array = [];
- const guildOwnerId = GuildStore.getGuild(channel.guild_id).ownerId;
- if (!GuildMemberStore.getMember(channel.guild_id, guildOwnerId)) membersToFetch.push(guildOwnerId);
+ const guildOwnerId = GuildStore.getGuild(guild_id).ownerId;
+ if (!GuildMemberStore.getMember(guild_id, guildOwnerId)) membersToFetch.push(guildOwnerId);
- Object.values(permissionOverwrites).forEach(({ type, id: userId }) => {
- if (type === 1) {
- if (!GuildMemberStore.getMember(channel.guild_id, userId)) membersToFetch.push(userId);
- }
- });
-
- if (membersToFetch.length > 0) {
- FluxDispatcher.dispatch({
- type: "GUILD_MEMBERS_REQUEST",
- guildIds: [channel.guild_id],
- userIds: membersToFetch
+ Object.values(permissionOverwrites).forEach(({ type, id: userId }) => {
+ if (type === 1 && !GuildMemberStore.getMember(guild_id, userId)) {
+ membersToFetch.push(userId);
+ }
});
- }
+
+ if (membersToFetch.length > 0) {
+ FluxDispatcher.dispatch({
+ type: "GUILD_MEMBERS_REQUEST",
+ guildIds: [guild_id],
+ userIds: membersToFetch
+ });
+ }
+
+ if (Settings.plugins.PermissionsViewer.enabled) {
+ setPermissions(Object.values(permissionOverwrites).map(overwrite => ({
+ type: overwrite.type as PermissionType,
+ id: overwrite.id,
+ overwriteAllow: overwrite.allow,
+ overwriteDeny: overwrite.deny
+ })));
+ }
+ }, [channelId]);
return (
@@ -182,7 +198,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
aria-hidden={true}
role="img"
>
-
+
)}
@@ -192,7 +208,7 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
{(!channel.isGuildVoice() && !channel.isGuildStageVoice()) && (
You can not see the {channel.isForumChannel() ? "posts" : "messages"} of this channel.
- {channel.isForumChannel() && topic && topic.length > 0 && "However you may see its guidelines:"}
+ {channel.isForumChannel() && topic && topic.length > 0 && " However you may see its guidelines:"}
)}
@@ -268,8 +284,49 @@ function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
}
-
Allowed users and roles:
-
+
+ {Settings.plugins.PermissionsViewer.enabled && (
+
+ {({ onMouseLeave, onMouseEnter }) => (
+
+ )}
+
+ )}
+
Allowed users and roles:
+
+ {({ onMouseLeave, onMouseEnter }) => (
+
+ )}
+
+
+ {viewAllowedUsersAndRoles &&
}