mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-09 14:43:03 -04:00
Merge branch 'main' into dev
This commit is contained in:
commit
85cb848ff0
2 changed files with 102 additions and 118 deletions
|
@ -3,19 +3,21 @@
|
||||||
* Copyright (c) 2024 Vendicated and contributors
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
import { definePluginSettings, Settings } from "@api/Settings";
|
|
||||||
import { EquicordDevs } from "@utils/constants";
|
import { addChatBarButton, ChatBarButton, removeChatBarButton } from "@api/ChatButtons";
|
||||||
import definePlugin, { OptionType } from "@utils/types";
|
|
||||||
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
|
import { ApplicationCommandInputType, ApplicationCommandOptionType, findOption, sendBotMessage } from "@api/Commands";
|
||||||
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
import { findGroupChildrenByChildId, NavContextMenuPatchCallback } from "@api/ContextMenu";
|
||||||
import { addChatBarButton, ChatBarButton, removeChatBarButton } from "@api/ChatButtons";
|
|
||||||
import { addPreSendListener, removePreSendListener, SendListener } from "@api/MessageEvents";
|
import { addPreSendListener, removePreSendListener, SendListener } from "@api/MessageEvents";
|
||||||
import { transferMessage } from "./native";
|
import { definePluginSettings, Settings } from "@api/Settings";
|
||||||
import { ErrorCard } from "@components/ErrorCard";
|
import { ErrorCard } from "@components/ErrorCard";
|
||||||
import { Link } from "@components/Link";
|
import { Link } from "@components/Link";
|
||||||
|
import { EquicordDevs } from "@utils/constants";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { classes } from "@utils/misc";
|
import { classes } from "@utils/misc";
|
||||||
import { MessageStore, Menu, React, Forms } from "@webpack/common";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
import { Forms, Menu, MessageStore, React } from "@webpack/common";
|
||||||
|
|
||||||
|
import { transferMessage } from "./native";
|
||||||
|
|
||||||
const furudosettings = definePluginSettings(
|
const furudosettings = definePluginSettings(
|
||||||
{
|
{
|
||||||
|
@ -104,7 +106,7 @@ function messageSendListenerFuncs() {
|
||||||
const FurudoSpeakChatToggle: ChatBarButton = ({ isMainChat }) => {
|
const FurudoSpeakChatToggle: ChatBarButton = ({ isMainChat }) => {
|
||||||
const { isEnabled, showIcon } = furudosettings.use(["isEnabled", "showIcon"]);
|
const { isEnabled, showIcon } = furudosettings.use(["isEnabled", "showIcon"]);
|
||||||
const toggle = async () => {
|
const toggle = async () => {
|
||||||
let done = await togglefunc();
|
const done = await togglefunc();
|
||||||
return done;
|
return done;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -199,7 +201,7 @@ export default definePlugin({
|
||||||
],
|
],
|
||||||
execute: async (args, ctx) => {
|
execute: async (args, ctx) => {
|
||||||
furudosettings.store.isEnabled = !!findOption(args, "value", !furudosettings.store.isEnabled);
|
furudosettings.store.isEnabled = !!findOption(args, "value", !furudosettings.store.isEnabled);
|
||||||
if (furudosettings.store.isEnabled) { messageSendListenerFuncs(); };
|
if (furudosettings.store.isEnabled) { messageSendListenerFuncs(); }
|
||||||
sendBotMessage(ctx.channel.id, {
|
sendBotMessage(ctx.channel.id, {
|
||||||
content: furudosettings.store.isEnabled ? "FurudoSpeak enabled!" : "FurudoSpeak disabled!",
|
content: furudosettings.store.isEnabled ? "FurudoSpeak enabled!" : "FurudoSpeak disabled!",
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,31 +1,16 @@
|
||||||
/*
|
/*
|
||||||
* Vencord, a modification for Discord's desktop app
|
* Vencord, a Discord client mod
|
||||||
* Copyright (c) 2023 Vendicated and contributors
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
*
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
* 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 { definePluginSettings, Settings } from "@api/Settings";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import { ErrorCard } from "@components/ErrorCard";
|
|
||||||
import { Devs, EquicordDevs } from "@utils/constants";
|
import { Devs, EquicordDevs } from "@utils/constants";
|
||||||
import { Logger } from "@utils/Logger";
|
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { wordsToTitle } from "@utils/text";
|
import { wordsToTitle } from "@utils/text";
|
||||||
import definePlugin, {
|
import definePlugin, {
|
||||||
OptionType,
|
OptionType,
|
||||||
PluginOptionsItem,
|
PluginOptionsItem,
|
||||||
ReporterTestable,
|
|
||||||
} from "@utils/types";
|
} from "@utils/types";
|
||||||
import { findByPropsLazy } from "@webpack";
|
import { findByPropsLazy } from "@webpack";
|
||||||
import {
|
import {
|
||||||
|
@ -61,7 +46,6 @@ const VoiceStateStore = findByPropsLazy(
|
||||||
|
|
||||||
async function speak(
|
async function speak(
|
||||||
text: string,
|
text: string,
|
||||||
settings: any = Settings.plugins.VcNarrator
|
|
||||||
) {
|
) {
|
||||||
if (text.trim().length === 0) return;
|
if (text.trim().length === 0) return;
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
|
@ -77,7 +61,7 @@ async function speak(
|
||||||
referrerPolicy: "no-referrer",
|
referrerPolicy: "no-referrer",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
text: text,
|
text: text,
|
||||||
voice: Settings.plugins.VcNarratorCustom.customVoice,
|
voice: settings.store.customVoice,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -94,15 +78,13 @@ async function speak(
|
||||||
const url = URL.createObjectURL(blob);
|
const url = URL.createObjectURL(blob);
|
||||||
|
|
||||||
const audio = new Audio(url);
|
const audio = new Audio(url);
|
||||||
audio.volume = 0.3;
|
audio.volume = settings.store.volume;
|
||||||
|
audio.playbackRate = settings.store.rate;
|
||||||
audio.play();
|
audio.play();
|
||||||
|
|
||||||
audio.volume = settings.volume;
|
|
||||||
audio.playbackRate = settings.rate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function clean(str: string) {
|
function clean(str: string) {
|
||||||
const replacer = Settings.plugins.VcNarrator.latinOnly
|
const replacer = settings.store.latinOnly
|
||||||
? /[^\p{Script=Latin}\p{Number}\p{Punctuation}\s]/gu
|
? /[^\p{Script=Latin}\p{Number}\p{Punctuation}\s]/gu
|
||||||
: /[^\p{Letter}\p{Number}\p{Punctuation}\s]/gu;
|
: /[^\p{Letter}\p{Number}\p{Punctuation}\s]/gu;
|
||||||
|
|
||||||
|
@ -155,9 +137,9 @@ function getTypeAndChannelId(
|
||||||
}
|
}
|
||||||
|
|
||||||
function playSample(tempSettings: any, type: string) {
|
function playSample(tempSettings: any, type: string) {
|
||||||
const settings = Object.assign(
|
const settingsobj = Object.assign(
|
||||||
{},
|
{},
|
||||||
Settings.plugins.VcNarrator,
|
settings.store,
|
||||||
tempSettings
|
tempSettings
|
||||||
);
|
);
|
||||||
const currentUser = UserStore.getCurrentUser();
|
const currentUser = UserStore.getCurrentUser();
|
||||||
|
@ -165,87 +147,17 @@ function playSample(tempSettings: any, type: string) {
|
||||||
|
|
||||||
speak(
|
speak(
|
||||||
formatText(
|
formatText(
|
||||||
settings[type + "Message"],
|
settingsobj[type + "Message"],
|
||||||
currentUser.username,
|
currentUser.username,
|
||||||
"general",
|
"general",
|
||||||
(currentUser as any).globalName ?? currentUser.username,
|
(currentUser as any).globalName ?? currentUser.username,
|
||||||
GuildMemberStore.getNick(myGuildId, currentUser.id) ??
|
GuildMemberStore.getNick(myGuildId, currentUser.id) ??
|
||||||
currentUser.username
|
currentUser.username
|
||||||
),
|
|
||||||
settings
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default definePlugin({
|
|
||||||
name: "VcNarratorCustom",
|
|
||||||
description:
|
|
||||||
"Announces when users join, leave, or move voice channels via narrator. TikTok TTS version; speechSynthesis is pretty boring. Ported from https://github.com/Loukious/Vencord",
|
|
||||||
authors: [Devs.Ven, Devs.Nyako, EquicordDevs.Loukios, EquicordDevs.examplegit],
|
|
||||||
|
|
||||||
flux: {
|
|
||||||
VOICE_STATE_UPDATES({ voiceStates }: { voiceStates: VoiceState[]; }) {
|
|
||||||
const myGuildId = SelectedGuildStore.getGuildId();
|
|
||||||
const myChanId = SelectedChannelStore.getVoiceChannelId();
|
|
||||||
const myId = UserStore.getCurrentUser().id;
|
|
||||||
|
|
||||||
if (
|
|
||||||
ChannelStore.getChannel(myChanId!)?.type ===
|
|
||||||
13 /* Stage Channel */
|
|
||||||
)
|
)
|
||||||
return;
|
|
||||||
|
|
||||||
for (const state of voiceStates) {
|
|
||||||
const { userId, channelId, oldChannelId } = state;
|
|
||||||
const isMe = userId === myId;
|
|
||||||
if (!isMe) {
|
|
||||||
if (!myChanId) continue;
|
|
||||||
if (channelId !== myChanId && oldChannelId !== myChanId)
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [type, id] = getTypeAndChannelId(state, isMe);
|
|
||||||
if (!type) continue;
|
|
||||||
|
|
||||||
const template = Settings.plugins.VcNarrator[type + "Message"];
|
|
||||||
const user =
|
|
||||||
isMe && !Settings.plugins.VcNarrator.sayOwnName
|
|
||||||
? ""
|
|
||||||
: UserStore.getUser(userId).username;
|
|
||||||
const displayName =
|
|
||||||
user &&
|
|
||||||
((UserStore.getUser(userId) as any).globalName ?? user);
|
|
||||||
const nickname =
|
|
||||||
user &&
|
|
||||||
(GuildMemberStore.getNick(myGuildId, userId) ??
|
|
||||||
displayName);
|
|
||||||
const channel = ChannelStore.getChannel(id).name;
|
|
||||||
|
|
||||||
speak(
|
|
||||||
formatText(template, user, channel, displayName, nickname)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
AUDIO_TOGGLE_SELF_MUTE() {
|
const settings = definePluginSettings({
|
||||||
const chanId = SelectedChannelStore.getVoiceChannelId()!;
|
|
||||||
const s = VoiceStateStore.getVoiceStateForChannel(
|
|
||||||
chanId
|
|
||||||
) as VoiceState;
|
|
||||||
if (!s) return;
|
|
||||||
},
|
|
||||||
|
|
||||||
AUDIO_TOGGLE_SELF_DEAF() {
|
|
||||||
const chanId = SelectedChannelStore.getVoiceChannelId()!;
|
|
||||||
const s = VoiceStateStore.getVoiceStateForChannel(
|
|
||||||
chanId
|
|
||||||
) as VoiceState;
|
|
||||||
if (!s) return;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
optionsCache: null as Record<string, PluginOptionsItem> | null,
|
|
||||||
settings: definePluginSettings(
|
|
||||||
{
|
|
||||||
customVoice: {
|
customVoice: {
|
||||||
type: OptionType.STRING,
|
type: OptionType.STRING,
|
||||||
description: "Custom voice id, currently just tiktok",
|
description: "Custom voice id, currently just tiktok",
|
||||||
|
@ -316,14 +228,84 @@ export default definePlugin({
|
||||||
description: "Undeafen Message (only self for now)",
|
description: "Undeafen Message (only self for now)",
|
||||||
default: "{{DISPLAY_NAME}} undeafened",
|
default: "{{DISPLAY_NAME}} undeafened",
|
||||||
},
|
},
|
||||||
},),
|
});
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "VcNarratorCustom",
|
||||||
|
description:
|
||||||
|
"Announces when users join, leave, or move voice channels via narrator. TikTok TTS version; speechSynthesis is pretty boring. Ported from https://github.com/Loukious/Vencord",
|
||||||
|
authors: [Devs.Ven, Devs.Nyako, EquicordDevs.Loukios, EquicordDevs.examplegit],
|
||||||
|
|
||||||
|
flux: {
|
||||||
|
VOICE_STATE_UPDATES({ voiceStates }: { voiceStates: VoiceState[]; }) {
|
||||||
|
const myGuildId = SelectedGuildStore.getGuildId();
|
||||||
|
const myChanId = SelectedChannelStore.getVoiceChannelId();
|
||||||
|
const myId = UserStore.getCurrentUser().id;
|
||||||
|
|
||||||
|
if (
|
||||||
|
ChannelStore.getChannel(myChanId!)?.type ===
|
||||||
|
13 /* Stage Channel */
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (const state of voiceStates) {
|
||||||
|
const { userId, channelId, oldChannelId } = state;
|
||||||
|
const isMe = userId === myId;
|
||||||
|
if (!isMe) {
|
||||||
|
if (!myChanId) continue;
|
||||||
|
if (channelId !== myChanId && oldChannelId !== myChanId)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const [type, id] = getTypeAndChannelId(state, isMe);
|
||||||
|
if (!type) continue;
|
||||||
|
|
||||||
|
const template = settings.store[type + "Message"];
|
||||||
|
const user =
|
||||||
|
isMe && !settings.store.sayOwnName
|
||||||
|
? ""
|
||||||
|
: UserStore.getUser(userId).username;
|
||||||
|
const displayName =
|
||||||
|
user &&
|
||||||
|
((UserStore.getUser(userId) as any).globalName ?? user);
|
||||||
|
const nickname =
|
||||||
|
user &&
|
||||||
|
(GuildMemberStore.getNick(myGuildId, userId) ??
|
||||||
|
displayName);
|
||||||
|
const channel = ChannelStore.getChannel(id).name;
|
||||||
|
|
||||||
|
speak(
|
||||||
|
formatText(template, user, channel, displayName, nickname)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
AUDIO_TOGGLE_SELF_MUTE() {
|
||||||
|
const chanId = SelectedChannelStore.getVoiceChannelId()!;
|
||||||
|
const s = VoiceStateStore.getVoiceStateForChannel(
|
||||||
|
chanId
|
||||||
|
) as VoiceState;
|
||||||
|
if (!s) return;
|
||||||
|
},
|
||||||
|
|
||||||
|
AUDIO_TOGGLE_SELF_DEAF() {
|
||||||
|
const chanId = SelectedChannelStore.getVoiceChannelId()!;
|
||||||
|
const s = VoiceStateStore.getVoiceStateForChannel(
|
||||||
|
chanId
|
||||||
|
) as VoiceState;
|
||||||
|
if (!s) return;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
optionsCache: null as Record<string, PluginOptionsItem> | null,
|
||||||
|
settings,
|
||||||
|
|
||||||
settingsAboutComponent({ tempSettings: s }) {
|
settingsAboutComponent({ tempSettings: s }) {
|
||||||
const types = useMemo(
|
const types = useMemo(
|
||||||
() =>
|
() =>
|
||||||
Object.keys(Vencord.Plugins.plugins.VcNarrator.options!)
|
Object.keys(settings.store)
|
||||||
.filter((k) => k.endsWith("Message"))
|
.filter(k => k.endsWith("Message"))
|
||||||
.map((k) => k.slice(0, -7)),
|
.map(k => k.slice(0, -7)),
|
||||||
[]
|
[]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -365,7 +347,7 @@ export default definePlugin({
|
||||||
}}
|
}}
|
||||||
className={"vc-narrator-buttons"}
|
className={"vc-narrator-buttons"}
|
||||||
>
|
>
|
||||||
{types.map((t) => (
|
{types.map(t => (
|
||||||
<Button key={t} onClick={() => playSample(s, t)}>
|
<Button key={t} onClick={() => playSample(s, t)}>
|
||||||
{wordsToTitle([t])}
|
{wordsToTitle([t])}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue