- Updated App entry point to utilize Expo Router, simplifying the navigation setup. - Removed legacy navigation components and services to streamline the codebase. - Adjusted package.json to reflect the new entry point and updated dependencies for compatibility. - Enhanced overall application structure by consolidating navigation logic and improving maintainability.
111 lines
3.4 KiB
TypeScript
111 lines
3.4 KiB
TypeScript
import { groupService } from '../services/groupService';
|
|
import { CursorPaginationResponse, GroupMemberResponse } from '../types/dto';
|
|
|
|
export const GROUP_MEMBER_LIST_PAGE_SIZE = 50;
|
|
|
|
export type GroupMemberListSourceKind = 'cursor' | 'offset';
|
|
|
|
export interface IGroupMemberListPagedSource {
|
|
restart(): void;
|
|
loadNext(): Promise<CursorPaginationResponse<GroupMemberResponse>>;
|
|
readonly hasMore: boolean;
|
|
}
|
|
|
|
export class NetworkCursorGroupMemberListPagedSource implements IGroupMemberListPagedSource {
|
|
private nextCursor: string | null = null;
|
|
private hasMoreAfterLastLoad = false;
|
|
private loadedOnce = false;
|
|
private readonly groupId: string;
|
|
private readonly pageSize: number;
|
|
|
|
constructor(groupId: string, pageSize: number = GROUP_MEMBER_LIST_PAGE_SIZE) {
|
|
this.groupId = groupId;
|
|
this.pageSize = pageSize;
|
|
}
|
|
|
|
restart(): void {
|
|
this.nextCursor = null;
|
|
this.hasMoreAfterLastLoad = false;
|
|
this.loadedOnce = false;
|
|
}
|
|
|
|
get hasMore(): boolean {
|
|
return this.loadedOnce && this.hasMoreAfterLastLoad;
|
|
}
|
|
|
|
async loadNext(): Promise<CursorPaginationResponse<GroupMemberResponse>> {
|
|
const response = await groupService.getGroupMembersCursor(
|
|
this.groupId,
|
|
this.nextCursor == null
|
|
? { page_size: this.pageSize }
|
|
: { cursor: this.nextCursor, page_size: this.pageSize }
|
|
);
|
|
|
|
this.nextCursor = response.next_cursor ?? null;
|
|
this.hasMoreAfterLastLoad = Boolean(response.has_more && response.next_cursor != null);
|
|
this.loadedOnce = true;
|
|
|
|
return {
|
|
list: response.list || [],
|
|
next_cursor: response.next_cursor ?? null,
|
|
prev_cursor: response.prev_cursor ?? null,
|
|
has_more: response.has_more ?? false,
|
|
};
|
|
}
|
|
}
|
|
|
|
export class NetworkOffsetGroupMemberListPagedSource implements IGroupMemberListPagedSource {
|
|
private nextPage = 1;
|
|
private hasMoreAfterLastLoad = false;
|
|
private loadedOnce = false;
|
|
private readonly groupId: string;
|
|
private readonly pageSize: number;
|
|
|
|
constructor(groupId: string, pageSize: number = GROUP_MEMBER_LIST_PAGE_SIZE) {
|
|
this.groupId = groupId;
|
|
this.pageSize = pageSize;
|
|
}
|
|
|
|
restart(): void {
|
|
this.nextPage = 1;
|
|
this.hasMoreAfterLastLoad = false;
|
|
this.loadedOnce = false;
|
|
}
|
|
|
|
get hasMore(): boolean {
|
|
return this.loadedOnce && this.hasMoreAfterLastLoad;
|
|
}
|
|
|
|
async loadNext(): Promise<CursorPaginationResponse<GroupMemberResponse>> {
|
|
const response = await groupService.getMembers(this.groupId, this.nextPage, this.pageSize);
|
|
const list = response.list || [];
|
|
const currentPage = response.page ?? this.nextPage;
|
|
const totalPages = response.total_pages ?? currentPage;
|
|
const hasMore = currentPage < totalPages;
|
|
const nextPageCursor = hasMore ? String(currentPage + 1) : null;
|
|
const prevPageCursor = currentPage > 1 ? String(currentPage - 1) : null;
|
|
|
|
this.nextPage = currentPage + 1;
|
|
this.hasMoreAfterLastLoad = hasMore;
|
|
this.loadedOnce = true;
|
|
|
|
return {
|
|
list,
|
|
next_cursor: nextPageCursor,
|
|
prev_cursor: prevPageCursor,
|
|
has_more: hasMore,
|
|
};
|
|
}
|
|
}
|
|
|
|
export function createRemoteGroupMemberListSource(
|
|
kind: GroupMemberListSourceKind,
|
|
groupId: string,
|
|
pageSize: number = GROUP_MEMBER_LIST_PAGE_SIZE
|
|
): IGroupMemberListPagedSource {
|
|
return kind === 'offset'
|
|
? new NetworkOffsetGroupMemberListPagedSource(groupId, pageSize)
|
|
: new NetworkCursorGroupMemberListPagedSource(groupId, pageSize);
|
|
}
|
|
|