Merge branch 'dev'
This commit is contained in:
commit
e764358ed5
17 changed files with 308 additions and 254 deletions
|
|
@ -162,6 +162,7 @@ export const globPlugins = kind => ({
|
|||
const fileName = file.name;
|
||||
if (fileName.startsWith("_") || fileName.startsWith(".")) continue;
|
||||
if (fileName === "index.ts") continue;
|
||||
if (/\.zip|rar|7z|tar|gz|bz2/.test(fileName)) continue;
|
||||
|
||||
const target = getPluginTarget(fileName);
|
||||
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ async function init() {
|
|||
|
||||
syncSettings();
|
||||
|
||||
if (!IS_WEB && !IS_UPDATER_DISABLED || !IS_DEV) {
|
||||
if (!IS_DEV && !IS_WEB && !IS_UPDATER_DISABLED) {
|
||||
runUpdateCheck();
|
||||
|
||||
// this tends to get really annoying, so only do this if the user has auto-update without notification enabled
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export function DonateButton({
|
|||
{...props}
|
||||
look={look}
|
||||
color={color}
|
||||
onClick={() => VencordNative.native.openExternal("https://ko-fi.com/authenticators")}
|
||||
onClick={() => VencordNative.native.openExternal("https://github.com/sponsors/thororen1234")}
|
||||
innerClassName="vc-donate-button"
|
||||
>
|
||||
<Heart />
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import "./VencordTab.css";
|
|||
|
||||
import { openNotificationLogModal } from "@api/Notifications/notificationLog";
|
||||
import { useSettings } from "@api/Settings";
|
||||
import { classNameFactory } from "@api/Styles";
|
||||
import { FolderIcon, GithubIcon, LogIcon, PaintbrushIcon, RestartIcon } from "@components/Icons";
|
||||
import { openContributorModal, openPluginModal, SettingsTab, wrapTab } from "@components/settings";
|
||||
import { DonateButton, InviteButton } from "@components/settings/DonateButton";
|
||||
|
|
@ -24,8 +23,6 @@ import BadgeAPI from "plugins/_api/badges";
|
|||
|
||||
import { openNotificationSettingsModal } from "./NotificationSettings";
|
||||
|
||||
const cl = classNameFactory("vc-settings-");
|
||||
|
||||
const DEFAULT_DONATE_IMAGE = "https://cdn.discordapp.com/emojis/1026533090627174460.png";
|
||||
const SHIGGY_DONATE_IMAGE = "https://i.imgur.com/57ATLZu.png";
|
||||
|
||||
|
|
@ -339,14 +336,14 @@ function DonateButtonComponent() {
|
|||
);
|
||||
}
|
||||
|
||||
function isVencordDonor(userId: string): boolean {
|
||||
const donorBadges = BadgeAPI.getDonorBadges(userId);
|
||||
return GuildMemberStore.getMember(VC_GUILD_ID, userId)?.roles.includes(VC_DONOR_ROLE_ID) || !!donorBadges;
|
||||
}
|
||||
export default wrapTab(EquicordSettings, "Equicord Settings");
|
||||
|
||||
export function isEquicordDonor(userId: string): boolean {
|
||||
const donorBadges = BadgeAPI.getEquicordDonorBadges(userId);
|
||||
return GuildMemberStore.getMember(GUILD_ID, userId)?.roles.includes(DONOR_ROLE_ID) || !!donorBadges;
|
||||
}
|
||||
|
||||
export default wrapTab(EquicordSettings, "Equicord Settings");
|
||||
export function isVencordDonor(userId: string): boolean {
|
||||
const donorBadges = BadgeAPI.getDonorBadges(userId);
|
||||
return GuildMemberStore.getMember(VC_GUILD_ID, userId)?.roles.includes(VC_DONOR_ROLE_ID) || !!donorBadges;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||
import { EquicordDevs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { Menu, ChannelStore, NavigationRouter, FluxDispatcher, MessageActions, MessageStore } from "@webpack/common";
|
||||
|
||||
interface ChannelSelectEvent {
|
||||
type: "CHANNEL_SELECT";
|
||||
channelId: string | null;
|
||||
guildId: string | null;
|
||||
}
|
||||
|
||||
let lastChan = "0";
|
||||
|
||||
function jumpToPresent(channelId, { limit }: { limit?: number } = {}) {
|
||||
MessageActions.trackJump(channelId, null, "Present");
|
||||
|
||||
const jump = { present: true };
|
||||
|
||||
if (MessageStore.hasPresent(channelId)) {
|
||||
FluxDispatcher.dispatch({
|
||||
type: "LOAD_MESSAGES_SUCCESS_CACHED",
|
||||
jump,
|
||||
channelId,
|
||||
limit
|
||||
});
|
||||
} else {
|
||||
MessageActions.fetchMessages({
|
||||
channelId,
|
||||
limit,
|
||||
jump
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function autoJump(channel: any) {
|
||||
const guildId = channel.guild_id ?? "@me";
|
||||
const channelId = channel.id;
|
||||
|
||||
if (channelId === lastChan) return;
|
||||
|
||||
NavigationRouter.transitionTo(`/channels/${guildId}/${channelId}`);
|
||||
lastChan = channelId;
|
||||
|
||||
jumpToPresent(channelId, { limit: 100 });
|
||||
}
|
||||
|
||||
const MenuPatch: NavContextMenuPatchCallback = (children, { channel }) => {
|
||||
children.push(
|
||||
<Menu.MenuItem
|
||||
id="auto-jump"
|
||||
label="Jump to Last Message"
|
||||
action={() => autoJump(channel)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default definePlugin({
|
||||
name: "AutoJump",
|
||||
description: "Automatically jumps to the last message in selected channel & adds a context-menu option to jump to the last message.",
|
||||
authors: [EquicordDevs.omaw],
|
||||
contextMenus: {
|
||||
"channel-context": MenuPatch,
|
||||
"user-context": MenuPatch,
|
||||
"thread-context": MenuPatch
|
||||
},
|
||||
flux: {
|
||||
async CHANNEL_SELECT({ guildId, channelId }: ChannelSelectEvent) {
|
||||
if (!guildId || !channelId) return;
|
||||
const channel = ChannelStore.getChannel(channelId);
|
||||
if (!channel || lastChan === channel.id) return;
|
||||
autoJump(channel);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -15,6 +15,11 @@ const settings = definePluginSettings({
|
|||
description: "Automatically fill command with all arguements instead of just required ones",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: true,
|
||||
},
|
||||
allowNewlinesInCommands: {
|
||||
description: "Allow newlines in command inputs (Shift + Enter)",
|
||||
type: OptionType.BOOLEAN,
|
||||
default: true,
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -40,6 +45,26 @@ export default definePlugin({
|
|||
replace: "true"
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
find: '"italics"),!0;',
|
||||
predicate: () => settings.store.allowNewlinesInCommands,
|
||||
replacement: [
|
||||
{
|
||||
match: /case (\i\.\i)\.TAB:if\(null!=(\i).selection&&\i\((\i)(?=.{0,300}(\i\.\i\.insertText))/,
|
||||
replace: (orig, keys, editor, event, insertText) => {
|
||||
return `case ${keys}.ENTER:
|
||||
if(${event}.shiftKey){
|
||||
${event}.preventDefault();
|
||||
${event}.stopPropagation();
|
||||
${insertText}(${editor},'\\n');
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
${orig}`;
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
commands: [
|
||||
|
|
|
|||
|
|
@ -1,49 +1,42 @@
|
|||
/*
|
||||
* Vencord, a modification for Discord's desktop app
|
||||
* Copyright (c) 2022 Vendicated and Megumin
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import "@equicordplugins/_misc/styles.css";
|
||||
|
||||
import { Devs, EQUICORD_HELPERS, EquicordDevs, GUILD_ID } from "@utils/constants";
|
||||
import { definePluginSettings, Settings } from "@api/Settings";
|
||||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import definePlugin from "@utils/types";
|
||||
import { Button, ChannelStore, Flex, Forms, GuildMemberStore, showToast, Toasts } from "@webpack/common";
|
||||
import { isEquicordGuild, isEquicordSupport } from "@utils/misc";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
import { Button, Flex, showToast, Toasts } from "@webpack/common";
|
||||
import { JSX } from "react";
|
||||
|
||||
import { toggleEnabled } from "./utils";
|
||||
|
||||
const settings = definePluginSettings({
|
||||
disableCreateDMButton: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Disables the create dm button",
|
||||
restartNeeded: true,
|
||||
default: false,
|
||||
},
|
||||
disableDMContextMenu: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Disables the DM list context menu in favor of the x button",
|
||||
restartNeeded: true,
|
||||
default: false
|
||||
}
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
name: "EquicordHelper",
|
||||
description: "Fixes some misc issues with discord",
|
||||
description: "Used to provide support, fix discord caused crashes, and other misc features.",
|
||||
authors: [Devs.thororen, EquicordDevs.nyx, EquicordDevs.Naibuu],
|
||||
settingsAboutComponent: () => <>
|
||||
<Forms.FormText className="plugin-warning" style={{ textAlign: "left" }}>
|
||||
This plugin was created to allow us as the Equicord Team & Contributors
|
||||
to fix miscellaneous issues Discord may run into or cause.
|
||||
<br />
|
||||
This includes but is not limited to:
|
||||
<br />
|
||||
- Unknown Resolution/FPS Fixed?
|
||||
<br />
|
||||
- Whitelists all domains in CSP
|
||||
</Forms.FormText>
|
||||
</>,
|
||||
required: true,
|
||||
settings,
|
||||
patches: [
|
||||
// Fixes Unknown Resolution/FPS Crashing
|
||||
{
|
||||
|
|
@ -58,47 +51,83 @@ export default definePlugin({
|
|||
replace: "return $1;"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
find: ".createDMButtonContainer,",
|
||||
replacement: {
|
||||
match: /"create-dm"\)/,
|
||||
replace: "$&&&false"
|
||||
},
|
||||
predicate: () => settings.store.disableCreateDMButton
|
||||
},
|
||||
{
|
||||
find: "#{intl::d+e27u::raw}",
|
||||
replacement: {
|
||||
match: /\{dotsInsteadOfCloseButton:(\i),rearrangeContextMenu:(\i).*?autoTrackExposure:!0\}\)/,
|
||||
replace: "$1=false,$2=false"
|
||||
},
|
||||
predicate: () => settings.store.disableDMContextMenu
|
||||
},
|
||||
],
|
||||
renderMessageAccessory(props) {
|
||||
const buttons = [] as JSX.Element[];
|
||||
|
||||
const equicordSupport = GuildMemberStore.getMember(GUILD_ID, props.message.author.id)?.roles?.includes(EQUICORD_HELPERS);
|
||||
|
||||
const msg = props.message.content?.toLowerCase() ?? "";
|
||||
|
||||
const contentWords = (msg.match(/`\w+`/g) ?? []).map(e => e.slice(1, -1));
|
||||
const matchedPlugins = Object.keys(Vencord.Plugins.plugins).filter(name => contentWords.includes(name.toLowerCase()));
|
||||
const matchedPlugin = matchedPlugins.sort((a, b) => b.length - a.length)[0];
|
||||
const pluginData = matchedPlugin && Vencord.Plugins.plugins[matchedPlugin];
|
||||
const equicordGuild = ChannelStore.getChannel(props.channel.id)?.guild_id === GUILD_ID;
|
||||
const ableCheck = msg.startsWith("enable") || msg.startsWith("disable");
|
||||
const shouldAddPluginButtons = equicordGuild && equicordSupport && matchedPlugin && pluginData && ableCheck;
|
||||
|
||||
if (shouldAddPluginButtons) {
|
||||
if (pluginData.required || pluginData.name.endsWith("API")) return;
|
||||
const isEnabled = Vencord.Plugins.isPluginEnabled(matchedPlugin);
|
||||
buttons.push(
|
||||
<Button
|
||||
key="vc-plugin-toggle"
|
||||
color={isEnabled ? Button.Colors.RED : Button.Colors.GREEN}
|
||||
onClick={async () => {
|
||||
try {
|
||||
const success = await toggleEnabled(matchedPlugin);
|
||||
if (success) showToast(`${isEnabled ? "Disabled" : "Enabled"} ${matchedPlugin}`, Toasts.Type.SUCCESS);
|
||||
} catch (e) {
|
||||
new Logger(this.name).error("Error while toggling:", e);
|
||||
showToast(`Failed to toggle ${matchedPlugin}`, Toasts.Type.FAILURE);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{`${isEnabled ? "Disable" : "Enable"} ${matchedPlugin}`}
|
||||
</Button>
|
||||
);
|
||||
start() {
|
||||
if (Settings.plugins?.PinDMs?.disableCreateDMButton) {
|
||||
settings.store.disableCreateDMButton = true;
|
||||
}
|
||||
|
||||
return buttons.length
|
||||
? <Flex>{buttons}</Flex>
|
||||
: null;
|
||||
},
|
||||
renderMessageAccessory(props) {
|
||||
return pluginToggleButtons(props);
|
||||
}
|
||||
});
|
||||
|
||||
function pluginToggleButtons(props) {
|
||||
const buttons = [] as JSX.Element[];
|
||||
const msg = props.message.content?.toLowerCase() ?? "";
|
||||
|
||||
const contentWords = (msg.match(/`\w+`/g) ?? []).map(e => e.slice(1, -1));
|
||||
const matchedPlugins = Object.keys(Vencord.Plugins.plugins).filter(name => contentWords.includes(name.toLowerCase()));
|
||||
const matchedPlugin = matchedPlugins.sort((a, b) => b.length - a.length)[0];
|
||||
const pluginData = matchedPlugin ? Vencord.Plugins.plugins[matchedPlugin] : null;
|
||||
|
||||
const isEquicord = isEquicordGuild(props.channel.id) && isEquicordSupport(props.message.author.id);
|
||||
const startsWithEnabled = msg.startsWith("enable");
|
||||
const startsWithDisabled = msg.startsWith("disable");
|
||||
|
||||
const shouldAddPluginButtons = pluginData && isEquicord && (startsWithEnabled || startsWithDisabled);
|
||||
|
||||
if (shouldAddPluginButtons) {
|
||||
if (pluginData.required || pluginData.name.endsWith("API")) return;
|
||||
const isEnabled = Vencord.Plugins.isPluginEnabled(matchedPlugin);
|
||||
|
||||
let label = `${matchedPlugin} is already ${isEnabled ? "enabled" : "disabled"}`;
|
||||
let disabled = true;
|
||||
|
||||
if ((startsWithDisabled && isEnabled) || (startsWithEnabled && !isEnabled)) {
|
||||
label = `${isEnabled ? "Disable" : "Enable"} ${matchedPlugin}`;
|
||||
disabled = false;
|
||||
}
|
||||
|
||||
buttons.push(
|
||||
<Button
|
||||
key="vc-plugin-toggle"
|
||||
color={disabled ? Button.Colors.PRIMARY : (isEnabled ? Button.Colors.RED : Button.Colors.GREEN)}
|
||||
disabled={disabled}
|
||||
size={Button.Sizes.SMALL}
|
||||
onClick={async () => {
|
||||
try {
|
||||
const success = await toggleEnabled(matchedPlugin);
|
||||
if (success) showToast(`${label}`, Toasts.Type.SUCCESS);
|
||||
} catch (e) {
|
||||
new Logger("EquicordHelper").error("Error while toggling:", e);
|
||||
showToast(`Failed to ${label.toLowerCase()}`, Toasts.Type.FAILURE);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return buttons.length
|
||||
? <Flex>{buttons}</Flex>
|
||||
: null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +1,40 @@
|
|||
/*
|
||||
* Vencord, a modification for Discord's desktop app
|
||||
* Copyright (c) 2022 Vendicated and Megumin
|
||||
*
|
||||
* 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/>.
|
||||
*/
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2025 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { definePluginSettings } from "@api/Settings";
|
||||
import { Devs, EquicordDevs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import definePlugin, { OptionType } from "@utils/types";
|
||||
|
||||
let clickCount = 0;
|
||||
|
||||
function play() {
|
||||
clickCount++;
|
||||
|
||||
if (clickCount % 10 === 0) {
|
||||
const triggerAmount = settings.store.amount;
|
||||
|
||||
if (clickCount % triggerAmount === 0) {
|
||||
const audio = new Audio("https://github.com/Equicord/Equibored/raw/main/sounds/equissant/croissant.mp3");
|
||||
audio.play();
|
||||
clickCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
const settings = definePluginSettings({
|
||||
amount: {
|
||||
type: OptionType.NUMBER,
|
||||
description: "amount of clicks to trigger crossant",
|
||||
default: 10,
|
||||
}
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
name: "Equissant",
|
||||
description: "Crossant every 10 clicks :trolley:",
|
||||
description: "Crossant every specified amount of clicks :trolley:",
|
||||
authors: [EquicordDevs.SomeAspy, Devs.thororen],
|
||||
settings,
|
||||
start() {
|
||||
document.addEventListener("click", play);
|
||||
},
|
||||
|
|
|
|||
|
|
@ -65,6 +65,19 @@ const settings = definePluginSettings({
|
|||
description: "Jellyfin user ID obtained from your user profile URL",
|
||||
type: OptionType.STRING,
|
||||
},
|
||||
nameDisplay: {
|
||||
description: "Choose how the application name should appear in Rich Presence",
|
||||
type: OptionType.SELECT,
|
||||
options: [
|
||||
{ label: "Series/Movie Name", value: "default", default: true },
|
||||
{ label: "Series - Episode/Track/Movie Name", value: "full" },
|
||||
{ label: "Custom", value: "custom" },
|
||||
],
|
||||
},
|
||||
customName: {
|
||||
description: "Custom Rich Presence name (only used if 'Custom' is selected).\nOptions: {name}, {series}, {season}, {episode}, {artist}, {album}, {year}",
|
||||
type: OptionType.STRING,
|
||||
},
|
||||
overrideRichPresenceType: {
|
||||
description: "Override the rich presence type",
|
||||
type: OptionType.SELECT,
|
||||
|
|
@ -113,16 +126,27 @@ function setActivity(activity: Activity | null) {
|
|||
export default definePlugin({
|
||||
name: "JellyfinRichPresence",
|
||||
description: "Rich presence for Jellyfin media server",
|
||||
authors: [EquicordDevs.vmohammad],
|
||||
authors: [EquicordDevs.vmohammad, EquicordDevs.SerStars],
|
||||
|
||||
settingsAboutComponent: () => (
|
||||
<>
|
||||
<Forms.FormTitle tag="h3">How to get an API key</Forms.FormTitle>
|
||||
<Forms.FormText>
|
||||
An API key is required to fetch your current media. To get one, go to your
|
||||
Jellyfin dashboard, navigate to Administration {">"} API Keys and
|
||||
create a new API key. <br /> <br />
|
||||
|
||||
Auth token can be found by following these steps:
|
||||
<ol style={{ marginTop: 8, marginBottom: 8, paddingLeft: 20 }}>
|
||||
<li>1. Log into your Jellyfin instance</li>
|
||||
<li>2. Open your browser's Developer Tools (usually F12 or right-click then Inspect)</li>
|
||||
<li>3. Go to the <b>Network</b> tab in Developer Tools</li>
|
||||
<li>4. Look for requests to your Jellyfin server</li>
|
||||
<li>
|
||||
5. In the request headers, find <code>X-MediaBrowser-Token</code> or <code>Authorization</code>
|
||||
<br />
|
||||
<i>
|
||||
Easiest way: press <b>Ctrl+F</b> in the Developer Tools and search for <code>X-MediaBrowser-Token</code>
|
||||
</i>
|
||||
</li>
|
||||
</ol>
|
||||
<br />
|
||||
You'll also need your User ID, which can be found in the url of your user profile page.
|
||||
</Forms.FormText>
|
||||
</>
|
||||
|
|
@ -197,6 +221,8 @@ export default definePlugin({
|
|||
|
||||
async getActivity(): Promise<Activity | null> {
|
||||
let richPresenceType;
|
||||
let appName: string;
|
||||
const nameSetting = settings.store.nameDisplay || "default";
|
||||
|
||||
const mediaData = await this.fetchMediaData();
|
||||
if (!mediaData) return null;
|
||||
|
|
@ -214,6 +240,40 @@ export default definePlugin({
|
|||
}
|
||||
}
|
||||
|
||||
const templateReplace = (template: string) => {
|
||||
return template
|
||||
.replace(/\{name\}/g, mediaData.name || "")
|
||||
.replace(/\{series\}/g, mediaData.seriesName || "")
|
||||
.replace(/\{season\}/g, mediaData.seasonNumber?.toString() || "")
|
||||
.replace(/\{episode\}/g, mediaData.episodeNumber?.toString() || "")
|
||||
.replace(/\{artist\}/g, mediaData.artist || "")
|
||||
.replace(/\{album\}/g, mediaData.album || "")
|
||||
.replace(/\{year\}/g, mediaData.year?.toString() || "");
|
||||
};
|
||||
|
||||
switch (nameSetting) {
|
||||
case "full":
|
||||
if (mediaData.type === "Episode" && mediaData.seriesName) {
|
||||
appName = `${mediaData.seriesName} - ${mediaData.name}`;
|
||||
} else if (mediaData.type === "Audio") {
|
||||
appName = `${mediaData.artist || "Unknown Artist"} - ${mediaData.name}`;
|
||||
} else {
|
||||
appName = mediaData.name || "Jellyfin";
|
||||
}
|
||||
break;
|
||||
case "custom":
|
||||
appName = templateReplace(settings.store.customName || "{name} on Jellyfish");
|
||||
break;
|
||||
case "default":
|
||||
default:
|
||||
if (mediaData.type === "Episode" && mediaData.seriesName) {
|
||||
appName = mediaData.seriesName;
|
||||
} else {
|
||||
appName = mediaData.name || "Jellyfin";
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
const largeImage = mediaData.imageUrl;
|
||||
const assets: ActivityAssets = {
|
||||
large_image: largeImage ? await getApplicationAsset(largeImage) : await getApplicationAsset("jellyfin"),
|
||||
|
|
@ -243,8 +303,7 @@ export default definePlugin({
|
|||
|
||||
return {
|
||||
application_id: applicationId,
|
||||
name: "Jellyfin",
|
||||
|
||||
name: appName,
|
||||
details: getDetails(),
|
||||
state: getState() || "something",
|
||||
assets,
|
||||
|
|
|
|||
59
src/equicordplugins/jumpTo/index.tsx
Normal file
59
src/equicordplugins/jumpTo/index.tsx
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||
import { migratePluginSettings } from "@api/Settings";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { Menu, NavigationRouter, RestAPI } from "@webpack/common";
|
||||
|
||||
function jumpToFirstMessage(props) {
|
||||
const guildid = props.guild_id !== null ? props.guild_id : "@me";
|
||||
const channelid = props.id;
|
||||
const url = `/channels/${guildid}/${channelid}/0`;
|
||||
NavigationRouter.transitionTo(url);
|
||||
}
|
||||
|
||||
async function jumpToBottom(props) {
|
||||
const guildid = props.guild_id ?? "@me";
|
||||
const channelid = props.id;
|
||||
const res = await RestAPI.get({
|
||||
url: `/channels/${channelid}/messages?limit=1`
|
||||
});
|
||||
|
||||
const lastMessageId = res.body?.[0]?.id;
|
||||
if (!lastMessageId) return;
|
||||
|
||||
const url = `/channels/${guildid}/${channelid}/${lastMessageId}`;
|
||||
NavigationRouter.transitionTo(url);
|
||||
}
|
||||
|
||||
const MenuPatch: NavContextMenuPatchCallback = (children, { channel }) => {
|
||||
children.push(
|
||||
<Menu.MenuItem
|
||||
id="vc-jump-to-first"
|
||||
label="Jump To First Message"
|
||||
action={() => jumpToFirstMessage(channel)}
|
||||
/>,
|
||||
<Menu.MenuItem
|
||||
id="vc-jump-to-bottom"
|
||||
label="Jump To Bottom"
|
||||
action={() => jumpToBottom(channel)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
migratePluginSettings("JumpTo", "JumpToStart", "AutoJump");
|
||||
export default definePlugin({
|
||||
name: "JumpTo",
|
||||
description: "Adds context menu options to jump to the start or bottom of a channel/DM",
|
||||
authors: [Devs.Samwich, Devs.thororen],
|
||||
contextMenus: {
|
||||
"channel-context": MenuPatch,
|
||||
"user-context": MenuPatch,
|
||||
"thread-context": MenuPatch
|
||||
}
|
||||
});
|
||||
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
* Vencord, a Discord client mod
|
||||
* Copyright (c) 2024 Vendicated and contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
import { NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||
import { Devs } from "@utils/constants";
|
||||
import definePlugin from "@utils/types";
|
||||
import { Menu, NavigationRouter } from "@webpack/common";
|
||||
|
||||
function jumpToFirstMessage(props) {
|
||||
const guildid = props.guild_id !== null ? props.guild_id : "@me";
|
||||
const channelid = props.id;
|
||||
const url = `/channels/${guildid}/${channelid}/0`;
|
||||
NavigationRouter.transitionTo(url);
|
||||
}
|
||||
|
||||
const MenuPatch: NavContextMenuPatchCallback = (children, { channel }) => {
|
||||
children.push(
|
||||
<Menu.MenuItem
|
||||
id="vc-jump-to-first"
|
||||
label="Jump To First Message"
|
||||
action={() => {
|
||||
jumpToFirstMessage(channel);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default definePlugin({
|
||||
name: "JumpToStart",
|
||||
description: "Adds a context menu option to jump to the start of a channel/DM",
|
||||
authors: [Devs.Samwich],
|
||||
contextMenus:
|
||||
{
|
||||
"channel-context": MenuPatch,
|
||||
"user-context": MenuPatch,
|
||||
"thread-context": MenuPatch
|
||||
}
|
||||
});
|
||||
|
|
@ -22,11 +22,11 @@ import ErrorBoundary from "@components/ErrorBoundary";
|
|||
import { Flex } from "@components/Flex";
|
||||
import { Link } from "@components/Link";
|
||||
import { openUpdaterModal } from "@components/settings/tabs/updater";
|
||||
import { CONTRIB_ROLE_ID, Devs, DONOR_ROLE_ID, EQUIBOP_CONTRIB_ROLE_ID, EQUICORD_HELPERS, EQUICORD_TEAM, GUILD_ID, SUPPORT_CHANNEL_ID, SUPPORT_CHANNEL_IDS, VC_CONTRIB_ROLE_ID, VC_DONOR_ROLE_ID, VC_GUILD_ID, VC_REGULAR_ROLE_ID, VC_SUPPORT_CHANNEL_IDS, VENCORD_CONTRIB_ROLE_ID } from "@utils/constants";
|
||||
import { CONTRIB_ROLE_ID, Devs, DONOR_ROLE_ID, EQUIBOP_CONTRIB_ROLE_ID, EQUICORD_TEAM, GUILD_ID, SUPPORT_CHANNEL_ID, SUPPORT_CHANNEL_IDS, VC_CONTRIB_ROLE_ID, VC_DONOR_ROLE_ID, VC_GUILD_ID, VC_REGULAR_ROLE_ID, VC_SUPPORT_CHANNEL_IDS, VENCORD_CONTRIB_ROLE_ID } from "@utils/constants";
|
||||
import { sendMessage } from "@utils/discord";
|
||||
import { Logger } from "@utils/Logger";
|
||||
import { Margins } from "@utils/margins";
|
||||
import { isEquicordPluginDev, isPluginDev, tryOrElse } from "@utils/misc";
|
||||
import { isEquicordGuild, isEquicordPluginDev, isEquicordSupport, isPluginDev, isSupportChannel, tryOrElse } from "@utils/misc";
|
||||
import { relaunch } from "@utils/native";
|
||||
import { onlyOnce } from "@utils/onlyOnce";
|
||||
import { makeCodeblock } from "@utils/text";
|
||||
|
|
@ -183,7 +183,7 @@ function generatePluginList() {
|
|||
</div>
|
||||
});
|
||||
|
||||
return `${user.username} have more than 100 plugins enabled, please reduce the number of enabled plugins to get support.`;
|
||||
return `${user.username} has more than 100 plugins enabled, please reduce the number of enabled plugins to get support.`;
|
||||
}
|
||||
|
||||
return content;
|
||||
|
|
@ -219,14 +219,14 @@ export default definePlugin({
|
|||
name: "equicord-debug",
|
||||
description: "Send Equicord debug info",
|
||||
// @ts-ignore
|
||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || isEquicordPluginDev(UserStore.getCurrentUser()?.id) || GUILD_ID === ctx?.guild?.id,
|
||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || isEquicordPluginDev(UserStore.getCurrentUser()?.id) || isEquicordGuild(ctx?.guild?.id, true),
|
||||
execute: async () => ({ content: await generateDebugInfoMessage() })
|
||||
},
|
||||
{
|
||||
name: "equicord-plugins",
|
||||
description: "Send Equicord plugin list",
|
||||
// @ts-ignore
|
||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || isEquicordPluginDev(UserStore.getCurrentUser()?.id) || GUILD_ID === ctx?.guild?.id,
|
||||
predicate: ctx => isPluginDev(UserStore.getCurrentUser()?.id) || isEquicordPluginDev(UserStore.getCurrentUser()?.id) || isEquicordGuild(ctx?.guild?.id, true),
|
||||
execute: () => {
|
||||
const pluginList = generatePluginList();
|
||||
return { content: typeof pluginList === "string" ? pluginList : "Unable to generate plugin list." };
|
||||
|
|
@ -328,11 +328,11 @@ export default definePlugin({
|
|||
renderMessageAccessory(props) {
|
||||
const buttons = [] as JSX.Element[];
|
||||
|
||||
const equicordSupport = GuildMemberStore.getMember(GUILD_ID, props.message.author.id)?.roles?.includes(EQUICORD_HELPERS);
|
||||
const equicordSupport = isEquicordSupport(props.message.author.id);
|
||||
|
||||
const shouldAddUpdateButton =
|
||||
!IS_UPDATER_DISABLED
|
||||
&& ((props.channel.id === SUPPORT_CHANNEL_ID && equicordSupport))
|
||||
&& ((isSupportChannel(props.channel.id) && equicordSupport))
|
||||
&& props.message.content?.includes("update");
|
||||
|
||||
if (shouldAddUpdateButton) {
|
||||
|
|
@ -357,7 +357,7 @@ export default definePlugin({
|
|||
);
|
||||
}
|
||||
|
||||
if (props.channel.id === SUPPORT_CHANNEL_ID && PermissionStore.can(PermissionsBits.SEND_MESSAGES, props.channel)) {
|
||||
if (isSupportChannel(props.channel.id) && PermissionStore.can(PermissionsBits.SEND_MESSAGES, props.channel)) {
|
||||
if (props.message.content.includes("/equicord-debug") || props.message.content.includes("/equicord-plugins")) {
|
||||
buttons.push(
|
||||
<Button
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ export default definePlugin({
|
|||
},
|
||||
{
|
||||
match: /case \i\.\i\.DEVELOPER_OPTIONS:return \i;/,
|
||||
replace: "$&case 'VencordPlugins':return $self.PluginsSubmenu();"
|
||||
replace: "$&case 'EquicordPlugins':return $self.PluginsSubmenu();"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const settings = definePluginSettings({
|
|||
},
|
||||
alwaysPlaySound: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Play message sound even when message sound is disabled",
|
||||
description: "Play the message notification sound even when its disabled",
|
||||
restartNeeded: true,
|
||||
default: false
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,11 +62,6 @@ export const settings = definePluginSettings({
|
|||
default: {} as Record<string, Category[]>,
|
||||
description: "",
|
||||
},
|
||||
disableCreateDMButton: {
|
||||
type: OptionType.BOOLEAN,
|
||||
description: "Disables the create dm button",
|
||||
default: true
|
||||
}
|
||||
});
|
||||
|
||||
export default definePlugin({
|
||||
|
|
@ -159,14 +154,6 @@ export default definePlugin({
|
|||
replace: "$self.getAllUncollapsedChannels().concat($&.filter(c=>!$self.isPinned(c)))"
|
||||
}
|
||||
},
|
||||
{
|
||||
find: ".createDMButtonContainer,",
|
||||
replacement: {
|
||||
match: /"create-dm"\)/,
|
||||
replace: "$&&&false"
|
||||
},
|
||||
predicate: () => settings.store.disableCreateDMButton
|
||||
},
|
||||
],
|
||||
|
||||
sections: null as number[] | null,
|
||||
|
|
|
|||
|
|
@ -134,6 +134,7 @@ function getNextMessage(isUp: boolean, isReply: boolean) {
|
|||
if (m.deleted) return false;
|
||||
if (!isReply && m.author.id !== meId) return false; // editing only own messages
|
||||
if (hasNoBlockedMessages && NoBlockedMessagesPlugin.isBlocked(m)) return false;
|
||||
if (m.type === 6) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -16,10 +16,10 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { Toasts } from "@webpack/common";
|
||||
import { ChannelStore, GuildMemberStore, Toasts } from "@webpack/common";
|
||||
|
||||
import { copyToClipboard } from "./clipboard";
|
||||
import { EquicordDevsById, VencordDevsById } from "./constants";
|
||||
import { EQUICORD_HELPERS, EquicordDevsById, GUILD_ID, SUPPORT_CHANNEL_ID, VencordDevsById } from "./constants";
|
||||
|
||||
/**
|
||||
* Calls .join(" ") on the arguments
|
||||
|
|
@ -116,3 +116,19 @@ export function tryOrElse<T>(func: () => T, fallback: T): T {
|
|||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
export function isEquicordGuild(id: string, isGuildId: boolean = false): boolean {
|
||||
if (isGuildId) return id === GUILD_ID;
|
||||
|
||||
const channel = ChannelStore.getChannel(id);
|
||||
return channel.guild_id === GUILD_ID;
|
||||
}
|
||||
|
||||
export function isSupportChannel(channelId: string): boolean {
|
||||
return channelId === SUPPORT_CHANNEL_ID;
|
||||
}
|
||||
|
||||
export function isEquicordSupport(userId: string): boolean {
|
||||
const member = GuildMemberStore.getMember(GUILD_ID, userId);
|
||||
return member?.roles?.includes(EQUICORD_HELPERS) || false;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue