import * as React from 'react'; import { useCallback, useEffect, useMemo, useState } from 'react'; import JoplinServerApi from '@joplin/lib/JoplinServerApi'; import { _, _n } from '@joplin/lib/locale'; import Folder from '@joplin/lib/models/Folder'; import shim from '@joplin/lib/shim'; import DialogButtonRow, { ClickEvent } from './DialogButtonRow'; import Dialog from '@joplin/lib/components/Dialog'; import DialogTitle from './DialogTitle'; import { FolderEntity } from '@joplin/lib/services/database/types'; import ShareService from '@joplin/lib/services/share/ShareService'; import { ShareType, StateShare } from '@joplin/lib/services/share/reducer'; import { connect } from 'react-redux'; import { AppState } from '../app.reducer'; import useEncryptionWarningMessage from '@joplin/lib/components/shared/ShareNoteDialog/useEncryptionWarningMessage'; import { clipboard } from 'electron'; import useOnPublishFolderLinkClick from '@joplin/lib/components/shared/PublishFolderDialog/useOnPublishFolderLinkClick'; import useShareStatusMessage from '@joplin/lib/components/shared/ShareNoteDialog/useShareStatusMessage'; import { SharingStatus } from '@joplin/lib/components/shared/ShareNoteDialog/types'; import Button from './Button/Button'; interface Props { themeId: number; folderId: string; onClose: ()=> void; shares: StateShare[]; folders: FolderEntity[]; } export function PublishFolderDialog(props: Props) { const [folder, setFolder] = useState(null); const [noteCount, setNoteCount] = useState(0); const [publishFolderStatus, setPublishFolderStatus] = useState(SharingStatus.Unknown); const [isUnpublishing, setIsUnpublishing] = useState(false); const encryptionWarning = useEncryptionWarningMessage(); const publishedShare = useMemo(() => { return props.shares.find(share => share.type === ShareType.PublishedFolder && share.folder_id === props.folderId) || null; }, [props.folderId, props.shares]); const loadData = useCallback(async () => { const loadedFolder = await Folder.load(props.folderId); const childFolderIds = await Folder.childrenIds(props.folderId); const allFolderIds = [props.folderId, ...childFolderIds]; let loadedNoteCount = 0; for (const folderId of allFolderIds) { loadedNoteCount += (await Folder.noteIds(folderId)).length; } setFolder(loadedFolder); setNoteCount(loadedNoteCount); }, [props.folderId]); useEffect(() => { void ShareService.instance().refreshShares(); void loadData(); }, [loadData]); const onShareUrlReady = useCallback((url: string) => { clipboard.writeText(url); }, []); const publishFolderLinkButton_click = useOnPublishFolderLinkClick({ folderId: props.folderId, publishedShare, setPublishFolderStatus, onShareUrlReady, }); const onDialogButtonClick = useCallback((_event: ClickEvent) => { props.onClose(); }, [props]); const onUnpublishFolderClick = useCallback(async () => { setIsUnpublishing(true); try { await ShareService.instance().unpublishFolder(props.folderId); } catch (error) { void shim.showErrorDialog(JoplinServerApi.connectionErrorMessage(error as Error)); } finally { setIsUnpublishing(false); } }, [props.folderId]); const statusMessage = useShareStatusMessage({ sharesState: publishFolderStatus, noteCount: 1 }); return (

{_('Notebook: %s', folder ? folder.title : '...')}

{_('Status: %s', publishedShare ? _('Published') : _('Not published'))}

{_n('%d note in notebook', '%d notes in notebook', noteCount, noteCount)}

{publishedShare && (
{statusMessage}
{encryptionWarning &&
{encryptionWarning}
}
); } const mapStateToProps = (state: AppState) => { return { shares: state.shareService.shares, folders: state.folders, }; }; export default connect(mapStateToProps)(PublishFolderDialog);