// // NoteEditorScreen.swift // Peered // // Created by Oskar Chybowski on 25/09/2025. // import MultipeerConnectivity import SwiftUI struct NoteEditorScreen: View { let note: Note @State private var noteAdvertiser: NoteEditingSessionServer @State private var noteContent: String = "" @State private var remoteNoteContent: String? = nil @State private var timer = Timer.publish(every: 5, on: .current, in: .common) .autoconnect() @State private var showManageMembers = false init(note: Note, peer: OwnPeer) { self.note = note self._noteAdvertiser = .init(initialValue: .init(peer: peer)) } var body: some View { NoteTextEditor(text: $noteContent, remoteText: remoteNoteContent) .toolbar { ToolbarItem(placement: .primaryAction) { Button("Manage members") { showManageMembers = true } } } .sheet(isPresented: $showManageMembers) { NavigationStack { ManageMembersScreen( noteAdvertiser: noteAdvertiser, noteTitle: note.name, noteContent: $noteContent ) } } .onReceive(noteAdvertiser.noteChangesEmitter) { message in guard message.senderID != noteAdvertiser.ownPeer.peer.displayName else { return } remoteNoteContent = message.content } .task(id: noteContent) { if noteContent == remoteNoteContent { return } let connectedPeers = noteAdvertiser.visiblePeers .filter { $0.state == .joined } .map(\.mcPeer) guard !connectedPeers.isEmpty else { return } try? await Task.sleep(nanoseconds: 500_000_000) guard !Task.isCancelled else { return } noteAdvertiser.send(note: noteContent, to: connectedPeers) } .onAppear { noteContent = (try? String(contentsOf: note.path, encoding: .utf8)) ?? "" noteAdvertiser.startServer() } .onDisappear { noteAdvertiser.stopServer() saveNote() } .onReceive(timer) { _ in saveNote() } } func saveNote() { try? noteContent.write(to: note.path, atomically: true, encoding: .utf8) } }