Follows: followed tags/pools, feeds, unseen badges and blacklist cloud
Backend (new apps.follows): - FollowedTag/FollowedPool/FollowedPost models; per-user follows with unseen tracking, plus FollowCloud for the cached blacklist cloud. - Two periodic commands sharing one fetch path: sync_followed_tags and sync_followed_pools fetch each followed tag/pool's newest posts (one e621 search per unique follow), store unseen feed rows, refresh covers and pool metadata; both fall back to anonymous e621 access. - API: /api/follows/tags|pools (follow, unfollow, mark seen), a merged feed with per-follow filtering, and /api/follows/cloud/ which rebuilds the blacklisted-tag cloud in a daemon thread when its 10 min cache is stale (polling returns building/ready). - e621 client now supports anonymous reads; trimmed posts carry preview URLs for covers and feed tiles. Frontend: - /followed page: follow forms, cover cards with unseen badges and Mark seen, merged feed with filter/unseen toggle, and a blacklist cloud panel that polls while building. Followed nav entry added.
This commit is contained in:
@@ -204,6 +204,77 @@ export interface MatchTask {
|
||||
updated_at: string;
|
||||
}
|
||||
|
||||
export interface FollowCoverData {
|
||||
post_id: number | null;
|
||||
rating: string | null;
|
||||
preview_url: string | null;
|
||||
score: number | null;
|
||||
fav_count: number | null;
|
||||
}
|
||||
|
||||
export interface FollowedTag {
|
||||
id: number;
|
||||
tag: string;
|
||||
unseen_count: number;
|
||||
cover_data: FollowCoverData | null;
|
||||
last_synced_at: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface FollowedPool {
|
||||
id: number;
|
||||
pool_id: number;
|
||||
name: string;
|
||||
post_count: number;
|
||||
unseen_count: number;
|
||||
cover_data: FollowCoverData | null;
|
||||
last_synced_at: string | null;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface FollowFeedSource {
|
||||
kind: "tag" | "pool";
|
||||
id: number;
|
||||
label: string;
|
||||
}
|
||||
|
||||
export interface FollowFeedEntry {
|
||||
post_id: number;
|
||||
seen: boolean;
|
||||
data: {
|
||||
id?: number | null;
|
||||
rating?: string | null;
|
||||
tags?: Record<string, string[]>;
|
||||
score?: { total?: number | null } | null;
|
||||
fav_count?: number | null;
|
||||
file?: {
|
||||
width?: number | null;
|
||||
height?: number | null;
|
||||
ext?: string | null;
|
||||
} | null;
|
||||
preview?: { url?: string | null } | null;
|
||||
};
|
||||
sources: FollowFeedSource[];
|
||||
}
|
||||
|
||||
export interface FollowFeed {
|
||||
count: number;
|
||||
page: number;
|
||||
per_page: number;
|
||||
has_next: boolean;
|
||||
results: FollowFeedEntry[];
|
||||
}
|
||||
|
||||
export interface FollowCloud {
|
||||
status: "ready" | "building";
|
||||
stale: boolean;
|
||||
tags: [string, number][];
|
||||
posts: number;
|
||||
source: "user" | "default" | null;
|
||||
blacklist_count: number;
|
||||
computed_at: string | null;
|
||||
}
|
||||
|
||||
export interface E621IqdbCandidate {
|
||||
post_id: number | null;
|
||||
score: number | null;
|
||||
|
||||
Reference in New Issue
Block a user