Add a blacklist editor that saves to e621

The Online sidebar's "Your blacklist" section is editable now: typing a
tag appends it and each entry gets an x to remove it. Changes are written
straight to the e621 account (PATCH /users/{id}.json with
user[blacklisted_tags]); the store keeps the fetched profile for the id,
updates the list optimistically and reloads it from e621. The Followed
page's blacklist cloud is rebuilt afterwards via the new
/api/follows/cloud/?refresh=1 force flag.

Verified against the live API with a reversible add/verify/restore test.
This commit is contained in:
2026-09-17 20:35:23 -05:00
parent f7e2242e5f
commit cad659b75f
4 changed files with 142 additions and 17 deletions
+19 -2
View File
@@ -3,17 +3,21 @@ import { create } from "zustand";
import { api } from "@/lib/api";
import {
effectiveCredentials,
updateBlacklist,
verifyE621Credentials,
type E621Credentials,
type E621User,
} from "@/lib/e621";
interface E621State {
credentials: E621Credentials | null;
profile: E621User | null;
blacklist: string[];
loading: boolean;
ready: boolean;
load: () => Promise<void>;
loadBlacklist: () => Promise<void>;
saveBlacklist: (lines: string[]) => Promise<void>;
save: (values: {
username: string;
api_key: string;
@@ -24,6 +28,7 @@ interface E621State {
export const useE621 = create<E621State>((set, get) => ({
credentials: null,
profile: null,
blacklist: [],
loading: false,
ready: false,
@@ -48,12 +53,23 @@ export const useE621 = create<E621State>((set, get) => ({
.split("\n")
.map((tag) => tag.trim())
.filter(Boolean);
set({ blacklist: tags });
set({ blacklist: tags, profile: user });
} catch {
// Keep the last known blacklist when e621 is unreachable.
}
},
saveBlacklist: async (lines) => {
const credentials = get().credentials;
const profile = get().profile;
if (!credentials?.configured || !profile) {
throw new Error("Add e621 credentials in Account to edit your blacklist.");
}
await updateBlacklist(credentials, profile.id, lines.join("\n"));
set({ blacklist: lines });
await get().loadBlacklist();
},
save: async (values) => {
const credentials = await api<E621Credentials>("/api/auth/e621/", {
method: "PUT",
@@ -64,5 +80,6 @@ export const useE621 = create<E621State>((set, get) => ({
return credentials;
},
clear: () => set({ credentials: null, blacklist: [], ready: false }),
clear: () =>
set({ credentials: null, profile: null, blacklist: [], ready: false }),
}));