pl-hooks: Fixes, new hooks
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
e583d15d0d
commit
11a27f9504
15 changed files with 112 additions and 40 deletions
|
@ -11,7 +11,7 @@ import FaviconService from 'pl-fe/utils/favicon-service';
|
|||
FaviconService.initFaviconService();
|
||||
|
||||
const getNotifTotals = (state: RootState): number => {
|
||||
const notifications = state.notifications.unread || 0;
|
||||
const notifications = state.notifications.unread;
|
||||
const reports = state.admin.openReports.count();
|
||||
const approvals = state.admin.awaitingApproval.count();
|
||||
return notifications + reports + approvals;
|
||||
|
|
|
@ -433,8 +433,8 @@ const EventHeader: React.FC<IEventHeader> = ({ status }) => {
|
|||
id='event.participants'
|
||||
defaultMessage='{count} {rawCount, plural, one {person} other {people}} going'
|
||||
values={{
|
||||
rawCount: event.participants_count || 0,
|
||||
count: shortNumberFormat(event.participants_count || 0),
|
||||
rawCount: event.participants_count,
|
||||
count: shortNumberFormat(event.participants_count),
|
||||
}}
|
||||
/>
|
||||
</span>
|
||||
|
|
|
@ -51,7 +51,7 @@ interface GetTextDirectionOpts {
|
|||
}
|
||||
|
||||
/** Get the direction of the text. */
|
||||
const getTextDirection = (text: string, { fallback = 'ltr', confidence }: GetTextDirectionOpts = {}): 'ltr' | 'rtl' => {
|
||||
const getTextDirection = (text?: string, { fallback = 'ltr', confidence }: GetTextDirectionOpts = {}): 'ltr' | 'rtl' => {
|
||||
if (!text) return fallback;
|
||||
return isRtl(text, confidence) ? 'rtl' : 'ltr';
|
||||
};
|
||||
|
|
|
@ -16,8 +16,8 @@ interface UseAccountOpts {
|
|||
}
|
||||
|
||||
const useAccount = (accountId?: string, opts: UseAccountOpts = {}) => {
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
|
||||
const accountQuery = useQuery({
|
||||
queryKey: ['accounts', 'entities', accountId],
|
||||
|
|
|
@ -7,8 +7,8 @@ import { importEntities } from 'pl-hooks/importer';
|
|||
import { useAccount, type UseAccountOpts } from './useAccount';
|
||||
|
||||
const useAccountLookup = (acct?: string, opts: UseAccountOpts = {}) => {
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
const { features } = client;
|
||||
|
||||
const accountIdQuery = useQuery({
|
||||
|
|
|
@ -4,8 +4,8 @@ import { usePlHooksApiClient } from 'pl-hooks/contexts/api-client';
|
|||
import { usePlHooksQueryClient } from 'pl-hooks/contexts/query-client';
|
||||
|
||||
const useAccountRelationship = (accountId?: string) => {
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['accounts', 'entities', accountId],
|
||||
|
|
21
packages/pl-hooks/lib/hooks/instance/useInstance.ts
Normal file
21
packages/pl-hooks/lib/hooks/instance/useInstance.ts
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
import { instanceSchema } from 'pl-api';
|
||||
import * as v from 'valibot';
|
||||
|
||||
import { usePlHooksApiClient } from 'pl-hooks/contexts/api-client';
|
||||
import { usePlHooksQueryClient } from 'pl-hooks/contexts/query-client';
|
||||
|
||||
const placeholderData = v.parse(instanceSchema, {});
|
||||
|
||||
const useInstance = () => {
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['instance'],
|
||||
queryFn: client.instance.getInstance,
|
||||
placeholderData,
|
||||
}, queryClient);
|
||||
};
|
||||
|
||||
export { useInstance };
|
|
@ -0,0 +1,38 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { usePlHooksApiClient } from 'pl-hooks/contexts/api-client';
|
||||
import { usePlHooksQueryClient } from 'pl-hooks/contexts/query-client';
|
||||
|
||||
import { useInstance } from './useInstance';
|
||||
|
||||
const useTranslationLanguages = () => {
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
const { data: instance } = useInstance();
|
||||
|
||||
const {
|
||||
allow_unauthenticated: allowUnauthenticated,
|
||||
} = instance!.pleroma.metadata.translation;
|
||||
|
||||
const getTranslationLanguages = async () => {
|
||||
const metadata = instance!.pleroma.metadata;
|
||||
|
||||
if (metadata.translation.source_languages?.length) {
|
||||
return Object.fromEntries(metadata.translation.source_languages.map(source => [
|
||||
source,
|
||||
metadata.translation.target_languages!.filter(lang => lang !== source),
|
||||
]));
|
||||
}
|
||||
|
||||
return client.instance.getInstanceTranslationLanguages();
|
||||
};
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['instance', 'translationLanguages'],
|
||||
queryFn: getTranslationLanguages,
|
||||
placeholderData: {},
|
||||
enabled: allowUnauthenticated && client.features.translations,
|
||||
}, queryClient);
|
||||
};
|
||||
|
||||
export { useTranslationLanguages };
|
|
@ -8,8 +8,8 @@ import type { PlApiClient } from 'pl-api';
|
|||
type Timeline = 'home' | 'notifications';
|
||||
|
||||
const useMarker = (timeline: Timeline) => {
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['markers', timeline],
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import { useMutation } from '@tanstack/react-query';
|
||||
|
||||
import { usePlHooksApiClient } from 'pl-hooks/contexts/api-client';
|
||||
import { queryClient } from 'pl-hooks/contexts/query-client';
|
||||
import { usePlHooksQueryClient } from 'pl-hooks/contexts/query-client';
|
||||
|
||||
import type { Timeline } from './useMarkers';
|
||||
import type { Marker } from 'pl-api';
|
||||
|
||||
const useUpdateMarkerMutation = (timeline: Timeline) => {
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
|
||||
return useMutation({
|
||||
mutationFn: (lastReadId: string) => client.timelines.saveMarkers({
|
||||
|
@ -20,7 +21,7 @@ const useUpdateMarkerMutation = (timeline: Timeline) => {
|
|||
...marker,
|
||||
last_read_id: lastReadId,
|
||||
}) : undefined),
|
||||
});
|
||||
}, queryClient);
|
||||
};
|
||||
|
||||
export { useUpdateMarkerMutation };
|
||||
|
|
|
@ -25,8 +25,8 @@ const importNotification = (notification: NormalizedNotification) => {
|
|||
};
|
||||
|
||||
const useNotification = (notificationId: string) => {
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
|
||||
const notificationQuery = useQuery({
|
||||
queryKey: ['notifications', 'entities', notificationId],
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { useInfiniteQuery } from '@tanstack/react-query';
|
||||
import { InfiniteData, useInfiniteQuery, UseInfiniteQueryResult } from '@tanstack/react-query';
|
||||
|
||||
import { usePlHooksApiClient } from 'pl-hooks/contexts/api-client';
|
||||
import { queryClient, usePlHooksQueryClient } from 'pl-hooks/contexts/query-client';
|
||||
|
@ -33,9 +33,13 @@ const importNotifications = (response: PaginatedResponse<BaseNotification>) => {
|
|||
};
|
||||
};
|
||||
|
||||
const useNotificationList = (params: UseNotificationParams) => {
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
const useNotificationList = (params: UseNotificationParams): Omit<UseInfiniteQueryResult<InfiniteData<{
|
||||
items: string[];
|
||||
previous: (() => Promise<PaginatedResponse<BaseNotification>>) | null;
|
||||
next: (() => Promise<PaginatedResponse<BaseNotification>>) | null;
|
||||
}, unknown>, Error>, 'data'> & { data: string[] } => {
|
||||
const { client } = usePlHooksApiClient();
|
||||
const queryClient = usePlHooksQueryClient();
|
||||
|
||||
const notificationsQuery = useInfiniteQuery({
|
||||
queryKey: getQueryKey(params),
|
||||
|
@ -47,7 +51,7 @@ const useNotificationList = (params: UseNotificationParams) => {
|
|||
getNextPageParam: (response) => response,
|
||||
}, queryClient);
|
||||
|
||||
const data = flattenPages<string>(notificationsQuery.data) || [];
|
||||
const data: string[] = flattenPages<string>(notificationsQuery.data) || [];
|
||||
|
||||
return {
|
||||
...notificationsQuery,
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useQueries, useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { usePlHooksApiClient } from 'pl-hooks/contexts/api-client';
|
||||
import { queryClient, usePlHooksQueryClient } from 'pl-hooks/contexts/query-client';
|
||||
import { importEntities } from 'pl-hooks/importer';
|
||||
import { useAccount } from 'pl-hooks/main';
|
||||
import { type Account, normalizeAccount } from 'pl-hooks/normalizers/normalizeAccount';
|
||||
|
||||
import { normalizeStatus, type Status } from '../../normalizers/normalizeStatus';
|
||||
|
||||
import type { Account } from 'pl-hooks/normalizers/normalizeAccount';
|
||||
|
||||
// const toServerSideType = (columnType: string): Filter['context'][0] => {
|
||||
// switch (columnType) {
|
||||
// case 'home':
|
||||
|
@ -101,11 +101,14 @@ const useStatus = (statusId?: string, opts: { language?: string } = {}) => {
|
|||
|
||||
const status = statusQuery.data;
|
||||
|
||||
queryClient.getQueriesData({ queryKey: ['test', ['t']] });
|
||||
|
||||
const accountsQuery = queryClient.getQueriesData<Account>({
|
||||
queryKey: ['accounts', 'entities', status?.account_ids],
|
||||
});
|
||||
const accountsQuery = useQueries({
|
||||
queries: status?.account_ids.map(accountId => ({
|
||||
queryKey: ['accounts', 'entities', accountId],
|
||||
queryFn: () => client.accounts.getAccount(accountId!)
|
||||
.then(account => (importEntities({ accounts: [account] }, { withParents: false }), account))
|
||||
.then(normalizeAccount),
|
||||
})) || [],
|
||||
}, queryClient);
|
||||
|
||||
let data: (Status & {
|
||||
account: Account;
|
||||
|
@ -115,8 +118,8 @@ const useStatus = (statusId?: string, opts: { language?: string } = {}) => {
|
|||
if (status) {
|
||||
data = {
|
||||
...status,
|
||||
account: accountsQuery[0][1]!,
|
||||
accounts: accountsQuery.map(([_, account]) => account!).filter(Boolean),
|
||||
account: accountsQuery[0].data!,
|
||||
accounts: accountsQuery.map(({ data }) => data!).filter(Boolean),
|
||||
// quote,
|
||||
// reblog,
|
||||
// poll
|
||||
|
|
|
@ -11,9 +11,9 @@ import type {
|
|||
Status as BaseStatus,
|
||||
} from 'pl-api';
|
||||
|
||||
const importAccount = (account: BaseAccount) => {
|
||||
return queryClient.setQueryData<BaseAccount>(['accounts', 'entities', account.id], account);
|
||||
};
|
||||
const importAccount = (account: BaseAccount) => queryClient.setQueryData<BaseAccount>(
|
||||
['accounts', 'entities', account.id], account,
|
||||
);
|
||||
|
||||
const importGroup = (group: BaseGroup) => queryClient.setQueryData<BaseGroup>(
|
||||
['groups', 'entities', group.id], group,
|
||||
|
@ -33,8 +33,7 @@ const importRelationship = (relationship: BaseRelationship) => queryClient.setQu
|
|||
);
|
||||
|
||||
const importStatus = (status: BaseStatus) => queryClient.setQueryData<Status>(
|
||||
['statuses', 'entities', status.id],
|
||||
_ => normalizeStatus(status),
|
||||
['statuses', 'entities', status.id], normalizeStatus(status),
|
||||
);
|
||||
|
||||
const isEmpty = (object: Record<string, any>) => !Object.values(object).some(value => value);
|
||||
|
@ -56,23 +55,30 @@ const importEntities = (entities: {
|
|||
const relationships: Record<string, BaseRelationship> = {};
|
||||
const statuses: Record<string, BaseStatus> = {};
|
||||
|
||||
const processAccount = (account: BaseAccount) => {
|
||||
const processAccount = (account: BaseAccount, withSelf = true) => {
|
||||
if (withSelf) accounts[account.id] = account;
|
||||
|
||||
queryClient.setQueryData<string>(['accounts', 'byAcct', account.acct.toLocaleLowerCase()], account.id);
|
||||
|
||||
if (account.moved) processAccount(account.moved);
|
||||
if (account.relationship) relationships[account.relationship.id] = account.relationship;
|
||||
};
|
||||
|
||||
const processNotification = (notification: DeduplicatedNotification) => {
|
||||
const processNotification = (notification: DeduplicatedNotification, withSelf = true) => {
|
||||
if (withSelf) notifications[notification.id] = notification;
|
||||
|
||||
processAccount(notification.account);
|
||||
if (notification.type === 'move') processAccount(notification.target);
|
||||
|
||||
if (['mention', 'status', 'reblog', 'favourite', 'poll', 'update', 'emoji_reaction', 'event_reminder', 'participation_accepted', 'participation_request'].includes(notification.type))
|
||||
if (['mention', 'status', 'reblog', 'favourite', 'poll', 'update', 'emoji_reaction', 'event_reminder', 'participation_accepted', 'participation_request'].includes(notification.type)) {
|
||||
// @ts-ignore
|
||||
processStatus(notification.status);
|
||||
}
|
||||
};
|
||||
|
||||
const processStatus = (status: BaseStatus) => {
|
||||
const processStatus = (status: BaseStatus, withSelf = true) => {
|
||||
if (withSelf) statuses[status.id] = status;
|
||||
|
||||
if (status.account) {
|
||||
processAccount(status.account);
|
||||
}
|
||||
|
@ -84,17 +90,14 @@ const importEntities = (entities: {
|
|||
};
|
||||
|
||||
if (options.withParents) {
|
||||
entities.accounts?.forEach(account => accounts[account.id] = account);
|
||||
entities.groups?.forEach(group => groups[group.id] = group);
|
||||
entities.notifications?.forEach(notification => notifications[notification.id] = notification);
|
||||
entities.polls?.forEach(poll => polls[poll.id] = poll);
|
||||
entities.relationships?.forEach(relationship => relationships[relationship.id] = relationship);
|
||||
entities.statuses?.forEach(status => statuses[status.id] = status);
|
||||
}
|
||||
|
||||
entities.accounts?.forEach((account) => processAccount(account));
|
||||
entities.notifications?.forEach((notification) => processNotification(notification));
|
||||
entities.statuses?.forEach((status) => processStatus(status));
|
||||
entities.accounts?.forEach((account) => processAccount(account, options.withParents));
|
||||
entities.notifications?.forEach((notification) => processNotification(notification, options.withParents));
|
||||
entities.statuses?.forEach((status) => processStatus(status, options.withParents));
|
||||
|
||||
if (!isEmpty(accounts)) Object.values(accounts).forEach(importAccount);
|
||||
if (!isEmpty(groups)) Object.values(groups).forEach(importGroup);
|
||||
|
|
|
@ -4,6 +4,8 @@ export * from './contexts/query-client';
|
|||
export * from './hooks/accounts/useAccount';
|
||||
export * from './hooks/accounts/useAccountLookup';
|
||||
export * from './hooks/accounts/useAccountRelationship';
|
||||
export * from './hooks/instance/useInstance';
|
||||
export * from './hooks/instance/useTranslationLanguages';
|
||||
export * from './hooks/markers/useMarkers';
|
||||
export * from './hooks/markers/useUpdateMarkerMutation';
|
||||
export * from './hooks/notifications/useNotification';
|
||||
|
|
Loading…
Reference in a new issue