1
0
mirror of https://github.com/laurent22/joplin.git synced 2024-12-24 10:27:10 +02:00
joplin/packages/app-mobile/components/screens/ShareManager/AcceptedShareItem.tsx

96 lines
3.0 KiB
TypeScript

import * as React from 'react';
import { ShareInvitation } from '@joplin/lib/services/share/reducer';
import { Button, Card, Icon } from 'react-native-paper';
import { _ } from '@joplin/lib/locale';
import { useCallback, useState } from 'react';
import ShareService from '@joplin/lib/services/share/ShareService';
import shim from '@joplin/lib/shim';
import useAsyncEffect from '@joplin/lib/hooks/useAsyncEffect';
import Folder from '@joplin/lib/models/Folder';
import { FolderEntity } from '@joplin/lib/services/database/types';
import Logger from '@joplin/utils/Logger';
import { ViewStyle } from 'react-native';
interface Props {
invitation: ShareInvitation;
processing: boolean;
containerStyle: ViewStyle;
}
const AcceptedIcon = (props: { size: number }) => <Icon {...props} source='account-multiple-check'/>;
const useFolderTitle = (folderId: string) => {
const [folderTitle, setFolderTitle] = useState(undefined);
useAsyncEffect(async event => {
let folder: FolderEntity|null = null;
// If the share was just accepted, the folder might not exist yet.
// In this case, check for the shared item multiple times.
while (!folder && !event.cancelled) {
folder = await Folder.load(folderId);
if (folder) {
setFolderTitle(folder.title);
break;
}
await new Promise<void>(resolve => {
shim.setTimeout(() => resolve(), 1000);
});
}
}, [folderId]);
return folderTitle ?? '...';
};
const logger = Logger.create('AcceptedShareItem');
const AcceptedShareItem: React.FC<Props> = props => {
const invitation = props.invitation;
const sharer = invitation.share.user;
const [leaving, setLeaving] = useState(false);
// The "leave share" button can be briefly visible after leaving a share.
// When this is the case, keep track of hasLeft to prevent clicking it.
const [hasLeft, setHasLeft] = useState(false);
const onLeaveShare = useCallback(async () => {
try {
setLeaving(true);
if (await shim.showConfirmationDialog(_('This will remove the notebook from your collection and you will no longer have access to its content. Do you wish to continue?'))) {
await ShareService.instance().leaveSharedFolder(invitation.share.folder_id, sharer.id);
setHasLeft(true);
}
} catch (error) {
logger.error('Failed to leave share', error);
await shim.showMessageBox(
_('Error: %s', error),
{ buttons: [_('OK')] },
);
} finally {
setLeaving(false);
}
}, [invitation, sharer]);
const folderId = invitation.share.folder_id;
const folderTitle = useFolderTitle(folderId);
return <Card style={props.containerStyle}>
<Card.Title
left={AcceptedIcon}
title={_('Notebook: %s (%s)', folderTitle, folderId)}
subtitle={_('Share from %s (%s)', sharer.full_name, sharer.email)}
/>
<Card.Actions>
<Button
icon='share-off'
onPress={onLeaveShare}
disabled={props.processing || leaving || hasLeft}
loading={leaving || !folderTitle}
>{_('Leave notebook')}</Button>
</Card.Actions>
</Card>;
};
export default AcceptedShareItem;