wangdl
1c0a625192
feat: add "阅读原文件" button to KnowledgeDetailPage
...
Blue gradient button at bottom of plain text content view.
Writes content to temp .md file and navigates to MaterialReaderView,
which triggers reading event collection.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 21:19:05 +08:00
wangdl
def8c4c93a
fix: all iOS compile errors - protocols, missing fields, colors, shadowed max
...
- Protocol conformance: list→listAll with extension defaults
- ContinueLearningResponse has no lastPosition→use nil
- LearningSession has no readingTargetType/materialId→use defaults
- Color.zxBlue→Color.blue, Color.zxIndigo→Color.indigo
- Shadowed max parameter→Swift.max
- ForEach Identifiable→explicit id: \.id
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 17:14:34 +08:00
wangdl
d28dba29fc
fix: AuthManager has no currentUserId, use KeychainHelper.getUserId()
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 17:03:38 +08:00
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
968a78852c
chore: remove iOS CI/CD workflow per project decision
...
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 15:10:13 +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
8b27430ed1
docs: add iOS ops docs + CI config (IOS-INFO-028~031)
...
iOS CI/CD / Build & Test (push) Has been cancelled
- rust-ffi-update.md: FFI binding update workflow
- app-store-submission-checklist.md: 9-section App Store review
- ios-ci.yml: GitHub Actions build + test on macos-15
- firebase-crashlytics-integration.md: Crashlytics setup guide
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 14:25:15 +08:00
wangdl
08b4c21ca2
docs: add V2 event pipeline architecture doc (IOS-INFO-027)
...
- Architecture: iOS export → Rust EventBuffer → API batch upload
- Event types, sequence numbers, ACK mechanism
- Session state machine, error handling, performance comparison
- iOS UploadScheduler integration, app lifecycle handling
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 14:23:51 +08:00
wangdl
6c2f742676
docs: add iOS reading info integration guide (IOS-INFO-026)
...
- Architecture diagram: Swift UI → SessionManager → Collector → Queue → API
- Core components: Context, SessionManager, Events, Position, UploadQueue
- API protocol: batch upload, progress query, continue-learning, summary
- Path resolution, marked-read store, app lifecycle, error handling
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-18 14:23:12 +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