mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-07 21:53:04 -04:00
* Revert "Drop HideServers"
This reverts commit bb8a68b45e
.
* Fix HideServers
This commit is contained in:
parent
ccbe5c16f1
commit
a068fb8e8a
8 changed files with 448 additions and 3 deletions
|
@ -77,6 +77,7 @@ You can join our [discord server](https://discord.gg/5Xh2W87egW) for commits, ch
|
||||||
- GlobalBadges by HypedDomi & Hosted by Wolfie
|
- GlobalBadges by HypedDomi & Hosted by Wolfie
|
||||||
- GoogleThat by Samwich
|
- GoogleThat by Samwich
|
||||||
- HideChatButtons by iamme
|
- HideChatButtons by iamme
|
||||||
|
- HideServers by bepvte
|
||||||
- HolyNotes by Wolfie
|
- HolyNotes by Wolfie
|
||||||
- HomeTyping by Samwich
|
- HomeTyping by Samwich
|
||||||
- HopOn by ImLvna
|
- HopOn by ImLvna
|
||||||
|
|
58
src/equicordplugins/hideServers/HiddenServersStore.ts
Normal file
58
src/equicordplugins/hideServers/HiddenServersStore.ts
Normal file
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as DataStore from "@api/DataStore";
|
||||||
|
import { findStoreLazy, proxyLazyWebpack } from "@webpack";
|
||||||
|
import { Flux, FluxDispatcher, GuildStore } from "@webpack/common";
|
||||||
|
import { Guild } from "discord-types/general";
|
||||||
|
|
||||||
|
|
||||||
|
export const HiddenServersStore = proxyLazyWebpack(() => {
|
||||||
|
const { Store } = Flux;
|
||||||
|
|
||||||
|
const SortedGuildStore = findStoreLazy("SortedGuildStore");
|
||||||
|
const DB_KEY = "HideServers_servers";
|
||||||
|
|
||||||
|
class HiddenServersStore extends Store {
|
||||||
|
private _hiddenGuilds: Set<string> = new Set();
|
||||||
|
public get hiddenGuilds() {
|
||||||
|
return this._hiddenGuilds;
|
||||||
|
}
|
||||||
|
// id try to use .initialize() but i dont know how it works
|
||||||
|
public async load() {
|
||||||
|
const data = await DataStore.get(DB_KEY);
|
||||||
|
if (data && data instanceof Set) {
|
||||||
|
this._hiddenGuilds = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public unload() {
|
||||||
|
this._hiddenGuilds.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public addHidden(guild: Guild) {
|
||||||
|
this._hiddenGuilds.add(guild.id);
|
||||||
|
DataStore.set(DB_KEY, this._hiddenGuilds);
|
||||||
|
this.emitChange();
|
||||||
|
}
|
||||||
|
public removeHidden(id: string) {
|
||||||
|
this._hiddenGuilds.delete(id);
|
||||||
|
DataStore.set(DB_KEY, this._hiddenGuilds);
|
||||||
|
this.emitChange();
|
||||||
|
}
|
||||||
|
public clearHidden() {
|
||||||
|
this._hiddenGuilds.clear();
|
||||||
|
DataStore.del(DB_KEY);
|
||||||
|
this.emitChange();
|
||||||
|
}
|
||||||
|
public hiddenGuildsDetail(): Guild[] {
|
||||||
|
const sortedGuildIds = SortedGuildStore.getFlattenedGuildIds() as string[];
|
||||||
|
// otherwise the list is in order of increasing id number which is confusing
|
||||||
|
return sortedGuildIds.filter(id => this._hiddenGuilds.has(id)).map(id => GuildStore.getGuild(id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new HiddenServersStore(FluxDispatcher);
|
||||||
|
});
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import "./style.css";
|
||||||
|
|
||||||
|
import { classNameFactory } from "@api/Styles";
|
||||||
|
import { Button, GuildStore, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
|
import { HiddenServersStore } from "../HiddenServersStore";
|
||||||
|
import { openHiddenServersModal } from "./HiddenServersMenu";
|
||||||
|
|
||||||
|
const cl = classNameFactory("vc-hideservers-");
|
||||||
|
|
||||||
|
function HiddenServersButton() {
|
||||||
|
const hiddenGuilds = useStateFromStores([HiddenServersStore], () => HiddenServersStore.hiddenGuilds, undefined, (old, newer) => old.size === newer.size);
|
||||||
|
// if youve left a server dont show it in the count
|
||||||
|
const actuallyHidden = Array.from(hiddenGuilds).filter(x => GuildStore.getGuild(x)).length;
|
||||||
|
return (
|
||||||
|
<div className={cl("button-wrapper")}>
|
||||||
|
{actuallyHidden > 0 ? (
|
||||||
|
<Button
|
||||||
|
className={cl("button")}
|
||||||
|
look={Button.Looks.BLANK}
|
||||||
|
size={Button.Sizes.MIN}
|
||||||
|
onClick={() => openHiddenServersModal()}
|
||||||
|
>
|
||||||
|
{actuallyHidden} Hidden
|
||||||
|
</Button>
|
||||||
|
) : null}
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default () => { return <HiddenServersButton />; };
|
105
src/equicordplugins/hideServers/components/HiddenServersMenu.tsx
Normal file
105
src/equicordplugins/hideServers/components/HiddenServersMenu.tsx
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { classNameFactory } from "@api/Styles";
|
||||||
|
import { classes } from "@utils/misc";
|
||||||
|
import {
|
||||||
|
closeModal,
|
||||||
|
ModalCloseButton,
|
||||||
|
ModalContent,
|
||||||
|
ModalHeader,
|
||||||
|
ModalProps,
|
||||||
|
ModalRoot,
|
||||||
|
ModalSize,
|
||||||
|
openModal,
|
||||||
|
} from "@utils/modal";
|
||||||
|
import { findByPropsLazy } from "@webpack";
|
||||||
|
import { Button, Forms, IconUtils, Text, useStateFromStores } from "@webpack/common";
|
||||||
|
import { Guild } from "discord-types/general";
|
||||||
|
|
||||||
|
import { HiddenServersStore } from "../HiddenServersStore";
|
||||||
|
|
||||||
|
const cl = classNameFactory("vc-hideservers-");
|
||||||
|
const IconClasses = findByPropsLazy("icon", "acronym", "childWrapper");
|
||||||
|
|
||||||
|
function HiddenServersModal({
|
||||||
|
modalProps,
|
||||||
|
close,
|
||||||
|
}: {
|
||||||
|
modalProps: ModalProps;
|
||||||
|
close(): void;
|
||||||
|
}) {
|
||||||
|
const servers = useStateFromStores([HiddenServersStore], () => HiddenServersStore.hiddenGuildsDetail());
|
||||||
|
return (
|
||||||
|
<ModalRoot {...modalProps} size={ModalSize.LARGE}>
|
||||||
|
<ModalHeader>
|
||||||
|
<Text variant="heading-lg/semibold" style={{ flexGrow: 1 }}>
|
||||||
|
Hidden Servers
|
||||||
|
</Text>
|
||||||
|
<ModalCloseButton onClick={close} />
|
||||||
|
</ModalHeader>
|
||||||
|
|
||||||
|
<ModalContent>
|
||||||
|
<HiddenServersMenu servers={servers} />
|
||||||
|
</ModalContent>
|
||||||
|
</ModalRoot>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function HiddenServersMenu({ servers }: { servers: Guild[]; }) {
|
||||||
|
return <div className={cl("list")}>
|
||||||
|
{servers.length > 0 ? (
|
||||||
|
servers.map(server => (
|
||||||
|
<div key={server.id} className={cl("row")}>
|
||||||
|
<div className={cl("guildicon")}>
|
||||||
|
{server.icon
|
||||||
|
? <img height="48" width="48"
|
||||||
|
src={IconUtils.getGuildIconURL({
|
||||||
|
id: server.id,
|
||||||
|
icon: server.icon,
|
||||||
|
canAnimate: true,
|
||||||
|
size: 240,
|
||||||
|
})} />
|
||||||
|
: <div
|
||||||
|
aria-hidden
|
||||||
|
className={classes(
|
||||||
|
IconClasses.childWrapper,
|
||||||
|
IconClasses.acronym
|
||||||
|
)}>
|
||||||
|
{server.acronym}
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<Forms.FormTitle className={cl("name")}>
|
||||||
|
{server.name}
|
||||||
|
</Forms.FormTitle>
|
||||||
|
<Button
|
||||||
|
className={"row-button"}
|
||||||
|
color={Button.Colors.PRIMARY}
|
||||||
|
onClick={() => HiddenServersStore.removeHidden(server.id)}
|
||||||
|
>
|
||||||
|
Remove
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
))
|
||||||
|
) : (
|
||||||
|
<Text variant="heading-sm/medium">
|
||||||
|
No hidden servers
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function openHiddenServersModal() {
|
||||||
|
const key = openModal(modalProps => {
|
||||||
|
return (
|
||||||
|
<HiddenServersModal
|
||||||
|
modalProps={modalProps}
|
||||||
|
close={() => closeModal(key)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
47
src/equicordplugins/hideServers/components/style.css
Normal file
47
src/equicordplugins/hideServers/components/style.css
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
.vc-hideservers-button-wrapper {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 0 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-hideservers-button {
|
||||||
|
max-width: 48px;
|
||||||
|
font-size: 60%;
|
||||||
|
background-color: var(--background-primary);
|
||||||
|
color: var(--header-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-hideservers-list {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copied from blocked row */
|
||||||
|
.vc-hideservers-row {
|
||||||
|
height: 62px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
margin-left: 20px;
|
||||||
|
margin-right: 20px;
|
||||||
|
border-top: 1px solid var(--background-modifier-accent);
|
||||||
|
border-bottom: 1px solid transparent;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-hideservers-guildicon {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-hideservers-guildicon img {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-hideservers-name {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vc-hideservers-row-button {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
142
src/equicordplugins/hideServers/index.tsx
Normal file
142
src/equicordplugins/hideServers/index.tsx
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
// additional thanks to mwittrien/DevilBro and nexpid for their server hiding plugins, which served as inspiration
|
||||||
|
|
||||||
|
import {
|
||||||
|
findGroupChildrenByChildId,
|
||||||
|
NavContextMenuPatchCallback,
|
||||||
|
} from "@api/ContextMenu";
|
||||||
|
import {
|
||||||
|
addServerListElement,
|
||||||
|
removeServerListElement,
|
||||||
|
ServerListRenderPosition,
|
||||||
|
} from "@api/ServerList";
|
||||||
|
import { EquicordDevs } from "@utils/constants";
|
||||||
|
import definePlugin from "@utils/types";
|
||||||
|
import { Menu, React, useStateFromStores } from "@webpack/common";
|
||||||
|
import { Guild } from "discord-types/general";
|
||||||
|
|
||||||
|
import hiddenServersButton from "./components/HiddenServersButton";
|
||||||
|
import { HiddenServersStore } from "./HiddenServersStore";
|
||||||
|
import settings from "./settings";
|
||||||
|
|
||||||
|
type guildsNode = {
|
||||||
|
type: "guild" | "folder";
|
||||||
|
id: number | string;
|
||||||
|
children: guildsNode[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type qsResult = {
|
||||||
|
type: "GUILD" | string;
|
||||||
|
record?: {
|
||||||
|
id?: string;
|
||||||
|
guild_id?: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const Patch: NavContextMenuPatchCallback = (
|
||||||
|
children,
|
||||||
|
{ guild }: { guild: Guild; }
|
||||||
|
) => {
|
||||||
|
const group = findGroupChildrenByChildId("privacy", children);
|
||||||
|
|
||||||
|
group?.push(
|
||||||
|
<Menu.MenuItem
|
||||||
|
id="vc-hide-server"
|
||||||
|
label="Hide Server"
|
||||||
|
action={() => HiddenServersStore.addHidden(guild)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export function addIndicator() {
|
||||||
|
addServerListElement(ServerListRenderPosition.Below, hiddenServersButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeIndicator() {
|
||||||
|
removeServerListElement(ServerListRenderPosition.Below, hiddenServersButton);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default definePlugin({
|
||||||
|
name: "HideServers",
|
||||||
|
description: "Allows you to hide servers from the guild list and quick switcher by right clicking them",
|
||||||
|
authors: [EquicordDevs.bep],
|
||||||
|
tags: ["guild", "server", "hide"],
|
||||||
|
|
||||||
|
dependencies: ["ServerListAPI"],
|
||||||
|
contextMenus: {
|
||||||
|
"guild-context": Patch,
|
||||||
|
"guild-header-popout": Patch,
|
||||||
|
},
|
||||||
|
patches: [
|
||||||
|
{
|
||||||
|
find: '("guildsnav")',
|
||||||
|
replacement: [
|
||||||
|
{
|
||||||
|
match: /(?<=#{intl::SERVERS}\),gap:"xs",children:.{0,100}?)(\i)(\.map\(.{5,30}\}\))/,
|
||||||
|
replace: "$self.useFilteredGuilds($1)$2"
|
||||||
|
},
|
||||||
|
// despite my best efforts, the above doesnt trigger a rerender
|
||||||
|
{
|
||||||
|
match: /let{disableAppDownload.{0,10}isPlatformEmbedded/,
|
||||||
|
replace: "$self.useStore();$&",
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
find: "#{intl::QUICKSWITCHER_PROTIP}",
|
||||||
|
replacement: {
|
||||||
|
match: /(?<=renderResults\(\){)let{query/,
|
||||||
|
replace: "this.props.results = $self.filteredGuildResults(this.props.results);$&",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
settings,
|
||||||
|
useStore: () => { useStateFromStores([HiddenServersStore], () => HiddenServersStore.hiddenGuilds, undefined, (old, newer) => old.size === newer.size); },
|
||||||
|
|
||||||
|
async start() {
|
||||||
|
if (settings.store.showIndicator) {
|
||||||
|
addIndicator();
|
||||||
|
}
|
||||||
|
await HiddenServersStore.load();
|
||||||
|
},
|
||||||
|
|
||||||
|
async stop() {
|
||||||
|
removeIndicator();
|
||||||
|
HiddenServersStore.unload();
|
||||||
|
},
|
||||||
|
|
||||||
|
useFilteredGuilds(guilds: guildsNode[]): guildsNode[] {
|
||||||
|
const hiddenGuilds = useStateFromStores([HiddenServersStore], () => HiddenServersStore.hiddenGuilds, undefined, (old, newer) => old.size === newer.size);
|
||||||
|
return guilds.flatMap(guild => {
|
||||||
|
if (!(hiddenGuilds instanceof Set)) return [guild];
|
||||||
|
if (hiddenGuilds.has(guild.id.toString())) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
const newGuild = Object.assign({}, guild);
|
||||||
|
newGuild.children = guild.children.filter(
|
||||||
|
child => !hiddenGuilds.has(child.id.toString())
|
||||||
|
);
|
||||||
|
|
||||||
|
return [newGuild];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
filteredGuildResults(results: qsResult[]): qsResult[] {
|
||||||
|
// not used in a component so no useStateFromStore
|
||||||
|
const { hiddenGuilds } = HiddenServersStore;
|
||||||
|
return results.filter(result => {
|
||||||
|
if (result?.record?.guild_id && hiddenGuilds.has(result.record.guild_id)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (result.type === "GUILD" && hiddenGuilds.has(result.record!.id!)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
51
src/equicordplugins/hideServers/settings.tsx
Normal file
51
src/equicordplugins/hideServers/settings.tsx
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Vencord, a Discord client mod
|
||||||
|
* Copyright (c) 2024 Vendicated and contributors
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { definePluginSettings } from "@api/Settings";
|
||||||
|
import { OptionType } from "@utils/types";
|
||||||
|
import { Button, useStateFromStores } from "@webpack/common";
|
||||||
|
|
||||||
|
import { addIndicator, removeIndicator } from ".";
|
||||||
|
import { HiddenServersMenu } from "./components/HiddenServersMenu";
|
||||||
|
import { HiddenServersStore } from "./HiddenServersStore";
|
||||||
|
|
||||||
|
export default definePluginSettings({
|
||||||
|
showIndicator: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
description: "Show menu to unhide servers at the bottom of the list",
|
||||||
|
default: true,
|
||||||
|
onChange: val => {
|
||||||
|
if (val) {
|
||||||
|
addIndicator();
|
||||||
|
} else {
|
||||||
|
removeIndicator();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
guildsList: {
|
||||||
|
type: OptionType.COMPONENT,
|
||||||
|
description: "Remove hidden servers",
|
||||||
|
component: () => {
|
||||||
|
const detail = useStateFromStores([HiddenServersStore], () => HiddenServersStore.hiddenGuildsDetail());
|
||||||
|
return <HiddenServersMenu servers={detail} />;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
resetHidden: {
|
||||||
|
type: OptionType.COMPONENT,
|
||||||
|
description: "Remove all hidden guilds from the list",
|
||||||
|
component: () => (
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
size={Button.Sizes.SMALL}
|
||||||
|
color={Button.Colors.RED}
|
||||||
|
onClick={() => HiddenServersStore.clearHidden()}
|
||||||
|
>
|
||||||
|
Reset Hidden Servers
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
},
|
||||||
|
});
|
|
@ -32,11 +32,15 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "#{intl::SERVERS}),children",
|
find: "#{intl::SERVERS}),gap:\"xs\",children:",
|
||||||
replacement: [
|
replacement: [
|
||||||
{
|
{
|
||||||
match: /(?<=#{intl::SERVERS}\),children:)\i\.map\(\i\)/,
|
match: /(?<=#{intl::SERVERS}\),gap:"xs",children:)(\i\.map\(.{10,50}?)(}\))/,
|
||||||
replace: "Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.In).concat($&)"
|
replace: "Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.In).concat($1)$2"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
match: /children:.{0,2000}?\{\}\)\]/,
|
||||||
|
replace: "$&.concat(Vencord.Api.ServerList.renderAll(Vencord.Api.ServerList.ServerListRenderPosition.Below))"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue