// ─── Session ───────────────────────────────────────────────────────────────── export interface SessionData { did?: string handle?: string avatar?: string } // ─── Profiles & Relationships ───────────────────────────────────────────────── export interface Profile { did: string handle: string displayName?: string avatar?: string } /** * Relationship between the logged-in user and another account. * * following — user follows them → highlight amber, deselect by default * follower — they follow user → highlight blue, select by default * mutual — both follow each other → highlight purple, deselect by default * none — no relationship → no highlight, select by default */ export type RelationshipStatus = 'following' | 'follower' | 'mutual' | 'none' // ─── Engagement ─────────────────────────────────────────────────────────────── export type EngagementType = 'op' | 'like' | 'repost' | 'quote' | 'reply' export interface BlockCriteria { blockOp: boolean blockLikes: boolean blockReposts: boolean blockQuotes: boolean blockReplies: boolean } export interface PostData { uri: string cid: string url: string author: Profile text: string createdAt: string likeCount?: number repostCount?: number replyCount?: number quoteCount?: number } /** * A reply or quote post's text, shown in the account list so the user can * judge tone before blocking. Preview-time only — never persisted to the * blockEvent record (PDS record size). */ export interface EngagementComment { text: string /** AT URI of the reply/quote post */ uri: string type: 'reply' | 'quote' } export interface EngagementAccount { profile: Profile engagementTypes: EngagementType[] relationship: RelationshipStatus /** Reply/quote text by this account on the source post, if any — capped * server-side; commentCount carries the true total for "+N more" */ comments?: EngagementComment[] /** Total distinct comments by this account (may exceed comments.length) */ commentCount?: number /** Managed client-side — not sent from API */ selected?: boolean } // ─── List Editor ────────────────────────────────────────────────────────────── export interface ListData { uri: string cid: string url: string name: string description?: string creator: Profile memberCount?: number /** e.g. 'app.bsky.graph.defs#modlist' | 'app.bsky.graph.defs#curatelist' */ purpose: string } export interface ListEngagementResponse { list: ListData accounts: EngagementAccount[] isSubscribed: boolean subscriptionRkey?: string } export interface CreateListResponse { listUri: string listRkey: string subscriptionRkey: string total: number } // ─── API Response Types ─────────────────────────────────────────────────────── export interface PostEngagementResponse { post: PostData accounts: EngagementAccount[] } export interface StartBlocksResponse { jobId: string eventRkey: string total: number } export interface ValidateResponse { total: number completed: number failed: number pending: number status: 'complete' | 'partial' | 'pending' isRunning: boolean failedDids: string[] } // ─── Custom Lexicon ─────────────────────────────────────────────────────────── export interface BlockEventRecord { $type: 'app.flockoff.blockEvent' sourcePostUri: string sourcePostUrl?: string createdAt: string criteria: BlockCriteria stats?: { total: number completed: number failed: number } pendingDids: string[] blockedDids: string[] failedDids: string[] blockedRkeys: string[] listUri?: string undoneAt?: string } export interface BlockEventSummary { rkey: string cid: string record: BlockEventRecord } // ─── Queue ──────────────────────────────────────────────────────────────────── export type JobStatus = 'running' | 'complete' | 'failed' export interface QueueJob { id: string did: string eventRkey: string status: JobStatus total: number completed: number failed: number pendingDids: string[] blockedDids: string[] failedDids: string[] blockedRkeys: string[] sseClients: Set startedAt: Date /** If set, newly blocked accounts are also added to this block list as listitems */ listUri?: string } export interface ProgressMessage { jobId: string status: JobStatus total: number completed: number failed: number }