Update: admin panel fixes, badge icons, studio improvements, gitea runner v5
Gitea Actions Runner Test / test-job (push) Successful in 2s
CI / check (push) Failing after 21s
CI / tests-unit (push) Skipped
CI / tests-integration (push) Skipped
CI / tests-ui (push) Skipped
CI / preflight (push) Skipped
CI / deploy (push) Skipped
Gitea Actions Runner Test / test-job (push) Successful in 2s
CI / check (push) Failing after 21s
CI / tests-unit (push) Skipped
CI / tests-integration (push) Skipped
CI / tests-ui (push) Skipped
CI / preflight (push) Skipped
CI / deploy (push) Skipped
This commit is contained in:
1 parent
afc8909d3f
commit
a06db72c65
7 files changed
+185
-47
No files matched your search
@@ -124,6 +124,7 @@ const GRID_ROW_H = 176;
|
||||
// Persisted UI preferences (survive reloads).
|
||||
const LS_VIEW_MODE = "studio:viewMode";
|
||||
const LS_SORT_BY = "studio:sortBy";
|
||||
const LS_FILTERS = "studio.filters";
|
||||
const SORT_KEYS = [
|
||||
"default",
|
||||
"name",
|
||||
@@ -228,10 +229,31 @@ export function StudioClient({
|
||||
const [activeSource, setActiveSource] = useState<string>("");
|
||||
const [activeSourceName, setActiveSourceName] = useState("");
|
||||
|
||||
// Filters
|
||||
const [typeFilter, setTypeFilter] = useState<string>("all");
|
||||
const [categoryFilter, setCategoryFilter] = useState<string>("all");
|
||||
const [statusFilter, setStatusFilter] = useState<string>("all");
|
||||
// Filter persistence in localStorage
|
||||
const storedFilters = JSON.parse(
|
||||
localStorage.getItem(LS_FILTERS) ||
|
||||
'{"typeFilter":"all","categoryFilter":"all","statusFilter":"all"}',
|
||||
);
|
||||
const [typeFilter, setTypeFilter] = useState<string>(
|
||||
storedFilters.typeFilter || "all",
|
||||
);
|
||||
const [categoryFilter, setCategoryFilter] = useState<string>(
|
||||
storedFilters.categoryFilter || "all",
|
||||
);
|
||||
const [statusFilter, setStatusFilter] = useState<string>(
|
||||
storedFilters.statusFilter || "all",
|
||||
);
|
||||
// Sync to localStorage on change
|
||||
useEffect(() => {
|
||||
localStorage.setItem(
|
||||
LS_FILTERS,
|
||||
JSON.stringify({
|
||||
typeFilter,
|
||||
categoryFilter,
|
||||
statusFilter,
|
||||
}),
|
||||
);
|
||||
}, [typeFilter, categoryFilter, statusFilter]);
|
||||
const [sortBy, setSortBy] = useState<string>(() =>
|
||||
readLs(LS_SORT_BY, "default", SORT_KEYS),
|
||||
);
|
||||
@@ -378,7 +400,7 @@ export function StudioClient({
|
||||
|
||||
// ── Grid virtualization ─────────────────────────────────────────
|
||||
const [gridCols, setGridCols] = useState(1);
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
const el = listRef.current;
|
||||
if (viewMode !== "grid" || !el) return;
|
||||
const update = () => {
|
||||
|
||||
@@ -4,10 +4,8 @@ import type { FurniItem } from "./studio-types";
|
||||
|
||||
export function getFurniImageUrl(item: FurniItem) {
|
||||
if (item.iconUrl) return item.iconUrl;
|
||||
const base = item.classname.includes("*")
|
||||
? item.classname.substring(0, item.classname.indexOf("*"))
|
||||
: item.classname;
|
||||
return `https://images.habbo.com/dcr/hof_furni/${item.revision}/${encodeURIComponent(base)}_icon.png`;
|
||||
const iconName = item.classname.replace(/\*/g, "_");
|
||||
return `/swf/dcr/hof_furni/icons/${encodeURIComponent(iconName)}_icon.png`;
|
||||
}
|
||||
|
||||
export function getFurniIconUrl(classname: string, revision: number) {
|
||||
@@ -23,10 +21,11 @@ export function handleImgError(
|
||||
const iconName = item.classname.replace(/\*/g, "_");
|
||||
if (!img.dataset.fallback) {
|
||||
img.dataset.fallback = "1";
|
||||
img.src = getFurniIconUrl(item.classname, item.revision);
|
||||
img.src = `/swf/dcr/hof_furni/icons/${encodeURIComponent(iconName)}_icon.png`;
|
||||
} else if (img.dataset.fallback === "1") {
|
||||
img.dataset.fallback = "2";
|
||||
img.src = `/swf/dcr/hof_furni/icons/${encodeURIComponent(iconName)}_icon.png`;
|
||||
img.src =
|
||||
'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" viewBox="0 0 24 24" fill="none" stroke="%2399a0aa" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2.5"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg>';
|
||||
} else {
|
||||
img.src =
|
||||
'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="56" height="56" viewBox="0 0 24 24" fill="none" stroke="%2399a0aa" stroke-width="1.5"><rect x="3" y="3" width="18" height="18" rx="2.5"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg>';
|
||||
|
||||
Reference in new issue
Block a user