mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-07-25 06:18:45 +08:00
feat(core): add public user service (#10695)
This commit is contained in:
@@ -16,6 +16,7 @@ export { EventSourceService } from './services/eventsource';
|
||||
export { FetchService } from './services/fetch';
|
||||
export { GraphQLService } from './services/graphql';
|
||||
export { InvoicesService } from './services/invoices';
|
||||
export { PublicUserService } from './services/public-user';
|
||||
export { SelfhostGenerateLicenseService } from './services/selfhost-generate-license';
|
||||
export { SelfhostLicenseService } from './services/selfhost-license';
|
||||
export { ServerService } from './services/server';
|
||||
@@ -63,6 +64,7 @@ import { EventSourceService } from './services/eventsource';
|
||||
import { FetchService } from './services/fetch';
|
||||
import { GraphQLService } from './services/graphql';
|
||||
import { InvoicesService } from './services/invoices';
|
||||
import { PublicUserService } from './services/public-user';
|
||||
import { SelfhostGenerateLicenseService } from './services/selfhost-generate-license';
|
||||
import { SelfhostLicenseService } from './services/selfhost-license';
|
||||
import { ServerService } from './services/server';
|
||||
@@ -79,6 +81,7 @@ import { AuthStore } from './stores/auth';
|
||||
import { CloudDocMetaStore } from './stores/cloud-doc-meta';
|
||||
import { InviteInfoStore } from './stores/invite-info';
|
||||
import { InvoicesStore } from './stores/invoices';
|
||||
import { PublicUserStore } from './stores/public-user';
|
||||
import { SelfhostGenerateLicenseStore } from './stores/selfhost-generate-license';
|
||||
import { SelfhostLicenseStore } from './stores/selfhost-license';
|
||||
import { ServerConfigStore } from './stores/server-config';
|
||||
@@ -147,7 +150,9 @@ export function configureCloudModule(framework: Framework) {
|
||||
.store(SelfhostGenerateLicenseStore, [GraphQLService])
|
||||
.store(InviteInfoStore, [GraphQLService])
|
||||
.service(AcceptInviteService, [AcceptInviteStore, InviteInfoStore])
|
||||
.store(AcceptInviteStore, [GraphQLService]);
|
||||
.store(AcceptInviteStore, [GraphQLService])
|
||||
.service(PublicUserService, [PublicUserStore])
|
||||
.store(PublicUserStore, [GraphQLService]);
|
||||
|
||||
framework
|
||||
.scope(WorkspaceScope)
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
import {
|
||||
effect,
|
||||
fromPromise,
|
||||
LiveData,
|
||||
Service,
|
||||
smartRetry,
|
||||
} from '@toeverything/infra';
|
||||
import { catchError, EMPTY, exhaustMap, groupBy, mergeMap } from 'rxjs';
|
||||
|
||||
import type { PublicUserStore } from '../stores/public-user';
|
||||
|
||||
type RemovedUserInfo = {
|
||||
id: string;
|
||||
removed: true;
|
||||
};
|
||||
|
||||
type ExistedUserInfo = {
|
||||
id: string;
|
||||
name?: string | null;
|
||||
avatar?: string | null;
|
||||
removed?: false;
|
||||
};
|
||||
|
||||
export type PublicUserInfo = RemovedUserInfo | ExistedUserInfo;
|
||||
|
||||
export class PublicUserService extends Service {
|
||||
constructor(private readonly store: PublicUserStore) {
|
||||
super();
|
||||
}
|
||||
|
||||
publicUsers$ = new LiveData<Map<string, PublicUserInfo | null>>(new Map());
|
||||
|
||||
publicUser$(id: string) {
|
||||
return this.publicUsers$.selector(map => map.get(id) ?? null);
|
||||
}
|
||||
|
||||
error$ = new LiveData<any | null>(null);
|
||||
|
||||
revalidate = effect(
|
||||
groupBy((id: string) => id),
|
||||
mergeMap(id$ =>
|
||||
id$.pipe(
|
||||
exhaustMap(id =>
|
||||
fromPromise(async signal => {
|
||||
const user = await this.store.getPublicUserById(id, signal);
|
||||
if (!user) {
|
||||
return {
|
||||
id,
|
||||
removed: true,
|
||||
};
|
||||
}
|
||||
return {
|
||||
id,
|
||||
name: user.name,
|
||||
avatarUrl: user.avatarUrl,
|
||||
};
|
||||
}).pipe(
|
||||
smartRetry(),
|
||||
catchError(error => {
|
||||
console.error(error);
|
||||
this.error$.next(error);
|
||||
return EMPTY;
|
||||
}),
|
||||
mergeMap(user => {
|
||||
const publicUsers = new Map(this.publicUsers$.value);
|
||||
publicUsers.set(user.id, user);
|
||||
this.publicUsers$.next(publicUsers);
|
||||
return EMPTY;
|
||||
})
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
import { getPublicUserByIdQuery } from '@affine/graphql';
|
||||
import { Store } from '@toeverything/infra';
|
||||
|
||||
import type { GraphQLService } from '../services/graphql';
|
||||
|
||||
export class PublicUserStore extends Store {
|
||||
constructor(private readonly gqlService: GraphQLService) {
|
||||
super();
|
||||
}
|
||||
|
||||
async getPublicUserById(id: string, signal?: AbortSignal) {
|
||||
const result = await this.gqlService.gql({
|
||||
query: getPublicUserByIdQuery,
|
||||
variables: {
|
||||
id,
|
||||
},
|
||||
context: {
|
||||
signal,
|
||||
},
|
||||
});
|
||||
|
||||
return result.publicUserById;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user