declare namespace CF2021 { export interface GlobalInfoStorePayload { connectionState: "connected" | "offline" | "connecting"; onlineUsers: number; websocketUrl: string; streamUrl?: string; } interface ProgramScheduleEntry { id: number; number: string; title: string; proposer: string; discussionOpened: boolean; description?: string; expectedStartAt: Date; expectedFinishAt?: Date; } export interface ProgramStorePayload { items: { [key: number]: ProgramScheduleEntry; }; currentId?: number; scheduleIds: number[]; } interface GroupMapping { id: number; code: string; name: string; } export interface AnonymousAuthStorePayload { isAuthenticated: false; } export interface UserAuthStorePayload extends AnonymousAuthStorePayload { isAuthenticated: true; user: { name: string; username: string; role: "regp" | "member" | "chairman"; accessToken: string; // These are optional as they're loaded separately. id?: number; isBanned?: boolean; group?: string; secret?: string; }; } export type AuthStorePayload = | AnonymousAuthStorePayload | UserAuthStorePayload; export type AnnouncementType = | "rejected-procedure-proposal" | "accepted-procedure-proposal" | "suggested-procedure-proposal" | "voting" | "announcement" | "user-ban"; export interface Announcement { id: number; datetime: Date; type: AnnouncementType; content: string; link?: string; relatedPostId: string; seen: boolean; } export interface AnnouncementStorePayload { items: { [key: number]: Announcement; }; itemIds: number[]; } export type PostType = "post" | "procedure-proposal"; export interface AbstractPost { id: number; datetime: Date; author: { id: number; name: string; username: string; group: string; isBanned: boolean; }; type: PostType; content: string; contentHtml: string; ranking: { score: number; likes: number; dislikes: number; myVote: "like" | "dislike" | "none"; }; historyLog: { attribute: string; newValue: string; datetime: Date; originator: "self" | "chairman"; }[]; modified: boolean; archived: boolean; hidden: boolean; seen: boolean; } export interface DiscussionPost extends AbstractPost { type: "post"; } export type ProposalPostState = | "pending" | "announced" | "accepted" | "rejected" | "rejected-by-chairman"; export interface ProposalPost extends AbstractPost { type: "procedure-proposal"; state: ProposalPostState; } export type Post = ProposalPost | DiscussionPost; export interface PostStoreItems { [key: string]: Post; } export interface PostStoreFilters { flags: "all" | "active" | "archived"; sort: "byDate" | "byScore"; type: "all" | "proposalsOnly" | "discussionOnly"; showPendingProposals: boolean; } export interface PostStorePayload { items: PostStoreItems; itemCount: number; window: { items: string[]; itemCount: number; page: number; perPage: number; }; filters: PostStoreFilters; } }