added stickers and emojies list
This commit is contained in:
parent
24276d1379
commit
43894f2fc9
26 changed files with 1118 additions and 14 deletions
|
|
@ -8,7 +8,9 @@ import {
|
|||
Shield,
|
||||
ShieldCheck,
|
||||
Users,
|
||||
Gift
|
||||
Gift,
|
||||
Sticker,
|
||||
Smile
|
||||
} from "lucide-react";
|
||||
import { useEffect, useState, type ReactNode } from "react";
|
||||
import { api } from "../api";
|
||||
|
|
@ -76,6 +78,8 @@ export function Shell({
|
|||
<NavLink icon={<Users size={16} />} href="/accounts" route={route} navigate={navigate}>{t("layout.accounts")}</NavLink>
|
||||
<NavLink icon={<ShieldCheck size={16} />} href="/channels" route={route} navigate={navigate}>{t("layout.channels")}</NavLink>
|
||||
<NavLink icon={<Gift size={16} />} href="/gifts" route={route} navigate={navigate}>{t("layout.gifts")}</NavLink>
|
||||
<NavLink icon={<Sticker size={16} />} href="/stickers" route={route} navigate={navigate}>{t("layout.stickers")}</NavLink>
|
||||
<NavLink icon={<Smile size={16} />} href="/emoji" route={route} navigate={navigate}>{t("layout.emoji")}</NavLink>
|
||||
<div className={`nav-section ${messagesActive ? "active" : ""} ${messagesOpen ? "open" : ""}`}>
|
||||
<button
|
||||
className="nav-section-toggle"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
import lottie from "lottie-web/build/player/lottie_light_canvas";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { api, errorMessage } from "../api";
|
||||
|
||||
// One preview cell in a sticker/emoji set's preview grid. Mounted only while
|
||||
// its modal is open, and only for the one set being viewed — not on the list
|
||||
// page — so this never repeats the "100 animations on one page" lag.
|
||||
//
|
||||
// Documents come back either as Lottie JSON (TGS-animated) or as a raw raster
|
||||
// image (static webp/png/etc, e.g. the "GestosLol" pack) — branch on the
|
||||
// response's real Content-Type rather than assuming every document animates.
|
||||
export function StickerDocumentPreview({ documentID, className = "", showError = true }: { documentID: string; className?: string; showError?: boolean }) {
|
||||
const host = useRef<HTMLDivElement>(null);
|
||||
const animation = useRef<ReturnType<typeof lottie.loadAnimation> | null>(null);
|
||||
const [error, setError] = useState("");
|
||||
const [imageURL, setImageURL] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
let objectURL: string | null = null;
|
||||
setError("");
|
||||
setImageURL(null);
|
||||
|
||||
fetch(api.stickerDocumentAnimationURL(documentID), { credentials: "same-origin" })
|
||||
.then(async (response) => {
|
||||
if (!response.ok) {
|
||||
const body = await response.json().catch(() => null);
|
||||
throw new Error(body?.error || response.statusText);
|
||||
}
|
||||
const contentType = response.headers.get("content-type") ?? "";
|
||||
if (contentType.includes("json")) {
|
||||
const data = await response.json();
|
||||
if (cancelled || !host.current) return;
|
||||
animation.current?.destroy();
|
||||
animation.current = lottie.loadAnimation({
|
||||
container: host.current,
|
||||
renderer: "canvas",
|
||||
loop: true,
|
||||
autoplay: true,
|
||||
animationData: data
|
||||
});
|
||||
return;
|
||||
}
|
||||
const blob = await response.blob();
|
||||
if (cancelled) return;
|
||||
objectURL = URL.createObjectURL(blob);
|
||||
setImageURL(objectURL);
|
||||
})
|
||||
.catch((err) => {
|
||||
if (!cancelled) setError(errorMessage(err));
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
animation.current?.destroy();
|
||||
animation.current = null;
|
||||
if (objectURL) URL.revokeObjectURL(objectURL);
|
||||
};
|
||||
}, [documentID]);
|
||||
|
||||
return (
|
||||
<div className={`sticker-doc-cell ${className}`.trim()}>
|
||||
{imageURL ? (
|
||||
<img className="sticker-doc-image" src={imageURL} alt="" />
|
||||
) : (
|
||||
<div className="sticker-doc-canvas" ref={host} />
|
||||
)}
|
||||
{error && showError && <span className="sticker-doc-error">{error}</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue