import * as React from 'react'; import { Button, Divider, Text } from 'react-native-paper'; import { View, StyleSheet, ScrollView, Linking } from 'react-native'; import Note from '@joplin/lib/models/Note'; import { NoteEntity } from '@joplin/lib/services/database/types'; import { StateShare } from '@joplin/lib/services/share/reducer'; import ShareService from '@joplin/lib/services/share/ShareService'; import { useCallback, useEffect, useMemo, useState } from 'react'; import useAsyncEffect from '@joplin/lib/hooks/useAsyncEffect'; import Clipboard from '@react-native-clipboard/clipboard'; import useOnShareLinkClick from '@joplin/lib/components/shared/ShareNoteDialog/useOnShareLinkClick'; import onUnshareNoteClick from '@joplin/lib/components/shared/ShareNoteDialog/onUnshareNoteClick'; import useShareStatusMessage from '@joplin/lib/components/shared/ShareNoteDialog/useShareStatusMessage'; import useEncryptionWarningMessage from '@joplin/lib/components/shared/ShareNoteDialog/useEncryptionWarningMessage'; import { SharingStatus } from '@joplin/lib/components/shared/ShareNoteDialog/types'; import { AppState } from '../../utils/types'; import { connect } from 'react-redux'; import DismissibleDialog, { DialogSize } from '../DismissibleDialog'; import { _, _n } from '@joplin/lib/locale'; import { LinkButton, PrimaryButton } from '../buttons'; import { themeStyle } from '../global-style'; interface Props { themeId: number; noteId: string; visible: boolean; onClose: ()=> void; shares: StateShare[]; } const useStyles = (themeId: number) => { return useMemo(() => { const theme = themeStyle(themeId); return StyleSheet.create({ root: { flexGrow: 1, }, scrollingRegion: { flexGrow: 1, }, noteItem: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', paddingTop: 8, paddingBottom: 8, minHeight: 32, }, noteTitle: { fontSize: theme.fontSize, }, }); }, [themeId]); }; interface UnpublishProps { note: NoteEntity; onUnpublishStart: ()=> void; } const UnpublishButton: React.FC = ({ note, onUnpublishStart }) => { const [unpublishing, setUnpublishing] = useState(false); const onPress = useCallback(async () => { onUnpublishStart(); try { setUnpublishing(true); await onUnshareNoteClick({ noteId: note.id }); } finally { setUnpublishing(false); } }, [note, onUnpublishStart]); return ; }; const ShareNoteDialogContent: React.FC = ({ themeId, noteId, shares, }) => { const [notes, setNotes] = useState([]); const recursiveShare = false; const [sharesState, setSharesState] = useState(SharingStatus.Unknown); const [shareLinks, setShareLinks] = useState([]); const noteCount = notes.length; useEffect(() => { void ShareService.instance().refreshShares(); }, []); useAsyncEffect(async (event) => { const note = await Note.load(noteId); if (event.cancelled) return; setNotes([note]); }, [noteId]); const onCopyLinks = useCallback(async (links: string[]) => { setShareLinks(links); const linkText = links.join('\n'); Clipboard.setString(linkText); }, []); const onUnpublishStart = useCallback(() => { setShareLinks([]); }, []); const shareLinkButton_click = useOnShareLinkClick({ setSharesState, onShareUrlsReady: onCopyLinks, notes, recursiveShare, }); const styles = useStyles(themeId); const renderNote = (note: NoteEntity) => { const unshareButton = shares.find(s => s.note_id === note.id) ? ( ) : null; return ( {note.title}{unshareButton} ); }; const renderNoteList = (notes: NoteEntity[]) => { const noteComps = []; for (const note of notes) { noteComps.push(renderNote(note)); } return {noteComps}; }; const statusMessage = useShareStatusMessage({ sharesState, noteCount, }); const encryptionMessage = useEncryptionWarningMessage(); const renderEncryptionWarningMessage = () => { if (!encryptionMessage) return null; return <> {encryptionMessage} ; }; const renderLinks = () => { if (shareLinks.length === 0) return null; return <> {_('Links')} {shareLinks.map((link, index) => { return Linking.openURL(link)} key={`link-${index}`} >{link}; })} ; }; const copyButtonLoading = [SharingStatus.Creating, SharingStatus.Synchronizing].includes(sharesState); const copyLinkButton = { _n('Copy Shareable Link', 'Copy Shareable Links', noteCount) }; return {renderEncryptionWarningMessage()} {renderNoteList(notes)} {renderLinks()} {statusMessage} {copyLinkButton} ; }; const ShareNoteDialog: React.FC = props => { return {props.visible ? : null} ; }; const mapStateToProps = (state: AppState) => { return { themeId: state.settings.theme, shares: state.shareService.shares.filter(s => !!s.note_id), }; }; export default connect(mapStateToProps)(ShareNoteDialog);