mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-17 18:37:04 -04:00
Update
This commit is contained in:
parent
992523682d
commit
ee8a5a977e
5 changed files with 81 additions and 36 deletions
|
@ -8,7 +8,7 @@ import { CodeBlock } from "@components/CodeBlock";
|
||||||
import { Heart } from "@components/Heart";
|
import { Heart } from "@components/Heart";
|
||||||
import { openInviteModal } from "@utils/discord";
|
import { openInviteModal } from "@utils/discord";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
import { ModalContent, ModalFooter, ModalHeader, ModalRoot, openModal } from "@utils/modal";
|
import { ModalContent, ModalFooter, ModalHeader, ModalRoot, ModalSize, openModal } from "@utils/modal";
|
||||||
import { findComponentByCodeLazy } from "@webpack";
|
import { findComponentByCodeLazy } from "@webpack";
|
||||||
import { Button, Clipboard, Forms, React, showToast, Toasts } from "@webpack/common";
|
import { Button, Clipboard, Forms, React, showToast, Toasts } from "@webpack/common";
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ export const ThemeInfoModal: React.FC<ThemeInfoModalProps> = ({ author, theme, .
|
||||||
<Forms.FormTitle tag="h5" style={{ marginTop: "10px" }}>Source</Forms.FormTitle>
|
<Forms.FormTitle tag="h5" style={{ marginTop: "10px" }}>Source</Forms.FormTitle>
|
||||||
<Forms.FormText>
|
<Forms.FormText>
|
||||||
<Button onClick={() => openModal(modalProps => (
|
<Button onClick={() => openModal(modalProps => (
|
||||||
<ModalRoot {...modalProps}>
|
<ModalRoot {...modalProps} size={ModalSize.LARGE}>
|
||||||
<ModalHeader>
|
<ModalHeader>
|
||||||
<Forms.FormTitle tag="h4">Theme Source</Forms.FormTitle>
|
<Forms.FormTitle tag="h4">Theme Source</Forms.FormTitle>
|
||||||
</ModalHeader>
|
</ModalHeader>
|
||||||
|
|
|
@ -4,17 +4,14 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/* eslint-disable indent */
|
||||||
* Vencord, a Discord client mod
|
|
||||||
* Copyright (c) 2024 Vendicated and contributors
|
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
*/
|
|
||||||
|
|
||||||
import "./styles.css";
|
import "./styles.css";
|
||||||
|
|
||||||
import { generateId } from "@api/Commands";
|
import { generateId } from "@api/Commands";
|
||||||
|
import { Settings } from "@api/Settings";
|
||||||
import { classNameFactory } from "@api/Styles";
|
import { classNameFactory } from "@api/Styles";
|
||||||
import { CodeBlock } from "@components/CodeBlock";
|
import { CodeBlock } from "@components/CodeBlock";
|
||||||
|
import { OpenExternalIcon } from "@components/Icons";
|
||||||
import { SettingsTab, wrapTab } from "@components/VencordSettings/shared";
|
import { SettingsTab, wrapTab } from "@components/VencordSettings/shared";
|
||||||
import { proxyLazy } from "@utils/lazy";
|
import { proxyLazy } from "@utils/lazy";
|
||||||
import { Margins } from "@utils/margins";
|
import { Margins } from "@utils/margins";
|
||||||
|
@ -35,6 +32,32 @@ const TextAreaProps = findLazy(m => typeof m.textarea === "string");
|
||||||
|
|
||||||
const API_URL = "https://themes-delta.vercel.app/api";
|
const API_URL = "https://themes-delta.vercel.app/api";
|
||||||
|
|
||||||
|
async function fetchThemes(url: string): Promise<Theme[]> {
|
||||||
|
const response = await fetch(url);
|
||||||
|
const data = await response.json();
|
||||||
|
const themes: Theme[] = Object.values(data);
|
||||||
|
themes.forEach(theme => {
|
||||||
|
if (!theme.source) {
|
||||||
|
theme.source = `${API_URL}/${theme.name}`;
|
||||||
|
} else {
|
||||||
|
theme.source = theme.source.replace("?raw=true", "") + "?raw=true";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return themes.sort((a, b) => new Date(b.release_date).getTime() - new Date(a.release_date).getTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
function API_TYPE(theme, returnAll?: boolean) {
|
||||||
|
if (!theme) return;
|
||||||
|
const settings = Settings.plugins.ThemeLibrary.domain ?? false;
|
||||||
|
|
||||||
|
if (returnAll) {
|
||||||
|
const url = settings ? "https://raw.githubusercontent.com/Faf4a/plugins/main/assets/meta.json" : `${API_URL}/themes`;
|
||||||
|
return fetchThemes(url);
|
||||||
|
} else {
|
||||||
|
return settings ? theme.source : `${API_URL}/${theme.name}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function themeRequest(path: string, options: RequestInit = {}) {
|
async function themeRequest(path: string, options: RequestInit = {}) {
|
||||||
return fetch(API_URL + path, {
|
return fetch(API_URL + path, {
|
||||||
...options,
|
...options,
|
||||||
|
@ -84,7 +107,7 @@ function ThemeTab() {
|
||||||
const onStatusChange = (status: SearchStatus) => setSearchValue(prev => ({ ...prev, status }));
|
const onStatusChange = (status: SearchStatus) => setSearchValue(prev => ({ ...prev, status }));
|
||||||
|
|
||||||
const themeFilter = (theme: Theme) => {
|
const themeFilter = (theme: Theme) => {
|
||||||
const enabled = themeLinks.includes("https://themes-delta.vercel.app/api/" + theme.name);
|
const enabled = themeLinks.includes(API_TYPE(theme));
|
||||||
if (enabled && searchValue.status === SearchStatus.DISABLED) return false;
|
if (enabled && searchValue.status === SearchStatus.DISABLED) return false;
|
||||||
if (!theme.tags.includes("theme") && searchValue.status === SearchStatus.THEME) return false;
|
if (!theme.tags.includes("theme") && searchValue.status === SearchStatus.THEME) return false;
|
||||||
if (!theme.tags.includes("snippet") && searchValue.status === SearchStatus.SNIPPET) return false;
|
if (!theme.tags.includes("snippet") && searchValue.status === SearchStatus.SNIPPET) return false;
|
||||||
|
@ -103,15 +126,13 @@ function ThemeTab() {
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
themeRequest("/themes", {
|
Promise.resolve(API_TYPE({}, true)).then(themes => {
|
||||||
method: "GET",
|
|
||||||
}).then(async (response: Response) => {
|
|
||||||
const data = await response.json();
|
|
||||||
const themes: Theme[] = Object.values(data);
|
|
||||||
themes.sort((a, b) => new Date(b.release_date).getTime() - new Date(a.release_date).getTime());
|
|
||||||
setThemes(themes);
|
setThemes(themes);
|
||||||
setFilteredThemes(themes);
|
setFilteredThemes(themes);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
}).catch(err => {
|
||||||
|
console.error("Failed to load 'ThemeLibrary'", err);
|
||||||
|
setLoading(true);
|
||||||
});
|
});
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
@ -119,6 +140,7 @@ function ThemeTab() {
|
||||||
setThemeLinks(Vencord.Settings.themeLinks);
|
setThemeLinks(Vencord.Settings.themeLinks);
|
||||||
}, [Vencord.Settings.themeLinks]);
|
}, [Vencord.Settings.themeLinks]);
|
||||||
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const filteredThemes = themes.filter(themeFilter);
|
const filteredThemes = themes.filter(themeFilter);
|
||||||
setFilteredThemes(filteredThemes);
|
setFilteredThemes(filteredThemes);
|
||||||
|
@ -161,7 +183,7 @@ function ThemeTab() {
|
||||||
overflowWrap: "break-word",
|
overflowWrap: "break-word",
|
||||||
marginTop: 8,
|
marginTop: 8,
|
||||||
}}
|
}}
|
||||||
className="vce-theme-text">
|
className="vce-theme-text">
|
||||||
{theme.name}
|
{theme.name}
|
||||||
</Forms.FormTitle>
|
</Forms.FormTitle>
|
||||||
<Forms.FormText className="vce-theme-text">
|
<Forms.FormText className="vce-theme-text">
|
||||||
|
@ -182,10 +204,10 @@ function ThemeTab() {
|
||||||
</Forms.FormText>
|
</Forms.FormText>
|
||||||
)}
|
)}
|
||||||
<div style={{ marginTop: "8px", display: "flex", flexDirection: "row" }}>
|
<div style={{ marginTop: "8px", display: "flex", flexDirection: "row" }}>
|
||||||
{themeLinks.includes("https://themes-delta.vercel.app/api/" + theme.name) ? (
|
{themeLinks.includes(API_TYPE(theme)) ? (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const onlineThemeLinks = themeLinks.filter(x => x !== "https://themes-delta.vercel.app/api/" + theme.name);
|
const onlineThemeLinks = themeLinks.filter(x => x !== API_TYPE(theme));
|
||||||
setThemeLinks(onlineThemeLinks);
|
setThemeLinks(onlineThemeLinks);
|
||||||
Vencord.Settings.themeLinks = onlineThemeLinks;
|
Vencord.Settings.themeLinks = onlineThemeLinks;
|
||||||
}}
|
}}
|
||||||
|
@ -199,7 +221,7 @@ function ThemeTab() {
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const onlineThemeLinks = [...themeLinks, `https://themes-delta.vercel.app/api/${theme.name}`];
|
const onlineThemeLinks = [...themeLinks, API_TYPE(theme)];
|
||||||
setThemeLinks(onlineThemeLinks);
|
setThemeLinks(onlineThemeLinks);
|
||||||
Vencord.Settings.themeLinks = onlineThemeLinks;
|
Vencord.Settings.themeLinks = onlineThemeLinks;
|
||||||
}}
|
}}
|
||||||
|
@ -223,12 +245,13 @@ function ThemeTab() {
|
||||||
Theme Info
|
Theme Info
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => VencordNative.native.openExternal(`https://themes-delta.vercel.app/api/${theme.name}`)}
|
onClick={() => VencordNative.native.openExternal(API_TYPE(theme).replace("?raw=true", ""))}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
color={Button.Colors.LINK}
|
color={Button.Colors.LINK}
|
||||||
look={Button.Looks.LINK}
|
look={Button.Looks.LINK}
|
||||||
|
style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
|
||||||
>
|
>
|
||||||
View Source
|
View Source <OpenExternalIcon height={16} width={16} />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -276,7 +299,7 @@ function ThemeTab() {
|
||||||
overflowWrap: "break-word",
|
overflowWrap: "break-word",
|
||||||
marginTop: 8,
|
marginTop: 8,
|
||||||
}}
|
}}
|
||||||
className="vce-theme-text">
|
className="vce-theme-text">
|
||||||
{theme.name}
|
{theme.name}
|
||||||
</Forms.FormTitle>
|
</Forms.FormTitle>
|
||||||
<Forms.FormText className="vce-theme-text">
|
<Forms.FormText className="vce-theme-text">
|
||||||
|
@ -285,7 +308,8 @@ function ThemeTab() {
|
||||||
<img
|
<img
|
||||||
role="presentation"
|
role="presentation"
|
||||||
src={theme.thumbnail_url}
|
src={theme.thumbnail_url}
|
||||||
alt="Theme Preview Image"
|
loading="lazy"
|
||||||
|
alt={theme.name}
|
||||||
className="vce-theme-info-preview"
|
className="vce-theme-info-preview"
|
||||||
/>
|
/>
|
||||||
<div className="vce-theme-info">
|
<div className="vce-theme-info">
|
||||||
|
@ -303,10 +327,10 @@ function ThemeTab() {
|
||||||
</Forms.FormText>
|
</Forms.FormText>
|
||||||
)}
|
)}
|
||||||
<div style={{ marginTop: "8px", display: "flex", flexDirection: "row" }}>
|
<div style={{ marginTop: "8px", display: "flex", flexDirection: "row" }}>
|
||||||
{themeLinks.includes("https://themes-delta.vercel.app/api/" + theme.name) ? (
|
{themeLinks.includes(API_TYPE(theme)) ? (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const onlineThemeLinks = themeLinks.filter(x => x !== "https://themes-delta.vercel.app/api/" + theme.name);
|
const onlineThemeLinks = themeLinks.filter(x => x !== API_TYPE(theme));
|
||||||
setThemeLinks(onlineThemeLinks);
|
setThemeLinks(onlineThemeLinks);
|
||||||
Vencord.Settings.themeLinks = onlineThemeLinks;
|
Vencord.Settings.themeLinks = onlineThemeLinks;
|
||||||
}}
|
}}
|
||||||
|
@ -320,7 +344,7 @@ function ThemeTab() {
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const onlineThemeLinks = [...themeLinks, `https://themes-delta.vercel.app/api/${theme.name}`];
|
const onlineThemeLinks = [...themeLinks, API_TYPE(theme)];
|
||||||
setThemeLinks(onlineThemeLinks);
|
setThemeLinks(onlineThemeLinks);
|
||||||
Vencord.Settings.themeLinks = onlineThemeLinks;
|
Vencord.Settings.themeLinks = onlineThemeLinks;
|
||||||
}}
|
}}
|
||||||
|
@ -344,12 +368,13 @@ function ThemeTab() {
|
||||||
Theme Info
|
Theme Info
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
onClick={() => VencordNative.native.openExternal(`https://themes-delta.vercel.app/api/${theme.name}`)}
|
onClick={() => VencordNative.native.openExternal(API_TYPE(theme).replace("?raw=true", ""))}
|
||||||
size={Button.Sizes.MEDIUM}
|
size={Button.Sizes.MEDIUM}
|
||||||
color={Button.Colors.LINK}
|
color={Button.Colors.LINK}
|
||||||
look={Button.Looks.LINK}
|
look={Button.Looks.LINK}
|
||||||
|
style={{ display: "flex", alignItems: "center", justifyContent: "center" }}
|
||||||
>
|
>
|
||||||
View Source
|
View Source <OpenExternalIcon height={16} width={16} />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* stylelint-disable property-no-vendor-prefix */
|
|
||||||
[data-tab-id="ThemeLibrary"]::before {
|
[data-tab-id="ThemeLibrary"]::before {
|
||||||
|
/* stylelint-disable-next-line property-no-vendor-prefix */
|
||||||
-webkit-mask: var(--si-widget) center/contain no-repeat !important;
|
-webkit-mask: var(--si-widget) center/contain no-repeat !important;
|
||||||
mask: var(--si-widget) center/contain no-repeat !important;
|
mask: var(--si-widget) center/contain no-repeat !important;
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.vce-theme-info-preview img {
|
.vce-theme-info-preview img {
|
||||||
width: 1080px;
|
width: 1080px !important;
|
||||||
height: 1920px;
|
height: 1920px !important;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,32 @@
|
||||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { EquicordDevs } from "@utils/constants";
|
import { definePluginSettings } from "@api/Settings";
|
||||||
import definePlugin from "@utils/types";
|
import definePlugin, { OptionType } from "@utils/types";
|
||||||
|
import { SettingsRouter } from "@webpack/common";
|
||||||
|
|
||||||
|
const settings = definePluginSettings({
|
||||||
|
domain: {
|
||||||
|
type: OptionType.BOOLEAN,
|
||||||
|
default: false,
|
||||||
|
description: "Use Github instead of the default domain for themes",
|
||||||
|
restartNeeded: false
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
export default definePlugin({
|
export default definePlugin({
|
||||||
name: "Theme Library",
|
name: "ThemeLibrary",
|
||||||
description: "A library of themes for Vencord.",
|
description: "A library of themes for Vencord.",
|
||||||
authors: [EquicordDevs.Fafa],
|
authors: [{
|
||||||
|
name: "Fafa",
|
||||||
|
id: 428188716641812481n,
|
||||||
|
}],
|
||||||
|
settings,
|
||||||
|
toolboxActions: {
|
||||||
|
"Open Theme Library": () => {
|
||||||
|
SettingsRouter.open("ThemeLibrary");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
const customSettingsSections = (
|
const customSettingsSections = (
|
||||||
|
@ -35,5 +54,5 @@ export default definePlugin({
|
||||||
const i = customSettingsSections.findIndex(section => section({}).id === "ThemeSection");
|
const i = customSettingsSections.findIndex(section => section({}).id === "ThemeSection");
|
||||||
|
|
||||||
if (i !== -1) customSettingsSections.splice(i, 1);
|
if (i !== -1) customSettingsSections.splice(i, 1);
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -33,6 +33,7 @@ export interface Theme {
|
||||||
invite_link: string;
|
invite_link: string;
|
||||||
avatar_hash: string;
|
avatar_hash: string;
|
||||||
};
|
};
|
||||||
|
source?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ThemeInfoModalProps extends ModalProps {
|
export interface ThemeInfoModalProps extends ModalProps {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue