More Store Stuff

This commit is contained in:
thororen 2026-09-25 09:57:00 -04:00
parent 3d4b9d5099
commit 00edef7369
No known key found for this signature in database
9 changed files with 40 additions and 87 deletions

View file

@ -32,6 +32,7 @@ export interface SpotifySocketAndDevice {
export interface SpotifyArtist {
id: string;
name: string;
external_urls: { spotify: string; };
}
export interface SpotifyImage {

View file

@ -69,7 +69,7 @@ export class UserGuildSettingsStore extends FluxStore {
getPendingChannelUpdates(guildId: string): Record<string, any>;
getState(): UserGuildSettingsState;
isCategoryMuted(guildId: string, channelId: string): boolean;
isChannelMuted(guildId: string, channelId: string): boolean;
isChannelMuted(guildId: string | null, channelId: string): boolean;
isChannelOptedIn(guildId: string, channelId: string, usePending?: boolean): boolean;
isChannelOrParentOptedIn(guildId: string, channelId: string, usePending?: boolean): boolean;
isChannelRecordOrParentOptedIn(channel: Channel, usePending?: boolean): boolean;

View file

@ -13,7 +13,7 @@ import { findComponentByCodeLazy, findCssClassesLazy } from "@webpack";
import { React, useRef, useState } from "@webpack/common";
const CloseButton = findComponentByCodeLazy("CLOSE_BUTTON_LABEL");
import { MutableRefObject } from "react";
import type { RefObject } from "react";
import { jumper } from "./index";
@ -22,7 +22,7 @@ const containerStyles = findCssClassesLazy("containerBottom", "containerTop");
export default function ReplyNavigator({ replies }: { replies: Message[]; }) {
const [page, setPage] = useState(1);
const [visible, setVisible] = useState(true);
const ref: MutableRefObject<HTMLDivElement | null> = useRef(null);
const ref: RefObject<HTMLDivElement | null> = useRef(null);
React.useEffect(() => {
setPage(1);
setVisible(true);

View file

@ -11,7 +11,7 @@ import { Paragraph } from "@components/Paragraph";
import { IS_WINDOWS } from "@utils/constants";
import { Logger } from "@utils/Logger";
import { OptionType } from "@utils/types";
import { findByCodeLazy, findByPropsLazy } from "@webpack";
import { findByCodeLazy } from "@webpack";
import { MediaEngineStore, SearchableSelect, useEffect, useState } from "@webpack/common";
interface PickerProps {
@ -20,7 +20,6 @@ interface PickerProps {
}
const getDesktopSources = findByCodeLazy("desktop sources");
const configModule = findByPropsLazy("getOutputVolume");
const log = new Logger("InstantScreenShare");
export const settings = definePluginSettings({
@ -73,7 +72,7 @@ export async function getCurrentMedia() {
if (settings.store.includeVideoDevices) {
try {
const videoDevices = Object.values(configModule.getVideoDevices() || {});
const videoDevices = Object.values(MediaEngineStore.getVideoDevices() || {});
const videoSources = videoDevices.map((device: any) => ({
id: device.id,
name: device.name,
@ -127,7 +126,7 @@ function ScreenSetting() {
if (includeVideoDevices) {
try {
const videoDevices = Object.values(configModule.getVideoDevices() || {});
const videoDevices = Object.values(MediaEngineStore.getVideoDevices() || {});
const videoSources = videoDevices.map((device: any) => ({
id: device.id,
name: device.name,

View file

@ -9,7 +9,6 @@ import { QrCodeIcon } from "@components/Icons";
import { wrapTab } from "@components/settings";
import loginWithQR from "@equicordplugins/loginWithQR";
import { images } from "@equicordplugins/loginWithQR/images";
import { findByPropsLazy } from "@webpack";
import {
RestAPI,
useEffect,
@ -17,7 +16,7 @@ import {
useState,
} from "@webpack/common";
import jsQR, { QRCode } from "jsqr";
import { MutableRefObject, ReactElement } from "react";
import type { ReactElement, RefObject } from "react";
import { cl, Spinner, SpinnerTypes } from "..";
import openVerifyModal from "./VerifyModal";
@ -43,7 +42,7 @@ interface QrModalProps {
location?: QRCode["location"]
) => Promise<void>;
}
type QrModalPropsRef = MutableRefObject<QrModalProps>;
type QrModalPropsRef = RefObject<QrModalProps>;
const limitSize = (width: number, height: number) => {
if (width > height) {
@ -55,14 +54,11 @@ const limitSize = (width: number, height: number) => {
}
};
const { getVideoDeviceId } = findByPropsLazy("getVideoDeviceId");
const tokenRegex = /^https:\/\/discord\.com\/ra\/([\w-]+)$/;
const verifyUrl = async (
token: string,
{ current: modalProps }: QrModalPropsRef
) => {
// yay
let handshake: string | null = null;
try {
const res = await RestAPI.post({

View file

@ -6,20 +6,17 @@
import { addContextMenuPatch, NavContextMenuPatchCallback, removeContextMenuPatch } from "@api/ContextMenu";
import { updateMessage } from "@api/MessageUpdater";
import { findStoreLazy } from "@webpack";
import { FluxDispatcher, Menu, MessageActions, React, Toasts, UserStore } from "@webpack/common";
import { FluxDispatcher, Menu, MessageActions, React, SortedGuildStore, Toasts, UserStore } from "@webpack/common";
import { openLogModal } from "../components/LogsModal";
import { deleteMessageIDB } from "../db";
import { settings } from "../index";
import { addToXAndRemoveFromOpposite, ListType, removeFromX } from ".";
const SortedGuildStore = findStoreLazy("SortedGuildStore");
const idFunctions = {
Folder: props =>
props?.folderId &&
SortedGuildStore?.getGuildFolders?.().find(f => f?.folderId === props.folderId)?.guildIds,
SortedGuildStore.getGuildFolders().find(f => f?.folderId === props.folderId)?.guildIds,
Server: props => props?.guild?.id,
User: props => props?.message?.author?.id || props?.user?.id,
Channel: props => props.message?.channel_id || props.channel?.id

View file

@ -9,12 +9,12 @@ import { Button } from "@components/Button";
import { EquicordDevs } from "@utils/constants";
import definePlugin, { makeRange, OptionType } from "@utils/types";
import { Channel, Message } from "@vencord/discord-types";
import { findByPropsLazy, findStore } from "@webpack";
import { ChannelStore, IconUtils, MessageStore, NavigationRouter, PresenceStore, RelationshipStore, SelectedChannelStore, StreamerModeStore, UserStore } from "@webpack/common";
import { UserNotificationSetting } from "@vencord/discord-types/enums";
import { findByPropsLazy } from "@webpack";
import { ChannelStore, IconUtils, MessageStore, NavigationRouter, PresenceStore, RelationshipStore, SelectedChannelStore, StreamerModeStore, UserGuildSettingsStore, UserStore } from "@webpack/common";
import { setContainerPosition, showNotification, teardownNotifications } from "./components/Notifications";
const MuteStore = findByPropsLazy("isSuppressEveryoneEnabled");
const SelectedChannelActionCreators = findByPropsLazy("selectPrivateChannel");
const ChannelRTCActions = findByPropsLazy("updateChatOpen", "toggleParticipants");
@ -23,12 +23,6 @@ const ID_REGEX = /^\d{17,20}$/;
let ignoredUsers: string[] = [];
let notifyFor: string[] = [];
enum NotificationLevel {
ALL_MESSAGES = 0,
ONLY_MENTIONS = 1,
NO_MESSAGES = 2
}
export const settings = definePluginSettings({
position: {
type: OptionType.SELECT,
@ -147,7 +141,7 @@ export default definePlugin({
if (
(!settings.store.directMessages && channel.isDM()) // If DM notifications are disabled.
|| (!settings.store.groupMessages && channel.isGroupDM()) // If group DM notifications are disabled.
|| MuteStore.isChannelMuted(null, channel.id) // If the user has muted the DM/group channel.
|| UserGuildSettingsStore.isChannelMuted(null, channel.id) // If the user has muted the DM/group channel.
) return;
}
@ -208,19 +202,19 @@ function shouldNotifyForGuildMessage(message: Message, channel: Channel): boolea
if (settings.store.friendServerNotifications && RelationshipStore.isFriend(message.author.id)) return true;
// Respect the user's mute state for the guild/category/channel.
if (MuteStore.isGuildOrCategoryOrChannelMuted(channel.guild_id, channel.id)) return false;
if (UserGuildSettingsStore.isGuildOrCategoryOrChannelMuted(channel.guild_id, channel.id)) return false;
// Resolve the user's configured notification level for the channel/guild.
const userGuildSettings = findStore("UserGuildSettingsStore").getAllSettings().userGuildSettings[channel.guild_id];
const userGuildSettings = UserGuildSettingsStore.getAllSettings().userGuildSettings[channel.guild_id];
if (!userGuildSettings) return false;
const channelOverride = userGuildSettings.channel_overrides?.[channel.id];
const level: NotificationLevel = (channelOverride && typeof channelOverride === "object" && "message_notifications" in channelOverride)
const level: UserNotificationSetting = (channelOverride && typeof channelOverride === "object" && "message_notifications" in channelOverride)
? channelOverride.message_notifications
: (typeof userGuildSettings.message_notifications === "number" ? userGuildSettings.message_notifications : NotificationLevel.NO_MESSAGES);
: (typeof userGuildSettings.message_notifications === "number" ? userGuildSettings.message_notifications : UserNotificationSetting.NO_MESSAGES);
if (level === NotificationLevel.NO_MESSAGES) return false;
if (level === NotificationLevel.ALL_MESSAGES) return true;
if (level === UserNotificationSetting.NO_MESSAGES) return false;
if (level === UserNotificationSetting.ALL_MESSAGES) return true;
// Otherwise we only notify if the user was mentioned.
return message.content.includes(`<@${UserStore.getCurrentUser().id}>`);

View file

@ -13,9 +13,8 @@ import { Link } from "@components/Link";
import { Devs } from "@utils/constants";
import { identity } from "@utils/misc";
import definePlugin, { OptionType } from "@utils/types";
import { findByPropsLazy } from "@webpack";
import { FluxDispatcher, Select, Slider, useEffect, useState } from "@webpack/common";
const configModule = findByPropsLazy("getOutputVolume");
import { VideoDevice } from "@vencord/discord-types";
import { FluxDispatcher, MediaEngineStore, Select, Slider, useEffect, useState } from "@webpack/common";
const settings = definePluginSettings({
title1: {
@ -91,10 +90,10 @@ const settings = definePluginSettings({
});
function OutputVolumeComponent() {
const [outputVolume, setOutputVolume] = useState(configModule.getOutputVolume());
const [outputVolume, setOutputVolume] = useState(MediaEngineStore.getOutputVolume());
useEffect(() => {
const listener = () => setOutputVolume(configModule.getOutputVolume());
const listener = () => setOutputVolume(MediaEngineStore.getOutputVolume());
FluxDispatcher.subscribe("AUDIO_SET_OUTPUT_VOLUME", listener);
return () => FluxDispatcher.unsubscribe("AUDIO_SET_OUTPUT_VOLUME", listener);
}, []);
@ -113,10 +112,10 @@ function OutputVolumeComponent() {
}
function InputVolumeComponent() {
const [inputVolume, setInputVolume] = useState(configModule.getInputVolume());
const [inputVolume, setInputVolume] = useState(MediaEngineStore.getInputVolume());
useEffect(() => {
const listener = () => setInputVolume(configModule.getInputVolume());
const listener = () => setInputVolume(MediaEngineStore.getInputVolume());
FluxDispatcher.subscribe("AUDIO_SET_INPUT_VOLUME", listener);
return () => FluxDispatcher.unsubscribe("AUDIO_SET_INPUT_VOLUME", listener);
}, []);
@ -135,10 +134,10 @@ function InputVolumeComponent() {
}
function OutputDeviceComponent() {
const [outputDevice, setOutputDevice] = useState(configModule.getOutputDeviceId());
const [outputDevice, setOutputDevice] = useState(MediaEngineStore.getOutputDeviceId());
useEffect(() => {
const listener = () => setOutputDevice(configModule.getOutputDeviceId());
const listener = () => setOutputDevice(MediaEngineStore.getOutputDeviceId());
FluxDispatcher.subscribe("AUDIO_SET_OUTPUT_DEVICE", listener);
return () => FluxDispatcher.unsubscribe("AUDIO_SET_OUTPUT_DEVICE", listener);
}, []);
@ -146,7 +145,7 @@ function OutputDeviceComponent() {
return (
<>
{settings.store.showOutputDeviceHeader && <Heading>Output device</Heading>}
<Select options={Object.values(configModule.getOutputDevices()).map((device: any /* i am NOT typing this*/) => {
<Select options={Object.values(MediaEngineStore.getOutputDevices()).map((device: any /* i am NOT typing this*/) => {
return { value: device.id, label: settings.store.showOutputDeviceHeader ? device.name : `🔊 ${device.name}` };
})}
serialize={identity}
@ -164,10 +163,10 @@ function OutputDeviceComponent() {
}
function InputDeviceComponent() {
const [inputDevice, setInputDevice] = useState(configModule.getInputDeviceId());
const [inputDevice, setInputDevice] = useState(MediaEngineStore.getInputDeviceId());
useEffect(() => {
const listener = () => setInputDevice(configModule.getInputDeviceId());
const listener = () => setInputDevice(MediaEngineStore.getInputDeviceId());
FluxDispatcher.subscribe("AUDIO_SET_INPUT_DEVICE", listener);
return () => FluxDispatcher.unsubscribe("AUDIO_SET_INPUT_DEVICE", listener);
}, []);
@ -175,7 +174,7 @@ function InputDeviceComponent() {
return (
<div style={{ marginTop: "10px" }}>
{settings.store.showInputDeviceHeader && <Heading>Input device</Heading>}
<Select options={Object.values(configModule.getInputDevices()).map((device: any /* i am NOT typing this*/) => {
<Select options={Object.values(MediaEngineStore.getInputDevices()).map((device: any /* i am NOT typing this*/) => {
return { value: device.id, label: settings.store.showInputDeviceHeader ? device.name : `🎤 ${device.name}` };
})}
serialize={identity}
@ -193,10 +192,10 @@ function InputDeviceComponent() {
}
function VideoDeviceComponent() {
const [videoDevice, setVideoDevice] = useState(configModule.getVideoDeviceId());
const [videoDevice, setVideoDevice] = useState(MediaEngineStore.getVideoDeviceId());
useEffect(() => {
const listener = () => setVideoDevice(configModule.getVideoDeviceId());
const listener = () => setVideoDevice(MediaEngineStore.getVideoDeviceId());
FluxDispatcher.subscribe("MEDIA_ENGINE_SET_VIDEO_DEVICE", listener);
return () => FluxDispatcher.unsubscribe("MEDIA_ENGINE_SET_VIDEO_DEVICE", listener);
}, []);
@ -204,7 +203,7 @@ function VideoDeviceComponent() {
return (
<div style={{ marginTop: "10px" }}>
{settings.store.showVideoDeviceHeader && <Heading>Camera</Heading>}
<Select options={Object.values(configModule.getVideoDevices()).map((device: any /* i am NOT typing this*/) => {
<Select options={Object.values(MediaEngineStore.getVideoDevices()).map((device: VideoDevice) => {
return { value: device.id, label: settings.store.showVideoDeviceHeader ? device.name : `📷 ${device.name}` };
})}
serialize={identity}

View file

@ -20,50 +20,17 @@ import { ApplicationCommandInputType, findOption, OptionalMessageOption, sendBot
import { Devs } from "@utils/constants";
import { sendMessage } from "@utils/discord";
import definePlugin from "@utils/types";
import { Command } from "@vencord/discord-types";
import { findByPropsLazy } from "@webpack";
import { FluxDispatcher, MessageActions, PendingReplyStore } from "@webpack/common";
import { Command, SpotifyTrack } from "@vencord/discord-types";
import { FluxDispatcher, MessageActions, PendingReplyStore, SpotifyStore } from "@webpack/common";
interface Album {
id: string;
image: {
height: number;
width: number;
url: string;
};
name: string;
}
interface Artist {
external_urls: {
spotify: string;
};
href: string;
id: string;
name: string;
type: "artist" | string;
uri: string;
}
interface Track {
id: string | null;
album: Album;
artists: Artist[];
duration: number;
isLocal: boolean;
name: string;
}
const Spotify = findByPropsLazy("getPlayerState");
function makeCommand(name: string, formatUrl: (track: Track) => string): Command {
function makeCommand(name: string, formatUrl: (track: SpotifyTrack) => string): Command {
return {
name,
description: `Share your current Spotify ${name} in chat`,
inputType: ApplicationCommandInputType.BUILT_IN,
options: [OptionalMessageOption],
execute(options, { channel }) {
const track: Track | null = Spotify.getTrack();
const track = SpotifyStore.getTrack();
if (!track) {
return sendBotMessage(channel.id, {
content: "You're not listening to any music."