Files
Mastodon/app/javascript/mastodon/models/status.ts
T

147 lines
3.9 KiB
TypeScript

import type { RecordOf } from 'immutable';
import type { ApiCollectionJSON } from '@/mastodon/api_types/collections';
import type { ApiCustomEmojiJSON } from '@/mastodon/api_types/custom_emoji';
import type {
ApiAudioAttachmentJSON,
ApiGifvAttachmentJSON,
ApiImageAttachmentJSON,
ApiMediaAttachmentJSON,
ApiUnknownAttachmentJSON,
ApiVideoAttachmentJSON,
MediaAttachmentType,
} from '@/mastodon/api_types/media_attachments';
import type {
ApiQuoteJSON,
ApiQuotePolicyJSON,
} from '@/mastodon/api_types/quotes';
import type {
ApiFilterResultJSON,
ApiMentionJSON,
ApiPreviewCardAuthorJSON,
ApiPreviewCardJSON,
ApiStatusTranslationJSON,
ApiTagJSON,
StatusVisibility,
} from '@/mastodon/api_types/statuses';
import type { AccountShapeFull } from './account';
export type { StatusVisibility } from '@/mastodon/api_types/statuses';
// Temporary until we type it correctly
export type Status = Immutable.Map<string, unknown>;
export interface StatusShape {
id: string;
account: string;
created_at: string;
edited_at?: string;
application: {
name: string;
website?: string;
};
hidden: boolean;
language: string;
muted: boolean;
pinned: boolean;
filtered: FilterResult[];
sensitive: boolean;
collapsed: boolean | null;
uri: string;
url: string | null;
isLoading?: boolean;
// Content
content: string;
contentHtml: string;
in_reply_to_account_id?: string;
in_reply_to_id?: string;
search_index?: string;
spoilerHtml?: string;
spoiler_text?: string;
// Embeds
card?: CardShape;
emojis: Pick<ApiCustomEmojiJSON, 'shortcode' | 'static_url' | 'url'>[];
media_attachments: MediaAttachmentShape[];
mentions: ApiMentionJSON[];
poll?: string;
quote?: Omit<ApiQuoteJSON, 'quoted_status'> & {
quoted_status?: string;
};
reblog?: string;
tagged_collections: ApiCollectionJSON[];
tags: ApiTagJSON[];
translation?: StatusTranslation;
// Interactions
bookmarked: boolean;
favourited: boolean;
favourites_count: number;
quote_approval: ApiQuotePolicyJSON | null;
quotes_count: number;
reblogged: boolean;
reblogs_count: number;
replies_count: number;
visibility: StatusVisibility;
}
export type ExpandedStatusShape = Omit<StatusShape, 'account' | 'reblog'> & {
account: AccountShapeFull;
reblog?: Omit<ExpandedStatusShape, 'reblog'>;
};
export type CardShape = Omit<ApiPreviewCardJSON, 'authors'> & {
authors: (Omit<ApiPreviewCardAuthorJSON, 'author'> & {
accountId?: string;
})[];
};
export type Card = RecordOf<CardShape>;
export type MediaAttachment = Immutable.Map<string, unknown>;
export type MediaAttachmentShape<
TAttachmentJSON extends ApiMediaAttachmentJSON = ApiMediaAttachmentJSON,
> = Omit<TAttachmentJSON, 'remote_url'> & {
remote_url: string | null;
translation?: {
description: string;
};
};
export function isMediaAttachmentOfType(
attachment: MediaAttachmentShape,
type: 'image',
): attachment is MediaAttachmentShape<ApiImageAttachmentJSON>;
export function isMediaAttachmentOfType(
attachment: MediaAttachmentShape,
type: 'video',
): attachment is MediaAttachmentShape<ApiVideoAttachmentJSON>;
export function isMediaAttachmentOfType(
attachment: MediaAttachmentShape,
type: 'gifv',
): attachment is MediaAttachmentShape<ApiGifvAttachmentJSON>;
export function isMediaAttachmentOfType(
attachment: MediaAttachmentShape,
type: 'audio',
): attachment is MediaAttachmentShape<ApiAudioAttachmentJSON>;
export function isMediaAttachmentOfType(
attachment: MediaAttachmentShape,
type: 'unknown',
): attachment is MediaAttachmentShape<ApiUnknownAttachmentJSON>;
export function isMediaAttachmentOfType(
attachment: MediaAttachmentShape,
type: MediaAttachmentType,
) {
return attachment.type === type;
}
export type CollectionAttachment = RecordOf<ApiCollectionJSON>;
export type FilterResult = Omit<ApiFilterResultJSON, 'filter'> & {
filter: string;
};
export type StatusTranslation = Omit<ApiStatusTranslationJSON, 'poll'>;