pl-fe: Support kmyblue bookmark folders

Signed-off-by: Nicole Mikołajczyk <git@mkljczk.pl>
This commit is contained in:
Nicole Mikołajczyk
2025-04-22 15:12:18 +02:00
parent 45ef897415
commit e802012cf8
3 changed files with 130 additions and 23 deletions

View File

@ -2,6 +2,7 @@ import React, { useCallback, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { bookmark } from 'pl-fe/actions/interactions';
import { ListItem } from 'pl-fe/components/list';
import { RadioGroup, RadioItem } from 'pl-fe/components/radio';
import Emoji from 'pl-fe/components/ui/emoji';
import HStack from 'pl-fe/components/ui/hstack';
@ -9,10 +10,12 @@ import Icon from 'pl-fe/components/ui/icon';
import Modal from 'pl-fe/components/ui/modal';
import Spinner from 'pl-fe/components/ui/spinner';
import Stack from 'pl-fe/components/ui/stack';
import Toggle from 'pl-fe/components/ui/toggle';
import NewFolderForm from 'pl-fe/features/bookmark-folders/components/new-folder-form';
import { useAppDispatch } from 'pl-fe/hooks/use-app-dispatch';
import { useAppSelector } from 'pl-fe/hooks/use-app-selector';
import { useBookmarkFolders } from 'pl-fe/queries/statuses/use-bookmark-folders';
import { useFeatures } from 'pl-fe/hooks/use-features';
import { useAddBookmarkToFolder, useBookmarkFolders, useRemoveBookmarkFromFolder, useStatusBookmarkFolders } from 'pl-fe/queries/statuses/use-bookmark-folders';
import { makeGetStatus } from 'pl-fe/selectors';
import type { BaseModalProps } from '../modal-root';
@ -25,10 +28,14 @@ const SelectBookmarkFolderModal: React.FC<SelectBookmarkFolderModalProps & BaseM
const getStatus = useCallback(makeGetStatus(), []);
const status = useAppSelector(state => getStatus(state, { id: statusId }))!;
const dispatch = useAppDispatch();
const features = useFeatures();
const [selectedFolder, setSelectedFolder] = useState(status.bookmark_folder);
const { isFetching, data: bookmarkFolders } = useBookmarkFolders(data => data);
const { data: selectedBookmarkFolders, isPending: fetchingSelectedBookmarkFolders } = useStatusBookmarkFolders(statusId);
const { mutate: addBookmarkToFolder, isPending: addingBookmarkToFolder } = useAddBookmarkToFolder(statusId);
const { mutate: removeBookmarkFromFolder, isPending: removingBookmarkFromFolder } = useRemoveBookmarkFromFolder(statusId);
const onChange: React.ChangeEventHandler<HTMLInputElement> = e => {
const folderId = e.target.value;
@ -43,23 +50,19 @@ const SelectBookmarkFolderModal: React.FC<SelectBookmarkFolderModalProps & BaseM
onClose('SELECT_BOOKMARK_FOLDER');
};
const items = [
<RadioItem
key='all'
label={
<HStack alignItems='center' space={2}>
<Icon src={require('@tabler/icons/outline/bookmarks.svg')} size={20} />
<span><FormattedMessage id='bookmark_folders.all_bookmarks' defaultMessage='All bookmarks' /></span>
</HStack>
}
checked={selectedFolder === null}
value=''
/>,
];
const toggleBookmarkFolder = (folderId: string) => {
if (selectedBookmarkFolders?.includes(folderId)) {
removeBookmarkFromFolder(folderId);
} else {
addBookmarkToFolder(folderId);
}
};
if (!isFetching) {
items.push(...((bookmarkFolders || []).map((folder) => (
<RadioItem
let items;
if (features.bookmarkFoldersMultiple) {
items = (bookmarkFolders || []).map((folder) => (
<ListItem
key={folder.id}
label={
<HStack alignItems='center' space={2}>
@ -73,10 +76,50 @@ const SelectBookmarkFolderModal: React.FC<SelectBookmarkFolderModalProps & BaseM
<span>{folder.name}</span>
</HStack>
}
checked={selectedFolder === folder.id}
value={folder.id}
/>
))));
>
<Toggle
checked={selectedBookmarkFolders?.includes(folder.id)}
onChange={() => toggleBookmarkFolder(folder.id)}
disabled={fetchingSelectedBookmarkFolders || addingBookmarkToFolder || removingBookmarkFromFolder}
/>
</ListItem>
));
} else {
items = [
<RadioItem
key='all'
label={
<HStack alignItems='center' space={2}>
<Icon src={require('@tabler/icons/outline/bookmarks.svg')} size={20} />
<span><FormattedMessage id='bookmark_folders.all_bookmarks' defaultMessage='All bookmarks' /></span>
</HStack>
}
checked={selectedFolder === null}
value=''
/>,
];
if (!isFetching) {
items.push(...((bookmarkFolders || []).map((folder) => (
<RadioItem
key={folder.id}
label={
<HStack alignItems='center' space={2}>
{folder.emoji ? (
<Emoji
emoji={folder.emoji}
src={folder.emoji_url || undefined}
className='size-5 flex-none'
/>
) : <Icon src={require('@tabler/icons/outline/folder.svg')} size={20} />}
<span>{folder.name}</span>
</HStack>
}
checked={selectedFolder === folder.id}
value={folder.id}
/>
))));
}
}
const body = isFetching ? <Spinner /> : (