mirror of
https://github.com/Equicord/Equicord.git
synced 2025-06-08 14:13:01 -04:00
Fix: MoreStickers tab (#94)
* feat(MoreStickers): ready for dynamic sticker pack feature * fix(MoreStickers): Sticker+ tab --------- Co-authored-by: thororen1234 <thororen1234@users.noreply.github.com> Co-authored-by: thororen1234 <78185467+thororen1234@users.noreply.github.com>
This commit is contained in:
parent
22751c00eb
commit
70066cae7f
5 changed files with 123 additions and 9 deletions
|
@ -11,7 +11,7 @@ import { Button, Forms, React, TabBar, Text, TextArea, Toasts } from "@webpack/c
|
||||||
|
|
||||||
import { convert as convertLineEP, getIdFromUrl as getLineEmojiPackIdFromUrl, getStickerPackById as getLineEmojiPackById, isLineEmojiPackHtml, parseHtml as getLineEPFromHtml } from "../lineEmojis";
|
import { convert as convertLineEP, getIdFromUrl as getLineEmojiPackIdFromUrl, getStickerPackById as getLineEmojiPackById, isLineEmojiPackHtml, parseHtml as getLineEPFromHtml } from "../lineEmojis";
|
||||||
import { convert as convertLineSP, getIdFromUrl as getLineStickerPackIdFromUrl, getStickerPackById as getLineStickerPackById, isLineStickerPackHtml, parseHtml as getLineSPFromHtml } from "../lineStickers";
|
import { convert as convertLineSP, getIdFromUrl as getLineStickerPackIdFromUrl, getStickerPackById as getLineStickerPackById, isLineStickerPackHtml, parseHtml as getLineSPFromHtml } from "../lineStickers";
|
||||||
import { migrate } from "../migrate-v1";
|
import { isV1, migrate } from "../migrate-v1";
|
||||||
import { deleteStickerPack, getStickerPack, getStickerPackMetas, saveStickerPack } from "../stickers";
|
import { deleteStickerPack, getStickerPack, getStickerPackMetas, saveStickerPack } from "../stickers";
|
||||||
import { SettingsTabsKey, Sticker, StickerPack, StickerPackMeta } from "../types";
|
import { SettingsTabsKey, Sticker, StickerPack, StickerPackMeta } from "../types";
|
||||||
import { cl, clPicker, Mutex } from "../utils";
|
import { cl, clPicker, Mutex } from "../utils";
|
||||||
|
@ -92,6 +92,7 @@ export const Settings = () => {
|
||||||
const [addStickerHtml, setAddStickerHtml] = React.useState<string>("");
|
const [addStickerHtml, setAddStickerHtml] = React.useState<string>("");
|
||||||
const [tab, setTab] = React.useState<SettingsTabsKey>(SettingsTabsKey.ADD_STICKER_PACK_URL);
|
const [tab, setTab] = React.useState<SettingsTabsKey>(SettingsTabsKey.ADD_STICKER_PACK_URL);
|
||||||
const [hoveredStickerPackId, setHoveredStickerPackId] = React.useState<string | null>(null);
|
const [hoveredStickerPackId, setHoveredStickerPackId] = React.useState<string | null>(null);
|
||||||
|
const [_isV1, setV1] = React.useState<boolean>(false);
|
||||||
|
|
||||||
async function refreshStickerPackMetas() {
|
async function refreshStickerPackMetas() {
|
||||||
setstickerPackMetas(await getStickerPackMetas());
|
setstickerPackMetas(await getStickerPackMetas());
|
||||||
|
@ -99,6 +100,9 @@ export const Settings = () => {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
refreshStickerPackMetas();
|
refreshStickerPackMetas();
|
||||||
}, []);
|
}, []);
|
||||||
|
React.useEffect(() => {
|
||||||
|
isV1().then(setV1);
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cl("settings")}>
|
<div className={cl("settings")}>
|
||||||
|
@ -365,7 +369,7 @@ export const Settings = () => {
|
||||||
|
|
||||||
<Flex flexDirection="row" style={{
|
<Flex flexDirection="row" style={{
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center"
|
justifyContent: "start"
|
||||||
}} >
|
}} >
|
||||||
<Button
|
<Button
|
||||||
size={Button.Sizes.SMALL}
|
size={Button.Sizes.SMALL}
|
||||||
|
@ -399,6 +403,9 @@ export const Settings = () => {
|
||||||
onClick={async e => {
|
onClick={async e => {
|
||||||
await migrate();
|
await migrate();
|
||||||
}}
|
}}
|
||||||
|
style={{
|
||||||
|
display: _isV1 ? "unset" : "none"
|
||||||
|
}}
|
||||||
>Migrate from v1</Button>
|
>Migrate from v1</Button>
|
||||||
</Flex>
|
</Flex>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -64,11 +64,11 @@ export default definePlugin({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
find: "#{intl::EXPRESSION_PICKER_GIF}",
|
find: `role:"tablist","aria-label":`,
|
||||||
replacement: {
|
replacement: {
|
||||||
match: /role:"tablist",.+?#{intl::EXPRESSION_PICKER_CATEGORIES_A11Y_LABEL}\),children:(\[.*?\)\]}\)}\):null,)(.*?closePopout:\w.*?:null)/s,
|
match: /role:"tablist",.*?,?"aria-label":.+?\),children:(\[.*?\)\]}\)}\):null,)(.*?closePopout:\w.*?:null)/s,
|
||||||
replace: m => {
|
replace: m => {
|
||||||
const stickerTabRegex = /(\w+?)\?(\([^()]+?\))\((.{1,2}),{.{0,128},isActive:(.{1,2})===.{1,150},children:(.{1,10}#{intl::EXPRESSION_PICKER_STICKER}).*?:null/s;
|
const stickerTabRegex = /(\w+?)\?(\([^()]+?\))\((.{1,2}),{.{0,128},isActive:(.{1,2})===.{1,6}\.STICKER.{1,140},children:(.{1,2}\.intl\.string\(.+?\)).*?:null/s;
|
||||||
const res = m.replace(stickerTabRegex, (_m, canUseStickers, jsx, tabHeaderComp, currentTab, stickerText) => {
|
const res = m.replace(stickerTabRegex, (_m, canUseStickers, jsx, tabHeaderComp, currentTab, stickerText) => {
|
||||||
const isActive = `${currentTab}==="stickers+"`;
|
const isActive = `${currentTab}==="stickers+"`;
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -57,6 +57,20 @@ function migrateStickerPack(oldStickerPack: StickerPack): StickerPack {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function isV1() {
|
||||||
|
const newPackMetas = await getStickerPackMetas(PACKS_KEY);
|
||||||
|
if (newPackMetas.length > 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const oldPackMetas = await getStickerPackMetas(PACKS_KEY_OLD);
|
||||||
|
if (oldPackMetas.length === 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
export async function migrate() {
|
export async function migrate() {
|
||||||
const newPackMetas = await getStickerPackMetas(PACKS_KEY);
|
const newPackMetas = await getStickerPackMetas(PACKS_KEY);
|
||||||
if (newPackMetas.length > 0) {
|
if (newPackMetas.length > 0) {
|
||||||
|
|
|
@ -7,11 +7,12 @@
|
||||||
import * as DataStore from "@api/DataStore";
|
import * as DataStore from "@api/DataStore";
|
||||||
|
|
||||||
import { removeRecentStickerByPackId } from "./components";
|
import { removeRecentStickerByPackId } from "./components";
|
||||||
import { StickerPack, StickerPackMeta } from "./types";
|
import { DynamicPackSetMeta, DynamicStickerPackMeta, StickerPack, StickerPackMeta } from "./types";
|
||||||
import { Mutex } from "./utils";
|
import { Mutex } from "./utils";
|
||||||
const mutex = new Mutex();
|
const mutex = new Mutex();
|
||||||
|
|
||||||
const PACKS_KEY = "MoreStickers:Packs";
|
const PACKS_KEY = "MoreStickers:Packs";
|
||||||
|
const DYNAMIC_PACK_SET_METAS_KEY = "MoreStickers:DynamicPackSetMetas";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert StickerPack to StickerPackMeta
|
* Convert StickerPack to StickerPackMeta
|
||||||
|
@ -24,7 +25,8 @@ function stickerPackToMeta(sp: StickerPack): StickerPackMeta {
|
||||||
id: sp.id,
|
id: sp.id,
|
||||||
title: sp.title,
|
title: sp.title,
|
||||||
author: sp.author,
|
author: sp.author,
|
||||||
logo: sp.logo
|
logo: sp.logo,
|
||||||
|
dynamic: sp.dynamic,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,8 +45,11 @@ export async function saveStickerPack(sp: StickerPack, packsKey: string = PACKS_
|
||||||
const unlock = await mutex.lock();
|
const unlock = await mutex.lock();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const packs = (await DataStore.get(packsKey) ?? null) as (StickerPackMeta[] | null);
|
let packs = (await DataStore.get(packsKey) ?? null) as (StickerPackMeta[] | null);
|
||||||
await DataStore.set(packsKey, packs === null ? [meta] : [...packs, meta]);
|
if (packs?.some(p => p.id === sp.id)) {
|
||||||
|
packs = packs.map(p => p.id === sp.id ? meta : p);
|
||||||
|
}
|
||||||
|
await DataStore.set(packsKey, packs === null ? [meta] : packs);
|
||||||
} finally {
|
} finally {
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
@ -106,3 +111,66 @@ export async function deleteStickerPack(id: string, packsKey: string = PACKS_KEY
|
||||||
})()
|
})()
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------- Dynamic Packs ----------------------------
|
||||||
|
|
||||||
|
export async function getDynamicStickerPack(dspm: DynamicStickerPackMeta): Promise<StickerPack | null> {
|
||||||
|
const dsp = await fetch(dspm.dynamic.refreshUrl, {
|
||||||
|
headers: dspm.dynamic.authHeaders,
|
||||||
|
});
|
||||||
|
if (!dsp.ok) return null;
|
||||||
|
return await dsp.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getDynamicPackSetMetas(dpsmKey: string = DYNAMIC_PACK_SET_METAS_KEY): Promise<DynamicPackSetMeta[] | null> {
|
||||||
|
return (await DataStore.get(dpsmKey)) ?? null as DynamicPackSetMeta[] | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasDynamicPackSetMeta(dpsm: DynamicPackSetMeta, metas?: DynamicPackSetMeta[] | null): boolean {
|
||||||
|
return !!metas?.some(m => m.id === dpsm.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchDynamicPackSetMeta(dpsm: DynamicPackSetMeta): Promise<DynamicPackSetMeta | null> {
|
||||||
|
const dpsm_ = await fetch(dpsm.refreshUrl, {
|
||||||
|
headers: dpsm.authHeaders,
|
||||||
|
});
|
||||||
|
if (!dpsm_.ok) return null;
|
||||||
|
|
||||||
|
const dpsmData = await dpsm_.json();
|
||||||
|
return dpsmData as DynamicPackSetMeta;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function refreshDynamicPackSet(old: DynamicPackSetMeta, _new: DynamicPackSetMeta): Promise<void> {
|
||||||
|
const oldPacks = old.packs.map(p => p.id);
|
||||||
|
const newPacks = _new.packs.map(p => p.id);
|
||||||
|
|
||||||
|
const toRemove = oldPacks.filter(p => !newPacks.includes(p));
|
||||||
|
const toAdd = newPacks.filter(p => !oldPacks.includes(p));
|
||||||
|
|
||||||
|
await Promise.all([
|
||||||
|
...toRemove.map(id => deleteStickerPack(id)),
|
||||||
|
...toAdd.map(id => getDynamicStickerPack(_new.packs.find(p => p.id === id)!).then(sp => sp && saveStickerPack(sp)))
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function saveDynamicPackSetMeta(dpsm: DynamicPackSetMeta, dpsmKey: string = DYNAMIC_PACK_SET_METAS_KEY): Promise<void> {
|
||||||
|
let metas = (await DataStore.get(dpsmKey) ?? null) as (DynamicPackSetMeta[] | null);
|
||||||
|
if (hasDynamicPackSetMeta(dpsm, metas)) {
|
||||||
|
await refreshDynamicPackSet(metas!.find(m => m.id === dpsm.id)!, dpsm);
|
||||||
|
metas = metas!.map(m => m.id === dpsm.id ? dpsm : m);
|
||||||
|
}
|
||||||
|
|
||||||
|
const unlock = await mutex.lock();
|
||||||
|
try {
|
||||||
|
await DataStore.set(dpsmKey, metas === null ? [dpsm] : metas);
|
||||||
|
} finally {
|
||||||
|
unlock();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function fetchAndRefreshDynamicPackSet(dpsm: DynamicPackSetMeta, dpsmKey: string = DYNAMIC_PACK_SET_METAS_KEY): Promise<void> {
|
||||||
|
const _new = await fetchDynamicPackSetMeta(dpsm);
|
||||||
|
if (!_new) return;
|
||||||
|
|
||||||
|
await saveDynamicPackSetMeta(_new, dpsmKey);
|
||||||
|
}
|
||||||
|
|
|
@ -138,6 +138,16 @@ export interface StickerPackMeta {
|
||||||
url?: string;
|
url?: string;
|
||||||
};
|
};
|
||||||
logo: Sticker;
|
logo: Sticker;
|
||||||
|
|
||||||
|
dynamic?: DynamicStickerPackMeta["dynamic"];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DynamicStickerPackMeta extends StickerPackMeta {
|
||||||
|
dynamic: {
|
||||||
|
version?: string;
|
||||||
|
refreshUrl: string;
|
||||||
|
authHeaders?: Record<string, string>;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StickerPack extends StickerPackMeta {
|
export interface StickerPack extends StickerPackMeta {
|
||||||
|
@ -148,3 +158,18 @@ export interface FFmpegState {
|
||||||
ffmpeg?: FFmpeg;
|
ffmpeg?: FFmpeg;
|
||||||
isLoaded: boolean;
|
isLoaded: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DynamicPackSetMeta {
|
||||||
|
id: string;
|
||||||
|
version?: string;
|
||||||
|
|
||||||
|
title?: string;
|
||||||
|
author?: {
|
||||||
|
name: string;
|
||||||
|
url?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
packs: DynamicStickerPackMeta[];
|
||||||
|
refreshUrl: string;
|
||||||
|
authHeaders?: Record<string, string>;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue