aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/showHiddenChannels/components
diff options
context:
space:
mode:
authorNuckyz <61953774+Nuckyz@users.noreply.github.com>2023-02-01 08:11:05 -0300
committerGitHub <noreply@github.com>2023-02-01 12:11:05 +0100
commit369d179bbf67d34fc4d5f8312d19a106f3552373 (patch)
tree54849a5a410a00201f5a5ccd2803f31c6fb9475a /src/plugins/showHiddenChannels/components
parent8f4e8d0a9bd29b59cd9ea4e3228fd1b3e73fbfd9 (diff)
downloadVencord-369d179bbf67d34fc4d5f8312d19a106f3552373.tar.gz
Vencord-369d179bbf67d34fc4d5f8312d19a106f3552373.tar.bz2
Vencord-369d179bbf67d34fc4d5f8312d19a106f3552373.zip
ShowHiddenChannels: New screen for showing hidden channels (#460)
Co-authored-by: Ven <vendicated@riseup.net>
Diffstat (limited to 'src/plugins/showHiddenChannels/components')
-rw-r--r--src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx202
1 files changed, 202 insertions, 0 deletions
diff --git a/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
new file mode 100644
index 0000000..e5c5ee2
--- /dev/null
+++ b/src/plugins/showHiddenChannels/components/HiddenChannelLockScreen.tsx
@@ -0,0 +1,202 @@
+/*
+ * Vencord, a modification for Discord's desktop app
+ * Copyright (c) 2022 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 ErrorBoundary from "@components/ErrorBoundary";
+import { LazyComponent } from "@utils/misc";
+import { proxyLazy } from "@utils/proxyLazy";
+import { formatDuration } from "@utils/text";
+import { find, findByCode, findByPropsLazy, findLazy } from "@webpack";
+import { moment, Parser, SnowflakeUtils, Text, Timestamp, Tooltip } from "@webpack/common";
+import { Channel } from "discord-types/general";
+
+enum SortOrderTypesTyping {
+ LATEST_ACTIVITY = 0,
+ CREATION_DATE = 1
+}
+
+enum ForumLayoutTypesTyping {
+ DEFAULT = 0,
+ LIST = 1,
+ GRID = 2
+}
+
+interface DefaultReaction {
+ emojiId: string | null;
+ emojiName: string | null;
+}
+
+interface Tag {
+ id: string;
+ name: string;
+ emojiId: string | null;
+ emojiName: string | null;
+ moderated: boolean;
+}
+
+interface ExtendedChannel extends Channel {
+ defaultThreadRateLimitPerUser?: number;
+ defaultSortOrder?: SortOrderTypesTyping | null;
+ defaultForumLayout?: ForumLayoutTypesTyping;
+ defaultReactionEmoji?: DefaultReaction | null;
+ availableTags?: Array<Tag>;
+}
+
+const ChatClasses = findByPropsLazy("chat", "chatContent");
+const TagClasses = findLazy(m => typeof m.tags === "string" && Object.entries(m).length === 1); // Object exported with a single key called tags
+const ChannelTypes = findByPropsLazy("GUILD_TEXT", "GUILD_FORUM");
+const SortOrderTypes = findLazy(m => typeof m.LATEST_ACTIVITY === "number");
+const ForumLayoutTypes = findLazy(m => typeof m.LIST === "number");
+const ChannelFlags = findLazy(m => typeof m.REQUIRE_TAG === "number");
+const TagComponent = LazyComponent(() => find(m => {
+ if (typeof m !== "function") return false;
+
+ const code = Function.prototype.toString.call(m);
+ // Get the component which doesn't include increasedActivity logic
+ return code.includes(".Messages.FORUM_TAG_A11Y_FILTER_BY_TAG") && !code.includes("increasedActivityPill");
+}));
+const EmojiComponent = LazyComponent(() => findByCode('.jumboable?"jumbo":"default"'));
+
+const ChannelTypesToChannelNames = proxyLazy(() => ({
+ [ChannelTypes.GUILD_TEXT]: "text",
+ [ChannelTypes.GUILD_ANNOUNCEMENT]: "announcement",
+ [ChannelTypes.GUILD_FORUM]: "forum"
+}));
+
+const SortOrderTypesToNames = proxyLazy(() => ({
+ [SortOrderTypes.LATEST_ACTIVITY]: "Latest activity",
+ [SortOrderTypes.CREATION_DATE]: "Creation date"
+}));
+
+const ForumLayoutTypesToNames = proxyLazy(() => ({
+ [ForumLayoutTypes.DEFAULT]: "Not set",
+ [ForumLayoutTypes.LIST]: "List view",
+ [ForumLayoutTypes.GRID]: "Gallery view"
+}));
+
+// Icon from the modal when clicking a message link you don't have access to view
+const HiddenChannelLogo = "/assets/433e3ec4319a9d11b0cbe39342614982.svg";
+
+function HiddenChannelLockScreen({ channel }: { channel: ExtendedChannel; }) {
+ const {
+ type,
+ topic,
+ lastMessageId,
+ defaultForumLayout,
+ lastPinTimestamp,
+ defaultAutoArchiveDuration,
+ availableTags,
+ id: channelId,
+ rateLimitPerUser,
+ defaultThreadRateLimitPerUser,
+ defaultSortOrder,
+ defaultReactionEmoji
+ } = channel;
+
+ return (
+ <div className={ChatClasses.chat + " " + "shc-lock-screen-container"}>
+ <img className="shc-lock-screen-logo" src={HiddenChannelLogo} />
+
+ <div className="shc-lock-screen-heading-container">
+ <Text variant="heading-xxl/bold">This is a hidden {ChannelTypesToChannelNames[type]} channel.</Text>
+ {channel.isNSFW() &&
+ <Tooltip text="NSFW">
+ {({ onMouseLeave, onMouseEnter }) => (
+ <svg
+ onMouseLeave={onMouseLeave}
+ onMouseEnter={onMouseEnter}
+ className="shc-lock-screen-heading-nsfw-icon"
+ width="32"
+ height="32"
+ viewBox="0 0 48 48"
+ aria-hidden={true}
+ role="img"
+ >
+ <path d="M.7 43.05 24 2.85l23.3 40.2Zm23.55-6.25q.75 0 1.275-.525.525-.525.525-1.275 0-.75-.525-1.3t-1.275-.55q-.8 0-1.325.55-.525.55-.525 1.3t.55 1.275q.55.525 1.3.525Zm-1.85-6.1h3.65V19.4H22.4Z" />
+ </svg>
+ )}
+ </Tooltip>
+ }
+ </div>
+
+ <Text variant="text-lg/normal">
+ You can not see the {channel.isForumChannel() ? "posts" : "messages"} of this channel.
+ {channel.isForumChannel() && topic && topic.length > 0 && "However you may see its guidelines:"}
+ </Text >
+
+ {channel.isForumChannel() && topic && topic.length > 0 && (
+ <div className="shc-lock-screen-topic-container">
+ {Parser.parseTopic(topic, false, { channelId })}
+ </div>
+ )}
+
+ {lastMessageId &&
+ <Text variant="text-md/normal">
+ Last {channel.isForumChannel() ? "post" : "message"} created:
+ <Timestamp timestamp={moment(SnowflakeUtils.extractTimestamp(lastMessageId))} />
+ </Text>
+ }
+
+ {lastPinTimestamp &&
+ <Text variant="text-md/normal">Last message pin: <Timestamp timestamp={moment(lastPinTimestamp)} /></Text>
+ }
+ {(rateLimitPerUser ?? 0) > 0 &&
+ <Text variant="text-md/normal">Slowmode: {formatDuration(rateLimitPerUser! * 1000)}</Text>
+ }
+ {(defaultThreadRateLimitPerUser ?? 0) > 0 &&
+ <Text variant="text-md/normal">
+ Default thread slowmode: {formatDuration(defaultThreadRateLimitPerUser! * 1000)}
+ </Text>
+ }
+ {(defaultAutoArchiveDuration ?? 0) > 0 &&
+ <Text variant="text-md/normal">
+ Default inactivity duration before archiving {channel.isForumChannel() ? "posts" : "threads"}:
+ {formatDuration(defaultAutoArchiveDuration! * 1000 * 60)}
+ </Text>
+ }
+ {defaultForumLayout != null &&
+ <Text variant="text-md/normal">Default layout: {ForumLayoutTypesToNames[defaultForumLayout]}</Text>
+ }
+ {defaultSortOrder != null &&
+ <Text variant="text-md/normal">Default sort order: {SortOrderTypesToNames[defaultSortOrder]}</Text>
+ }
+ {defaultReactionEmoji != null &&
+ <div className="shc-lock-screen-default-emoji-container">
+ <Text variant="text-md/normal">Default reaction emoji:</Text>
+ <EmojiComponent node={{
+ type: defaultReactionEmoji.emojiName ? "emoji" : "customEmoji",
+ name: defaultReactionEmoji.emojiName ?? "",
+ emojiId: defaultReactionEmoji.emojiId
+ }} />
+ </div>
+ }
+ {channel.hasFlag(ChannelFlags.REQUIRE_TAG) &&
+ <Text variant="text-md/normal">Posts on this forum require a tag to be set.</Text>
+ }
+ {availableTags && availableTags.length > 0 &&
+ <div className="shc-lock-screen-tags-container">
+ <Text variant="text-lg/bold">Available tags:</Text>
+ <div className={TagClasses.tags}>
+ {availableTags.map(tag => <TagComponent tag={tag} />)}
+ </div>
+ </div>
+ }
+ </div>
+ );
+}
+
+export default ErrorBoundary.wrap(HiddenChannelLockScreen);