Skip to content

feat: marketplace tab + 一键发布 + Settings 风格市场配置#444

Merged
appergb merged 4 commits into
betafrom
feat/marketplace-tab
May 15, 2026
Merged

feat: marketplace tab + 一键发布 + Settings 风格市场配置#444
appergb merged 4 commits into
betafrom
feat/marketplace-tab

Conversation

@appergb
Copy link
Copy Markdown
Collaborator

@appergb appergb commented May 15, 2026

User description

Summary

新增 Style Pack Marketplace 客户端集成(对接 openless-marketplace 私有后端):

  • 新 tab pages/Marketplace.tsx:搜索 + 排序(热度/最新)+ 卡片列表 + 详情 Modal + 上传选包器
  • 5 个 IPCcommands.rs):list / detail / install / upload / like —— 通过 HTTP 调 marketplace backend
  • UserPreferences 加两字段marketplaceBaseUrl / marketplaceDevLogin(dev 模式 auth)
  • Style.tsx 详情页加「发布到风格市场」按钮:复用 marketplace_upload IPC
  • Settings.tsx 加「风格市场」折叠区配置 backend URL + GitHub login
  • 5 语言 i18n(zh-CN / en / zh-TW / ja / ko)

Test plan

  • cargo test --lib → 263 全过
  • tsc --noEmit → 0 error
  • 后端端到端:上传 / 安装 / 点赞 / 搜索 / 排序 全通
  • MCP agent 自动审核:注入 prompt → reject / 正常 → approve
  • 手工 UI 验证:新装 OpenLess 后 Settings → 风格市场 填本地 URL → 浏览 + 安装一个 demo pack

不发 tag

合并到 beta,等下一个 Beta 一起发版。


PR Type

Enhancement


Description

  • Add Marketplace browsing and detail modal

  • Wire Rust IPC to marketplace backend

  • Persist marketplace URL and dev login

  • Add publish button and translations


Diagram Walkthrough

flowchart LR
  Shell["App navigation"] -- "opens Marketplace tab" --> MarketplacePage["Marketplace UI"]
  Settings["Settings page"] -- "save prefs" --> UserPrefs["Marketplace preferences"]
  StylePage["Style page"] -- "publish pack" --> IPC["Marketplace IPC"]
  MarketplacePage -- "browse / install / like" --> IPC
  UserPrefs -- "base URL + dev login" --> IPC
  IPC -- "HTTP requests" --> Backend["Marketplace backend"]
  IPC -- "install ZIP" --> Local["Local style packs"]
Loading

File Walkthrough

Relevant files
Enhancement
14 files
commands.rs
Add marketplace HTTP command handlers                                       
+240/-0 
lib.rs
Register new marketplace commands                                               
+5/-0     
FloatingShell.tsx
Add Marketplace tab to navigation                                               
+2/-0     
en.ts
Add English marketplace copy                                                         
+35/-0   
ja.ts
Add Japanese marketplace localization strings                       
+6/-0     
ko.ts
Add Korean marketplace localization strings                           
+6/-0     
zh-CN.ts
Add Simplified Chinese marketplace copy                                   
+35/-0   
zh-TW.ts
Add Traditional Chinese marketplace copy                                 
+35/-0   
ipc.ts
Add marketplace IPC wrappers and mocks                                     
+62/-0   
types.ts
Add marketplace TypeScript interfaces                                       
+24/-0   
Marketplace.tsx
Implement marketplace browse and actions                                 
+483/-0 
Settings.tsx
Add marketplace settings section                                                 
+32/-0   
Style.tsx
Add publish to marketplace action                                               
+40/-0   
useAppState.ts
Extend app state with marketplace tab                                       
+1/-0     
Configuration changes
1 files
types.rs
Persist marketplace preferences in user settings                 
+18/-0   
Tests
1 files
stylePrefs.test.ts
Update preference fixtures for marketplace                             
+2/-0     

baiqing added 2 commits May 15, 2026 14:02
围绕 user goal 1 (a-e) 实现:
- (a) 后端验证:5 个 marketplace_* IPC,HTTP 通过 reqwest 调 backend
- (b) 上传与拉取无问题:marketplace_install / marketplace_upload 复用本地 ZIP IPC
- (c) 单独弹窗:详情 + 上传选包器走 Modal 半透明背景中央卡片
- (d) 搜索框:顶部 input 300ms 防抖 + server-side ?q= 过滤
- (e) 按排名推荐:默认 sort=popular(按 like_count DESC)

后端 IPC(commands.rs):
- marketplace_list / detail / install / upload / like
- HTTP base URL 走 prefs.marketplace_base_url(默认 http://127.0.0.1:8090)
- dev-mode auth 走 prefs.marketplace_dev_login → X-Dev-User header
- install 路径:下载 ZIP 到 temp → 调既有 import_from_zip → 删 temp
- upload 路径:export 本地 pack → multipart POST → 后端入审核队列

UserPreferences 加两个字段(5 处 wiring:struct/Wire/Default×2/Deserialize):
- marketplace_base_url (空 = localhost:8090 默认)
- marketplace_dev_login (空 = 上传按钮 disabled)

前端:
- types.ts 加 MarketplaceListItem / MarketplaceDetail
- ipc.ts 加 5 个 wrapper + mock fixture(vite dev 模式仍可演示 UI)
- pages/Marketplace.tsx (~350 行) UI:搜索 / 排序 toggle / 卡片 grid / 详情弹窗 / 上传选包器
- FloatingShell.tsx + state/useAppState.ts 加 marketplace AppTab
- 5 语言 i18n 补全 nav.marketplace + marketplace.* 子树(en/zh-CN/zh-TW 完整,ja/ko nav 本地化 + 子树 fallback en)

cargo test 263 全过;tsc 0 error。
…oal 2.e)

Goal 2.e 一键发版到云端:
- Style.tsx 详情页加「发布到风格市场」按钮(在导出 ZIP 旁),
  调既有 marketplace_upload IPC。disabled 直到用户在 Settings 配 GitHub login。
- Settings.tsx 加「风格市场」折叠区:marketplaceBaseUrl + marketplaceDevLogin
  两个 input。base URL 空 = localhost:8090 dev 默认;生产填 https://api.<domain>。
- 5 语言 i18n(zh-CN/en/ja/ko/zh-TW)补全 marketplace 相关 settings 文案

cargo test 263 全过;tsc 0 error。
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 15, 2026

PR Reviewer Guide 🔍

(Review updated until commit 9e119e2)

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Like gating

The Like action is still enabled when marketplaceDevLogin is empty, but the Rust command always sends X-Dev-User and the Settings copy says likes are disabled without a login. In that case users can click Like, get a backend 401, and see an error instead of a disabled control.

<Btn variant="ghost" size="sm" onClick={() => void onLike()}>
   {t('marketplace.likeBtn')}

… (pr_agent #444 round 2)

pr_agent 提的两个真问题:

1. Security: arbitrary file write —— marketplace_install 用 backend-controlled
   pack_id 拼临时文件路径。若 backend 被攻陷返回路径遍历 id,可写客户端任意位置。
   修:4 个 marketplace_* IPC 全部加 is_valid_session_id() UUID-v4 白名单
   校验(跟 read_audio_recording 同套 boundary 校验)。

2. Race condition: 搜索 refresh 旧请求晚到覆盖新结果。用户连续输入时体验差。
   修:useRef 单调递增 seq token,response 到了 check seq 是否最新,stale 直接丢。

cargo test 263 全过;tsc 0 error。
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 4af7fec

跟 round 2 同类 race condition:openDetail 用户快速点两张卡片时,先点 A 的
detail response 可能晚于 B 到达 → 覆盖 B 的 detail / Install / Like 作用错对象。

修:复用 useRef seq token 模式,detailSeqRef 单调递增,response 比较 seq 丢
弃 stale。逻辑跟 refresh() 完全对称。
@github-actions
Copy link
Copy Markdown

Persistent review updated to latest commit 9e119e2

@appergb
Copy link
Copy Markdown
Collaborator Author

appergb commented May 15, 2026

pr_agent round 3 提的 Like gating 是真 UX 一致性问题但 LOW:

  • 实际行为:marketplaceDevLogin 空时 Rust 把 X-Dev-User 设成 'anonymous',后端接受不会 401(pr_agent 的 "backend 401" 描述不准)。所以最坏情况是点 Like 后看到错误,不是按钮 disabled
  • 修法:Like Btn 加 disabled={!canUpload} 跟 Upload 一致(1 行)。
  • 按 user memory rework 上限 1-2 轮(当前是 round 3 边界),这条 LOW 不在本 PR 修,记 TODO 在下个 Beta 一并改。

本 PR round 1-3 处理的真问题:

  • round 1 (commit 4af7fec):UUID-v4 白名单(security)+ refresh stale guard(race)
  • round 2 (commit 9e119e2):openDetail stale guard(同类 race)

Goal 4 验收继续 merge。

@appergb appergb merged commit 7420832 into beta May 15, 2026
4 checks passed
@appergb appergb deleted the feat/marketplace-tab branch May 15, 2026 07:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant