* fix: Logic error in toast fix: Remove useless component * fix: Logout not clearing all stores * Add icons to notification settings * Add eslint rule to enforce spaced comment * Add eslint rule for arrow-body-style * Add eslint rule to enforce self-closing components * Add menu to api key settings Fix: Deleting webhook subscription does not remove from UI Split webhook subscriptions into active and inactive Styling updates
104 lines
2.9 KiB
TypeScript
104 lines
2.9 KiB
TypeScript
import fractionalIndex from "fractional-index";
|
|
import { observer } from "mobx-react";
|
|
import * as React from "react";
|
|
import { useDrop } from "react-dnd";
|
|
import { useTranslation } from "react-i18next";
|
|
import Star from "~/models/Star";
|
|
import Flex from "~/components/Flex";
|
|
import useStores from "~/hooks/useStores";
|
|
import DropCursor from "./DropCursor";
|
|
import Header from "./Header";
|
|
import PlaceholderCollections from "./PlaceholderCollections";
|
|
import Relative from "./Relative";
|
|
import SidebarLink from "./SidebarLink";
|
|
import StarredContext from "./StarredContext";
|
|
import StarredLink from "./StarredLink";
|
|
|
|
const STARRED_PAGINATION_LIMIT = 10;
|
|
|
|
function Starred() {
|
|
const [fetchError, setFetchError] = React.useState();
|
|
const [displayedStarsCount, setDisplayedStarsCount] = React.useState(
|
|
STARRED_PAGINATION_LIMIT
|
|
);
|
|
const { stars } = useStores();
|
|
const { t } = useTranslation();
|
|
|
|
const fetchResults = React.useCallback(
|
|
async (offset = 0) => {
|
|
try {
|
|
await stars.fetchPage({
|
|
limit: STARRED_PAGINATION_LIMIT + 1,
|
|
offset,
|
|
});
|
|
} catch (error) {
|
|
setFetchError(error);
|
|
}
|
|
},
|
|
[stars]
|
|
);
|
|
|
|
React.useEffect(() => {
|
|
fetchResults();
|
|
}, []);
|
|
|
|
const handleShowMore = async () => {
|
|
await fetchResults(displayedStarsCount);
|
|
setDisplayedStarsCount((prev) => prev + STARRED_PAGINATION_LIMIT);
|
|
};
|
|
|
|
// Drop to reorder document
|
|
const [{ isOverReorder, isDraggingAnyStar }, dropToReorder] = useDrop({
|
|
accept: "star",
|
|
drop: async (item: { star: Star }) => {
|
|
item.star.save({
|
|
index: fractionalIndex(null, stars.orderedData[0].index),
|
|
});
|
|
},
|
|
collect: (monitor) => ({
|
|
isOverReorder: !!monitor.isOver(),
|
|
isDraggingAnyStar: monitor.getItemType() === "star",
|
|
}),
|
|
});
|
|
|
|
if (!stars.orderedData.length) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<StarredContext.Provider value={true}>
|
|
<Flex column>
|
|
<Header id="starred" title={t("Starred")}>
|
|
<Relative>
|
|
{isDraggingAnyStar && (
|
|
<DropCursor
|
|
isActiveDrop={isOverReorder}
|
|
innerRef={dropToReorder}
|
|
position="top"
|
|
/>
|
|
)}
|
|
{stars.orderedData.slice(0, displayedStarsCount).map((star) => (
|
|
<StarredLink key={star.id} star={star} />
|
|
))}
|
|
{stars.orderedData.length > displayedStarsCount && (
|
|
<SidebarLink
|
|
onClick={handleShowMore}
|
|
label={`${t("Show more")}…`}
|
|
disabled={stars.isFetching}
|
|
depth={0}
|
|
/>
|
|
)}
|
|
{(stars.isFetching || fetchError) && !stars.orderedData.length && (
|
|
<Flex column>
|
|
<PlaceholderCollections />
|
|
</Flex>
|
|
)}
|
|
</Relative>
|
|
</Header>
|
|
</Flex>
|
|
</StarredContext.Provider>
|
|
);
|
|
}
|
|
|
|
export default observer(Starred);
|