diff --git a/src/plugins/betterRoleContext/index.tsx b/src/plugins/betterRoleContext/index.tsx
index 1029c07e2..afef63908 100644
--- a/src/plugins/betterRoleContext/index.tsx
+++ b/src/plugins/betterRoleContext/index.tsx
@@ -83,7 +83,7 @@ export default definePlugin({
if (!role) return;
if (role.colorString) {
- children.push(
+ children.unshift(
{
+ await GuildSettingsActions.open(guild.id, "ROLES");
+ GuildSettingsActions.selectRole(id);
+ }}
+ icon={PencilIcon}
+ />
+ );
+ }
+
if (role.icon) {
children.push(
{
- await GuildSettingsActions.open(guild.id, "ROLES");
- GuildSettingsActions.selectRole(id);
- }}
- icon={PencilIcon}
- />
- );
- }
}
}
});
diff --git a/src/plugins/ircColors/README.md b/src/plugins/ircColors/README.md
new file mode 100644
index 000000000..9d9c7634b
--- /dev/null
+++ b/src/plugins/ircColors/README.md
@@ -0,0 +1,17 @@
+# IrcColors
+
+Makes username colors in chat unique, like in IRC clients
+
+
+
+Improves chat readability by assigning every user an unique nickname color,
+making distinguishing between different users easier. Inspired by the feature
+in many IRC clients, such as HexChat or WeeChat.
+
+Keep in mind this overrides role colors in chat, so if you wish to know
+someone's role color without checking their profile, enable the role dot: go to
+**User Settings**, **Accessibility** and switch **Role Colors** to **Show role
+colors next to names**.
+
+Created for use with the [Compact++](https://gitlab.com/Grzesiek11/compactplusplus-discord-theme)
+theme.
diff --git a/src/plugins/ircColors/index.ts b/src/plugins/ircColors/index.ts
new file mode 100644
index 000000000..d5cc5f3e4
--- /dev/null
+++ b/src/plugins/ircColors/index.ts
@@ -0,0 +1,94 @@
+/*
+ * 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 { definePluginSettings } from "@api/Settings";
+import { Devs } from "@utils/constants";
+import definePlugin, { OptionType } from "@utils/types";
+
+// Compute a 64-bit FNV-1a hash of the passed data
+function hash(id: bigint) {
+ const fnvPrime = 1099511628211n;
+ const offsetBasis = 14695981039346656037n;
+
+ let result = offsetBasis;
+ for (let i = 7n; i >= 0n; i--) {
+ result ^= (id >> (8n * i)) & 0xffn;
+ result = (result * fnvPrime) % 2n ** 32n;
+ }
+
+ return result;
+}
+
+// Calculate a CSS color string based on the user ID
+function calculateNameColorForUser(id: bigint) {
+ const idHash = hash(id);
+
+ return `hsl(${idHash % 360n}, 100%, ${settings.store.lightness}%)`;
+}
+
+const settings = definePluginSettings({
+ lightness: {
+ description: "Lightness, in %. Change if the colors are too light or too dark. Reopen the chat to apply.",
+ type: OptionType.NUMBER,
+ default: 70,
+ },
+ memberListColors: {
+ description: "Replace role colors in the member list",
+ restartNeeded: true,
+ type: OptionType.BOOLEAN,
+ default: true,
+ },
+});
+
+export default definePlugin({
+ name: "IrcColors",
+ description: "Makes username colors in chat unique, like in IRC clients",
+ authors: [Devs.Grzesiek11],
+ patches: [
+ {
+ find: '="SYSTEM_TAG"',
+ replacement: {
+ match: /(?<=className:\i\.username,style:.{0,50}:void 0,)/,
+ replace: "style:{color:$self.calculateNameColorForMessageContext(arguments[0])},",
+ },
+ },
+ {
+ find: ".NameWithRole,{roleName:",
+ replacement: {
+ match: /(?<=color:)null!=.{0,50}?(?=,)/,
+ replace: "$self.calculateNameColorForListContext(arguments[0])",
+ },
+ predicate: () => settings.store.memberListColors,
+ },
+ ],
+ settings,
+ calculateNameColorForMessageContext(context: any) {
+ const id = context?.message?.author?.id;
+ if (id == null) {
+ return null;
+ }
+ return calculateNameColorForUser(BigInt(id));
+ },
+ calculateNameColorForListContext(context: any) {
+ const id = context?.user?.id;
+ if (id == null) {
+ return null;
+ }
+ return calculateNameColorForUser(BigInt(id));
+ },
+});
diff --git a/src/plugins/lastfm/index.tsx b/src/plugins/lastfm/index.tsx
index 02fd694f8..77fa27841 100644
--- a/src/plugins/lastfm/index.tsx
+++ b/src/plugins/lastfm/index.tsx
@@ -86,7 +86,7 @@ const placeholderId = "2a96cbd8b46e442fc41c2b86b821562f";
const logger = new Logger("LastFMRichPresence");
-const presenceStore = findByPropsLazy("getLocalPresence");
+const PresenceStore = findByPropsLazy("getLocalPresence");
async function getApplicationAsset(key: string): Promise {
return (await ApplicationAssetUtils.fetchAssetIds(applicationId, [key]))[0];
@@ -124,6 +124,11 @@ const settings = definePluginSettings({
type: OptionType.BOOLEAN,
default: true,
},
+ hideWithActivity: {
+ description: "Hide Last.fm presence if you have any other presence",
+ type: OptionType.BOOLEAN,
+ default: false,
+ },
statusName: {
description: "custom status text",
type: OptionType.STRING,
@@ -274,12 +279,16 @@ export default definePlugin({
},
async getActivity(): Promise {
+ if (settings.store.hideWithActivity) {
+ if (PresenceStore.getActivities().some(a => a.application_id !== applicationId)) {
+ return null;
+ }
+ }
+
if (settings.store.hideWithSpotify) {
- for (const activity of presenceStore.getActivities()) {
- if (activity.type === ActivityType.LISTENING && activity.application_id !== applicationId) {
- // there is already music status because of Spotify or richerCider (probably more)
- return null;
- }
+ if (PresenceStore.getActivities().some(a => a.type === ActivityType.LISTENING && a.application_id !== applicationId)) {
+ // there is already music status because of Spotify or richerCider (probably more)
+ return null;
}
}
diff --git a/src/plugins/viewRaw/index.tsx b/src/plugins/viewRaw/index.tsx
index b45919a21..ddcbd3b46 100644
--- a/src/plugins/viewRaw/index.tsx
+++ b/src/plugins/viewRaw/index.tsx
@@ -22,12 +22,12 @@ import { CodeBlock } from "@components/CodeBlock";
import ErrorBoundary from "@components/ErrorBoundary";
import { Flex } from "@components/Flex";
import { Devs } from "@utils/constants";
-import { getIntlMessage } from "@utils/discord";
+import { getCurrentGuild, getIntlMessage } from "@utils/discord";
import { Margins } from "@utils/margins";
import { copyWithToast } from "@utils/misc";
import { closeModal, ModalCloseButton, ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize, openModal } from "@utils/modal";
import definePlugin, { OptionType } from "@utils/types";
-import { Button, ChannelStore, Forms, Menu, Text } from "@webpack/common";
+import { Button, ChannelStore, Forms, GuildStore, Menu, Text } from "@webpack/common";
import { Message } from "discord-types/general";
@@ -118,7 +118,7 @@ const settings = definePluginSettings({
}
});
-function MakeContextCallback(name: "Guild" | "User" | "Channel"): NavContextMenuPatchCallback {
+function MakeContextCallback(name: "Guild" | "Role" | "User" | "Channel"): NavContextMenuPatchCallback {
return (children, props) => {
const value = props[name.toLowerCase()];
if (!value) return;
@@ -144,6 +144,23 @@ function MakeContextCallback(name: "Guild" | "User" | "Channel"): NavContextMenu
};
}
+const devContextCallback: NavContextMenuPatchCallback = (children, { id }: { id: string; }) => {
+ const guild = getCurrentGuild();
+ if (!guild) return;
+
+ const role = GuildStore.getRole(guild.id, id);
+ if (!role) return;
+
+ children.push(
+ openViewRawModal(JSON.stringify(role, null, 4), "Role")}
+ icon={CopyIcon}
+ />
+ );
+};
+
export default definePlugin({
name: "ViewRaw",
description: "Copy and view the raw content/data of any message, channel or guild",
@@ -152,10 +169,12 @@ export default definePlugin({
contextMenus: {
"guild-context": MakeContextCallback("Guild"),
+ "guild-settings-role-context": MakeContextCallback("Role"),
"channel-context": MakeContextCallback("Channel"),
"thread-context": MakeContextCallback("Channel"),
"gdm-context": MakeContextCallback("Channel"),
- "user-context": MakeContextCallback("User")
+ "user-context": MakeContextCallback("User"),
+ "dev-context": devContextCallback
},
renderMessagePopoverButton(msg) {