diff --git a/package.json b/package.json index 958346e..98e2076 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "build": "vite build", "nitro": "nitro build", "lint": "eslint .", + "favicon": "tsx ./scripts/favicon.ts", "test": "vitest", "preview": "vite preview" }, @@ -21,12 +22,11 @@ "@tanstack/react-router": "^1.58.9", "@tanstack/router-devtools": "^1.58.9", "@unocss/reset": "^0.62.4", - "array-differences": "^3.0.2", "clsx": "^2.1.1", - "dayjs": "^1.11.13", - "framer-motion": "^11.8.0", + "favicons-scraper": "^1.3.2", "h3": "^1.12.0", "jotai": "^2.10.0", + "node-fetch": "^3.3.2", "react": "^18.3.1", "react-dom": "^18.3.1", "react-intersection-observer": "^9.13.1", @@ -45,8 +45,8 @@ "eslint": "^9.11.1", "eslint-plugin-react-hooks": "^5.1.0-rc-778e1ed2-20240926", "eslint-plugin-react-refresh": "^0.4.12", - "globals": "^15.9.0", "nitropack": "^2.9.7", + "tsx": "^4.19.1", "typescript": "^5.6.2", "typescript-eslint": "^8.7.0", "unocss": "^0.62.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85900d8..19be070 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,24 +32,21 @@ importers: '@unocss/reset': specifier: ^0.62.4 version: 0.62.4 - array-differences: - specifier: ^3.0.2 - version: 3.0.2 clsx: specifier: ^2.1.1 version: 2.1.1 - dayjs: - specifier: ^1.11.13 - version: 1.11.13 - framer-motion: - specifier: ^11.8.0 - version: 11.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + favicons-scraper: + specifier: ^1.3.2 + version: 1.3.2 h3: specifier: ^1.12.0 version: 1.12.0 jotai: specifier: ^2.10.0 version: 2.10.0(@types/react@18.3.9)(react@18.3.1) + node-fetch: + specifier: ^3.3.2 + version: 3.3.2 react: specifier: ^18.3.1 version: 18.3.1 @@ -99,12 +96,12 @@ importers: eslint-plugin-react-refresh: specifier: ^0.4.12 version: 0.4.12(eslint@9.11.1(jiti@1.21.6)) - globals: - specifier: ^15.9.0 - version: 15.9.0 nitropack: specifier: ^2.9.7 version: 2.9.7(magicast@0.3.5) + tsx: + specifier: ^4.19.1 + version: 4.19.1 typescript: specifier: ^5.6.2 version: 5.6.2 @@ -1799,9 +1796,6 @@ packages: argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - array-differences@3.0.2: - resolution: {integrity: sha512-raP8rW7DyS3AypmGHlvuSxXUdTXVvQxPHDlWFyQ0DLw4BMb//1qJtUlBRRK6ePLfQV3B3L5tLSe7qix+uEf14w==} - assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} @@ -2064,8 +2058,9 @@ packages: csstype@3.1.3: resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - dayjs@1.11.13: - resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} db0@0.1.4: resolution: {integrity: sha512-Ft6eCwONYxlwLjBXSJxw0t0RYtA5gW9mq8JfBXn9TtC0nDPlqePAhpv9v4g9aONBi6JI1OXHTKKkUYGd+BOrCA==} @@ -2554,6 +2549,9 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + favicons-scraper@1.3.2: + resolution: {integrity: sha512-rsEBzLyEdJFEg/fzAx0vl8HypWwjSxisdHTaZ1W/jrKRuCm+0GG4xVWrOfhvG18dAhG2eKBW0tfhGarQt/HL8w==} + fdir@6.3.0: resolution: {integrity: sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==} peerDependencies: @@ -2562,6 +2560,10 @@ packages: picomatch: optional: true + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + file-entry-cache@8.0.0: resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} engines: {node: '>=16.0.0'} @@ -2596,19 +2598,9 @@ packages: resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} engines: {node: '>=14'} - framer-motion@11.8.0: - resolution: {integrity: sha512-q/axN/PFRdKmzPK6PO2OhbLUMWXXZuiejdM1/3FhC2hm4YIetc+qeco2EvWm4u1/UTFmevclE492wGFNfSZ4eQ==} - peerDependencies: - '@emotion/is-prop-valid': '*' - react: ^18.0.0 - react-dom: ^18.0.0 - peerDependenciesMeta: - '@emotion/is-prop-valid': - optional: true - react: - optional: true - react-dom: - optional: true + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} fresh@0.5.2: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} @@ -3207,6 +3199,10 @@ packages: node-addon-api@7.1.1: resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + node-fetch-native@1.6.4: resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} @@ -3219,6 +3215,10 @@ packages: encoding: optional: true + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + node-forge@1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} @@ -4180,6 +4180,10 @@ packages: peerDependencies: eslint: '>=6.0.0' + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -5859,8 +5863,6 @@ snapshots: argparse@2.0.1: {} - array-differences@3.0.2: {} - assertion-error@2.0.1: {} async-sema@3.1.1: {} @@ -6110,7 +6112,7 @@ snapshots: csstype@3.1.3: {} - dayjs@1.11.13: {} + data-uri-to-buffer@4.0.1: {} db0@0.1.4: {} @@ -6769,10 +6771,17 @@ snapshots: dependencies: reusify: 1.0.4 + favicons-scraper@1.3.2: {} + fdir@6.3.0(picomatch@4.0.2): optionalDependencies: picomatch: 4.0.2 + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + file-entry-cache@8.0.0: dependencies: flat-cache: 4.0.1 @@ -6807,12 +6816,9 @@ snapshots: cross-spawn: 7.0.3 signal-exit: 4.1.0 - framer-motion@11.8.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + formdata-polyfill@4.0.10: dependencies: - tslib: 2.7.0 - optionalDependencies: - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) + fetch-blob: 3.2.0 fresh@0.5.2: {} @@ -7486,12 +7492,20 @@ snapshots: node-addon-api@7.1.1: {} + node-domexception@1.0.0: {} + node-fetch-native@1.6.4: {} node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + node-forge@1.3.1: {} node-gyp-build@4.8.2: {} @@ -8496,6 +8510,8 @@ snapshots: transitivePeerDependencies: - supports-color + web-streams-polyfill@3.3.3: {} + webidl-conversions@3.0.1: {} webpack-virtual-modules@0.6.2: {} diff --git a/public/icons/36kr.png b/public/icons/36kr.png new file mode 100644 index 0000000..5b9487a Binary files /dev/null and b/public/icons/36kr.png differ diff --git a/public/icons/acfun.png b/public/icons/acfun.png new file mode 100644 index 0000000..371abb6 Binary files /dev/null and b/public/icons/acfun.png differ diff --git a/public/icons/baidu.png b/public/icons/baidu.png new file mode 100644 index 0000000..1ba2409 Binary files /dev/null and b/public/icons/baidu.png differ diff --git a/public/icons/bilibili.png b/public/icons/bilibili.png new file mode 100644 index 0000000..13e839a Binary files /dev/null and b/public/icons/bilibili.png differ diff --git a/public/icons/cankaoxiaoxi.png b/public/icons/cankaoxiaoxi.png new file mode 100644 index 0000000..93192a6 Binary files /dev/null and b/public/icons/cankaoxiaoxi.png differ diff --git a/public/icons/douyin.png b/public/icons/douyin.png new file mode 100644 index 0000000..637ab31 Binary files /dev/null and b/public/icons/douyin.png differ diff --git a/public/icons/genshin.png b/public/icons/genshin.png new file mode 100644 index 0000000..d9f6746 Binary files /dev/null and b/public/icons/genshin.png differ diff --git a/public/icons/github.png b/public/icons/github.png new file mode 100644 index 0000000..dd4776c Binary files /dev/null and b/public/icons/github.png differ diff --git a/public/icons/hellogithub.png b/public/icons/hellogithub.png new file mode 100644 index 0000000..6533930 Binary files /dev/null and b/public/icons/hellogithub.png differ diff --git a/public/icons/honkai.png b/public/icons/honkai.png new file mode 100644 index 0000000..1f5626d Binary files /dev/null and b/public/icons/honkai.png differ diff --git a/public/icons/hupu.png b/public/icons/hupu.png new file mode 100644 index 0000000..c79ff4b Binary files /dev/null and b/public/icons/hupu.png differ diff --git a/public/icons/ithome.png b/public/icons/ithome.png new file mode 100644 index 0000000..a3c034f Binary files /dev/null and b/public/icons/ithome.png differ diff --git a/public/icons/jianshu.png b/public/icons/jianshu.png new file mode 100644 index 0000000..db2614b Binary files /dev/null and b/public/icons/jianshu.png differ diff --git a/public/icons/juejin.png b/public/icons/juejin.png new file mode 100644 index 0000000..1f3ea16 Binary files /dev/null and b/public/icons/juejin.png differ diff --git a/public/icons/kuaishou.png b/public/icons/kuaishou.png new file mode 100644 index 0000000..91c665a Binary files /dev/null and b/public/icons/kuaishou.png differ diff --git a/public/icons/lol.png b/public/icons/lol.png new file mode 100644 index 0000000..034c85f Binary files /dev/null and b/public/icons/lol.png differ diff --git a/public/icons/peopledaily.png b/public/icons/peopledaily.png new file mode 100644 index 0000000..ca69696 Binary files /dev/null and b/public/icons/peopledaily.png differ diff --git a/public/icons/sspai.png b/public/icons/sspai.png new file mode 100644 index 0000000..de7086c Binary files /dev/null and b/public/icons/sspai.png differ diff --git a/public/icons/starrail.png b/public/icons/starrail.png new file mode 100644 index 0000000..7acdc6f Binary files /dev/null and b/public/icons/starrail.png differ diff --git a/public/icons/thepaper.png b/public/icons/thepaper.png new file mode 100644 index 0000000..a9b3937 Binary files /dev/null and b/public/icons/thepaper.png differ diff --git a/public/icons/tieba.png b/public/icons/tieba.png new file mode 100644 index 0000000..e689d86 Binary files /dev/null and b/public/icons/tieba.png differ diff --git a/public/icons/toutiao.png b/public/icons/toutiao.png new file mode 100644 index 0000000..e0e974d Binary files /dev/null and b/public/icons/toutiao.png differ diff --git a/public/icons/v2ex.png b/public/icons/v2ex.png new file mode 100644 index 0000000..41b4075 Binary files /dev/null and b/public/icons/v2ex.png differ diff --git a/public/icons/weibo.png b/public/icons/weibo.png new file mode 100644 index 0000000..11a8804 Binary files /dev/null and b/public/icons/weibo.png differ diff --git a/public/icons/weread.png b/public/icons/weread.png new file mode 100644 index 0000000..4dd5ebf Binary files /dev/null and b/public/icons/weread.png differ diff --git a/public/icons/zaobao.png b/public/icons/zaobao.png new file mode 100644 index 0000000..321f0ae Binary files /dev/null and b/public/icons/zaobao.png differ diff --git a/public/icons/zhihu.png b/public/icons/zhihu.png new file mode 100644 index 0000000..e2c3b1c Binary files /dev/null and b/public/icons/zhihu.png differ diff --git a/scripts/favicon.ts b/scripts/favicon.ts new file mode 100644 index 0000000..0a95fcb --- /dev/null +++ b/scripts/favicon.ts @@ -0,0 +1,49 @@ +import fs from "node:fs" +import { fileURLToPath } from "node:url" +import { join } from "node:path" +import { getLogos } from "favicons-scraper" +import fetch from "node-fetch" +import { sources } from "../shared/data" + +const projectDir = fileURLToPath(new URL("..", import.meta.url)) +const iconsDir = join(projectDir, "public", "icons") +async function downloadImage(url: string, outputPath: string) { + try { + const response = await fetch(url) + if (!response.ok) { + throw new Error(`Could not fetch ${url}, status: ${response.status}`) + } + + const fileStream = fs.createWriteStream(outputPath) + + await new Promise((resolve, reject) => { + response.body?.pipe(fileStream) + fileStream.on("finish", resolve) + fileStream.on("error", reject) + }) + + console.log("Image downloaded successfully.") + } catch (error) { + console.error("Error downloading the image:", error) + } +} + +async function main() { + await Promise.all( + Object.entries(sources).map(async ([id, source]) => { + try { + const icon = join(iconsDir, `${id}.png`) + if (fs.existsSync(icon)) return + if (!source.home) return + const res = await getLogos(source.home) + if (res.length) { + await downloadImage(res[0].src, icon) + } + } catch (e) { + console.error(id, "\n", e ) + } + }), + ) +} + +main() diff --git a/server/sources/index.ts b/server/sources/index.ts new file mode 100644 index 0000000..e69de29 diff --git a/server/sources/weibo.ts b/server/sources/weibo.ts new file mode 100644 index 0000000..e69de29 diff --git a/shared/data.ts b/shared/data.ts index ef524ae..9ad769c 100644 --- a/shared/data.ts +++ b/shared/data.ts @@ -2,19 +2,55 @@ import type { Metadata } from "./types" export const sectionIds = ["focus", "social", "china", "world", "digital"] as const -export const sourceList = { - "36kr": "36氪", - "douyin": "抖音", - "hupu": "虎扑", - "zhihu": "知乎", - "weibo": "微博", - "tieba": "贴吧", - "zaobao": "联合早报", - "thepaper": "澎湃新闻", - "toutiao": "今日头条", - "cankaoxiaoxi": "参考消息", - "peopledaily": "人民日报", -} as const satisfies Record +export const sources = { + "36kr": { + name: "36氪", + home: "https://36kr.com", + }, + "douyin": { + name: "抖音", + home: "https://www.douyin.com", + }, + "hupu": { + name: "虎扑", + home: "https://hupu.com", + }, + "zhihu": { + name: "知乎", + home: "https://www.zhihu.com", + }, + "weibo": { + name: "微博", + home: "https://weibo.com", + }, + "tieba": { + name: "百度贴吧", + home: "https://tieba.baidu.com", + }, + "zaobao": { + name: "联合早报", + home: "https://www.zaobao.com", + }, + "thepaper": { + name: "澎湃新闻", + home: "https://www.thepaper.cn", + }, + "toutiao": { + name: "今日头条", + home: "https://www.toutiao.com", + }, + "cankaoxiaoxi": { + name: "参考消息", + home: "http://www.cankaoxiaoxi.com", + }, + "peopledaily": { + name: "人民日报", + home: "http://paper.people.com.cn", + }, +} as const satisfies Record export const metadata: Metadata = { focus: { diff --git a/shared/types.ts b/shared/types.ts index d73d521..53666db 100644 --- a/shared/types.ts +++ b/shared/types.ts @@ -1,6 +1,6 @@ -import type { sectionIds, sourceList } from "./data" +import type { sectionIds, sources } from "./data" -export type SourceID = keyof(typeof sourceList) +export type SourceID = keyof(typeof sources) export type SectionID = (typeof sectionIds)[number] export type Metadata = Record @@ -29,6 +29,5 @@ export interface SourceInfo { total: number link?: string updateTime: string - fromCache: boolean data: NewsItem[] } diff --git a/src/atoms.ts b/src/atoms.ts index 30e669b..02651c3 100644 --- a/src/atoms.ts +++ b/src/atoms.ts @@ -1,10 +1,10 @@ import { atom } from "jotai" import type { SectionID, SourceID } from "@shared/types" -import { metadata, sourceList } from "@shared/data" +import { metadata, sources } from "@shared/data" import { atomWithLocalStorage } from "./hooks/atomWithLocalStorage" export const focusSourcesAtom = atomWithLocalStorage("focusSources", [], (stored) => { - return stored.filter(item => item in sourceList) + return stored.filter(item => item in sources) }) function initRefetchSource() { @@ -17,7 +17,7 @@ function initRefetchSource() { if (!Number.isNaN(quitTime) && now - quitTime < 1000) { time = now } - return Object.fromEntries(Object.keys(sourceList).map(k => [k, time])) as Record + return Object.fromEntries(Object.keys(sources).map(k => [k, time])) as Record } export const refetchSourceAtom = atom(initRefetchSource()) diff --git a/src/components/Card.tsx b/src/components/Card.tsx index 38d164e..44b59d2 100644 --- a/src/components/Card.tsx +++ b/src/components/Card.tsx @@ -6,8 +6,8 @@ import clsx from "clsx" import { CSS } from "@dnd-kit/utilities" import { useInView } from "react-intersection-observer" import { useAtom } from "jotai" -import { forwardRef, useCallback, useEffect, useImperativeHandle, useRef } from "react" -import { sourceList } from "@shared/data" +import { forwardRef, useCallback, useImperativeHandle, useRef } from "react" +import { sources } from "@shared/data" import type { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities" import { useSortable } from "@dnd-kit/sortable" import { focusSourcesAtom, refetchSourceAtom } from "~/atoms" @@ -25,22 +25,13 @@ export const CardWrapper = forwardRef(({ id, withOpa threshold: 0, }) - // const bindRef = useCallback((node: HTMLDivElement) => { - // inViewRef(node) - // if (typeof dndRef === "function") { - // dndRef(node) - // } else if (dndRef) { - // dndRef.current = node - // } - // }, [inViewRef, dndRef]) - useImperativeHandle(dndRef, () => ref.current as HTMLDivElement) useImperativeHandle(inViewRef, () => ref.current as HTMLDivElement) return (
{subTitle} + if (subTitle) return {subTitle} } function UpdateTime({ query }: Query) { @@ -108,7 +99,7 @@ function UpdateTime({ query }: Query) { function Num({ num }: { num: number }) { const color = ["bg-red-900", "bg-red-500", "bg-red-400"] return ( - + {num} ) @@ -122,12 +113,12 @@ function NewsList({ query }: Query) { {items.slice(0, 20).map((item, i) => (
- - + + {item.title} {item.timestamp && ( - + {relativeTime(item.timestamp)} )} @@ -182,10 +173,13 @@ export function NewsCard({ id, inView, isDragging, listeners }: NewsCardProps) { return ( <> -
- - {sourceList[id]} - +
+
+ {id} e.currentTarget.hidden = true} /> + + {sources[id].name} + +
diff --git a/src/components/NewsCard.tsx b/src/components/NewsCard.tsx deleted file mode 100644 index 1dabcd1..0000000 --- a/src/components/NewsCard.tsx +++ /dev/null @@ -1,75 +0,0 @@ -import type { CSSProperties, HTMLAttributes } from "react" -import { useSortable } from "@dnd-kit/sortable" -import { CSS } from "@dnd-kit/utilities" -import { forwardRef } from "react" -import clsx from "clsx" -import type { SyntheticListenerMap } from "@dnd-kit/core/dist/hooks/utilities" - -type ItemProps = HTMLAttributes & { - id: string - withOpacity?: boolean - isDragging?: boolean - listeners?: SyntheticListenerMap -} - -export const Item = forwardRef(({ id, withOpacity, isDragging, listeners, style, ...props }, ref) => { - const inlineStyles: CSSProperties = { - transformOrigin: "50% 50%", - minHeight: "500px", - ...style, - } - - const css = [ - "border rounded-xl", - isDragging ? "scale-105" : "", - withOpacity && "op-50", - ] - - return ( -
-
- 你好 -
-
- {id} -
-
- ) -}) - -export function SortableItem(props: ItemProps) { - const { id } = props - const { - isDragging, - attributes, - listeners, - setNodeRef, - transform, - transition, - } = useSortable({ id }) - - const style = { - transform: CSS.Transform.toString(transform), - transition: transition || undefined, - } - - return ( - - ) -} diff --git a/src/components/Pure.tsx b/src/components/Pure.tsx index d26e676..4b31dd0 100644 --- a/src/components/Pure.tsx +++ b/src/components/Pure.tsx @@ -6,7 +6,7 @@ import { currentSectionAtom } from "~/atoms" export function GridContainer({ children }: PropsWithChildren) { return (
+
diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 997b89d..fc0a994 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -24,7 +24,7 @@ function IndexComponent() { return id && (
-
+
{sectionIds.map(section => (