kopia lustrzana https://gitlab.com/soapbox-pub/soapbox
ProfileHoverCard: use useAccount hook, add usePatronUser hook
rodzic
25d3925b76
commit
e01ee84ee9
|
@ -3,22 +3,25 @@ import { useEntity } from 'soapbox/entity-store/hooks';
|
||||||
import { useApi } from 'soapbox/hooks/useApi';
|
import { useApi } from 'soapbox/hooks/useApi';
|
||||||
import { type Account, accountSchema } from 'soapbox/schemas';
|
import { type Account, accountSchema } from 'soapbox/schemas';
|
||||||
|
|
||||||
|
|
||||||
import { useRelationships } from './useRelationships';
|
import { useRelationships } from './useRelationships';
|
||||||
|
|
||||||
function useAccount(id: string) {
|
function useAccount(accountId?: string) {
|
||||||
const api = useApi();
|
const api = useApi();
|
||||||
|
|
||||||
const { entity: account, ...result } = useEntity<Account>(
|
const { entity: account, ...result } = useEntity<Account>(
|
||||||
[Entities.ACCOUNTS, id],
|
[Entities.ACCOUNTS, accountId || ''],
|
||||||
() => api.get(`/api/v1/accounts/${id}`),
|
() => api.get(`/api/v1/accounts/${accountId}`),
|
||||||
{ schema: accountSchema },
|
{ schema: accountSchema, enabled: !!accountId },
|
||||||
);
|
);
|
||||||
const { relationships, isLoading } = useRelationships([account?.id as string]);
|
const {
|
||||||
|
relationships,
|
||||||
|
isLoading: isRelationshipLoading,
|
||||||
|
} = useRelationships(accountId ? [accountId] : []);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...result,
|
...result,
|
||||||
isLoading: result.isLoading || isLoading,
|
isLoading: result.isLoading,
|
||||||
|
isRelationshipLoading,
|
||||||
account: account ? { ...account, relationship: relationships[0] || null } : undefined,
|
account: account ? { ...account, relationship: relationships[0] || null } : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
import { Entities } from 'soapbox/entity-store/entities';
|
||||||
|
import { useEntity } from 'soapbox/entity-store/hooks';
|
||||||
|
import { useApi } from 'soapbox/hooks/useApi';
|
||||||
|
import { type PatronUser, patronUserSchema } from 'soapbox/schemas';
|
||||||
|
|
||||||
|
function usePatronUser(url?: string) {
|
||||||
|
const api = useApi();
|
||||||
|
|
||||||
|
const { entity: patronUser, ...result } = useEntity<PatronUser>(
|
||||||
|
[Entities.PATRON_USERS, url || ''],
|
||||||
|
() => api.get(`/api/patron/v1/accounts/${encodeURIComponent(url!)}`),
|
||||||
|
{ schema: patronUserSchema, enabled: !!url },
|
||||||
|
);
|
||||||
|
|
||||||
|
return { patronUser, ...result };
|
||||||
|
}
|
||||||
|
|
||||||
|
export { usePatronUser };
|
|
@ -3,6 +3,7 @@
|
||||||
* Accounts
|
* Accounts
|
||||||
*/
|
*/
|
||||||
export { useAccount } from './accounts/useAccount';
|
export { useAccount } from './accounts/useAccount';
|
||||||
|
export { usePatronUser } from './accounts/usePatronUser';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Groups
|
* Groups
|
||||||
|
|
|
@ -9,32 +9,30 @@ import {
|
||||||
closeProfileHoverCard,
|
closeProfileHoverCard,
|
||||||
updateProfileHoverCard,
|
updateProfileHoverCard,
|
||||||
} from 'soapbox/actions/profile-hover-card';
|
} from 'soapbox/actions/profile-hover-card';
|
||||||
|
import { useAccount, usePatronUser } from 'soapbox/api/hooks';
|
||||||
import Badge from 'soapbox/components/badge';
|
import Badge from 'soapbox/components/badge';
|
||||||
import ActionButton from 'soapbox/features/ui/components/action-button';
|
import ActionButton from 'soapbox/features/ui/components/action-button';
|
||||||
import BundleContainer from 'soapbox/features/ui/containers/bundle-container';
|
import BundleContainer from 'soapbox/features/ui/containers/bundle-container';
|
||||||
import { UserPanel } from 'soapbox/features/ui/util/async-components';
|
import { UserPanel } from 'soapbox/features/ui/util/async-components';
|
||||||
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
||||||
import { makeGetAccount } from 'soapbox/selectors';
|
|
||||||
import { isLocal } from 'soapbox/utils/accounts';
|
import { isLocal } from 'soapbox/utils/accounts';
|
||||||
|
|
||||||
import { showProfileHoverCard } from './hover-ref-wrapper';
|
import { showProfileHoverCard } from './hover-ref-wrapper';
|
||||||
import { Card, CardBody, HStack, Icon, Stack, Text } from './ui';
|
import { Card, CardBody, HStack, Icon, Stack, Text } from './ui';
|
||||||
|
|
||||||
|
import type { Account, PatronUser } from 'soapbox/schemas';
|
||||||
import type { AppDispatch } from 'soapbox/store';
|
import type { AppDispatch } from 'soapbox/store';
|
||||||
import type { Account } from 'soapbox/types/entities';
|
|
||||||
|
|
||||||
const getAccount = makeGetAccount();
|
const getBadges = (account?: Account, patronUser?: PatronUser): JSX.Element[] => {
|
||||||
|
|
||||||
const getBadges = (account: Account): JSX.Element[] => {
|
|
||||||
const badges = [];
|
const badges = [];
|
||||||
|
|
||||||
if (account.admin) {
|
if (account?.admin) {
|
||||||
badges.push(<Badge key='admin' slug='admin' title='Admin' />);
|
badges.push(<Badge key='admin' slug='admin' title='Admin' />);
|
||||||
} else if (account.moderator) {
|
} else if (account?.moderator) {
|
||||||
badges.push(<Badge key='moderator' slug='moderator' title='Moderator' />);
|
badges.push(<Badge key='moderator' slug='moderator' title='Moderator' />);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (account.getIn(['patron', 'is_patron'])) {
|
if (patronUser?.is_patron) {
|
||||||
badges.push(<Badge key='patron' slug='patron' title='Patron' />);
|
badges.push(<Badge key='patron' slug='patron' title='Patron' />);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +65,10 @@ export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }
|
||||||
|
|
||||||
const me = useAppSelector(state => state.me);
|
const me = useAppSelector(state => state.me);
|
||||||
const accountId: string | undefined = useAppSelector(state => state.profile_hover_card.accountId || undefined);
|
const accountId: string | undefined = useAppSelector(state => state.profile_hover_card.accountId || undefined);
|
||||||
const account = useAppSelector(state => accountId && getAccount(state, accountId));
|
const { account } = useAccount(accountId);
|
||||||
|
const { patronUser } = usePatronUser(account?.url);
|
||||||
const targetRef = useAppSelector(state => state.profile_hover_card.ref?.current);
|
const targetRef = useAppSelector(state => state.profile_hover_card.ref?.current);
|
||||||
const badges = account ? getBadges(account) : [];
|
const badges = getBadges(account, patronUser);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (accountId) dispatch(fetchRelationships([accountId]));
|
if (accountId) dispatch(fetchRelationships([accountId]));
|
||||||
|
@ -112,7 +111,7 @@ export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }
|
||||||
<BundleContainer fetchComponent={UserPanel}>
|
<BundleContainer fetchComponent={UserPanel}>
|
||||||
{Component => (
|
{Component => (
|
||||||
<Component
|
<Component
|
||||||
accountId={account.get('id')}
|
accountId={account.id}
|
||||||
action={<ActionButton account={account} small />}
|
action={<ActionButton account={account} small />}
|
||||||
badges={badges}
|
badges={badges}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -4,6 +4,7 @@ export enum Entities {
|
||||||
GROUP_MEMBERSHIPS = 'GroupMemberships',
|
GROUP_MEMBERSHIPS = 'GroupMemberships',
|
||||||
GROUP_RELATIONSHIPS = 'GroupRelationships',
|
GROUP_RELATIONSHIPS = 'GroupRelationships',
|
||||||
GROUP_TAGS = 'GroupTags',
|
GROUP_TAGS = 'GroupTags',
|
||||||
|
PATRON_USERS = 'PatronUsers',
|
||||||
RELATIONSHIPS = 'Relationships',
|
RELATIONSHIPS = 'Relationships',
|
||||||
STATUSES = 'Statuses'
|
STATUSES = 'Statuses'
|
||||||
}
|
}
|
|
@ -10,6 +10,7 @@ export { groupRelationshipSchema, type GroupRelationship } from './group-relatio
|
||||||
export { groupTagSchema, type GroupTag } from './group-tag';
|
export { groupTagSchema, type GroupTag } from './group-tag';
|
||||||
export { mentionSchema, type Mention } from './mention';
|
export { mentionSchema, type Mention } from './mention';
|
||||||
export { notificationSchema, type Notification } from './notification';
|
export { notificationSchema, type Notification } from './notification';
|
||||||
|
export { patronUserSchema, type PatronUser } from './patron';
|
||||||
export { pollSchema, type Poll, type PollOption } from './poll';
|
export { pollSchema, type Poll, type PollOption } from './poll';
|
||||||
export { relationshipSchema, type Relationship } from './relationship';
|
export { relationshipSchema, type Relationship } from './relationship';
|
||||||
export { statusSchema, type Status } from './status';
|
export { statusSchema, type Status } from './status';
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { z } from 'zod';
|
||||||
|
|
||||||
|
const patronUserSchema = z.object({
|
||||||
|
is_patron: z.boolean().catch(false),
|
||||||
|
url: z.string().url(),
|
||||||
|
}).transform((patron) => {
|
||||||
|
return {
|
||||||
|
id: patron.url,
|
||||||
|
...patron,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
type PatronUser = z.infer<typeof patronUserSchema>;
|
||||||
|
|
||||||
|
export { patronUserSchema, type PatronUser };
|
Ładowanie…
Reference in New Issue