Skip to content

Commit

Permalink
perf: optimize dnd re-render
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <tukon479@gmail.com>
  • Loading branch information
Innei committed Dec 9, 2024
1 parent 7969022 commit 12bd659
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 69 deletions.
4 changes: 2 additions & 2 deletions apps/renderer/src/modules/feed-column/category.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ type SortListProps = {
view: FeedViewType
showCollapse: boolean
}
const SortedFeedItems = (props: SortListProps) => {
const SortedFeedItems = memo((props: SortListProps) => {
const by = useFeedListSortSelector((s) => s.by)
switch (by) {
case "count": {
Expand All @@ -469,7 +469,7 @@ const SortedFeedItems = (props: SortListProps) => {
return <SortByUnreadList {...props} />
}
}
}
})

const SortByAlphabeticalList = (props: SortListProps) => {
const { ids, showCollapse, view } = props
Expand Down
146 changes: 79 additions & 67 deletions apps/renderer/src/modules/feed-column/item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ interface FeedItemProps {
view?: number
className?: string
}

const DraggableItemWrapper: Component<
{
className?: string
isInMultipleSelection: boolean
} & React.HTMLAttributes<HTMLDivElement>
> = ({ children, isInMultipleSelection, ...props }) => {
const draggableContext = useContext(DraggableContext)

return (
<div
{...draggableContext?.attributes}
{...draggableContext?.listeners}
style={isInMultipleSelection ? draggableContext?.style : undefined}
{...props}
>
{children}
</div>
)
}
const FeedItemImpl = ({ view, feedId, className }: FeedItemProps) => {
const { t } = useTranslation()
const subscription = useSubscriptionByFeedId(feedId)
Expand All @@ -60,7 +80,7 @@ const FeedItemImpl = ({ view, feedId, className }: FeedItemProps) => {
})

const [selectedFeedIds, setSelectedFeedIds] = useSelectedFeedIdsState()
const draggableContext = useContext(DraggableContext)

const isMobile = useMobile()
const isInMultipleSelection = !isMobile && selectedFeedIds.includes(feedId)
const isMultiSelectingButNotSelected =
Expand Down Expand Up @@ -141,79 +161,71 @@ const FeedItemImpl = ({ view, feedId, className }: FeedItemProps) => {
const isFeed = feed.type === "feed" || !feed.type

return (
<>
<DraggableItemWrapper
isInMultipleSelection={isInMultipleSelection}
data-feed-id={feedId}
data-active={
isMultiSelectingButNotSelected
? false
: isActive || isContextMenuOpen || isInMultipleSelection
}
className={cn(
feedColumnStyles.item,
isFeed ? "py-[2px]" : "py-1.5",
"justify-between py-[2px]",
className,
)}
onClick={handleClick}
onDoubleClick={() => {
window.open(UrlBuilder.shareFeed(feedId, view), "_blank")
}}
{...contextMenuProps}
>
<div
{...(isInMultipleSelection && draggableContext?.attributes
? draggableContext.attributes
: {})}
{...(isInMultipleSelection && draggableContext?.listeners
? draggableContext.listeners
: {})}
style={isInMultipleSelection ? draggableContext?.style : undefined}
data-feed-id={feedId}
data-active={
isMultiSelectingButNotSelected
? false
: isActive || isContextMenuOpen || isInMultipleSelection
}
className={cn(
feedColumnStyles.item,
isFeed ? "py-[2px]" : "py-1.5",
"justify-between py-[2px]",
className,
"flex min-w-0 items-center",
isFeed && feed.errorAt && "text-red-900 dark:text-red-500",
)}
onClick={handleClick}
onDoubleClick={() => {
window.open(UrlBuilder.shareFeed(feedId, view), "_blank")
}}
{...contextMenuProps}
>
<div
className={cn(
"flex min-w-0 items-center",
isFeed && feed.errorAt && "text-red-900 dark:text-red-500",
)}
>
<FeedIcon fallback feed={feed} size={16} />
<FeedTitle feed={feed} />
{isFeed && feed.errorAt && (
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<i className="i-mgc-wifi-off-cute-re ml-1 shrink-0 text-base" />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>
<FeedIcon fallback feed={feed} size={16} />
<FeedTitle feed={feed} />
{isFeed && feed.errorAt && (
<Tooltip delayDuration={300}>
<TooltipTrigger asChild>
<i className="i-mgc-wifi-off-cute-re ml-1 shrink-0 text-base" />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>
<div className="flex items-center gap-1">
<i className="i-mgc-time-cute-re" />
{t("feed_item.error_since")}{" "}
{dayjs
.duration(dayjs(feed.errorAt).diff(dayjs(), "minute"), "minute")
.humanize(true)}
</div>
{!!feed.errorMessage && (
<div className="flex items-center gap-1">
<i className="i-mgc-time-cute-re" />
{t("feed_item.error_since")}{" "}
{dayjs
.duration(dayjs(feed.errorAt).diff(dayjs(), "minute"), "minute")
.humanize(true)}
<i className="i-mgc-bug-cute-re" />
{feed.errorMessage}
</div>
{!!feed.errorMessage && (
<div className="flex items-center gap-1">
<i className="i-mgc-bug-cute-re" />
{feed.errorMessage}
</div>
)}
</TooltipContent>
</TooltipPortal>
</Tooltip>
)}
{subscription.isPrivate && (
<Tooltip delayDuration={300}>
<TooltipTrigger>
<OouiUserAnonymous className="ml-1 shrink-0 text-base" />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>{t("feed_item.not_publicly_visible")}</TooltipContent>
</TooltipPortal>
</Tooltip>
)}
</div>
<UnreadNumber unread={feedUnread} className="ml-2" />
)}
</TooltipContent>
</TooltipPortal>
</Tooltip>
)}
{subscription.isPrivate && (
<Tooltip delayDuration={300}>
<TooltipTrigger>
<OouiUserAnonymous className="ml-1 shrink-0 text-base" />
</TooltipTrigger>
<TooltipPortal>
<TooltipContent>{t("feed_item.not_publicly_visible")}</TooltipContent>
</TooltipPortal>
</Tooltip>
)}
</div>
</>
<UnreadNumber unread={feedUnread} className="ml-2" />
</DraggableItemWrapper>
)
}

Expand Down

0 comments on commit 12bd659

Please sign in to comment.