Merge branch 'main' of https://github.com/OTKUSteyler/GoonCord
This commit is contained in:
commit
27dc770a14
8 changed files with 546 additions and 1745 deletions
45
package.json
45
package.json
|
|
@ -13,45 +13,40 @@
|
||||||
},
|
},
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@saithodev/semantic-release-backmerge": "^4.0.1",
|
"@swc/core": "^1.15.47",
|
||||||
"@semantic-release/changelog": "^6.0.3",
|
"@swc/helpers": "^0.5.23",
|
||||||
"@semantic-release/exec": "^7.1.0",
|
"@types/node": "^26.1.2",
|
||||||
"@semantic-release/git": "^10.0.1",
|
|
||||||
"semantic-release": "^25.0.3",
|
|
||||||
"@swc/core": "^1.15.24",
|
|
||||||
"@swc/helpers": "^0.5.21",
|
|
||||||
"@types/node": "^25.5.2",
|
|
||||||
"@types/yargs-parser": "^21.0.3",
|
"@types/yargs-parser": "^21.0.3",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.58.0",
|
"@typescript-eslint/eslint-plugin": "^8.65.0",
|
||||||
"@typescript-eslint/parser": "^8.58.0",
|
"@typescript-eslint/parser": "^8.65.0",
|
||||||
"@typescript-eslint/typescript-estree": "^8.58.0",
|
"@typescript-eslint/typescript-estree": "^8.65.0",
|
||||||
"chalk": "^5.6.2",
|
"chalk": "^6.0.0",
|
||||||
"esbuild": "^0.28.0",
|
"esbuild": "^0.28.1",
|
||||||
"esbuild-plugin-globals": "^0.2.0",
|
"esbuild-plugin-globals": "^0.2.0",
|
||||||
"eslint": "^10.2.0",
|
"eslint": "^10.8.0",
|
||||||
"eslint-plugin-import-alias": "^1.2.0",
|
"eslint-plugin-import-alias": "^1.2.0",
|
||||||
"eslint-plugin-react": "^7.37.5",
|
"eslint-plugin-react": "^7.37.5",
|
||||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
"eslint-plugin-simple-import-sort": "^14.0.0",
|
||||||
"eslint-plugin-unused-imports": "^4.4.1",
|
"eslint-plugin-unused-imports": "^4.4.1",
|
||||||
"typescript": "^6.0.2",
|
"typescript": "^7.0.2",
|
||||||
"yargs-parser": "^22.0.0"
|
"yargs-parser": "^22.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@gullerya/object-observer": "^6.1.4",
|
"@gullerya/object-observer": "^7.0.0",
|
||||||
"@tanstack/react-query": "^5.96.2",
|
"@tanstack/react-query": "^5.101.4",
|
||||||
"@types/chroma-js": "~3.1.2",
|
"@types/chroma-js": "~3.1.2",
|
||||||
"@types/lodash": "~4.17.24",
|
"@types/lodash": "~4.17.24",
|
||||||
"@types/react": "19.2.14",
|
"@types/react": "19.2.17",
|
||||||
"es-toolkit": "^1.45.1",
|
"es-toolkit": "^1.50.0",
|
||||||
"fuzzysort": "^3.1.0",
|
"fuzzysort": "^3.1.0",
|
||||||
"intl-messageformat": "^11.2.0",
|
"intl-messageformat": "^11.2.12",
|
||||||
"moment": "2.30.1",
|
"moment": "2.30.1",
|
||||||
"react-devtools": "^7.0.1",
|
"react-devtools": "^7.0.1",
|
||||||
"react-native": "0.84.1",
|
"react-native": "0.86.2",
|
||||||
"react-native-reanimated": "^4.3.0",
|
"react-native-reanimated": "^4.5.3",
|
||||||
"react-native-webview": "^13.16.1",
|
"react-native-webview": "^14.0.1",
|
||||||
"spitroast": "^2.1.6",
|
"spitroast": "^2.1.6",
|
||||||
"type-fest": "^5.5.0"
|
"type-fest": "^5.8.0"
|
||||||
},
|
},
|
||||||
"trustedDependencies": [
|
"trustedDependencies": [
|
||||||
"@swc/core",
|
"@swc/core",
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ const config = {
|
||||||
"!ShiggyCord-deps-shim!": "./shims/depsModule.ts",
|
"!ShiggyCord-deps-shim!": "./shims/depsModule.ts",
|
||||||
spitroast: "./node_modules/spitroast",
|
spitroast: "./node_modules/spitroast",
|
||||||
"react/jsx-runtime": "./shims/jsxRuntime",
|
"react/jsx-runtime": "./shims/jsxRuntime",
|
||||||
|
"@gullerya/object-observer":
|
||||||
|
path.resolve("./node_modules/@gullerya/object-observer/dist/object-observer.min.js"),
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
globalPlugin({
|
globalPlugin({
|
||||||
|
|
@ -75,7 +77,7 @@ const config = {
|
||||||
constModules: {
|
constModules: {
|
||||||
globals: {
|
globals: {
|
||||||
"bunny-build-info": {
|
"bunny-build-info": {
|
||||||
version: `"1.4.1.4"`,
|
version: `"1.4.1.6"`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -23,52 +23,54 @@ const { showSimpleActionSheet } = lazyDestructure(() =>
|
||||||
|
|
||||||
// TODO: These styles work weirdly. Low DPI Has cramped text. Fix?
|
// TODO: These styles work weirdly. Low DPI Has cramped text. Fix?
|
||||||
const useStyles = createStyles({
|
const useStyles = createStyles({
|
||||||
card: {
|
card: {
|
||||||
backgroundColor: semanticColors?.CARD_SECONDARY_BG,
|
backgroundColor: semanticColors?.CARD_SECONDARY_BG,
|
||||||
borderRadius: 12,
|
borderRadius: 12,
|
||||||
overflow: "hidden",
|
overflow: "hidden"
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
padding: 0,
|
padding: 0,
|
||||||
},
|
},
|
||||||
headerLeading: {
|
headerLeading: {
|
||||||
flexDirection: "column",
|
flex: 1,
|
||||||
justifyContent: "center",
|
flexDirection: "column",
|
||||||
flexShrink: 1,
|
justifyContent: "center",
|
||||||
scale: 1.2,
|
scale: 1.2
|
||||||
},
|
},
|
||||||
headerTrailing: {
|
headerTrailing: {
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "row",
|
flexDirection: "row",
|
||||||
gap: 15,
|
gap: 15,
|
||||||
alignItems: "center",
|
alignItems: "center"
|
||||||
},
|
},
|
||||||
headerLabel: {
|
headerLabel: {
|
||||||
...TextStyleSheet["heading-md/semibold"],
|
...TextStyleSheet["heading-lg/semibold"],
|
||||||
color: semanticColors.MOBILE_TEXT_HEADING_PRIMARY,
|
},
|
||||||
},
|
headerLabelCompact: {
|
||||||
headerSubtitle: {
|
...TextStyleSheet["text-md/semibold"],
|
||||||
...TextStyleSheet["text-md/semibold"],
|
},
|
||||||
color: semanticColors.TEXT_MUTED,
|
headerSubtitle: {
|
||||||
},
|
...TextStyleSheet["text-sm/semibold"],
|
||||||
descriptionLabel: {
|
color: semanticColors.TEXT_MUTED,
|
||||||
...TextStyleSheet["text-md/semibold"],
|
},
|
||||||
color: semanticColors.TEXT_NORMAL,
|
descriptionLabel: {
|
||||||
},
|
...TextStyleSheet["text-md/semibold"],
|
||||||
actions: {
|
color: "text-strong",
|
||||||
flexDirection: "row-reverse",
|
},
|
||||||
alignItems: "center",
|
actions: {
|
||||||
gap: 5,
|
flexDirection: "row-reverse",
|
||||||
},
|
alignItems: "center",
|
||||||
iconStyle: {
|
gap: 5
|
||||||
tintColor: semanticColors.INTERACTIVE_ICON_DEFAULT,
|
},
|
||||||
opacity: 0.2,
|
iconStyle: {
|
||||||
height: 64,
|
tintColor: semanticColors.LOGO_PRIMARY,
|
||||||
width: 64,
|
opacity: 0.2,
|
||||||
left: void 0,
|
height: 64,
|
||||||
right: "30%",
|
width: 64,
|
||||||
top: "-10%",
|
left: void 0,
|
||||||
},
|
right: "30%",
|
||||||
|
top: "-10%"
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
interface Action {
|
interface Action {
|
||||||
|
|
|
||||||
56
src/index.ts
56
src/index.ts
|
|
@ -11,13 +11,8 @@ import { injectFluxInterceptor } from "@lib/api/flux";
|
||||||
import { patchJsx } from "@lib/api/react/jsx";
|
import { patchJsx } from "@lib/api/react/jsx";
|
||||||
import { logger } from "@lib/utils/logger";
|
import { logger } from "@lib/utils/logger";
|
||||||
import { patchSettings } from "@ui/settings";
|
import { patchSettings } from "@ui/settings";
|
||||||
import { updaterSettings } from "@lib/api/settings";
|
|
||||||
import { InteractionManager } from "react-native";
|
import { InteractionManager } from "react-native";
|
||||||
import { getDebugInfo, initDebugger } from "@lib/api/debug";
|
import { getDebugInfo, initDebugger } from "@lib/api/debug";
|
||||||
|
|
||||||
// Debug toggle helper (temporary runtime fallback). The helper is dynamically
|
|
||||||
// imported when needed (to avoid bundling it permanently) and removed after use.
|
|
||||||
|
|
||||||
import * as lib from "./lib";
|
import * as lib from "./lib";
|
||||||
import { timings } from "@lib/utils/timings";
|
import { timings } from "@lib/utils/timings";
|
||||||
|
|
||||||
|
|
@ -66,52 +61,19 @@ export default async () => {
|
||||||
const { VdPluginManager } = await import("@core/vendetta/plugins");
|
const { VdPluginManager } = await import("@core/vendetta/plugins");
|
||||||
const { initPlugins, updatePlugins } = await import("@lib/addons/plugins");
|
const { initPlugins, updatePlugins } = await import("@lib/addons/plugins");
|
||||||
|
|
||||||
// Initialize Vendetta plugins (may start many plugins) — do not block UI.
|
await Promise.all([
|
||||||
VdPluginManager.initPlugins()
|
VdPluginManager.initPlugins()
|
||||||
.then((u) => lib.unload.push(u))
|
.then((u) => u && lib.unload.push(u))
|
||||||
.catch((e) => logger.log("Vendetta init failed:", e));
|
.catch((e) => logger.log("Vendetta init failed:", e)),
|
||||||
|
initPlugins()
|
||||||
|
.catch((e) => logger.log("initPlugins failed:", e)),
|
||||||
|
]);
|
||||||
|
|
||||||
// Start ShiggyCord (Bunny) plugins now without forcing repository updates.
|
updatePlugins()
|
||||||
// Plugin repository fetching is deferred so the app can finish launching first.
|
.catch((e) => logger.log("updatePlugins failed:", e));
|
||||||
// Stagger plugin startup to reduce CPU/memory spikes: use smaller batches and a small interval.
|
|
||||||
// This keeps the UI responsive while plugins initialize in the background.
|
|
||||||
initPlugins({ staggerInterval: 500, batchSize: 2 });
|
|
||||||
|
|
||||||
// Attempt a lightweight recovery toggle if some core plugins failed to start.
|
|
||||||
try {
|
|
||||||
// Dynamically import the helper (if present) but suppress verbose errors.
|
|
||||||
const mod = await import("@core/debug/toggleCorePlugins").catch(
|
|
||||||
() => null,
|
|
||||||
);
|
|
||||||
if (mod?.default) {
|
|
||||||
// Run helper with minimal noise; ignore failures.
|
|
||||||
mod.default({ offDuration: 1500 }).catch(() => {});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to remove the helper source file (best-effort, ignore failures).
|
|
||||||
await import("@lib/api/native/fs")
|
|
||||||
.then((fs) => fs.removeFile("src/core/debug/toggleCorePlugins.ts"))
|
|
||||||
.catch(() => {});
|
|
||||||
} catch {
|
|
||||||
// suppressed
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update fonts in background
|
// Update fonts in background
|
||||||
updateFonts().catch((e) => logger.log("updateFonts failed:", e));
|
updateFonts().catch((e) => logger.log("updateFonts failed:", e));
|
||||||
|
|
||||||
// Schedule plugin repository update after a delay (5 minutes) so update work
|
|
||||||
// does not impact initial launch performance.
|
|
||||||
setTimeout(
|
|
||||||
() => {
|
|
||||||
updatePlugins().catch((e) =>
|
|
||||||
logger.log("updatePlugins failed (deferred 5min):", e),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
5 * 60 * 1000,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Note: we intentionally moved the call to `updatePlugins()` above so core
|
|
||||||
// plugins are registered prior to calling `initPlugins()`.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Preferred: wait until interactions finish (animations / navigation).
|
// Preferred: wait until interactions finish (animations / navigation).
|
||||||
|
|
|
||||||
|
|
@ -752,27 +752,54 @@ export async function updatePlugins() {
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const enabledIds = [...registeredPlugins.keys()].filter(
|
||||||
|
(id) => isPluginEnabled(id) && !pluginInstances.has(id),
|
||||||
|
);
|
||||||
|
await Promise.allSettled(
|
||||||
|
enabledIds.map(async (id) => {
|
||||||
|
try {
|
||||||
|
await startPlugin(id).catch((e) => {
|
||||||
|
console.error(`Failed to start plugin ${id}:`, e);
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.error(`Unexpected error while starting plugin ${id}:`, error);
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize plugins but stagger startup to avoid CPU spikes during app start.
|
* Register all installed plugins from local storage manifests without any
|
||||||
|
* network fetch. This lets initPlugins() start plugins immediately using
|
||||||
|
* previously-cached scripts, keeping startup snappy.
|
||||||
*
|
*
|
||||||
* This replaces the original "start all enabled plugins in parallel" approach
|
* Safe to call multiple times — skips already-registered plugins.
|
||||||
* with a configurable staggered startup: plugins are started in small batches and
|
|
||||||
* we await a small interval between batches. This reduces short-lived CPU and I/O contention
|
|
||||||
* that causes jank on low-end devices.
|
|
||||||
*
|
|
||||||
* Backwards-compatible: callers can still call initPlugins() with no arguments.
|
|
||||||
*
|
|
||||||
* Options:
|
|
||||||
* - staggerInterval (ms) - wait time between batches (default: 100)
|
|
||||||
* - batchSize - how many plugins to start concurrently in a single batch (default: 3)
|
|
||||||
*/
|
*/
|
||||||
export async function initPlugins(
|
export async function registerInstalledPlugins() {
|
||||||
options: { staggerInterval?: number; batchSize?: number } = {},
|
await awaitStorage(pluginRepositories, pluginSettings);
|
||||||
) {
|
|
||||||
const { staggerInterval = 100, batchSize = 3 } = options;
|
|
||||||
|
|
||||||
|
const ids = Object.keys(pluginSettings ?? {});
|
||||||
|
if (ids.length === 0) return;
|
||||||
|
|
||||||
|
// Load all manifest files from local storage in parallel.
|
||||||
|
const results = await Promise.allSettled(
|
||||||
|
ids.map(async (id) => {
|
||||||
|
if (registeredPlugins.has(id) || isCorePlugin(id)) return;
|
||||||
|
const loaded = await preloadStorageIfExists(`plugins/manifests/${id}.json`);
|
||||||
|
if (loaded) {
|
||||||
|
const manifest = getPreloadedStorage<t.BunnyPluginManifest>(
|
||||||
|
`plugins/manifests/${id}.json`,
|
||||||
|
);
|
||||||
|
if (manifest) {
|
||||||
|
registeredPlugins.set(id, manifest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function initPlugins() {
|
||||||
// Ensure core plugins are registered prior to any plugin startup logic so
|
// Ensure core plugins are registered prior to any plugin startup logic so
|
||||||
// settings pages and UI that read registered/core plugins show them.
|
// settings pages and UI that read registered/core plugins show them.
|
||||||
// registerCorePlugins is synchronous and idempotent, but call it here as a
|
// registerCorePlugins is synchronous and idempotent, but call it here as a
|
||||||
|
|
@ -784,6 +811,7 @@ export async function initPlugins(
|
||||||
}
|
}
|
||||||
|
|
||||||
await awaitStorage(pluginRepositories, pluginSettings);
|
await awaitStorage(pluginRepositories, pluginSettings);
|
||||||
|
await registerInstalledPlugins();
|
||||||
|
|
||||||
// Collect enabled plugin ids
|
// Collect enabled plugin ids
|
||||||
const enabledIds = [...registeredPlugins.keys()].filter((id) =>
|
const enabledIds = [...registeredPlugins.keys()].filter((id) =>
|
||||||
|
|
@ -792,32 +820,18 @@ export async function initPlugins(
|
||||||
|
|
||||||
if (enabledIds.length === 0) return;
|
if (enabledIds.length === 0) return;
|
||||||
|
|
||||||
// Helper sleep
|
// Start all enabled plugins in parallel
|
||||||
const sleep = (ms: number) => new Promise<void>((res) => setTimeout(res, ms));
|
await Promise.allSettled(
|
||||||
|
enabledIds.map(async (id) => {
|
||||||
// Start plugins in batches to avoid starting all at once.
|
try {
|
||||||
for (let i = 0; i < enabledIds.length; i += batchSize) {
|
// Only attempt to start if still enabled and not already started
|
||||||
const batch = enabledIds.slice(i, i + batchSize);
|
if (!isPluginEnabled(id) || pluginInstances.has(id)) return;
|
||||||
|
await startPlugin(id).catch((e) => {
|
||||||
// Start the batch in parallel but don't let exceptions bubble to halt everything.
|
console.error(`Failed to start plugin ${id}:`, e);
|
||||||
await Promise.allSettled(
|
});
|
||||||
batch.map(async (id) => {
|
} catch (error) {
|
||||||
try {
|
console.error(`Unexpected error while starting plugin ${id}:`, error);
|
||||||
// Only attempt to start if still enabled and not already started
|
}
|
||||||
if (!isPluginEnabled(id) || pluginInstances.has(id)) return;
|
}),
|
||||||
await startPlugin(id).catch((e) => {
|
);
|
||||||
// startPlugin may throw; ensure it doesn't crash the whole batch
|
|
||||||
console.error(`Failed to start plugin ${id}:`, e);
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Unexpected error while starting plugin ${id}:`, error);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
// If there are more plugins to start, wait before starting the next batch.
|
|
||||||
if (i + batchSize < enabledIds.length) {
|
|
||||||
await sleep(staggerInterval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ export function getCurrentTheme() {
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export function getThemeFromLoader(): VdThemeInfo | null {
|
export function getThemeFromLoader(): VdThemeInfo | null {
|
||||||
return getStoredTheme();
|
return getStoredTheme() ?? getCurrentTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -157,6 +157,7 @@ export async function initThemes() {
|
||||||
}
|
}
|
||||||
|
|
||||||
await newAwaitStorage(colorsPref);
|
await newAwaitStorage(colorsPref);
|
||||||
|
await awaitStorage(themes);
|
||||||
|
|
||||||
const currentTheme = getThemeFromLoader();
|
const currentTheme = getThemeFromLoader();
|
||||||
initColors(currentTheme?.data ?? null);
|
initColors(currentTheme?.data ?? null);
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ const rainLoaderIdentity = globalThis.__RAIN_LOADER__;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const vendettaLoaderIdentity = globalThis.__vendetta_loader;
|
const vendettaLoaderIdentity = globalThis.__vendetta_loader;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const shiggyLoaderIdentity = globalThis.__SHIGGY_LOADER__;
|
||||||
|
|
||||||
export interface VendettaLoaderIdentity {
|
export interface VendettaLoaderIdentity {
|
||||||
name: string;
|
name: string;
|
||||||
features: {
|
features: {
|
||||||
|
|
@ -36,6 +39,10 @@ export function isRa1nLoader() {
|
||||||
return rainLoaderIdentity != null;
|
return rainLoaderIdentity != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isShiggyLoader() {
|
||||||
|
return shiggyLoaderIdentity != null;
|
||||||
|
}
|
||||||
|
|
||||||
function polyfillVendettaLoaderIdentity() {
|
function polyfillVendettaLoaderIdentity() {
|
||||||
if (!isPyonLoader() || isVendettaLoader() || !isRa1nLoader()) return null;
|
if (!isPyonLoader() || isVendettaLoader() || !isRa1nLoader()) return null;
|
||||||
|
|
||||||
|
|
@ -98,6 +105,8 @@ export function getLoaderIdentity() {
|
||||||
return getVendettaLoaderIdentity();
|
return getVendettaLoaderIdentity();
|
||||||
} else if (isRa1nLoader()) {
|
} else if (isRa1nLoader()) {
|
||||||
return rainLoaderIdentity();
|
return rainLoaderIdentity();
|
||||||
|
} else if (isShiggyLoader()) {
|
||||||
|
return shiggyLoaderIdentity;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -116,6 +125,7 @@ export function getLoaderName() {
|
||||||
if (isPyonLoader()) return pyonLoaderIdentity.loaderName;
|
if (isPyonLoader()) return pyonLoaderIdentity.loaderName;
|
||||||
else if (isRa1nLoader()) return rainLoaderIdentity.loadername;
|
else if (isRa1nLoader()) return rainLoaderIdentity.loadername;
|
||||||
else if (isVendettaLoader()) return vendettaLoaderIdentity.name;
|
else if (isVendettaLoader()) return vendettaLoaderIdentity.name;
|
||||||
|
else if (isShiggyLoader()) return shiggyLoaderIdentity.loaderName;
|
||||||
|
|
||||||
return "Unknown";
|
return "Unknown";
|
||||||
}
|
}
|
||||||
|
|
@ -123,6 +133,7 @@ export function getLoaderName() {
|
||||||
export function getLoaderVersion(): string | null {
|
export function getLoaderVersion(): string | null {
|
||||||
if (isPyonLoader()) return pyonLoaderIdentity.loaderVersion;
|
if (isPyonLoader()) return pyonLoaderIdentity.loaderVersion;
|
||||||
else if (isRa1nLoader()) return rainLoaderIdentity.loaderVersion;
|
else if (isRa1nLoader()) return rainLoaderIdentity.loaderVersion;
|
||||||
|
else if (isShiggyLoader()) return shiggyLoaderIdentity.loaderVersion;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -144,7 +155,9 @@ export function isThemeSupported() {
|
||||||
} else if (isVendettaLoader()) {
|
} else if (isVendettaLoader()) {
|
||||||
return vendettaLoaderIdentity!!.features.themes != null;
|
return vendettaLoaderIdentity!!.features.themes != null;
|
||||||
} else if (isRa1nLoader()) {
|
} else if (isRa1nLoader()) {
|
||||||
return false; // Ra1n has theme support disabled, this is here just to make sure it doesnt think it does
|
return false; // Rain has theme support disabled, this is here just to make sure it doesnt think it does
|
||||||
|
} else if (isShiggyLoader()) {
|
||||||
|
return shiggyLoaderIdentity.hasThemeSupport;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -158,6 +171,8 @@ export function getStoredTheme(): VdThemeInfo | null {
|
||||||
if (!themeProp) return null;
|
if (!themeProp) return null;
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
return globalThis[themeProp] || null;
|
return globalThis[themeProp] || null;
|
||||||
|
} else if (isShiggyLoader()) {
|
||||||
|
return shiggyLoaderIdentity.storedTheme || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -168,6 +183,8 @@ export function getThemeFilePath() {
|
||||||
return "pyoncord/current-theme.json";
|
return "pyoncord/current-theme.json";
|
||||||
} else if (isVendettaLoader()) {
|
} else if (isVendettaLoader()) {
|
||||||
return "vendetta_theme.json";
|
return "vendetta_theme.json";
|
||||||
|
} else if (isShiggyLoader()) {
|
||||||
|
return "ShiggyCord/current-theme.json";
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -241,6 +258,7 @@ export function getLoaderConfigPath() {
|
||||||
|
|
||||||
export function isFontSupported() {
|
export function isFontSupported() {
|
||||||
if (isPyonLoader()) return pyonLoaderIdentity.fontPatch === 2;
|
if (isPyonLoader()) return pyonLoaderIdentity.fontPatch === 2;
|
||||||
|
else if (isShiggyLoader()) return shiggyLoaderIdentity.fontPatch === 2;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -248,4 +266,4 @@ export function isFontSupported() {
|
||||||
export async function clearBundle() {
|
export async function clearBundle() {
|
||||||
// TODO: This should be not be hardcoded, maybe put in loader.json?
|
// TODO: This should be not be hardcoded, maybe put in loader.json?
|
||||||
return void await removeCacheFile("bundle.js");
|
return void await removeCacheFile("bundle.js");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue