Skip to content

Commit

Permalink
feat: add loading for API call in watchlater / dislike related actions
Browse files Browse the repository at this point in the history
  • Loading branch information
magicdawn committed Oct 30, 2024
1 parent 8fb4d60 commit 990695c
Show file tree
Hide file tree
Showing 12 changed files with 109 additions and 97 deletions.
4 changes: 2 additions & 2 deletions src/auto-imports.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
export {}
declare global {
const Fragment: typeof import('react')['Fragment']
const IconSvgSpinnersBarsRotateFade: typeof import('~icons/svg-spinners/bars-rotate-fade.jsx')['default']
const IconTablerFaceIdError: typeof import('~icons/tabler/face-id-error.jsx')['default']
const clsx: typeof import('clsx')['clsx']
const createRef: typeof import('react')['createRef']
Expand All @@ -15,7 +16,7 @@ declare global {
const forwardRef: typeof import('react')['forwardRef']
const lazy: typeof import('react')['lazy']
const memo: typeof import('react')['memo']
const proxy: typeof import('valtio')['proxy']
const size: typeof import('polished')['size']
const startTransition: typeof import('react')['startTransition']
const useCallback: typeof import('react')['useCallback']
const useContext: typeof import('react')['useContext']
Expand All @@ -32,7 +33,6 @@ declare global {
const useMount: typeof import('ahooks')['useMount']
const useReducer: typeof import('react')['useReducer']
const useRef: typeof import('react')['useRef']
const useSnapshot: typeof import('valtio')['useSnapshot']
const useState: typeof import('react')['useState']
const useSyncExternalStore: typeof import('react')['useSyncExternalStore']
const useTransition: typeof import('react')['useTransition']
Expand Down
122 changes: 73 additions & 49 deletions src/components/ModalDislike/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import { DislikeIcon } from '$modules/icon'
import { AntdMessage } from '$utility'
import { toastRequestFail } from '$utility/toast'
import { Info } from '@icon-park/react'
import { useLockFn, useUpdateLayoutEffect } from 'ahooks'
import { useLockFn, useRequest, useUpdateLayoutEffect } from 'ahooks'
import { Spin } from 'antd'
import { clsx } from 'clsx'
import { delay } from 'es-toolkit'
import type { Root } from 'react-dom/client'
import { createRoot } from 'react-dom/client'
import { proxy, useSnapshot } from 'valtio'
Expand Down Expand Up @@ -40,14 +43,18 @@ export function delDislikeId(id: string) {
}

function ModalDislike({ show, onHide, item }: IProps) {
const $req = useRequest(async (item: AppRecItem, reason: Reason) => dislike(item, reason.id), {
manual: true,
})

const onDislike = useLockFn(async (reason: Reason) => {
if (!item) return

let success = false
let message: string = ''
let err: Error | undefined
try {
;({ success, message } = await dislike(item, reason.id))
;({ success, message } = await $req.runAsync(item, reason))
} catch (e) {
err = e as Error
}
Expand All @@ -59,6 +66,7 @@ function ModalDislike({ show, onHide, item }: IProps) {
if (success) {
AntdMessage.success('已标记不想看')
dislikedIds.set(item.param, { ...reason })
await delay(100)
onHide()
} else {
// fail
Expand Down Expand Up @@ -151,55 +159,71 @@ function ModalDislike({ show, onHide, item }: IProps) {
</div>

<div css={BaseModalStyle.modalBody} ref={modalBodyRef}>
<div
className='reason-list'
css={css`
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
`}
<Spin
spinning={$req.loading}
indicator={
<IconSvgSpinnersBarsRotateFade
css={css`
color: ${colorPrimaryValue};
.ant-spin .ant-spin-dot& {
width: 25px;
height: 25px;
}
`}
/>
}
>
{reasons.map((reason, index) => {
const active = index === activeIndex

return (
<button
className={clsx('reason', { active })}
css={[S.reason, active && S.reasonActive]}
key={reason.id}
data-id={reason.id}
onClick={() => {
setActiveIndex(index)
onDislike(reason)
}}
>
<span
className='reason-no'
css={css`
position: absolute;
left: 6px;
width: 20px;
height: 20px;
border-radius: 50%;
top: ${(32 - 20) / 2}px;
display: flex;
align-items: center;
justify-content: center;
background-color: ${colorPrimaryValue};
color: #fff;
`}
<div
className='reason-list'
css={css`
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
`}
>
{reasons.map((reason, index) => {
const active = index === activeIndex

return (
<button
className={clsx('reason', { active })}
css={[S.reason, active && S.reasonActive]}
key={reason.id}
data-id={reason.id}
disabled={$req.loading}
onClick={() => {
setActiveIndex(index)
onDislike(reason)
}}
>
{index + 1}
</span>
{reason.name}
</button>
)
})}
</div>
<span
className='reason-no'
css={css`
position: absolute;
left: 6px;
width: 20px;
height: 20px;
border-radius: 50%;
top: ${(32 - 20) / 2}px;
display: flex;
align-items: center;
justify-content: center;
background-color: ${colorPrimaryValue};
color: #fff;
`}
>
{index + 1}
</span>
{reason.name}
</button>
)
})}
</div>
</Spin>

<div
className='tips-container'
Expand Down
1 change: 1 addition & 0 deletions src/components/ModalSettings/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import type { BooleanSettingsKey } from '$modules/settings'
import { settings } from '$modules/settings'
import { AntdMessage, shouldDisableShortcut } from '$utility'
import { Tabs } from 'antd'
import { proxy, useSnapshot } from 'valtio'
import styles from './index.module.scss'
import { TabPaneAdvance } from './tab-panes/pane-advance'
import { TabPaneBasic } from './tab-panes/pane-basic'
Expand Down
1 change: 1 addition & 0 deletions src/components/RecHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { isMac } from '$ua'
import { getElementOffset, shouldDisableShortcut } from '$utility/dom'
import { Button, Space } from 'antd'
import { size } from 'polished'
import { useSnapshot } from 'valtio'
import { AccessKeyManage } from '../AccessKeyManage'
import { RefreshButton } from './RefreshButton'
import { headerState } from './index.shared'
Expand Down
1 change: 1 addition & 0 deletions src/components/RecHeader/tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useSettingsSnapshot } from '$modules/settings'
import { checkLoginStatus, useHasLogined } from '$utility'
import { proxyWithGmStorage } from '$utility/valtio'
import { Radio } from 'antd'
import { useSnapshot } from 'valtio'
import type { TabConfigItem } from './tab-config'
import { TabConfig, TabIcon, toastNeedLogin } from './tab-config'
import { ETab, TabKeys } from './tab-enum'
Expand Down
39 changes: 20 additions & 19 deletions src/components/VideoCard/use/useWatchlaterRelated.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { WatchLaterIcon } from '$modules/icon'
import { IconAnimatedChecked } from '$modules/icon/animated-checked'
import { watchLaterState } from '$modules/rec-services/watchlater'
import { AntdMessage } from '$utility'
import { usePrevious } from 'ahooks'
import { usePrevious, useRequest } from 'ahooks'
import { delay } from 'es-toolkit'
import { size } from 'polished'
import type { MouseEvent } from 'react'
Expand Down Expand Up @@ -43,10 +43,16 @@ export function useWatchlaterRelated({
return true
})()

const $req = useRequest(
(usingAction: typeof watchLaterAdd | typeof watchLaterDel, bvid: string) => {
return usingAction(bvid)
},
{ manual: true },
)

// watchLater added
const watchLaterAddedPrevious = usePrevious(watchLaterAdded)

const _requesting = useRef(false)
const onToggleWatchLater = useMemoizedFn(
async (
e?: MouseEvent,
Expand All @@ -55,24 +61,16 @@ export function useWatchlaterRelated({
e?.preventDefault()
e?.stopPropagation()

// already loading
if ($req.loading) return { success: false }

if (!avid || !bvid) {
return { success: false }
}

// run the action
usingAction ??= watchLaterAdded ? watchLaterDel : watchLaterAdd
if (usingAction !== watchLaterAdd && usingAction !== watchLaterDel) {
throw new Error('unexpected usingAction provided')
}

if (_requesting.current) return { success: false }
_requesting.current = true

let success = false
try {
success = await usingAction(avid)
} finally {
_requesting.current = false
}
const success = await $req.runAsync(usingAction, avid)

const targetState = usingAction === watchLaterAdd ? true : false
if (success) {
Expand Down Expand Up @@ -102,16 +100,19 @@ export function useWatchlaterRelated({
)

// <use href={watchLaterAdded ? '#widget-watch-save' : '#widget-watch-later'} />
// <svg width={addSize} height={addSize}>
// <use href={'#widget-watch-later'} />
// </svg>

const addSize = 20
const addedSize = 18
const icon = watchLaterAdded ? (
const icon = $req.loading ? (
<IconSvgSpinnersBarsRotateFade {...size(16)} />
) : watchLaterAdded ? (
<IconAnimatedChecked size={addedSize} useAnimation={watchLaterAddedPrevious === false} />
) : (
<WatchLaterIcon {...size(addSize)} />
)
// <svg width={addSize} height={addSize}>
// <use href={'#widget-watch-later'} />
// </svg>

const watchlaterButtonEl = hasWatchLaterEntry && (
<VideoCardActionButton
Expand Down
2 changes: 1 addition & 1 deletion src/modules/rec-services/dynamic-feed/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { settings } from '$modules/settings'
import { getUid, setPageTitle, whenIdle } from '$utility'
import { proxySetWithGmStorage } from '$utility/valtio'
import ms from 'ms'
import { snapshot } from 'valtio'
import { proxy, snapshot } from 'valtio'
import { subscribeKey } from 'valtio/utils'
import { getAllFollowGroups } from './group'
import type { FollowGroup } from './group/groups'
Expand Down
1 change: 1 addition & 0 deletions src/modules/rec-services/dynamic-feed/usage-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import type { AntdMenuItemType } from '$utility/type'
import { Avatar, Badge, Button, Checkbox, Dropdown, Input, Popover, Radio, Space } from 'antd'
import { delay } from 'es-toolkit'
import { fastSortWithOrders } from 'fast-sort-lens'
import { useSnapshot } from 'valtio'
import TablerFilter from '~icons/tabler/filter'
import TablerFilterCheck from '~icons/tabler/filter-check'
import { usePopupContainer } from '../_base'
Expand Down
1 change: 1 addition & 0 deletions src/modules/rec-services/hot/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { proxyWithGmStorage } from '$utility/valtio'
import { Button, Dropdown } from 'antd'
import { size } from 'polished'
import type { ReactNode } from 'react'
import { useSnapshot } from 'valtio'
import type { IService } from '../_base'
import { usePopupContainer } from '../_base'
import { PopularGeneralRecService } from './popular-general'
Expand Down
1 change: 1 addition & 0 deletions src/modules/rec-services/hot/ranking/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { isWebApiSuccess, request } from '$request'
import { toast } from '$utility'
import { proxyWithGmStorage } from '$utility/valtio'
import { Button, Popover } from 'antd'
import { useSnapshot } from 'valtio'
import { QueueStrategy, type IService } from '../../_base'
import type { RankingItem } from './api'
import {
Expand Down
2 changes: 1 addition & 1 deletion src/utility/valtio.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { isEqual, pick, throttle } from 'es-toolkit'
import { proxy, snapshot, subscribe } from 'valtio'
import { proxy, snapshot, subscribe, useSnapshot } from 'valtio'
import { proxySet } from 'valtio/utils'

export function valtioFactory<T>(computeValue: () => T) {
Expand Down
31 changes: 6 additions & 25 deletions vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,7 @@ export default defineConfig(({ command }) => ({
imports: [
'react',
// 'ahooks',
{
from: 'react',
imports: ['Fragment'],
},
{ from: 'react', imports: ['Fragment'] },
{
from: 'react',
imports: ['ComponentProps', 'CSSProperties', 'ReactNode', 'RefObject'],
Expand All @@ -141,27 +138,11 @@ export default defineConfig(({ command }) => ({
from: 'ahooks',
imports: ['useMemoizedFn', 'useKeyPress', 'useMount', 'useUpdateEffect'],
},
{
from: 'react-dom/client',
imports: ['createRoot'],
},
{
from: 'react-dom/client',
imports: ['Root'],
type: true,
},
{
from: 'valtio',
imports: ['useSnapshot', 'proxy'],
},
{
from: '@emotion/react',
imports: ['css'],
},
{
from: 'clsx',
imports: ['clsx'],
},
{ from: 'react-dom/client', imports: ['Root'], type: true },
{ from: 'react-dom/client', imports: ['createRoot'] },
{ from: '@emotion/react', imports: ['css'] },
{ from: 'clsx', imports: ['clsx'] },
{ from: 'polished', imports: ['size'] },
],
}),

Expand Down

0 comments on commit 990695c

Please sign in to comment.