nicolium: groups migrations
Signed-off-by: nicole mikołajczyk <git@mkljczk.pl>
This commit is contained in:
@ -2,16 +2,15 @@ import { GroupRoles } from 'pl-api';
|
||||
import React from 'react';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import { useJoinGroup } from '@/api/hooks/groups/use-join-group';
|
||||
import { useLeaveGroup } from '@/api/hooks/groups/use-leave-group';
|
||||
import Button from '@/components/ui/button';
|
||||
import { importEntities } from '@/entity-store/actions';
|
||||
import { Entities } from '@/entity-store/entities';
|
||||
import { useAppDispatch } from '@/hooks/use-app-dispatch';
|
||||
import {
|
||||
useJoinGroupMutation,
|
||||
useLeaveGroupMutation,
|
||||
} from '@/queries/groups/use-group-relationship';
|
||||
import { useModalsActions } from '@/stores/modals';
|
||||
import toast from '@/toast';
|
||||
|
||||
import type { Group, GroupRelationship } from 'pl-api';
|
||||
import type { Group } from 'pl-api';
|
||||
|
||||
interface IGroupActionButton {
|
||||
group: Pick<Group, 'id' | 'locked' | 'relationship'>;
|
||||
@ -33,12 +32,11 @@ const messages = defineMessages({
|
||||
});
|
||||
|
||||
const GroupActionButton = ({ group }: IGroupActionButton) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const intl = useIntl();
|
||||
|
||||
const { openModal } = useModalsActions();
|
||||
const joinGroup = useJoinGroup(group);
|
||||
const leaveGroup = useLeaveGroup(group);
|
||||
const { mutate: joinGroup, isPending: isJoiningGroup } = useJoinGroupMutation(group.id);
|
||||
const { mutate: leaveGroup, isPending: isLeavingGroup } = useLeaveGroupMutation(group.id);
|
||||
|
||||
const isRequested = group.relationship?.requested;
|
||||
const isNonMember = !group.relationship?.member && !isRequested;
|
||||
@ -46,26 +44,21 @@ const GroupActionButton = ({ group }: IGroupActionButton) => {
|
||||
const isAdmin = group.relationship?.role === GroupRoles.ADMIN;
|
||||
|
||||
const onJoinGroup = () =>
|
||||
joinGroup.mutate(
|
||||
{},
|
||||
{
|
||||
onSuccess() {
|
||||
joinGroup.invalidate();
|
||||
|
||||
toast.success(
|
||||
group.locked
|
||||
? intl.formatMessage(messages.joinRequestSuccess)
|
||||
: intl.formatMessage(messages.joinSuccess),
|
||||
);
|
||||
},
|
||||
onError(error) {
|
||||
const message = error.response?.json?.error;
|
||||
if (message) {
|
||||
toast.error(message);
|
||||
}
|
||||
},
|
||||
joinGroup(undefined, {
|
||||
onSuccess: () => {
|
||||
toast.success(
|
||||
group.locked
|
||||
? intl.formatMessage(messages.joinRequestSuccess)
|
||||
: intl.formatMessage(messages.joinSuccess),
|
||||
);
|
||||
},
|
||||
);
|
||||
// onError: (error) => {
|
||||
// const message = error.response?.json?.error;
|
||||
// if (message) {
|
||||
// toast.error(message);
|
||||
// }
|
||||
// },
|
||||
});
|
||||
|
||||
const onLeaveGroup = () => {
|
||||
openModal('CONFIRM', {
|
||||
@ -73,25 +66,15 @@ const GroupActionButton = ({ group }: IGroupActionButton) => {
|
||||
message: intl.formatMessage(messages.confirmationMessage),
|
||||
confirm: intl.formatMessage(messages.confirmationConfirm),
|
||||
onConfirm: () =>
|
||||
leaveGroup.mutate(group.relationship?.id as string, {
|
||||
onSuccess() {
|
||||
leaveGroup.invalidate();
|
||||
leaveGroup(undefined, {
|
||||
onSuccess: () => {
|
||||
toast.success(intl.formatMessage(messages.leaveSuccess));
|
||||
},
|
||||
}),
|
||||
});
|
||||
};
|
||||
|
||||
const onCancelRequest = () =>
|
||||
leaveGroup.mutate(group.relationship?.id as string, {
|
||||
onSuccess() {
|
||||
const entity = {
|
||||
...(group.relationship as GroupRelationship),
|
||||
requested: false,
|
||||
};
|
||||
dispatch(importEntities([entity], Entities.GROUP_RELATIONSHIPS));
|
||||
},
|
||||
});
|
||||
const onCancelRequest = () => leaveGroup();
|
||||
|
||||
if (isOwner || isAdmin) {
|
||||
return (
|
||||
@ -103,7 +86,7 @@ const GroupActionButton = ({ group }: IGroupActionButton) => {
|
||||
|
||||
if (isNonMember) {
|
||||
return (
|
||||
<Button theme='primary' onClick={onJoinGroup} disabled={joinGroup.isSubmitting}>
|
||||
<Button theme='primary' onClick={onJoinGroup} disabled={isJoiningGroup || isLeavingGroup}>
|
||||
{group.locked ? (
|
||||
<FormattedMessage id='group.join.private' defaultMessage='Request access' />
|
||||
) : (
|
||||
@ -115,14 +98,18 @@ const GroupActionButton = ({ group }: IGroupActionButton) => {
|
||||
|
||||
if (isRequested) {
|
||||
return (
|
||||
<Button theme='secondary' onClick={onCancelRequest} disabled={leaveGroup.isSubmitting}>
|
||||
<Button
|
||||
theme='secondary'
|
||||
onClick={onCancelRequest}
|
||||
disabled={isJoiningGroup || isLeavingGroup}
|
||||
>
|
||||
<FormattedMessage id='group.cancel_request' defaultMessage='Cancel request' />
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Button theme='secondary' onClick={onLeaveGroup} disabled={leaveGroup.isSubmitting}>
|
||||
<Button theme='secondary' onClick={onLeaveGroup} disabled={isJoiningGroup || isLeavingGroup}>
|
||||
<FormattedMessage id='group.leave' defaultMessage='Leave group' />
|
||||
</Button>
|
||||
);
|
||||
|
||||
@ -4,8 +4,6 @@ import React, { useMemo } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { useAccount } from '@/api/hooks/accounts/use-account';
|
||||
import { useDemoteGroupMember } from '@/api/hooks/groups/use-demote-group-member';
|
||||
import { usePromoteGroupMember } from '@/api/hooks/groups/use-promote-group-member';
|
||||
import Account from '@/components/account';
|
||||
import DropdownMenu from '@/components/dropdown-menu/dropdown-menu';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
@ -15,7 +13,9 @@ import PlaceholderAccount from '@/features/placeholder/components/placeholder-ac
|
||||
import { useAppDispatch } from '@/hooks/use-app-dispatch';
|
||||
import { useBlockGroupUserMutation } from '@/queries/groups/use-group-blocks';
|
||||
import {
|
||||
useDemoteGroupMemberMutation,
|
||||
useKickGroupMemberMutation,
|
||||
usePromoteGroupMemberMutation,
|
||||
type MinifiedGroupMember,
|
||||
} from '@/queries/groups/use-group-members';
|
||||
import { useModalsActions } from '@/stores/modals';
|
||||
@ -79,8 +79,8 @@ const GroupMemberListItem = ({ member, group }: IGroupMemberListItem) => {
|
||||
|
||||
const { mutate: blockGroupMember } = useBlockGroupUserMutation(group.id, member.account_id);
|
||||
const { mutate: kickGroupMember } = useKickGroupMemberMutation(group.id, member.account_id);
|
||||
const promoteGroupMember = usePromoteGroupMember(group, member);
|
||||
const demoteGroupMember = useDemoteGroupMember(group, member);
|
||||
const { mutate: promoteGroupMember } = usePromoteGroupMemberMutation(group.id);
|
||||
const { mutate: demoteGroupMember } = useDemoteGroupMemberMutation(group.id);
|
||||
|
||||
const { account, isLoading } = useAccount(member.account_id);
|
||||
|
||||
@ -91,6 +91,7 @@ const GroupMemberListItem = ({ member, group }: IGroupMemberListItem) => {
|
||||
// Member role
|
||||
const isMemberOwner = member.role === GroupRoles.OWNER;
|
||||
const isMemberAdmin = member.role === GroupRoles.ADMIN;
|
||||
// const isMemberModerator = membisMemberModeratorer.role === GroupRoles.MODERATOR;
|
||||
const isMemberUser = member.role === GroupRoles.USER;
|
||||
|
||||
const handleKickFromGroup = () => {
|
||||
@ -131,7 +132,7 @@ const GroupMemberListItem = ({ member, group }: IGroupMemberListItem) => {
|
||||
confirm: intl.formatMessage(messages.promoteConfirm),
|
||||
onConfirm: () => {
|
||||
promoteGroupMember(
|
||||
{ role: GroupRoles.ADMIN, account_ids: [member.account_id] },
|
||||
{ accountId: member.account_id, role: GroupRoles.ADMIN },
|
||||
{
|
||||
onSuccess() {
|
||||
toast.success(intl.formatMessage(messages.promotedToAdmin, { name: account?.acct }));
|
||||
@ -144,7 +145,7 @@ const GroupMemberListItem = ({ member, group }: IGroupMemberListItem) => {
|
||||
|
||||
const handleUserAssignment = () => {
|
||||
demoteGroupMember(
|
||||
{ role: GroupRoles.USER, account_ids: [member.account_id] },
|
||||
{ accountId: member.account_id, role: GroupRoles.USER },
|
||||
{
|
||||
onSuccess() {
|
||||
toast.success(intl.formatMessage(messages.demotedToUser, { name: account?.acct }));
|
||||
|
||||
@ -2,9 +2,9 @@ import { GroupRoles, type Group } from 'pl-api';
|
||||
import React, { useMemo } from 'react';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
import { useLeaveGroup } from '@/api/hooks/groups/use-leave-group';
|
||||
import DropdownMenu, { Menu } from '@/components/dropdown-menu';
|
||||
import IconButton from '@/components/ui/icon-button';
|
||||
import { useLeaveGroupMutation } from '@/queries/groups/use-group-relationship';
|
||||
import { useModalsActions } from '@/stores/modals';
|
||||
import toast from '@/toast';
|
||||
|
||||
@ -28,7 +28,7 @@ const GroupOptionsButton = ({ group }: IGroupActionButton) => {
|
||||
const { openModal } = useModalsActions();
|
||||
const intl = useIntl();
|
||||
|
||||
const leaveGroup = useLeaveGroup(group);
|
||||
const { mutate: leaveGroup } = useLeaveGroupMutation(group.id);
|
||||
|
||||
const isMember = group.relationship?.role === GroupRoles.USER;
|
||||
const isAdmin = group.relationship?.role === GroupRoles.ADMIN;
|
||||
@ -51,9 +51,8 @@ const GroupOptionsButton = ({ group }: IGroupActionButton) => {
|
||||
message: intl.formatMessage(messages.confirmationMessage),
|
||||
confirm: intl.formatMessage(messages.confirmationConfirm),
|
||||
onConfirm: () =>
|
||||
leaveGroup.mutate(group.relationship?.id as string, {
|
||||
onSuccess() {
|
||||
leaveGroup.invalidate();
|
||||
leaveGroup(undefined, {
|
||||
onSuccess: () => {
|
||||
toast.success(intl.formatMessage(messages.leaveSuccess));
|
||||
},
|
||||
}),
|
||||
|
||||
@ -9,27 +9,18 @@ import Stack from '@/components/ui/stack';
|
||||
import Text from '@/components/ui/text';
|
||||
import Emojify from '@/features/emoji/emojify';
|
||||
import GroupActionButton from '@/features/group/components/group-action-button';
|
||||
import { useGroupQuery } from '@/queries/groups/use-group';
|
||||
import { shortNumberFormat } from '@/utils/numbers';
|
||||
|
||||
import type { Group } from 'pl-api';
|
||||
|
||||
interface IGroupListItem {
|
||||
group: Pick<
|
||||
Group,
|
||||
| 'id'
|
||||
| 'avatar'
|
||||
| 'avatar_description'
|
||||
| 'display_name'
|
||||
| 'emojis'
|
||||
| 'locked'
|
||||
| 'members_count'
|
||||
| 'relationship'
|
||||
>;
|
||||
groupId: string;
|
||||
withJoinAction?: boolean;
|
||||
}
|
||||
|
||||
const GroupListItem = (props: IGroupListItem) => {
|
||||
const { group, withJoinAction = true } = props;
|
||||
const GroupListItem: React.FC<IGroupListItem> = ({ groupId, withJoinAction = true }) => {
|
||||
const { data: group } = useGroupQuery(groupId, true);
|
||||
|
||||
if (!group) return null;
|
||||
|
||||
return (
|
||||
<HStack alignItems='center' justifyContent='between' data-testid='group-list-item'>
|
||||
|
||||
@ -3,11 +3,11 @@ import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { groupComposeModal } from '@/actions/compose';
|
||||
import { useGroup } from '@/api/hooks/groups/use-group';
|
||||
import Avatar from '@/components/ui/avatar';
|
||||
import HStack from '@/components/ui/hstack';
|
||||
import Icon from '@/components/ui/icon';
|
||||
import { useAppDispatch } from '@/hooks/use-app-dispatch';
|
||||
import { useGroupQuery } from '@/queries/groups/use-group';
|
||||
import { useModalsActions } from '@/stores/modals';
|
||||
|
||||
import { layouts } from '../router';
|
||||
@ -19,7 +19,7 @@ interface IComposeButton {
|
||||
|
||||
const ComposeButton: React.FC<IComposeButton> = ({ shrink }) => {
|
||||
const match = useMatch({ from: layouts.group.id, shouldThrow: false });
|
||||
const { group } = useGroup(match?.params.groupId ?? '');
|
||||
const { data: group } = useGroupQuery(match?.params.groupId);
|
||||
const isGroupMember = !!group?.relationship?.member;
|
||||
|
||||
if (match && isGroupMember) {
|
||||
@ -49,7 +49,7 @@ const HomeComposeButton: React.FC<IComposeButton> = ({ shrink }) => {
|
||||
const GroupComposeButton: React.FC<IComposeButton> = ({ shrink }) => {
|
||||
const dispatch = useAppDispatch();
|
||||
const match = useMatch({ from: layouts.group.id, shouldThrow: false });
|
||||
const { group } = useGroup(match?.params.groupId ?? '');
|
||||
const { data: group } = useGroupQuery(match?.params.groupId);
|
||||
|
||||
if (!group) return null;
|
||||
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import React from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { useGroups } from '@/api/hooks/groups/use-groups';
|
||||
import Widget from '@/components/ui/widget';
|
||||
import GroupListItem from '@/features/groups/components/discover/group-list-item';
|
||||
import PlaceholderGroupSearch from '@/features/placeholder/components/placeholder-group-search';
|
||||
import { useGroupsQuery } from '@/queries/groups/use-groups';
|
||||
|
||||
const MyGroupsPanel = () => {
|
||||
const { groups, isFetching, isFetched, isError } = useGroups();
|
||||
const isEmpty = (isFetched && groups.length === 0) ?? isError;
|
||||
const { data: groupIds = [], isFetching, isError } = useGroupsQuery();
|
||||
const isEmpty = (!isFetching && groupIds.length === 0) ?? isError;
|
||||
|
||||
if (isEmpty) {
|
||||
return null;
|
||||
@ -20,9 +20,11 @@ const MyGroupsPanel = () => {
|
||||
? new Array(3)
|
||||
.fill(0)
|
||||
.map((_, idx) => <PlaceholderGroupSearch key={idx} withJoinAction={false} />)
|
||||
: groups
|
||||
: groupIds
|
||||
.slice(0, 3)
|
||||
.map((group) => <GroupListItem group={group} withJoinAction={false} key={group.id} />)}
|
||||
.map((groupId) => (
|
||||
<GroupListItem groupId={groupId} withJoinAction={false} key={groupId} />
|
||||
))}
|
||||
</Widget>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user