From 8cea9b88769b0ca539f4ae1bd6e3befed2320915 Mon Sep 17 00:00:00 2001 From: bill lau Date: Sun, 16 Nov 2025 09:21:40 +0800 Subject: [PATCH 1/3] create new blogger json file --- src/assets/new_blogger.json | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 src/assets/new_blogger.json diff --git a/src/assets/new_blogger.json b/src/assets/new_blogger.json new file mode 100644 index 0000000..da42320 --- /dev/null +++ b/src/assets/new_blogger.json @@ -0,0 +1,22 @@ +[ + { + "name": "罗磊", + "url": "https://luolei.org/" + }, + { + "name": "Ahmad Shadeed", + "url": "https://ishadeed.com/articles/" + }, + { + "name": "Kevin Kelly", + "url": "https://kk.org/" + }, + { + "name": "水星", + "url": "https://mercurychong.blogspot.com/" + }, + { + "name": "池建强", + "url": "https://macshuo.com/?paged=1" + } +] \ No newline at end of file From 3f5bd57a75ac1b54731a4be622cb147adc1ab30c Mon Sep 17 00:00:00 2001 From: bill lau Date: Sun, 16 Nov 2025 10:00:38 +0800 Subject: [PATCH 2/3] plan and implement spec --- newBlogger/plan.md | 85 +++++++++++++++++++++++++++++++++++++ newBlogger/spec.md | 5 +++ src/App.tsx | 17 +++++++- src/assets/new_blogger.json | 22 ---------- 4 files changed, 105 insertions(+), 24 deletions(-) create mode 100644 newBlogger/plan.md create mode 100644 newBlogger/spec.md delete mode 100644 src/assets/new_blogger.json diff --git a/newBlogger/plan.md b/newBlogger/plan.md new file mode 100644 index 0000000..8a679b3 --- /dev/null +++ b/newBlogger/plan.md @@ -0,0 +1,85 @@ +# 实施计划(基于 newBlogger/spec.md) + +本文将 spec.md 中的三点需求转化为可执行的实现方案与验收标准,目标是最小改动地在 `App.tsx` 的 Them 组件中完成数据重排与“New”标识展示。 + +## 背景与目标 +- 背景:当前 Them 组件直接展示 `blogs.json` 的数据顺序。 +- 目标: + 1) 将 `blogs.json` 最后 5 个项目移动到列表最前方显示; + 2) 这 5 个项目不再在列表末尾重复展示; + 3) 对这 5 个“最新”项目在卡片右上角展示“New”标志。 + +## 范围与影响 +- 主要修改文件: + - `src/App.tsx`(包含 Them 组件的页面逻辑) + - 如需样式支持:`src/App.css` 或与卡片组件相关的样式文件 +- 可能涉及:卡片渲染的 JSX(若有独立 Card 组件,则在该组件中加上“New”徽标的结构与样式;若直接在 Them 中渲染列表,则在对应 JSX 中新增徽标与样式类) +- 不在范围:后端、接口、数据结构的变更;`blogs.json` 内容本身不变。 + +## 设计方案 +### 数据处理 +- 假设:`blogs.json` 为数组,最后 5 个元素代表最新项目;保持这 5 个的相对顺序(与原数组中相同的顺序)。 +- 处理逻辑: + - `const last5 = blogs.slice(-5);` + - `const rest = blogs.slice(0, blogs.length - 5);` + - 最终用于渲染的数据:`const arranged = [...last5, ...rest];` + - 这样天然避免了在列表末尾再次出现这 5 个项目(无二次去重的开销)。 +- “New” 标识集合: + - 使用集合保存“最新 5 个”的唯一标识(`name+url`)。 + - 渲染时判断该集合包含该项,则在其卡片右上角显示“New”。 + +### UI 与样式 +- 在卡片右上角新增一个“New”徽标: + - 结构:在卡片容器内增加一个绝对定位的 `New`。 + - 使用Radix UI的相关组件来实现 + +### 类型与健壮性 +- 若存在 `Blog` 类型:扩展渲染阶段的临时标记方式(例如使用 `Set` 判断),避免修改原始数据结构。 +- 边界情况: + - 当 `blogs.length < 5`:将全部项目视为“最新”,全部前置并显示“New”。 + - 当 `blogs.length === 5`:全部前置并显示“New”,末尾无重复。 + - 当 `blogs.length === 0`:渲染空态占位(保持当前项目既有的空态策略)。 + +## 实施步骤 +1. 在 `src/App.tsx` 的 Them 组件中,读取原始 `blogs` 数组后,依据上述数据处理逻辑生成 `arranged`。 +2. 创建一个 `Set`(如 `newSet`)保存最新 5 个项目的唯一键((`name+url`)。 +3. 用 `arranged` 作为渲染数据源,渲染每个卡片时:若命中 `newSet`,在卡片右上角渲染“New”徽标。 +4. 使用Radix UI的相关组件来实现“New”徽标的样式 +5. 自测页面,确认顺序、去重、徽标展示符合预期。 + +## 验收标准 +- 顺序:`blogs.json` 的最后 5 条出现在列表最前方,且顺序与原数组中这 5 条的相对顺序一致。 +- 去重:前置的 5 条不会在列表后方再次出现。 +- 标识:这 5 条的卡片右上角显示“New”徽标;其余项目不显示。 +- 边界:当数据条数少于 5 时,现有全部数据均显示“New”,不产生错误或样式错位。 +- 回归:除上述变化外,其它样式与功能保持不变,无控制台报错与类型错误。 + +## 测试用例(手测为主) +- 数据 > 5 条: + - 前 5 个卡片均显示“New”;列表尾部不再出现这 5 条。 +- 数据 = 5 条: + - 全部显示“New”,列表中无重复。 +- 数据 < 5 条: + - 全部显示“New”,无报错,布局正常。 +- 空数组: + - 显示空态(与现有逻辑一致)。 + +## 风险与回滚 +- 风险: + - 缺少唯一键(无 `id`)时的判定可能不稳定。 + - 样式覆盖范围过大导致其它卡片布局受影响。 +- 规避: + - 若无 `id`,在判定集中使用稳妥的组合键(如 `name+url`),考虑是否需要使用md5(`name+url`)。 + - 新增样式使用独立类名,避免全局选择器。 +- 回滚方案: + - 保留原 `blogs` 渲染逻辑分支,或通过 Git 回滚到变更前版本。 + +## 工作量与时间预估 +- 研发实现:0.5 小时 +- 样式与自测:0.5 小时 +- 预估总计:1 小时内可完成 + +## 交付物 +- 代码变更:`src/App.tsx`(Them 组件)及必要的样式文件 +- 文档:本 `plan.md` +` \ No newline at end of file diff --git a/newBlogger/spec.md b/newBlogger/spec.md new file mode 100644 index 0000000..6f5e6ec --- /dev/null +++ b/newBlogger/spec.md @@ -0,0 +1,5 @@ +1. 在App.tsx页面里,Them这个组件,现在会展示const blogs: Blog[] = blogsData as Blog[];(其中blogsData的值为 import blogsData from './.assets/blogs.json')的数据,我希望做一个修改 + +2. 我希望Them组件,在展示blogs数组数据时,将blogs.json文件最下面的5个项目展示在最前面(因为这5个项目是最新的),另外因为这5个项目已经在最前面展示了,所以在最后面不要再展示了 + +3. 另外对于这5个新项目,在Card的右上角展示“New”的标志,代表这5个是新项目 diff --git a/src/App.tsx b/src/App.tsx index b995e12..c2b247d 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,4 +1,4 @@ -import { Card, Text } from '@radix-ui/themes' +import { Card, Text, Badge } from '@radix-ui/themes' import { Routes, Route, Link } from 'react-router' import './App.css' import blogsData from './assets/blogs.json' @@ -25,7 +25,15 @@ interface Blog { const blogs: Blog[] = blogsData as Blog[]; function Them() { - const { currentItems, currentPage, totalPages, startIndex, endIndex, totalItems, setPage } = usePagination(blogs, 20); + // 计算将最后5个项目前置的数组,并标记这些“最新”项 + const sliceCount = Math.min(5, blogs.length); + const lastN = blogs.slice(-sliceCount); + const rest = blogs.slice(0, blogs.length - sliceCount); + const arranged: Blog[] = [...lastN, ...rest]; + const toKey = (b: Blog) => `${b.name}|${b.url}`; + const newSet = new Set(lastN.map(toKey)); + + const { currentItems, currentPage, totalPages, startIndex, endIndex, totalItems, setPage } = usePagination(arranged, 20); return (
@@ -47,6 +55,11 @@ function Them() { decoding="async" /> + {newSet.has(toKey(blog)) && ( +
+ New +
+ )}
diff --git a/src/assets/new_blogger.json b/src/assets/new_blogger.json deleted file mode 100644 index da42320..0000000 --- a/src/assets/new_blogger.json +++ /dev/null @@ -1,22 +0,0 @@ -[ - { - "name": "罗磊", - "url": "https://luolei.org/" - }, - { - "name": "Ahmad Shadeed", - "url": "https://ishadeed.com/articles/" - }, - { - "name": "Kevin Kelly", - "url": "https://kk.org/" - }, - { - "name": "水星", - "url": "https://mercurychong.blogspot.com/" - }, - { - "name": "池建强", - "url": "https://macshuo.com/?paged=1" - } -] \ No newline at end of file From 75d65b1d0775268ea75763de2273c4dc84ae79c4 Mon Sep 17 00:00:00 2001 From: bill lau Date: Sun, 16 Nov 2025 10:02:43 +0800 Subject: [PATCH 3/3] remove work file --- newBlogger/plan.md | 85 ---------------------------------------------- newBlogger/spec.md | 5 --- 2 files changed, 90 deletions(-) delete mode 100644 newBlogger/plan.md delete mode 100644 newBlogger/spec.md diff --git a/newBlogger/plan.md b/newBlogger/plan.md deleted file mode 100644 index 8a679b3..0000000 --- a/newBlogger/plan.md +++ /dev/null @@ -1,85 +0,0 @@ -# 实施计划(基于 newBlogger/spec.md) - -本文将 spec.md 中的三点需求转化为可执行的实现方案与验收标准,目标是最小改动地在 `App.tsx` 的 Them 组件中完成数据重排与“New”标识展示。 - -## 背景与目标 -- 背景:当前 Them 组件直接展示 `blogs.json` 的数据顺序。 -- 目标: - 1) 将 `blogs.json` 最后 5 个项目移动到列表最前方显示; - 2) 这 5 个项目不再在列表末尾重复展示; - 3) 对这 5 个“最新”项目在卡片右上角展示“New”标志。 - -## 范围与影响 -- 主要修改文件: - - `src/App.tsx`(包含 Them 组件的页面逻辑) - - 如需样式支持:`src/App.css` 或与卡片组件相关的样式文件 -- 可能涉及:卡片渲染的 JSX(若有独立 Card 组件,则在该组件中加上“New”徽标的结构与样式;若直接在 Them 中渲染列表,则在对应 JSX 中新增徽标与样式类) -- 不在范围:后端、接口、数据结构的变更;`blogs.json` 内容本身不变。 - -## 设计方案 -### 数据处理 -- 假设:`blogs.json` 为数组,最后 5 个元素代表最新项目;保持这 5 个的相对顺序(与原数组中相同的顺序)。 -- 处理逻辑: - - `const last5 = blogs.slice(-5);` - - `const rest = blogs.slice(0, blogs.length - 5);` - - 最终用于渲染的数据:`const arranged = [...last5, ...rest];` - - 这样天然避免了在列表末尾再次出现这 5 个项目(无二次去重的开销)。 -- “New” 标识集合: - - 使用集合保存“最新 5 个”的唯一标识(`name+url`)。 - - 渲染时判断该集合包含该项,则在其卡片右上角显示“New”。 - -### UI 与样式 -- 在卡片右上角新增一个“New”徽标: - - 结构:在卡片容器内增加一个绝对定位的 `New`。 - - 使用Radix UI的相关组件来实现 - -### 类型与健壮性 -- 若存在 `Blog` 类型:扩展渲染阶段的临时标记方式(例如使用 `Set` 判断),避免修改原始数据结构。 -- 边界情况: - - 当 `blogs.length < 5`:将全部项目视为“最新”,全部前置并显示“New”。 - - 当 `blogs.length === 5`:全部前置并显示“New”,末尾无重复。 - - 当 `blogs.length === 0`:渲染空态占位(保持当前项目既有的空态策略)。 - -## 实施步骤 -1. 在 `src/App.tsx` 的 Them 组件中,读取原始 `blogs` 数组后,依据上述数据处理逻辑生成 `arranged`。 -2. 创建一个 `Set`(如 `newSet`)保存最新 5 个项目的唯一键((`name+url`)。 -3. 用 `arranged` 作为渲染数据源,渲染每个卡片时:若命中 `newSet`,在卡片右上角渲染“New”徽标。 -4. 使用Radix UI的相关组件来实现“New”徽标的样式 -5. 自测页面,确认顺序、去重、徽标展示符合预期。 - -## 验收标准 -- 顺序:`blogs.json` 的最后 5 条出现在列表最前方,且顺序与原数组中这 5 条的相对顺序一致。 -- 去重:前置的 5 条不会在列表后方再次出现。 -- 标识:这 5 条的卡片右上角显示“New”徽标;其余项目不显示。 -- 边界:当数据条数少于 5 时,现有全部数据均显示“New”,不产生错误或样式错位。 -- 回归:除上述变化外,其它样式与功能保持不变,无控制台报错与类型错误。 - -## 测试用例(手测为主) -- 数据 > 5 条: - - 前 5 个卡片均显示“New”;列表尾部不再出现这 5 条。 -- 数据 = 5 条: - - 全部显示“New”,列表中无重复。 -- 数据 < 5 条: - - 全部显示“New”,无报错,布局正常。 -- 空数组: - - 显示空态(与现有逻辑一致)。 - -## 风险与回滚 -- 风险: - - 缺少唯一键(无 `id`)时的判定可能不稳定。 - - 样式覆盖范围过大导致其它卡片布局受影响。 -- 规避: - - 若无 `id`,在判定集中使用稳妥的组合键(如 `name+url`),考虑是否需要使用md5(`name+url`)。 - - 新增样式使用独立类名,避免全局选择器。 -- 回滚方案: - - 保留原 `blogs` 渲染逻辑分支,或通过 Git 回滚到变更前版本。 - -## 工作量与时间预估 -- 研发实现:0.5 小时 -- 样式与自测:0.5 小时 -- 预估总计:1 小时内可完成 - -## 交付物 -- 代码变更:`src/App.tsx`(Them 组件)及必要的样式文件 -- 文档:本 `plan.md` -` \ No newline at end of file diff --git a/newBlogger/spec.md b/newBlogger/spec.md deleted file mode 100644 index 6f5e6ec..0000000 --- a/newBlogger/spec.md +++ /dev/null @@ -1,5 +0,0 @@ -1. 在App.tsx页面里,Them这个组件,现在会展示const blogs: Blog[] = blogsData as Blog[];(其中blogsData的值为 import blogsData from './.assets/blogs.json')的数据,我希望做一个修改 - -2. 我希望Them组件,在展示blogs数组数据时,将blogs.json文件最下面的5个项目展示在最前面(因为这5个项目是最新的),另外因为这5个项目已经在最前面展示了,所以在最后面不要再展示了 - -3. 另外对于这5个新项目,在Card的右上角展示“New”的标志,代表这5个是新项目