mirror of
https://github.com/Sonny93/my-links.git
synced 2025-12-09 15:05:35 +00:00
refactor: recreate collection and global hotkey contexts as store (using zustand)
This commit is contained in:
@@ -10,8 +10,8 @@ import {
|
||||
import ModalWrapper from '~/components/common/modal/_modal_wrapper';
|
||||
import TextEllipsis from '~/components/common/text_ellipsis';
|
||||
import useClickOutside from '~/hooks/use_click_outside';
|
||||
import useGlobalHotkeys from '~/hooks/use_global_hotkeys';
|
||||
import useShortcut from '~/hooks/use_shortcut';
|
||||
import { useGlobalHotkeysStore } from '~/store/global_hotkeys_store';
|
||||
|
||||
interface ModalProps {
|
||||
title?: string;
|
||||
@@ -32,7 +32,7 @@ export default function Modal({
|
||||
close,
|
||||
}: ModalProps) {
|
||||
const modalRef = useRef<HTMLDivElement>(null);
|
||||
const { setGlobalHotkeysEnabled } = useGlobalHotkeys();
|
||||
const { setGlobalHotkeysEnabled } = useGlobalHotkeysStore();
|
||||
|
||||
useClickOutside(modalRef, close);
|
||||
useShortcut('ESCAPE_KEY', close, { disableGlobalCheck: true });
|
||||
|
||||
@@ -4,7 +4,7 @@ import CollectionHeader from '~/components/dashboard/collection/header/collectio
|
||||
import LinkList from '~/components/dashboard/link/link_list';
|
||||
import { NoCollection } from '~/components/dashboard/link/no_item';
|
||||
import Footer from '~/components/footer/footer';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import { useActiveCollection } from '~/store/collection_store';
|
||||
|
||||
export interface CollectionHeaderProps {
|
||||
showButtons: boolean;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import styled from '@emotion/styled';
|
||||
import TextEllipsis from '~/components/common/text_ellipsis';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import { useActiveCollection } from '~/store/collection_store';
|
||||
|
||||
const CollectionDescriptionStyle = styled.div({
|
||||
width: '100%',
|
||||
|
||||
@@ -6,7 +6,7 @@ import { CollectionHeaderProps } from '~/components/dashboard/collection/collect
|
||||
import CollectionControls from '~/components/dashboard/collection/header/collection_controls';
|
||||
import CollectionDescription from '~/components/dashboard/collection/header/collection_description';
|
||||
import VisibilityBadge from '~/components/visibilty/visibilty';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import { useActiveCollection } from '~/store/collection_store';
|
||||
|
||||
const paddingLeft = '1.25em';
|
||||
const paddingRight = '1.65em';
|
||||
|
||||
@@ -5,8 +5,8 @@ import { useEffect, useRef } from 'react';
|
||||
import { AiFillFolderOpen, AiOutlineFolder } from 'react-icons/ai';
|
||||
import TextEllipsis from '~/components/common/text_ellipsis';
|
||||
import { Item } from '~/components/dashboard/side_nav/nav_item';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import { appendCollectionId } from '~/lib/navigation';
|
||||
import { useActiveCollection } from '~/store/collection_store';
|
||||
import { CollectionWithLinks } from '~/types/app';
|
||||
|
||||
const CollectionItemStyle = styled(Item, {
|
||||
|
||||
@@ -2,9 +2,8 @@ import styled from '@emotion/styled';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import CollectionItem from '~/components/dashboard/collection/list/collection_item';
|
||||
import CollectionListContainer from '~/components/dashboard/collection/list/collection_list_container';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import useCollections from '~/hooks/use_collections';
|
||||
import useShortcut from '~/hooks/use_shortcut';
|
||||
import { useActiveCollection, useCollections } from '~/store/collection_store';
|
||||
|
||||
const SideMenu = styled.nav(({ theme }) => ({
|
||||
height: '100%',
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
import { Link as InertiaLink } from '@inertiajs/react';
|
||||
import { route } from '@izzyjs/route/client';
|
||||
import { ActionIcon, Menu } from '@mantine/core';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { BsThreeDotsVertical } from 'react-icons/bs';
|
||||
import { FaRegEye } from 'react-icons/fa';
|
||||
import { GoPencil } from 'react-icons/go';
|
||||
import { IoTrashOutline } from 'react-icons/io5';
|
||||
import { MdFavorite, MdFavoriteBorder } from 'react-icons/md';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import useCollections from '~/hooks/use_collections';
|
||||
import { onFavorite } from '~/lib/favorite';
|
||||
import { appendCollectionId, appendLinkId } from '~/lib/navigation';
|
||||
import { useFavorites } from '~/store/collection_store';
|
||||
import { Link } from '~/types/app';
|
||||
|
||||
interface LinksControlsProps {
|
||||
@@ -22,34 +20,9 @@ export default function LinkControls({
|
||||
link,
|
||||
showGoToCollection = false,
|
||||
}: LinksControlsProps) {
|
||||
const { collections, setCollections } = useCollections();
|
||||
const { setActiveCollection } = useActiveCollection();
|
||||
const { toggleFavorite } = useFavorites();
|
||||
const { t } = useTranslation('common');
|
||||
|
||||
const toggleFavorite = useCallback(
|
||||
(linkId: Link['id']) => {
|
||||
let linkIndex = 0;
|
||||
const collectionIndex = collections.findIndex(({ links }) => {
|
||||
const lIndex = links.findIndex((l) => l.id === linkId);
|
||||
if (lIndex !== -1) {
|
||||
linkIndex = lIndex;
|
||||
}
|
||||
return lIndex !== -1;
|
||||
});
|
||||
|
||||
const collectionLink = collections[collectionIndex].links[linkIndex];
|
||||
const collectionsCopy = [...collections];
|
||||
collectionsCopy[collectionIndex].links[linkIndex] = {
|
||||
...collectionLink,
|
||||
favorite: !collectionLink.favorite,
|
||||
};
|
||||
|
||||
setCollections(collectionsCopy);
|
||||
setActiveCollection(collectionsCopy[collectionIndex]);
|
||||
},
|
||||
[collections, setCollections]
|
||||
);
|
||||
|
||||
const onFavoriteCallback = () => toggleFavorite(link.id);
|
||||
return (
|
||||
<Menu withinPortal shadow="md" width={200}>
|
||||
|
||||
@@ -2,8 +2,8 @@ import styled from '@emotion/styled';
|
||||
import { Link } from '@inertiajs/react';
|
||||
import { route } from '@izzyjs/route/client';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import { appendCollectionId } from '~/lib/navigation';
|
||||
import { useActiveCollection } from '~/store/collection_store';
|
||||
import { fadeIn } from '~/styles/keyframes';
|
||||
|
||||
const NoCollectionStyle = styled.div({
|
||||
|
||||
@@ -7,11 +7,10 @@ import Modal from '~/components/common/modal/modal';
|
||||
import NoSearchResult from '~/components/dashboard/search/no_search_result';
|
||||
import SearchResultList from '~/components/dashboard/search/search_result_list';
|
||||
import { GOOGLE_SEARCH_URL } from '~/constants';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import useCollections from '~/hooks/use_collections';
|
||||
import useToggle from '~/hooks/use_modal';
|
||||
import useShortcut from '~/hooks/use_shortcut';
|
||||
import { makeRequest } from '~/lib/request';
|
||||
import { useActiveCollection, useCollections } from '~/store/collection_store';
|
||||
import { SearchResult } from '~/types/search';
|
||||
|
||||
const SearchInput = styled.input(({ theme }) => ({
|
||||
|
||||
@@ -4,7 +4,7 @@ import { AiOutlineFolder } from 'react-icons/ai';
|
||||
import Legend from '~/components/common/legend';
|
||||
import TextEllipsis from '~/components/common/text_ellipsis';
|
||||
import LinkFavicon from '~/components/dashboard/link/link_favicon';
|
||||
import useCollections from '~/hooks/use_collections';
|
||||
import { useCollections } from '~/store/collection_store';
|
||||
import {
|
||||
SearchResult,
|
||||
SearchResultCollection,
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AiFillStar, AiOutlineStar } from 'react-icons/ai';
|
||||
import { DropdownItemButton } from '~/components/common/dropdown/dropdown_item';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import useCollections from '~/hooks/use_collections';
|
||||
import { onFavorite } from '~/lib/favorite';
|
||||
import { useFavorites } from '~/store/collection_store';
|
||||
import { Link } from '~/types/app';
|
||||
|
||||
const StarItem = styled(DropdownItemButton)(({ theme }) => ({
|
||||
@@ -13,34 +11,9 @@ const StarItem = styled(DropdownItemButton)(({ theme }) => ({
|
||||
}));
|
||||
|
||||
export default function FavoriteDropdownItem({ link }: { link: Link }) {
|
||||
const { collections, setCollections } = useCollections();
|
||||
const { setActiveCollection } = useActiveCollection();
|
||||
const { toggleFavorite } = useFavorites();
|
||||
const { t } = useTranslation();
|
||||
|
||||
const toggleFavorite = useCallback(
|
||||
(linkId: Link['id']) => {
|
||||
let linkIndex = 0;
|
||||
const collectionIndex = collections.findIndex(({ links }) => {
|
||||
const lIndex = links.findIndex((l) => l.id === linkId);
|
||||
if (lIndex !== -1) {
|
||||
linkIndex = lIndex;
|
||||
}
|
||||
return lIndex !== -1;
|
||||
});
|
||||
|
||||
const collectionLink = collections[collectionIndex].links[linkIndex];
|
||||
const collectionsCopy = [...collections];
|
||||
collectionsCopy[collectionIndex].links[linkIndex] = {
|
||||
...collectionLink,
|
||||
favorite: !collectionLink.favorite,
|
||||
};
|
||||
|
||||
setCollections(collectionsCopy);
|
||||
setActiveCollection(collectionsCopy[collectionIndex]);
|
||||
},
|
||||
[collections, setCollections]
|
||||
);
|
||||
|
||||
const onFavoriteCallback = () => toggleFavorite(link.id);
|
||||
return (
|
||||
<StarItem
|
||||
|
||||
@@ -2,7 +2,7 @@ import styled from '@emotion/styled';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import FavoriteListContainer from '~/components/dashboard/side_nav/favorite/favorite_container';
|
||||
import FavoriteItem from '~/components/dashboard/side_nav/favorite/favorite_item';
|
||||
import useFavorites from '~/hooks/use_favorites';
|
||||
import { useFavorites } from '~/store/collection_store';
|
||||
|
||||
const FavoriteLabel = styled.p(({ theme }) => ({
|
||||
color: theme.colors.grey,
|
||||
|
||||
@@ -8,10 +8,10 @@ import FavoriteList from '~/components/dashboard/side_nav/favorite/favorite_list
|
||||
import { Item, ItemLink } from '~/components/dashboard/side_nav/nav_item';
|
||||
import UserCard from '~/components/dashboard/side_nav/user_card';
|
||||
import ModalSettings from '~/components/settings/settings_modal';
|
||||
import useActiveCollection from '~/hooks/use_active_collection';
|
||||
import useUser from '~/hooks/use_user';
|
||||
import { rgba } from '~/lib/color';
|
||||
import { appendCollectionId } from '~/lib/navigation';
|
||||
import { useActiveCollection } from '~/store/collection_store';
|
||||
|
||||
const SideMenu = styled.nav(({ theme }) => ({
|
||||
height: '100%',
|
||||
|
||||
Reference in New Issue
Block a user