refactor: Add more type support to MkPagination
This commit is contained in:
parent
914fff5658
commit
3d39daff8c
16 changed files with 234 additions and 145 deletions
|
@ -24,13 +24,14 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import MkChannelPreview from "@/components/MkChannelPreview.vue";
|
||||
import type { Paging } from "@/components/MkPagination.vue";
|
||||
import type { PagingOf } from "@/components/MkPagination.vue";
|
||||
import MkPagination from "@/components/MkPagination.vue";
|
||||
import { i18n } from "@/i18n";
|
||||
import type { entities } from "firefish-js";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
pagination: Paging;
|
||||
pagination: PagingOf<entities.Channel>;
|
||||
noGap?: boolean;
|
||||
extractor?: (item: any) => any;
|
||||
}>(),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<div>
|
||||
<MkPagination
|
||||
v-slot="{ items }"
|
||||
v-slot="{ items }: { items: entities.DriveFile[]}"
|
||||
:pagination="pagination"
|
||||
class="urempief"
|
||||
:class="{ grid: viewMode === 'grid' }"
|
||||
|
@ -53,13 +53,15 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { acct } from "firefish-js";
|
||||
import type { entities } from "firefish-js";
|
||||
import MkPagination from "@/components/MkPagination.vue";
|
||||
import type { PagingOf } from "@/components/MkPagination.vue";
|
||||
import MkDriveFileThumbnail from "@/components/MkDriveFileThumbnail.vue";
|
||||
import bytes from "@/filters/bytes";
|
||||
import { i18n } from "@/i18n";
|
||||
|
||||
defineProps<{
|
||||
pagination: any;
|
||||
pagination: PagingOf<entities.DriveFile>;
|
||||
viewMode: "grid" | "list";
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
@ -40,17 +40,18 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from "vue";
|
||||
import type { Paging } from "@/components/MkPagination.vue";
|
||||
import type { PagingOf } from "@/components/MkPagination.vue";
|
||||
import XNote from "@/components/MkNote.vue";
|
||||
import XList from "@/components/MkDateSeparatedList.vue";
|
||||
import MkPagination from "@/components/MkPagination.vue";
|
||||
import { i18n } from "@/i18n";
|
||||
import { scroll } from "@/scripts/scroll";
|
||||
import type { entities } from "firefish-js";
|
||||
|
||||
const tlEl = ref<HTMLElement>();
|
||||
|
||||
defineProps<{
|
||||
pagination: Paging;
|
||||
pagination: PagingOf<entities.Note>;
|
||||
noGap?: boolean;
|
||||
disableAutoLoad?: boolean;
|
||||
}>();
|
||||
|
|
|
@ -19,12 +19,8 @@
|
|||
:no-gap="true"
|
||||
>
|
||||
<XNote
|
||||
v-if="
|
||||
['reply', 'quote', 'mention'].includes(
|
||||
notification.type,
|
||||
)
|
||||
"
|
||||
:key="notification.id"
|
||||
v-if="isNoteNotification(notification)"
|
||||
:key="'nn-' + notification.id"
|
||||
:note="notification.note"
|
||||
:collapsed-reply="
|
||||
notification.type === 'reply' ||
|
||||
|
@ -34,7 +30,7 @@
|
|||
/>
|
||||
<XNotification
|
||||
v-else
|
||||
:key="notification.id"
|
||||
:key="'n-' + notification.id"
|
||||
:notification="notification"
|
||||
:with-time="true"
|
||||
:full="true"
|
||||
|
@ -47,8 +43,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onMounted, onUnmounted, ref } from "vue";
|
||||
import type { notificationTypes } from "firefish-js";
|
||||
import type { Paging } from "@/components/MkPagination.vue";
|
||||
import type { entities, notificationTypes } from "firefish-js";
|
||||
import MkPagination from "@/components/MkPagination.vue";
|
||||
import XNotification from "@/components/MkNotification.vue";
|
||||
import XList from "@/components/MkDateSeparatedList.vue";
|
||||
|
@ -66,20 +61,29 @@ const stream = useStream();
|
|||
|
||||
const pagingComponent = ref<InstanceType<typeof MkPagination>>();
|
||||
|
||||
const pagination: Paging = {
|
||||
const pagination = {
|
||||
endpoint: "i/notifications" as const,
|
||||
limit: 10,
|
||||
params: computed(() => ({
|
||||
includeTypes: props.includeTypes ?? undefined,
|
||||
excludeTypes: props.includeTypes ? undefined : me.mutingNotificationTypes,
|
||||
excludeTypes: props.includeTypes ? undefined : me?.mutingNotificationTypes,
|
||||
unreadOnly: props.unreadOnly,
|
||||
})),
|
||||
};
|
||||
|
||||
const onNotification = (notification) => {
|
||||
function isNoteNotification(
|
||||
n: entities.Notification,
|
||||
): n is
|
||||
| entities.ReplyNotification
|
||||
| entities.QuoteNotification
|
||||
| entities.MentionNotification {
|
||||
return n.type === "reply" || n.type === "quote" || n.type === "mention";
|
||||
}
|
||||
|
||||
const onNotification = (notification: entities.Notification) => {
|
||||
const isMuted = props.includeTypes
|
||||
? !props.includeTypes.includes(notification.type)
|
||||
: me.mutingNotificationTypes.includes(notification.type);
|
||||
: me?.mutingNotificationTypes.includes(notification.type);
|
||||
if (isMuted || document.visibilityState === "visible") {
|
||||
stream.send("readNotification", {
|
||||
id: notification.id,
|
||||
|
|
|
@ -66,10 +66,10 @@
|
|||
</transition>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
<script lang="ts" setup generic="E extends keyof Endpoints">
|
||||
import type { ComputedRef } from "vue";
|
||||
import { computed, isRef, onActivated, onDeactivated, ref, watch } from "vue";
|
||||
import type { Endpoints } from "firefish-js";
|
||||
import type { Endpoints, TypeUtils } from "firefish-js";
|
||||
import * as os from "@/os";
|
||||
import {
|
||||
getScrollContainer,
|
||||
|
@ -100,11 +100,13 @@ export interface Paging<E extends keyof Endpoints = keyof Endpoints> {
|
|||
offsetMode?: boolean;
|
||||
}
|
||||
|
||||
export type PagingOf<T> = Paging<TypeUtils.EndpointsOf<T[]>>;
|
||||
|
||||
const SECOND_FETCH_LIMIT = 30;
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
pagination: Paging;
|
||||
pagination: Paging<E>;
|
||||
disableAutoLoad?: boolean;
|
||||
displayLimit?: number;
|
||||
}>(),
|
||||
|
@ -113,14 +115,17 @@ const props = withDefaults(
|
|||
},
|
||||
);
|
||||
|
||||
const slots = defineSlots<{
|
||||
default(props: { items: Item[] }): unknown;
|
||||
empty(props: null): never;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: "queue", count: number): void;
|
||||
(ev: "status", error: boolean): void;
|
||||
}>();
|
||||
|
||||
type Item = Endpoints[typeof props.pagination.endpoint]["res"] & {
|
||||
id: string;
|
||||
};
|
||||
type Item = Endpoints[E]["res"][number];
|
||||
|
||||
const rootEl = ref<HTMLElement>();
|
||||
const items = ref<Item[]>([]);
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
|
||||
<script lang="ts" setup>
|
||||
import { computed, onUnmounted, provide, ref } from "vue";
|
||||
import type { Endpoints } from "firefish-js";
|
||||
import type { entities } from "firefish-js";
|
||||
import MkPullToRefresh from "@/components/MkPullToRefresh.vue";
|
||||
import XNotes from "@/components/MkNotes.vue";
|
||||
import MkInfo from "@/components/MkInfo.vue";
|
||||
|
@ -54,10 +54,23 @@ import { isSignedIn, me } from "@/me";
|
|||
import { i18n } from "@/i18n";
|
||||
import { defaultStore } from "@/store";
|
||||
import icon from "@/scripts/icon";
|
||||
import type { Paging } from "@/components/MkPagination.vue";
|
||||
import type { EndpointsOf } from "@/components/MkPagination.vue";
|
||||
|
||||
export type TimelineSource =
|
||||
| "antenna"
|
||||
| "home"
|
||||
| "local"
|
||||
| "recommended"
|
||||
| "social"
|
||||
| "global"
|
||||
| "mentions"
|
||||
| "directs"
|
||||
| "list"
|
||||
| "channel"
|
||||
| "file";
|
||||
|
||||
const props = defineProps<{
|
||||
src: string;
|
||||
src: TimelineSource;
|
||||
list?: string;
|
||||
antenna?: string;
|
||||
channel?: string;
|
||||
|
@ -73,7 +86,7 @@ const emit = defineEmits<{
|
|||
const tlComponent = ref<InstanceType<typeof XNotes>>();
|
||||
const pullToRefreshComponent = ref<InstanceType<typeof MkPullToRefresh>>();
|
||||
|
||||
let endpoint = ""; // keyof Endpoints
|
||||
let endpoint: EndpointsOf<entities.Note[]>; // keyof Endpoints
|
||||
let query: {
|
||||
antennaId?: string | undefined;
|
||||
withReplies?: boolean;
|
||||
|
@ -81,7 +94,9 @@ let query: {
|
|||
listId?: string | undefined;
|
||||
channelId?: string | undefined;
|
||||
fileId?: string | undefined;
|
||||
};
|
||||
} = {};
|
||||
|
||||
// FIXME: The type defination is wrong here, need fix
|
||||
let connection: {
|
||||
on: (
|
||||
arg0: string,
|
||||
|
@ -96,14 +111,14 @@ let tlHintClosed: boolean;
|
|||
let tlNotesCount = 0;
|
||||
const queue = ref(0);
|
||||
|
||||
const prepend = (note) => {
|
||||
const prepend = (note: entities.Note) => {
|
||||
tlNotesCount++;
|
||||
tlComponent.value?.pagingComponent?.prepend(note);
|
||||
|
||||
emit("note");
|
||||
|
||||
if (props.sound) {
|
||||
sound.play(isSignedIn && note.userId === me.id ? "noteMy" : "note");
|
||||
sound.play(isSignedIn && note.userId === me?.id ? "noteMy" : "note");
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -169,14 +184,17 @@ if (props.src === "antenna") {
|
|||
query = {
|
||||
fileId: props.fileId,
|
||||
};
|
||||
} else {
|
||||
throw "NoEndpointError";
|
||||
}
|
||||
|
||||
const stream = useStream();
|
||||
|
||||
function connectChannel() {
|
||||
if (props.src === "antenna") {
|
||||
if (!props.antenna) throw "NoAntennaProvided";
|
||||
connection = stream.useChannel("antenna", {
|
||||
antennaId: props.antenna!,
|
||||
antennaId: props.antenna,
|
||||
});
|
||||
} else if (props.src === "home") {
|
||||
connection = stream.useChannel("homeTimeline", {
|
||||
|
@ -265,8 +283,8 @@ function reloadTimeline() {
|
|||
});
|
||||
}
|
||||
|
||||
const pagination: Paging = {
|
||||
endpoint: endpoint as keyof Endpoints,
|
||||
const pagination = {
|
||||
endpoint,
|
||||
limit: 10,
|
||||
params: query,
|
||||
};
|
||||
|
|
|
@ -113,10 +113,11 @@ import MkInstanceCardMini from "@/components/MkInstanceCardMini.vue";
|
|||
import FormSplit from "@/components/form/split.vue";
|
||||
import { i18n } from "@/i18n";
|
||||
import icon from "@/scripts/icon";
|
||||
import type { instanceSortParam } from "firefish-js";
|
||||
|
||||
const host = ref("");
|
||||
const state = ref("federating");
|
||||
const sort = ref("+pubSub");
|
||||
const sort = ref<(typeof instanceSortParam)[number]>("+pubSub");
|
||||
const pagination = {
|
||||
endpoint: "federation/instances" as const,
|
||||
limit: 10,
|
||||
|
|
|
@ -94,7 +94,7 @@ const origin = ref("local");
|
|||
const type = ref(null);
|
||||
const searchHost = ref("");
|
||||
const userId = ref("");
|
||||
const viewMode = ref("grid");
|
||||
const viewMode = ref<"list" | "grid">("grid");
|
||||
const pagination = {
|
||||
endpoint: "admin/drive/files" as const,
|
||||
limit: 10,
|
||||
|
|
|
@ -313,7 +313,7 @@ const isSilenced = ref(false);
|
|||
const faviconUrl = ref<string | null>(null);
|
||||
|
||||
const usersPagination = {
|
||||
endpoint: isAdmin ? "admin/show-users" : ("users" as const),
|
||||
endpoint: isAdmin ? ("admin/show-users" as const) : ("users" as const),
|
||||
limit: 10,
|
||||
params: {
|
||||
sort: "+updatedAt",
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
<MkPagination
|
||||
v-else
|
||||
ref="pagingComponent"
|
||||
v-slot="{ items }: { items: entities.NoteEdit[] }"
|
||||
v-slot="{ items }"
|
||||
:pagination="pagination"
|
||||
>
|
||||
<div ref="tlEl" class="giivymft noGap">
|
||||
<XList
|
||||
v-slot="{ item }: { item: entities.Note }"
|
||||
v-slot="{ item }"
|
||||
:items="convertNoteEditsToNotes(items)"
|
||||
class="notes"
|
||||
:no-gap="true"
|
||||
|
@ -35,7 +35,6 @@
|
|||
<script lang="ts" setup>
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import MkPagination from "@/components/MkPagination.vue";
|
||||
import type { Paging } from "@/components/MkPagination.vue";
|
||||
import { api } from "@/os";
|
||||
import XList from "@/components/MkDateSeparatedList.vue";
|
||||
import XNote from "@/components/MkNote.vue";
|
||||
|
@ -50,7 +49,7 @@ const props = defineProps<{
|
|||
noteId: string;
|
||||
}>();
|
||||
|
||||
const pagination: Paging = {
|
||||
const pagination = {
|
||||
endpoint: "notes/history" as const,
|
||||
limit: 10,
|
||||
offsetMode: true,
|
||||
|
|
|
@ -38,6 +38,8 @@ import type {
|
|||
UserSorting,
|
||||
} from "./entities";
|
||||
|
||||
import type * as consts from "./consts";
|
||||
|
||||
type TODO = Record<string, any> | null;
|
||||
|
||||
type NoParams = Record<string, never>;
|
||||
|
@ -84,7 +86,7 @@ export type Endpoints = {
|
|||
"admin/server-info": { req: TODO; res: TODO };
|
||||
"admin/show-moderation-logs": { req: TODO; res: TODO };
|
||||
"admin/show-user": { req: TODO; res: TODO };
|
||||
"admin/show-users": { req: TODO; res: TODO };
|
||||
"admin/show-users": { req: TODO; res: User[] };
|
||||
"admin/silence-user": { req: TODO; res: TODO };
|
||||
"admin/suspend-user": { req: TODO; res: TODO };
|
||||
"admin/unsilence-user": { req: TODO; res: TODO };
|
||||
|
@ -101,7 +103,18 @@ export type Endpoints = {
|
|||
"admin/announcements/update": { req: TODO; res: TODO };
|
||||
"admin/drive/clean-remote-files": { req: TODO; res: TODO };
|
||||
"admin/drive/cleanup": { req: TODO; res: TODO };
|
||||
"admin/drive/files": { req: TODO; res: TODO };
|
||||
"admin/drive/files": {
|
||||
req: {
|
||||
limit?: number;
|
||||
sinceId?: DriveFile["id"];
|
||||
untilId?: DriveFile["id"];
|
||||
userId?: User["id"];
|
||||
type?: string;
|
||||
origin?: "combined" | "local" | "remote";
|
||||
hostname?: string;
|
||||
};
|
||||
res: DriveFile[];
|
||||
};
|
||||
"admin/drive/show-file": { req: TODO; res: TODO };
|
||||
"admin/emoji/add": { req: TODO; res: TODO };
|
||||
"admin/emoji/copy": { req: TODO; res: TODO };
|
||||
|
@ -200,7 +213,7 @@ export type Endpoints = {
|
|||
"channels/owned": { req: TODO; res: TODO };
|
||||
"channels/pin-note": { req: TODO; res: TODO };
|
||||
"channels/show": { req: TODO; res: TODO };
|
||||
"channels/timeline": { req: TODO; res: TODO };
|
||||
"channels/timeline": { req: TODO; res: Note[] };
|
||||
"channels/unfollow": { req: TODO; res: TODO };
|
||||
"channels/update": { req: TODO; res: TODO };
|
||||
|
||||
|
@ -238,7 +251,7 @@ export type Endpoints = {
|
|||
};
|
||||
res: DriveFile[];
|
||||
};
|
||||
"drive/files/attached-notes": { req: TODO; res: TODO };
|
||||
"drive/files/attached-notes": { req: TODO; res: Note[] };
|
||||
"drive/files/check-existence": { req: TODO; res: TODO };
|
||||
"drive/files/create": { req: TODO; res: TODO };
|
||||
"drive/files/delete": { req: { fileId: DriveFile["id"] }; res: null };
|
||||
|
@ -360,25 +373,7 @@ export type Endpoints = {
|
|||
publishing?: boolean | null;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
sort?:
|
||||
| "+pubSub"
|
||||
| "-pubSub"
|
||||
| "+notes"
|
||||
| "-notes"
|
||||
| "+users"
|
||||
| "-users"
|
||||
| "+following"
|
||||
| "-following"
|
||||
| "+followers"
|
||||
| "-followers"
|
||||
| "+caughtAt"
|
||||
| "-caughtAt"
|
||||
| "+lastCommunicatedAt"
|
||||
| "-lastCommunicatedAt"
|
||||
| "+driveUsage"
|
||||
| "-driveUsage"
|
||||
| "+driveFiles"
|
||||
| "-driveFiles";
|
||||
sort?: (typeof consts.instanceSortParam)[number];
|
||||
};
|
||||
res: Instance[];
|
||||
};
|
||||
|
|
|
@ -151,3 +151,24 @@ export const languages = [
|
|||
"yi",
|
||||
"zh",
|
||||
] as const;
|
||||
|
||||
export const instanceSortParam = [
|
||||
"+pubSub",
|
||||
"-pubSub",
|
||||
"+notes",
|
||||
"-notes",
|
||||
"+users",
|
||||
"-users",
|
||||
"+following",
|
||||
"-following",
|
||||
"+followers",
|
||||
"-followers",
|
||||
"+caughtAt",
|
||||
"-caughtAt",
|
||||
"+lastCommunicatedAt",
|
||||
"-lastCommunicatedAt",
|
||||
"+driveUsage",
|
||||
"-driveUsage",
|
||||
"+driveFiles",
|
||||
"-driveFiles",
|
||||
] as const;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import type * as consts from "./consts";
|
||||
|
||||
export type ID = string;
|
||||
export type DateString = string;
|
||||
|
||||
|
@ -108,7 +110,7 @@ export type MeDetailed = UserDetailed & {
|
|||
isExplorable: boolean;
|
||||
mutedWords: string[][];
|
||||
mutedPatterns: string[];
|
||||
mutingNotificationTypes: string[];
|
||||
mutingNotificationTypes: (typeof consts.notificationTypes)[number][];
|
||||
noCrawle: boolean;
|
||||
preventAiLearning: boolean;
|
||||
receiveAnnouncementEmail: boolean;
|
||||
|
@ -129,6 +131,8 @@ export type DriveFile = {
|
|||
blurhash: string;
|
||||
comment: string | null;
|
||||
properties: Record<string, any>;
|
||||
userId?: User["id"];
|
||||
user?: User;
|
||||
};
|
||||
|
||||
export type DriveFolder = TODO;
|
||||
|
@ -152,7 +156,8 @@ export type Note = {
|
|||
visibleUserIds?: User["id"][];
|
||||
lang?: string;
|
||||
localOnly?: boolean;
|
||||
channel?: Channel["id"];
|
||||
channelId?: Channel["id"];
|
||||
channel?: Channel;
|
||||
myReaction?: string;
|
||||
reactions: Record<string, number>;
|
||||
renoteCount: number;
|
||||
|
@ -199,82 +204,98 @@ export type NoteReaction = {
|
|||
type: string;
|
||||
};
|
||||
|
||||
export type Notification = {
|
||||
interface BaseNotification {
|
||||
id: ID;
|
||||
createdAt: DateString;
|
||||
isRead: boolean;
|
||||
} & (
|
||||
| {
|
||||
type: "reaction";
|
||||
reaction: string;
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
| {
|
||||
type: "reply";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
| {
|
||||
type: "renote";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
| {
|
||||
type: "quote";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
| {
|
||||
type: "mention";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
| {
|
||||
type: "pollVote";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
| {
|
||||
type: "pollEnded";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
| {
|
||||
type: "follow";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
}
|
||||
| {
|
||||
type: "followRequestAccepted";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
}
|
||||
| {
|
||||
type: "receiveFollowRequest";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
}
|
||||
| {
|
||||
type: "groupInvited";
|
||||
invitation: UserGroup;
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
}
|
||||
| {
|
||||
type: "app";
|
||||
header?: string | null;
|
||||
body: string;
|
||||
icon?: string | null;
|
||||
}
|
||||
);
|
||||
type: (typeof consts.notificationTypes)[number];
|
||||
}
|
||||
|
||||
export interface ReactionNotification extends BaseNotification {
|
||||
type: "reaction";
|
||||
reaction: string;
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
export interface ReplyNotification extends BaseNotification {
|
||||
type: "reply";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
export interface RenoteNotification extends BaseNotification {
|
||||
type: "renote";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
export interface QuoteNotification extends BaseNotification {
|
||||
type: "quote";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
export interface MentionNotification extends BaseNotification {
|
||||
type: "mention";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
export interface PollVoteNotification extends BaseNotification {
|
||||
type: "pollVote";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
export interface PollEndedNotification extends BaseNotification {
|
||||
type: "pollEnded";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
}
|
||||
export interface FollowNotification extends BaseNotification {
|
||||
type: "follow";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
}
|
||||
|
||||
export interface FollowRequestAcceptedNotification extends BaseNotification {
|
||||
type: "followRequestAccepted";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
}
|
||||
export interface ReceiveFollowRequestNotification extends BaseNotification {
|
||||
type: "receiveFollowRequest";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
}
|
||||
export interface GroupInvitedNotification extends BaseNotification {
|
||||
type: "groupInvited";
|
||||
invitation: UserGroup;
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
}
|
||||
export interface AppNotification extends BaseNotification {
|
||||
type: "app";
|
||||
header?: string | null;
|
||||
body: string;
|
||||
icon?: string | null;
|
||||
}
|
||||
|
||||
export type Notification =
|
||||
| ReactionNotification
|
||||
| ReplyNotification
|
||||
| RenoteNotification
|
||||
| QuoteNotification
|
||||
| MentionNotification
|
||||
| PollVoteNotification
|
||||
| PollEndedNotification
|
||||
| FollowNotification
|
||||
| FollowRequestAcceptedNotification
|
||||
| ReceiveFollowRequestNotification
|
||||
| GroupInvitedNotification
|
||||
| AppNotification;
|
||||
|
||||
export type MessagingMessage = {
|
||||
id: ID;
|
||||
|
@ -451,6 +472,7 @@ export type FollowRequest = {
|
|||
|
||||
export type Channel = {
|
||||
id: ID;
|
||||
name: string;
|
||||
// TODO
|
||||
};
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import { Endpoints } from "./api.types";
|
|||
import * as consts from "./consts";
|
||||
import Stream, { Connection } from "./streaming";
|
||||
import * as StreamTypes from "./streaming.types";
|
||||
import type * as TypeUtils from "./type-utils";
|
||||
|
||||
export {
|
||||
Endpoints,
|
||||
|
@ -12,6 +13,7 @@ export {
|
|||
StreamTypes,
|
||||
acct,
|
||||
type Acct,
|
||||
type TypeUtils,
|
||||
};
|
||||
|
||||
export const permissions = consts.permissions;
|
||||
|
@ -20,6 +22,7 @@ export const noteVisibilities = consts.noteVisibilities;
|
|||
export const mutedNoteReasons = consts.mutedNoteReasons;
|
||||
export const languages = consts.languages;
|
||||
export const ffVisibility = consts.ffVisibility;
|
||||
export const instanceSortParam = consts.instanceSortParam;
|
||||
|
||||
// api extractor not supported yet
|
||||
//export * as api from './api';
|
||||
|
|
|
@ -13,6 +13,10 @@ import type {
|
|||
|
||||
type FIXME = any;
|
||||
|
||||
type TimelineParams = {
|
||||
withReplies?: boolean;
|
||||
};
|
||||
|
||||
export type Channels = {
|
||||
main: {
|
||||
params: null;
|
||||
|
@ -56,35 +60,35 @@ export type Channels = {
|
|||
receives: null;
|
||||
};
|
||||
homeTimeline: {
|
||||
params: null;
|
||||
params?: TimelineParams;
|
||||
events: {
|
||||
note: (payload: Note) => void;
|
||||
};
|
||||
receives: null;
|
||||
};
|
||||
localTimeline: {
|
||||
params: null;
|
||||
params: TimelineParams;
|
||||
events: {
|
||||
note: (payload: Note) => void;
|
||||
};
|
||||
receives: null;
|
||||
};
|
||||
hybridTimeline: {
|
||||
params: null;
|
||||
params: TimelineParams;
|
||||
events: {
|
||||
note: (payload: Note) => void;
|
||||
};
|
||||
receives: null;
|
||||
};
|
||||
recommendedTimeline: {
|
||||
params: null;
|
||||
params: TimelineParams;
|
||||
events: {
|
||||
note: (payload: Note) => void;
|
||||
};
|
||||
receives: null;
|
||||
};
|
||||
globalTimeline: {
|
||||
params: null;
|
||||
params: TimelineParams;
|
||||
events: {
|
||||
note: (payload: Note) => void;
|
||||
};
|
||||
|
|
13
packages/firefish-js/src/type-utils.ts
Normal file
13
packages/firefish-js/src/type-utils.ts
Normal file
|
@ -0,0 +1,13 @@
|
|||
import type { Endpoints } from "./api.types";
|
||||
|
||||
export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <
|
||||
T,
|
||||
>() => T extends Y ? 1 : 2
|
||||
? true
|
||||
: false;
|
||||
|
||||
export type PropertyOfType<Type, U> = {
|
||||
[K in keyof Type]: Type[K] extends U ? K : never;
|
||||
}[keyof Type];
|
||||
|
||||
export type EndpointsOf<T> = PropertyOfType<Endpoints, { res: T }>;
|
Loading…
Reference in a new issue