wangdl
0cf727899a
fix: add getLearningRecords adapter for cursor param mismatch
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 17:00:03 +08:00
wangdl
d8125ddf34
fix: iOS compile errors - protocol mismatches + void return
...
- ReadingRuntimeAdapter: clearExportedEvents is void, return count separately
- ActivityViewModel: FocusItemServicing.list→listAll, add days/type? params
- ActivityViewModelTests: update mocks to match new protocol signatures
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 16:58:23 +08:00
wangdl
b0df8ee58e
feat: add en/ja localization support (IOS-INFO-037)
...
iOS CI/CD / Build & Test (push) Has been cancelled
- en.lproj/Localizable.strings: English translations
- ja.lproj/Localizable.strings: Japanese translations
- Covers common, navigation, reader, progress, analysis, study, AI
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 14:26:24 +08:00
wangdl
de384dc027
test: fill iOS coverage gaps - fromBlockScroll, refresh, View helpers
...
- fromBlockScroll: success + empty/negative/OOB guard tests (4)
- StudyHomeViewModel.refresh: stats update + mainAction update (2)
- View helpers: statusLabel(4) + formatSeconds(7) standalone tests
- formatFileSize smoke test (indirect via View init)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:44:54 +08:00
wangdl
c7de97279b
test: add P1-fallback + refresh tests for StudyHomeViewModel
...
- P1 fallback: continueService throws → falls to unfinished session
- refresh: updates stats without setting loadingState
- Fix: remove nonexistent materialId/readingTargetType from LearningSession mock
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:25:41 +08:00
wangdl
9ec6fdc3d5
test: add StudyHomeViewModel unit tests with DI (IOS-INFO-037)
...
- Add 6 service protocols (SessionServicing, ReviewServicing,
KBListServicing, QuizListServicing, ActivityHomeServicing,
ContinueLearningServicing)
- ViewModel init supports DI with defaults to .shared
- 16 tests: initial state, loadAll stats, all 5 priority levels
(continueSession→todaysReview→selfTest→startLearning→empty),
banner, weekly stats from summary/streak
- Priority P1 continueSession tested with mock API + temp file
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:23:08 +08:00
wangdl
3a8266ece2
test: add ActivityViewModel unit tests with DI (IOS-INFO-036)
...
- Add 5 service protocols (ActivityServicing, FocusItemServicing,
ReadingContinueServicing, LearningStatusServicing)
- ViewModel init supports DI with defaults to .shared
- Mock services for all 10 parallel calls in loadAll/refresh
- 20 tests: initial state, summary/focus/heatmap/streak/trends/recos,
learningSummary/readingTrend/continueReading/recentRecords,
errorMessage on nil summary, refresh clears error
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:19:07 +08:00
wangdl
203e45df34
test: remove View helper tests from ViewModel test file
...
- statusLabel/formatSeconds belong to MaterialDetailView, not ViewModel
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:15:26 +08:00
wangdl
833bc70121
test: add load() tests with mock service DI (IOS-INFO-035)
...
- Add service protocols (KnowledgeBaseServicing, KnowledgeItemServicing,
QuizServicing, ReadingProgressServicing) for dependency injection
- ViewModel init accepts optional mock services, defaults to .shared
- Mock service classes for test isolation
- load() tests: itemCount, quizCount, aiStatus ready/processing,
isLoading, readingStatus/seconds, isMarkedRead, progress error,
nil materialId skips progress
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:14:49 +08:00
wangdl
61de3e1d57
test: add MaterialDetailViewModel unit tests (IOS-INFO-035)
...
- 20 tests covering initial state + helpers
- Initial state: isLoading, aiStatus, itemCount, quizCount, isMarkedRead,
readingSeconds, readingStatus, knowledgeBaseId, materialId
- init without materialId defaults to nil
- statusLabel: completed/in_progress/unknown/nil → Chinese labels
- formatSeconds: seconds(0/30/59), minutes(60/3599), hours(3600/3660/7200)
- Edge: nil materialId skips progress fetch
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:11:36 +08:00
wangdl
4348823ca1
test: add ReadingPositionAdapter.fromValue unit tests (IOS-INFO-034)
...
- 23 tests: fromValue (12) + clamp (2) + blockId (8)
- fromValue: Markdown/Text/Pdf/Image/Epub complete + defaults
- fromValue: nil blockId→nil for Markdown, nil chapterId→nil for Epub
- fromValue: unknown/nil type → .unknown
- clamp: > 1 → 1.0, < 0 → 0.0
- blockId: all 7 DocumentBlock variants + horizontalRule
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:09:05 +08:00
wangdl
86054edd5f
test: add resolveKnowledgeSource + full type inference tests
...
- Add resolveKnowledgeSource path test (knowledge_sources/<id>/)
- Add empty knowledge_sources directory test
- Add .txt→text and .epub→epub type inference
- Add .png/.jpg/.jpeg/.webp→image inference
- Remove misleading test that only asserted nil
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:07:30 +08:00
wangdl
2fa459d9ea
test: add MaterialPathResolver unit tests (IOS-INFO-033)
...
- 7 tests covering resolve and materialType inference
- resolve nil for nonexistent file
- resolve finds file in Documents directory
- resolve finds file in Caches directory
- type inference: .md→markdown, .pdf→pdf
- unknown apiType defaults to .unknown
- temp file creation + cleanup in test
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:04:37 +08:00
wangdl
335859df0e
test: remove redundant singleton test in MarkedReadStore tests
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:04:03 +08:00
wangdl
cdc5c10076
test: add MarkedReadStore unit tests (IOS-INFO-032)
...
- 10 tests covering MarkedReadStore full API
- contains: unmarked=false, after-mark=true, after-unmark=false
- mark: persists to UserDefaults, idempotent, multiple IDs
- unmark: removes from persisted array, nonexistent safe
- Persistence: survives re-init (UserDefaults-backed)
- Edge case: empty string as materialId
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 13:00:26 +08:00
wangdl
82bcbb9efb
feat: iOS 学习功能增强 - 阅读API、材料阅读器、分析、学习首页
...
- ReadingAPI: 阅读进度同步
- MaterialPathResolver: 材料路径解析
- MarkedReadStore: 已读标记存储
- MaterialReaderView/DetailView/ReadingPositionAdapter: 阅读器增强
- AnalysisHomeView/ActivityViewModel: 分析首页
- StudyHomeView/StudyHomeViewModel: 学习首页
- LibrarySubpages: 图书馆子页面
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 11:22:26 +08:00
wangdl
3abe17a84e
test: add queue UUID path coverage in LocalQueueTests
...
- Add test_markRetry_works_with_queue_item_id (uses queue UUID not eventId)
- Update test_markDead_after_max_retries to use queue item id from batch
- Fixes review finding: tests previously only used eventId, not queue UUID
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-15 21:58:04 +08:00
wangdl
12b73b7445
fix: extend APIError.statusCode to cover all cases
...
- unauthorized → 401
- serverError → extract code string as Int
- networkError → NSError.code
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-15 21:56:36 +08:00
wangdl
4ba747af46
feat: iOS learning info P0 complete (IOS-INFO-000~017, 038~039)
...
Models: ReadingMaterialContext, ReadingEventUploadItem, AppContext
Runtime: ReadingRuntimeAdapter, SessionManager, RecoveryService
Reader: MaterialReaderView lifecycle, Heartbeat Timer, Position Adapter
Export: EventMapper, UploadQueue, export→queue→ack flow
Tests: 16 test files covering models, runtime, lifecycle, upload
Docs: ios-learning-info-architecture.md
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-15 21:53:36 +08:00
wangdl
f421fbb721
fix: G1 context registry — prevent empty contexts from dropping all export events
...
- Add ReadingContextRegistry for SessionManager→Pipeline context sharing
- Wire registry into SessionManager (register on open, unregister on close)
- Fix Pipeline to auto-pull from registry when contexts not provided
- Fix ScenePhase to not pass empty contexts
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 22:08:03 +08:00
wangdl
51b9365ece
feat: M-IOS-INFO Batch D-F complete (38/38)
...
Batch D: MarkedAsRead UI, reading progress query, position restore, continue learning, source reading status
Batch E: NetworkMonitor, summary/trend/heatmap alignment, learning records, error handling, background upload, debug/logging
Batch F: Test stubs, iOS integration doc
Batch G: V2 FFI/MarkedAsRead/export-ack coverage verification
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 21:26:03 +08:00
wangdl
80c1d660cd
feat: #80 标记已读 UI + 乐观更新
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 20:49:41 +08:00
wangdl
697220de00
fix: APIConfig baseURL longde.cloud → api.longde.cloud
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 20:39:57 +08:00
wangdl
a6dde9f0c6
feat: M-IOS-INFO V2 reading event system + iOS 26 build fixes
...
- Add zx_documentFFI bridging header + modulemap
- Update zx_document.swift (patched for static linking + iOS 26 SDK)
- Replace XCFramework with V2 symbols
- Add V2 types: ReadingMaterialContext, ReadingEventUploadItem, ReadingRuntimeAdapter
- Add V2 session manager: ReadingRuntimeSessionManager
- Add V2 position adapter: ReadingPositionAdapter
- Add V2 event mapper: ReadingEventMapper
- Add upload queue + pipeline: ReadingEventUploadQueue
- Add reading API client: ReadingAPI
- Fix QuickNoteSheet for new NoteAnchor fields (positionSnapshot)
- Restore MaterialReaderView lifecycle events (onAppear/onDisappear)
- Add ScenePhase handling for app background/foreground
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-09 19:58:57 +08:00
wangdl
5fe29a7d8c
feat: #24 公开库发现 + 订阅管理
...
- KnowledgeBaseService 新增 discover/subscribe/unsubscribe API
- DiscoverView: 浏览公开库 + 订阅/取消订阅
- Route.discoverPublic + ProfileView 入口
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:36:34 +08:00
wangdl
9e1a8982a3
fix: 修复 LibrarySubpages 多余 } 导致的编译错误
2026-06-06 19:33:03 +08:00
wangdl
c428a57d0d
fix : #23 知识点详情增加来源信息 + 加入复习 + 收藏
...
- 内容区显示来源类型标签 (PDF/Word/Markdown等)
- 菜单新增「加入复习」(POST /reviews/generate-cards)
- 菜单新增「收藏/取消收藏」
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:28:04 +08:00
wangdl
1f75170b98
feat: #22 知识库分类管理页面
...
- KnowledgeFolder 模型 + CreateFolderRequest
- KnowledgeFolderService (list/create/update/delete)
- FolderManageView: 列表 + 新建/重命名/删除
- LibraryDetailPage 菜单「分类管理」入口
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:26:00 +08:00
wangdl
d9828bc3c8
fix : #34 #35 移除 contentHeightEstimate 80px 硬编码
...
- actualContentHeight 通过 GeometryReader 获取真实内容高度
- scrollProgress 使用实际高度计算,精度显著提升
- #36 ReadingEventCollector 已清理完毕(无 ObservableObject/Combine)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:22:08 +08:00
wangdl
5af29af549
fix : #21 设置页补全通知/存储/账号分组
...
- 通知: 复习提醒 + 导入完成 + 系统通知
- 数据与存储: 存储空间入口 + iCloud
- 账号: 个人资料 + 登录设备管理
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:19:31 +08:00
wangdl
695518b276
fix : #16 sortOption 接入后端排序 API
...
- KnowledgeItemService.list 加 sortBy/order 参数
- loadItems/refresh/loadMore 加 sortBy/order 参数
- sortOption onChange 触发重新加载
- sortParams 映射函数: 0→默认, 1→fileSize, 2→createdAt, 3→updatedAt
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 19:07:33 +08:00
wangdl
99dc2807be
feat: AIChat 全链路调试日志 + 错误详情展示
...
load/createSession/loadSession/send 都加了 print 日志:
- scope 参数
- 请求成功/失败状态
- 具体错误信息
sessionError 现在显示具体错误原因而非通用"创建对话失败"
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 18:19:30 +08:00
wangdl
9d0f426118
revert: 恢复 AddKnowledgePage 标签改动
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 18:15:51 +08:00
wangdl
4029da9c44
fix: DEBUG 调试标签放大 + 点击复制页面名
...
字号 9→13,padding 加大,背景加深,去掉 allowsHitTesting,点击复制 label
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 18:14:43 +08:00
wangdl
d8bdfe1dd4
fix: AddKnowledgePage 标签放大 + 文件名点击复制
...
- 标签字号 12→15 (内容来源/标题/内容)
- 文件列表项点击文件名复制到剪贴板
- 提示文字 12→13
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 18:10:00 +08:00
wangdl
1bbcf0acfb
fix: M-CHAT-A5 MaterialDetailView 传 knowledgeBaseId + title
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 18:03:27 +08:00
wangdl
0af5b6554d
fix: M-CHAT-A5/A9/A11 修复三个暂缓 issue
...
- A5: MaterialReaderView 传入 knowledgeBaseId (Route 新增参数)
- A9: 会话列表项显示 scope 图标 + 类型标签
- A11: 会话列表左滑归档 + 右滑置顶/取消置顶
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 18:02:26 +08:00
wangdl
491c3e7ef0
fix: M-CHAT audit 修复 7 个缺陷
...
- A1/A2(P0): listSessions 响应格式 + ChatEntryContext Hashable
- A3: forceCreate 支持,新对话按钮创建新会话
- A4: loadSession 更新 entryContext (scope 标签)
- A6: 死代码清理 (itemIds + AIMessageCitation)
- A8: sessions sheet scope 过滤
- A10: deleteSession 错误处理
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 17:58:45 +08:00
wangdl
2610bcf7f9
feat: M-CHAT iOS ChatScope 入口 + AI View 对接
...
## ChatEntryContext 模型
- ChatScopeType enum (knowledgeBase/folder/material/knowledgeItem/global)
- ChatEntryContext struct + ChatScopeSnapshot
- ChatSession 更新 (新增 13 个 scope 字段)
- CreateSessionRequest/UpdateChatSessionRequest
## Route + Service
- Route.aiChat 从 knowledgeBaseId 改为 ChatEntryContext
- RagChatService.createSession 接入 open-or-create API
- listSessions 支持 scope 过滤
- 新增 updateSession (PATCH)
## 6 个入口全部接入
- 知识库详情 → knowledge_base scope
- 资料详情 → material scope
- 资料阅读页 → material scope
- 知识点详情 → knowledge_item scope
- 全局入口 → global scope
## AI Chat View
- open-or-create: load() 直接调 POST /sessions
- 顶部 scope 指示器 (scopeLabel + scopeIcon)
- 新对话按钮在当前 scope 下工作
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 17:41:27 +08:00
wangdl
4ebb70c036
feat: 图标线型化 + 首页重设计 + 知识库卡片优化 + 知识点列表重构
...
- 所有 SF Symbol .fill 图标替换为线性版本
- 自定义加载动画全部替换为原生 ProgressView/refreshable
- StudyHomeView 重设计:优先级驱动主行动卡片
- ZLibraryCard 重新设计:封面图自适应、信息布局优化
- LibraryDetailPage:顶部KB信息区、···菜单、排序、长按操作
- 知识点列表:文件类型图标、学习时长、分割线样式
- 弥散渐变顶部背景
- 新增 icon-folder、icon-xmark SVG
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 20:07:15 +08:00
wangdl
52756d3bb0
feat(ios): 全局替换所有 systemName 为 Tabler SVG 图标
...
- 30+ 种 systemName 全部换为自定义 SVG
- 新增 list/clock/refresh/pencil 4 个 Tabler 图标
- 底部导航栏已使用自定义 SVG(无需改动)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:53:43 +08:00
wangdl
4889f6c832
feat(ios): 批量替换为 Tabler 图标(GitHub 直取)
...
- 所有已替换图标统一使用 Tabler outline 风格
- 描边 stroke-width=2, 24×24 viewBox
- 来源: raw.githubusercontent.com/tabler/tabler-icons/main/icons/outline/
- 新增: flame/calendar/sparkles/brain/books/warning/lightbulb/file/pin/mic/question/storage
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:50:30 +08:00
wangdl
39fb455f18
feat(ios): 设置图标替换为 Tabler 风格
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:45:04 +08:00
wangdl
70b9ee1250
fix(ios): 加号/垃圾桶图标尺寸放大 + 加号颜色统一
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 13:32:10 +08:00
wangdl
92f191c294
fix(ios): ContentView 缺少 import Combine
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 11:00:27 +08:00
wangdl
f6df01d9ca
feat(ios): TabBar 显示/隐藏增加入场出场动画
...
- TabBarState ObservableObject 管理可见性
- ContentView 用 .toolbar(hidden)+animation 驱动动画
- 子页面 hideTabBarWithAnimation() 替代静态 toolbar hidden
- 0.28s easeInOut 淡入淡出
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:57:39 +08:00
wangdl
7f252b48f0
fix(ios): TabBar 隐藏改回直接 .toolbar(.hidden, for: .tabBar)
...
- 移除 AnimatedTabBarHide 环境值动画系统
- 所有子页面统一使用 .toolbar(.hidden, for: .tabBar)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:52:32 +08:00
wangdl
5faff2f5ca
fix(ios): 临时移除问题图标,排查 asset import 错误
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:46:30 +08:00
wangdl
1de940657c
fix(ios): 方法图标 viewBox 恢复 100×100
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:43:32 +08:00
wangdl
8f5b0ce9f1
fix(ios): 学习方法行参数顺序修正
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 10:42:25 +08:00