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 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 { SettingsTabsKey, Sticker, StickerPack, StickerPackMeta } from "../types";
|
||||
import { cl, clPicker, Mutex } from "../utils";
|
||||
|
@ -92,6 +92,7 @@ export const Settings = () => {
|
|||
const [addStickerHtml, setAddStickerHtml] = React.useState<string>("");
|
||||
const [tab, setTab] = React.useState<SettingsTabsKey>(SettingsTabsKey.ADD_STICKER_PACK_URL);
|
||||
const [hoveredStickerPackId, setHoveredStickerPackId] = React.useState<string | null>(null);
|
||||
const [_isV1, setV1] = React.useState<boolean>(false);
|
||||
|
||||
async function refreshStickerPackMetas() {
|
||||
setstickerPackMetas(await getStickerPackMetas());
|
||||
|
@ -99,6 +100,9 @@ export const Settings = () => {
|
|||
React.useEffect(() => {
|
||||
refreshStickerPackMetas();
|
||||
}, []);
|
||||
React.useEffect(() => {
|
||||
isV1().then(setV1);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={cl("settings")}>
|
||||
|
@ -365,7 +369,7 @@ export const Settings = () => {
|
|||
|
||||
<Flex flexDirection="row" style={{
|
||||
alignItems: "center",
|
||||
justifyContent: "center"
|
||||
justifyContent: "start"
|
||||
}} >
|
||||
<Button
|
||||
size={Button.Sizes.SMALL}
|
||||
|
@ -399,6 +403,9 @@ export const Settings = () => {
|
|||
onClick={async e => {
|
||||
await migrate();
|
||||
}}
|
||||
style={{
|
||||
display: _isV1 ? "unset" : "none"
|
||||
}}
|
||||
>Migrate from v1</Button>
|
||||
</Flex>
|
||||
</div>
|
||||
|
|
|
@ -64,11 +64,11 @@ export default definePlugin({
|
|||
}
|
||||
},
|
||||
{
|
||||
find: "#{intl::EXPRESSION_PICKER_GIF}",
|
||||
find: `role:"tablist","aria-label":`,
|
||||
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 => {
|
||||
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 isActive = `${currentTab}==="stickers+"`;
|
||||
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() {
|
||||
const newPackMetas = await getStickerPackMetas(PACKS_KEY);
|
||||
if (newPackMetas.length > 0) {
|
||||
|
|
|
@ -7,11 +7,12 @@
|
|||
import * as DataStore from "@api/DataStore";
|
||||
|
||||
import { removeRecentStickerByPackId } from "./components";
|
||||
import { StickerPack, StickerPackMeta } from "./types";
|
||||
import { DynamicPackSetMeta, DynamicStickerPackMeta, StickerPack, StickerPackMeta } from "./types";
|
||||
import { Mutex } from "./utils";
|
||||
const mutex = new Mutex();
|
||||
|
||||
const PACKS_KEY = "MoreStickers:Packs";
|
||||
const DYNAMIC_PACK_SET_METAS_KEY = "MoreStickers:DynamicPackSetMetas";
|
||||
|
||||
/**
|
||||
* Convert StickerPack to StickerPackMeta
|
||||
|
@ -24,7 +25,8 @@ function stickerPackToMeta(sp: StickerPack): StickerPackMeta {
|
|||
id: sp.id,
|
||||
title: sp.title,
|
||||
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();
|
||||
|
||||
try {
|
||||
const packs = (await DataStore.get(packsKey) ?? null) as (StickerPackMeta[] | null);
|
||||
await DataStore.set(packsKey, packs === null ? [meta] : [...packs, meta]);
|
||||
let packs = (await DataStore.get(packsKey) ?? null) as (StickerPackMeta[] | null);
|
||||
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 {
|
||||
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;
|
||||
};
|
||||
logo: Sticker;
|
||||
|
||||
dynamic?: DynamicStickerPackMeta["dynamic"];
|
||||
}
|
||||
|
||||
export interface DynamicStickerPackMeta extends StickerPackMeta {
|
||||
dynamic: {
|
||||
version?: string;
|
||||
refreshUrl: string;
|
||||
authHeaders?: Record<string, string>;
|
||||
};
|
||||
}
|
||||
|
||||
export interface StickerPack extends StickerPackMeta {
|
||||
|
@ -148,3 +158,18 @@ export interface FFmpegState {
|
|||
ffmpeg?: FFmpeg;
|
||||
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