fix: active state on mobile

This commit is contained in:
Stephen Zhou 2024-11-25 18:21:04 +08:00
parent 199e0bc7c5
commit ad3a4cb556
No known key found for this signature in database
8 changed files with 46 additions and 30 deletions

View File

@ -1,5 +1,6 @@
import { getReadonlyRoute, getStableRouterNavigate } from "@follow/components/atoms/route.js"
import { isMobile } from "@follow/components/hooks/useMobile.js"
import { isMobile, useMobile } from "@follow/components/hooks/useMobile.js"
import { useSheetContext } from "@follow/components/ui/sheet/context.js"
import { FeedViewType } from "@follow/constants"
import { isUndefined } from "es-toolkit/compat"
@ -24,9 +25,16 @@ export type NavigateEntryOptions = Partial<{
/**
* @description a hook to navigate to `feedId`, `entryId`, add search for `view`, `level`
*/
// eslint-disable-next-line @eslint-react/hooks-extra/no-redundant-custom-hook, @eslint-react/hooks-extra/ensure-custom-hooks-using-other-hooks
export const useNavigateEntry = () => navigateEntry
export const useNavigateEntry = () => {
const sheetContext = useSheetContext()
const isMobile = useMobile()
return (navigateEntryOptions: NavigateEntryOptions) => {
navigateEntry(navigateEntryOptions)
if (isMobile) {
sheetContext?.dismiss()
}
}
}
export const navigateEntry = (options: NavigateEntryOptions) => {
const { entryId, feedId, view, folderName, inboxId, listId } = options || {}

View File

@ -41,7 +41,7 @@ import { NetworkStatusIndicator } from "~/modules/app/NetworkStatusIndicator"
import { LoginModalContent } from "~/modules/auth/LoginModalContent"
import { DebugRegistry } from "~/modules/debug/registry"
import { FeedColumn } from "~/modules/feed-column"
import { useSelectedFeedIds } from "~/modules/feed-column/atom"
import { getSelectedFeedIds, resetSelectedFeedIds } from "~/modules/feed-column/atom"
import { AutoUpdater } from "~/modules/feed-column/auto-updater"
import { useShortcutsModal } from "~/modules/modal/shortcuts"
import { CmdF } from "~/modules/panel/cmdf"
@ -82,7 +82,6 @@ export function MainDestopLayout() {
},
}),
)
const [selectedIds, setSelectedIds] = useSelectedFeedIds()
const { mutate } = useBatchUpdateSubscription()
const handleDragEnd = React.useCallback(
(event: DragEndEvent) => {
@ -95,11 +94,11 @@ export function MainDestopLayout() {
view: FeedViewType
}
mutate({ category, view, feedIdList: selectedIds })
mutate({ category, view, feedIdList: getSelectedFeedIds() })
setSelectedIds([])
resetSelectedFeedIds()
},
[mutate, selectedIds, setSelectedIds],
[mutate],
)
return (

View File

@ -35,16 +35,12 @@ export const setFeedListSortOrder = (order: FeedListSortOrder) => {
})
}
export const SELECT_NOTHING = []
export const [
,
useSelectedFeedIds,
,
useSetSelectedFeedIds,
getSelectedFeedIds,
setSelectedFeedIds,
useSelectedFeedIdsSelector,
] = createAtomHooks(atom<string[]>(SELECT_NOTHING))
const SELECT_NOTHING = []
export const [, useSelectedFeedIdsState, , , getSelectedFeedIds, setSelectedFeedIds, ,] =
createAtomHooks(atom<string[]>(SELECT_NOTHING))
export const resetSelectedFeedIds = () => {
setSelectedFeedIds(SELECT_NOTHING)
}
export const [, , useFeedAreaScrollProgressValue, , , setFeedAreaScrollProgressValue] =
createAtomHooks(atom(0))

View File

@ -25,7 +25,7 @@ import { getRouteParams } from "~/hooks/biz/useRouteParams"
import { useUnreadByView } from "~/store/unread/hooks"
import { WindowUnderBlur } from "../../components/ui/background"
import { getSelectedFeedIds, SELECT_NOTHING, setSelectedFeedIds } from "./atom"
import { getSelectedFeedIds, resetSelectedFeedIds, setSelectedFeedIds } from "./atom"
import { FeedColumnHeader } from "./header"
import { useShouldFreeUpSpace } from "./hook"
import { FeedList } from "./list"
@ -59,7 +59,7 @@ export function FeedColumn({ children, className }: PropsWithChildren<{ classNam
setActive_(args)
navigateBackHome(nextActive)
setSelectedFeedIds(SELECT_NOTHING)
resetSelectedFeedIds()
},
[active, navigateBackHome, setActive_],
)
@ -169,7 +169,11 @@ export function FeedColumn({ children, className }: PropsWithChildren<{ classNam
onPointerDown={useTypeScriptHappyCallback((e) => {
if (!(e.target instanceof HTMLElement) || !e.target.closest("[data-feed-id]")) {
const nextSelectedFeedIds = getSelectedFeedIds()
setSelectedFeedIds(nextSelectedFeedIds.length === 0 ? nextSelectedFeedIds : [])
if (nextSelectedFeedIds.length > 0) {
setSelectedFeedIds(nextSelectedFeedIds)
} else {
resetSelectedFeedIds()
}
}
}, [])}
>

View File

@ -1,3 +1,4 @@
import { useMobile } from "@follow/components/hooks/useMobile.js"
import { OouiUserAnonymous } from "@follow/components/icons/OouiUserAnonymous.jsx"
import {
Tooltip,
@ -29,7 +30,7 @@ import { useListById } from "~/store/list"
import { subscriptionActions, useSubscriptionByFeedId } from "~/store/subscription"
import { useFeedUnreadStore } from "~/store/unread"
import { useSelectedFeedIds } from "./atom"
import { useSelectedFeedIdsState } from "./atom"
import { DraggableContext } from "./context"
import { feedColumnStyles } from "./styles"
import { UnreadNumber } from "./unread-number"
@ -58,9 +59,10 @@ const FeedItemImpl = ({ view, feedId, className }: FeedItemProps) => {
}
})
const [selectedFeedIds, setSelectedFeedIds] = useSelectedFeedIds()
const [selectedFeedIds, setSelectedFeedIds] = useSelectedFeedIdsState()
const draggableContext = useContext(DraggableContext)
const isInMultipleSelection = selectedFeedIds.includes(feedId)
const isMobile = useMobile()
const isInMultipleSelection = !isMobile && selectedFeedIds.includes(feedId)
const isMultiSelectingButNotSelected = selectedFeedIds.length > 0 && !isInMultipleSelection
const handleClick: React.MouseEventHandler<HTMLDivElement> = useCallback(

View File

@ -10,7 +10,11 @@ import { useAuthQuery } from "~/hooks/common"
import { Queries } from "~/queries"
import { useCategoryOpenStateByView } from "~/store/subscription"
import { SELECT_NOTHING, setFeedAreaScrollProgressValue, useSelectedFeedIds } from "./atom"
import {
resetSelectedFeedIds,
setFeedAreaScrollProgressValue,
useSelectedFeedIdsState,
} from "./atom"
import { DraggableContext } from "./context"
import { useShouldFreeUpSpace } from "./hook"
import {
@ -45,7 +49,7 @@ const FeedListImpl = forwardRef<HTMLDivElement, { className?: string; view: numb
const scrollerRef = useRef<HTMLDivElement>(null)
const selectoRef = useRef<Selecto>(null)
const [selectedFeedIds, setSelectedFeedIds] = useSelectedFeedIds()
const [selectedFeedIds, setSelectedFeedIds] = useSelectedFeedIdsState()
const [currentStartFeedId, setCurrentStartFeedId] = useState<string | null>(null)
useEffect(() => {
if (selectedFeedIds.length <= 1) {
@ -135,7 +139,7 @@ const FeedListImpl = forwardRef<HTMLDivElement, { className?: string; view: numb
}}
onDragStart={(e) => {
if (!isKeyForMultiSelectPressed(e.inputEvent as MouseEvent)) {
setSelectedFeedIds(SELECT_NOTHING)
resetSelectedFeedIds()
}
}}
selectableTargets={["[data-feed-id]"]}

View File

@ -4,7 +4,7 @@ import { memo } from "react"
import { useTranslation } from "react-i18next"
import { useSidebarActiveViewValue } from "~/atoms/sidebar"
import { navigateEntry } from "~/hooks/biz/useNavigateEntry"
import { useNavigateEntry } from "~/hooks/biz/useNavigateEntry"
import { useAuthQuery } from "~/hooks/common"
import { Queries } from "~/queries"
import { useCategoryOpenStateByView } from "~/store/subscription"
@ -46,6 +46,8 @@ const FeedListImpl = ({ className, view }: { className?: string; view: number })
// 2 => 1, 2, 3
const shouldRender = view >= currentActiveView && view < currentActiveView + 2
const navigateEntry = useNavigateEntry()
return (
<div className={cn(className, "font-medium", !shouldRender && "hidden")}>
<ListHeader view={view} />
@ -87,6 +89,7 @@ const FeedListImpl = ({ className, view }: { className?: string; view: number })
onClick={() => {
navigateEntry({
view,
feedId: null,
})
}}
className={cn(feedColumnStyles.item, "px-2.5 py-[2px]")}

View File

@ -4,7 +4,7 @@ import { createContext, useContext } from "react"
interface SheetContextValue {
dismiss: () => void
}
export const SheetContext = createContext<SheetContextValue>(null!)
export const SheetContext = createContext<SheetContextValue | null>(null)
export const useSheetContext = () => useContext(SheetContext)
export const sheetStackAtom = atom([] as HTMLDivElement[])