diff --git a/package.json b/package.json index 3e6200a..8681885 100644 --- a/package.json +++ b/package.json @@ -25,13 +25,14 @@ "test": "vitest -c vitest.config.ts" }, "dependencies": { - "@dnd-kit/core": "^6.1.0", - "@dnd-kit/sortable": "^8.0.0", - "@dnd-kit/utilities": "^3.2.2", + "@atlaskit/pragmatic-drag-and-drop": "^1.4.0", + "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^1.4.0", + "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3", "@iconify-json/si": "^1.2.1", "@tanstack/react-query-devtools": "^5.59.9", "@tanstack/react-router": "^1.64.0", "@unocss/reset": "^0.63.4", + "ahooks": "^3.8.1", "better-sqlite3": "^11.3.0", "cheerio": "^1.0.0", "clsx": "^2.1.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3934d50..fa29cef 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,15 +17,15 @@ importers: .: dependencies: - '@dnd-kit/core': - specifier: ^6.1.0 - version: 6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@dnd-kit/sortable': - specifier: ^8.0.0 - version: 8.0.0(@dnd-kit/core@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) - '@dnd-kit/utilities': - specifier: ^3.2.2 - version: 3.2.2(react@18.3.1) + '@atlaskit/pragmatic-drag-and-drop': + specifier: ^1.4.0 + version: 1.4.0 + '@atlaskit/pragmatic-drag-and-drop-auto-scroll': + specifier: ^1.4.0 + version: 1.4.0 + '@atlaskit/pragmatic-drag-and-drop-hitbox': + specifier: ^1.0.3 + version: 1.0.3 '@iconify-json/si': specifier: ^1.2.1 version: 1.2.1 @@ -38,6 +38,9 @@ importers: '@unocss/reset': specifier: ^0.63.4 version: 0.63.6 + ahooks: + specifier: ^3.8.1 + version: 3.8.1(react@18.3.1) better-sqlite3: specifier: ^11.3.0 version: 11.5.0 @@ -244,6 +247,15 @@ packages: peerDependencies: ajv: '>=8' + '@atlaskit/pragmatic-drag-and-drop-auto-scroll@1.4.0': + resolution: {integrity: sha512-5GoikoTSW13UX76F9TDeWB8x3jbbGlp/Y+3aRkHe1MOBMkrWkwNpJ42MIVhhX/6NSeaZiPumP0KbGJVs2tOWSQ==} + + '@atlaskit/pragmatic-drag-and-drop-hitbox@1.0.3': + resolution: {integrity: sha512-/Sbu/HqN2VGLYBhnsG7SbRNg98XKkbF6L7XDdBi+izRybfaK1FeMfodPpm/xnBHPJzwYMdkE0qtLyv6afhgMUA==} + + '@atlaskit/pragmatic-drag-and-drop@1.4.0': + resolution: {integrity: sha512-qRY3PTJIcxfl/QB8Gwswz+BRvlmgAC5pB+J2hL6dkIxgqAgVwOhAamMUKsrOcFU/axG2Q7RbNs1xfoLKDuhoPg==} + '@babel/code-frame@7.25.9': resolution: {integrity: sha512-z88xeGxnzehn2sqZ8UdGQEvYErF1odv2CftxInpSYJt6uHuPe9YjahKZITGs3l5LeI9d2ROG+obuDAoSlqbNfQ==} engines: {node: '>=6.9.0'} @@ -801,28 +813,6 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@dnd-kit/accessibility@3.1.0': - resolution: {integrity: sha512-ea7IkhKvlJUv9iSHJOnxinBcoOI3ppGnnL+VDJ75O45Nss6HtZd8IdN8touXPDtASfeI2T2LImb8VOZcL47wjQ==} - peerDependencies: - react: '>=16.8.0' - - '@dnd-kit/core@6.1.0': - resolution: {integrity: sha512-J3cQBClB4TVxwGo3KEjssGEXNJqGVWx17aRTZ1ob0FliR5IjYgTxl5YJbKTzA6IzrtelotH19v6y7uoIRUZPSg==} - peerDependencies: - react: '>=16.8.0' - react-dom: '>=16.8.0' - - '@dnd-kit/sortable@8.0.0': - resolution: {integrity: sha512-U3jk5ebVXe1Lr7c2wU7SBZjcWdQP+j7peHJfCspnA81enlu88Mgd7CC8Q+pub9ubP7eKVETzJW+IBAhsqbSu/g==} - peerDependencies: - '@dnd-kit/core': ^6.1.0 - react: '>=16.8.0' - - '@dnd-kit/utilities@3.2.2': - resolution: {integrity: sha512-+MKAJEOfaBe5SmV6t34p80MMKhjvUz0vRrvVJbPT0WElzaOJ/1xs+D+KDv+tD/NE5ujfrChEcshd4fLn0wpiqg==} - peerDependencies: - react: '>=16.8.0' - '@es-joy/jsdoccomment@0.48.0': resolution: {integrity: sha512-G6QUWIcC+KvSwXNsJyDTHvqUdNoAVJPPgkc3+Uk4WBKqZvoXhlvazOgm9aL0HwihJLQf0l+tOE2UFzXBqCqgDw==} engines: {node: '>=16'} @@ -2634,6 +2624,12 @@ packages: resolution: {integrity: sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==} engines: {node: '>= 14'} + ahooks@3.8.1: + resolution: {integrity: sha512-JoP9+/RWO7MnI/uSKdvQ8WB10Y3oo1PjLv+4Sv4Vpm19Z86VUMdXh+RhWvMGxZZs06sq2p0xVtFk8Oh5ZObsoA==} + engines: {node: '>=8.0.0'} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -2765,6 +2761,9 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} + bind-event-listener@3.0.0: + resolution: {integrity: sha512-PJvH288AWQhKs2v9zyfYdPzlPqf5bXbGMmhmUIY9x4dAUGIWgomO771oBQNwJnMQSnUIXhKu6sgzpBRXTlvb8Q==} + bindings@1.5.0: resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} @@ -4064,6 +4063,9 @@ packages: resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} + intersection-observer@0.12.2: + resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==} + invariant@2.2.4: resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} @@ -4299,6 +4301,10 @@ packages: js-cookie@2.2.1: resolution: {integrity: sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==} + js-cookie@3.0.5: + resolution: {integrity: sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==} + engines: {node: '>=14'} + js-levenshtein@1.1.6: resolution: {integrity: sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==} engines: {node: '>=0.10.0'} @@ -4983,6 +4989,9 @@ packages: radix3@1.1.2: resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + raf-schd@4.0.3: + resolution: {integrity: sha512-tQkJl2GRWh83ui2DiPTJz9wEiMN20syf+5oKfB03yYP7ioZcJwsIK8FjrtLwH1m7C7e+Tt2yYBlrOpdT+dyeIQ==} + randombytes@2.1.0: resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} @@ -5002,6 +5011,9 @@ packages: peerDependencies: react: ^18.3.1 + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + react-remove-scroll-bar@2.3.6: resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} engines: {node: '>=10'} @@ -6247,6 +6259,22 @@ snapshots: jsonpointer: 5.0.1 leven: 3.1.0 + '@atlaskit/pragmatic-drag-and-drop-auto-scroll@1.4.0': + dependencies: + '@atlaskit/pragmatic-drag-and-drop': 1.4.0 + '@babel/runtime': 7.25.9 + + '@atlaskit/pragmatic-drag-and-drop-hitbox@1.0.3': + dependencies: + '@atlaskit/pragmatic-drag-and-drop': 1.4.0 + '@babel/runtime': 7.25.9 + + '@atlaskit/pragmatic-drag-and-drop@1.4.0': + dependencies: + '@babel/runtime': 7.25.9 + bind-event-listener: 3.0.0 + raf-schd: 4.0.3 + '@babel/code-frame@7.25.9': dependencies: '@babel/highlight': 7.25.9 @@ -6954,31 +6982,6 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@dnd-kit/accessibility@3.1.0(react@18.3.1)': - dependencies: - react: 18.3.1 - tslib: 2.8.0 - - '@dnd-kit/core@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@dnd-kit/accessibility': 3.1.0(react@18.3.1) - '@dnd-kit/utilities': 3.2.2(react@18.3.1) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - tslib: 2.8.0 - - '@dnd-kit/sortable@8.0.0(@dnd-kit/core@6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': - dependencies: - '@dnd-kit/core': 6.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@dnd-kit/utilities': 3.2.2(react@18.3.1) - react: 18.3.1 - tslib: 2.8.0 - - '@dnd-kit/utilities@3.2.2(react@18.3.1)': - dependencies: - react: 18.3.1 - tslib: 2.8.0 - '@es-joy/jsdoccomment@0.48.0': dependencies: comment-parser: 1.4.1 @@ -8694,6 +8697,19 @@ snapshots: transitivePeerDependencies: - supports-color + ahooks@3.8.1(react@18.3.1): + dependencies: + '@babel/runtime': 7.25.9 + dayjs: 1.11.13(patch_hash=4wu3h3hwxidwuv4ovjl53zavle) + intersection-observer: 0.12.2 + js-cookie: 3.0.5 + lodash: 4.17.21 + react: 18.3.1 + react-fast-compare: 3.2.2 + resize-observer-polyfill: 1.5.1 + screenfull: 5.2.0 + tslib: 2.8.0 + ajv@6.12.6: dependencies: fast-deep-equal: 3.1.3 @@ -8849,6 +8865,8 @@ snapshots: binary-extensions@2.3.0: {} + bind-event-listener@3.0.0: {} + bindings@1.5.0: dependencies: file-uri-to-path: 1.0.0 @@ -10437,6 +10455,8 @@ snapshots: hasown: 2.0.2 side-channel: 1.0.6 + intersection-observer@0.12.2: {} + invariant@2.2.4: dependencies: loose-envify: 1.4.0 @@ -10641,6 +10661,8 @@ snapshots: js-cookie@2.2.1: {} + js-cookie@3.0.5: {} + js-levenshtein@1.1.6: {} js-tokens@4.0.0: {} @@ -11407,6 +11429,8 @@ snapshots: radix3@1.1.2: {} + raf-schd@4.0.3: {} + randombytes@2.1.0: dependencies: safe-buffer: 5.2.1 @@ -11431,6 +11455,8 @@ snapshots: react: 18.3.1 scheduler: 0.23.2 + react-fast-compare@3.2.2: {} + react-remove-scroll-bar@2.3.6(@types/react@18.3.12)(react@18.3.1): dependencies: react: 18.3.1 diff --git a/src/components/column/card.tsx b/src/components/column/card.tsx index e6d514c..74ecbfa 100644 --- a/src/components/column/card.tsx +++ b/src/components/column/card.tsx @@ -1,7 +1,6 @@ import type { NewsItem, SourceID, SourceResponse } from "@shared/types" import { useQuery } from "@tanstack/react-query" import { AnimatePresence, motion, useInView } from "framer-motion" -import type { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities" import { useWindowSize } from "react-use" import { forwardRef, useImperativeHandle } from "react" import { OverlayScrollbar } from "../common/overlay-scrollbar" @@ -12,23 +11,23 @@ export interface ItemsProps extends React.HTMLAttributes { /** * 是否显示透明度,拖动时原卡片的样式 */ - isDragged?: boolean - handleListeners?: SyntheticListenerMap + isDragging?: boolean + setHandleRef?: (ref: HTMLElement | null) => void } interface NewsCardProps { id: SourceID - handleListeners?: SyntheticListenerMap + setHandleRef?: (ref: HTMLElement | null) => void } -export const CardWrapper = forwardRef(({ id, isDragged, handleListeners, style, ...props }, dndRef) => { +export const CardWrapper = forwardRef(({ id, isDragging, setHandleRef, style, ...props }, dndRef) => { const ref = useRef(null) const inView = useInView(ref, { once: true, }) - useImperativeHandle(dndRef, () => ref.current!) + useImperativeHandle(dndRef, () => ref.current! as HTMLDivElement) return (
(({ id, isDragg className={$( "flex flex-col h-500px rounded-2xl p-4 cursor-default", "backdrop-blur-5 transition-opacity-300", - isDragged && "op-50", + isDragging && "op-50", `bg-${sources[id].color}-500 dark:bg-${sources[id].color} bg-op-40!`, )} style={{ @@ -45,12 +44,12 @@ export const CardWrapper = forwardRef(({ id, isDragg }} {...props} > - {inView && } + {inView && }
) }) -function NewsCard({ id, handleListeners }: NewsCardProps) { +function NewsCard({ id, setHandleRef }: NewsCardProps) { const { refresh } = useRefetch() const { data, isFetching, isError } = useQuery({ queryKey: ["source", id], @@ -141,9 +140,9 @@ function NewsCard({ id, handleListeners }: NewsCardProps) { className={$("btn", isFocused ? "i-ph:star-fill" : "i-ph:star-duotone")} onClick={toggleFocus} /> - {handleListeners && ( + {setHandleRef && (