diff --git a/AIStudyApp/AIStudyApp.xcodeproj/project.xcworkspace/xcuserdata/Admin1.xcuserdatad/UserInterfaceState.xcuserstate b/AIStudyApp/AIStudyApp.xcodeproj/project.xcworkspace/xcuserdata/Admin1.xcuserdatad/UserInterfaceState.xcuserstate index dbf0672..d9f3afe 100644 Binary files a/AIStudyApp/AIStudyApp.xcodeproj/project.xcworkspace/xcuserdata/Admin1.xcuserdatad/UserInterfaceState.xcuserstate and b/AIStudyApp/AIStudyApp.xcodeproj/project.xcworkspace/xcuserdata/Admin1.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/AIStudyApp/AIStudyApp/Features/MaterialReader/MaterialReaderView.swift b/AIStudyApp/AIStudyApp/Features/MaterialReader/MaterialReaderView.swift index 8dfe539..58f0910 100644 --- a/AIStudyApp/AIStudyApp/Features/MaterialReader/MaterialReaderView.swift +++ b/AIStudyApp/AIStudyApp/Features/MaterialReader/MaterialReaderView.swift @@ -101,6 +101,7 @@ struct MaterialReaderView: View { @State private var hasRestoredPosition = false @State private var restoreBlockId: String? @State private var actualContentHeight: CGFloat = 1 + @State private var isMarkedRead = false private let title: String private let knowledgeBaseId: String? @@ -157,16 +158,26 @@ struct MaterialReaderView: View { .toolbarBackground(.hidden, for: .navigationBar) .toolbar { ToolbarItem(placement: .topBarTrailing) { - NavigationLink(value: Route.aiChat(context: ChatEntryContext( - scopeType: .material, - scopeId: vm.materialId, - scopeName: title, - parentKnowledgeBaseId: knowledgeBaseId, - createdFrom: "material_reader" - ))) { - Image(systemName: "bubble.left.and.bubble.right") - .font(.system(size: 16)) - .foregroundColor(Color.zxF05) + HStack(spacing: 16) { + Button { + markAsRead() + } label: { + Image(systemName: isMarkedRead ? "checkmark.circle.fill" : "checkmark.circle") + .font(.system(size: 16)) + .foregroundColor(isMarkedRead ? Color.green : Color.zxF05) + } + + NavigationLink(value: Route.aiChat(context: ChatEntryContext( + scopeType: .material, + scopeId: vm.materialId, + scopeName: title, + parentKnowledgeBaseId: knowledgeBaseId, + createdFrom: "material_reader" + ))) { + Image(systemName: "bubble.left.and.bubble.right") + .font(.system(size: 16)) + .foregroundColor(Color.zxF05) + } } } } @@ -293,6 +304,15 @@ struct MaterialReaderView: View { print("[READER] V1 session closed") } + /// Mark the current material as read — optimistic update + event push. + private func markAsRead() { + guard !isMarkedRead else { return } + isMarkedRead = true + sessionManager.markAsRead() + // V1 fallback + collector.markAsRead(materialId: vm.materialId) + } + /// Build a NoteAnchor from the current scroll position (for quick note). private func buildAnchor() -> NoteAnchor? { let pos = sessionManager.lastPosition ?? collector.lastPosition