diff --git a/damus/Features/Events/EventView.swift b/damus/Features/Events/EventView.swift index 5aa6352ba..98fadb7a1 100644 --- a/damus/Features/Events/EventView.swift +++ b/damus/Features/Events/EventView.swift @@ -29,6 +29,10 @@ struct EventView: View { self.pubkey = pubkey ?? event.pubkey } + var pollsFeatureEnabled: Bool { + damus.settings.enable_nip88_polls + } + var body: some View { VStack { if event.known_kind == .boost { @@ -47,7 +51,7 @@ struct EventView: View { LongformPreview(state: damus, ev: event, options: options) } else if event.known_kind == .highlight { HighlightView(state: damus, event: event, options: options) - } else if event.known_kind == .poll, let poll = PollEvent(event: event) { + } else if pollsFeatureEnabled, event.known_kind == .poll, let poll = PollEvent(event: event) { damus.polls.registerPollEvent(event) PollEventView(damus: damus, event: event, poll: poll, options: options) } else { diff --git a/damus/Features/Posting/Views/PostView.swift b/damus/Features/Posting/Views/PostView.swift index 6a6047a84..29d89c5f1 100644 --- a/damus/Features/Posting/Views/PostView.swift +++ b/damus/Features/Posting/Views/PostView.swift @@ -122,7 +122,12 @@ struct PostView: View { uploadTasks.removeAll() } + var pollsFeatureEnabled: Bool { + damus_state.settings.enable_nip88_polls + } + var pollComposerAvailable: Bool { + guard pollsFeatureEnabled else { return false } if case .posting = action { return true } @@ -151,7 +156,7 @@ struct PostView: View { } var pollIsValid: Bool { - guard pollComposerAvailable, pollDraft != nil else { return false } + guard pollsFeatureEnabled, pollComposerAvailable, pollDraft != nil else { return false } if pollQuestionText.isEmpty { return false } if pollOptionLabels.count < PollDraft.minimumOptions { return false } if pollHasDuplicateOptions { return false } @@ -178,7 +183,15 @@ struct PostView: View { } func send_post() { - let new_post = build_post(state: self.damus_state, post: self.post, action: action, uploadedMedias: uploadedMedias, references: self.references, filtered_pubkeys: filtered_pubkeys, pollDraft: pollDraft) + let new_post = build_post( + state: self.damus_state, + post: self.post, + action: action, + uploadedMedias: uploadedMedias, + references: self.references, + filtered_pubkeys: filtered_pubkeys, + pollDraft: pollsFeatureEnabled ? pollDraft : nil + ) notify(.post(.post(new_post))) @@ -197,7 +210,7 @@ struct PostView: View { } var posting_disabled: Bool { - if pollDraft != nil { + if pollsFeatureEnabled, pollDraft != nil { return uploading_disabled || !pollIsValid } switch action { @@ -320,8 +333,12 @@ struct PostView: View { self.uploadedMedias = draft.media self.post = draft.content - self.pollDraft = draft.pollDraft - self.pollDraft?.ensureMinimumOptions() + if pollsFeatureEnabled { + self.pollDraft = draft.pollDraft + self.pollDraft?.ensureMinimumOptions() + } else { + self.pollDraft = nil + } self.autoSaveModel.markSaved() // The draft we just loaded is saved to memory. Mark it as such. return true } @@ -336,9 +353,17 @@ struct PostView: View { draft.media = uploadedMedias draft.references = references draft.filtered_pubkeys = filtered_pubkeys - draft.pollDraft = pollDraft + if pollsFeatureEnabled { + draft.pollDraft = pollDraft + } } else { - let artifacts = DraftArtifacts(content: post, media: uploadedMedias, references: references, id: UUID().uuidString, pollDraft: pollDraft) + let artifacts = DraftArtifacts( + content: post, + media: uploadedMedias, + references: references, + id: UUID().uuidString, + pollDraft: pollsFeatureEnabled ? pollDraft : nil + ) set_draft_for_post(drafts: damus_state.drafts, action: action, artifacts: artifacts) } self.autoSaveModel.needsSaving() @@ -542,7 +567,7 @@ struct PostView: View { } // This if-block observes @ for tagging - if pollDraft == nil, let searching { + if (pollDraft == nil || !pollsFeatureEnabled), let searching { UserSearch(damus_state: damus_state, search: searching, focusWordAttributes: $focusWordAttributes, newCursorIndex: $newCursorIndex, post: $post) .frame(maxHeight: .infinity) .environmentObject(tagModel) @@ -559,7 +584,7 @@ struct PostView: View { } else { Divider() VStack(alignment: .leading) { - if pollDraft != nil { + if pollsFeatureEnabled, pollDraft != nil { PollComposerView( draft: Binding( get: { self.pollDraft ?? PollDraft.makeDefault() }, @@ -579,6 +604,7 @@ struct PostView: View { } .background(DamusColors.adaptableWhite.edgesIgnoringSafeArea(.all)) .onChange(of: pollDraft) { _ in + guard pollsFeatureEnabled else { return } post_changed(post: post, media: uploadedMedias) } .sheet(isPresented: $attach_media) { @@ -953,7 +979,15 @@ func build_post(state: DamusState, post: NSAttributedString, action: PostAction, acc.append(pk) } - return build_post(state: state, post: post, action: action, uploadedMedias: uploadedMedias, pubkeys: pks, pollDraft: pollDraft) + let effectivePollDraft = state.settings.enable_nip88_polls ? pollDraft : nil + return build_post( + state: state, + post: post, + action: action, + uploadedMedias: uploadedMedias, + pubkeys: pks, + pollDraft: effectivePollDraft + ) } /// This builds a Nostr post from draft data from `PostView` or other draft-related classes @@ -970,7 +1004,8 @@ func build_post(state: DamusState, post: NSAttributedString, action: PostAction, /// - pubkeys: The referenced pubkeys /// - Returns: A NostrPost, which can then be signed into an event. func build_post(state: DamusState, post: NSAttributedString, action: PostAction, uploadedMedias: [UploadedMedia], pubkeys: [Pubkey], pollDraft: PollDraft? = nil) -> NostrPost { - if let pollDraft, case .posting = action, let pollPost = build_poll_post(state: state, post: post, pollDraft: pollDraft) { + let pollsFeatureEnabled = state.settings.enable_nip88_polls + if pollsFeatureEnabled, let pollDraft, case .posting = action, let pollPost = build_poll_post(state: state, post: post, pollDraft: pollDraft) { return pollPost } diff --git a/damus/Features/Settings/Models/UserSettingsStore.swift b/damus/Features/Settings/Models/UserSettingsStore.swift index 0da7377cb..6fd2dec36 100644 --- a/damus/Features/Settings/Models/UserSettingsStore.swift +++ b/damus/Features/Settings/Models/UserSettingsStore.swift @@ -198,6 +198,9 @@ class UserSettingsStore: ObservableObject { @Setting(key: "truncate_mention_text", default_value: true) var truncate_mention_text: Bool + + @Setting(key: "enable_nip88_polls", default_value: false) + var enable_nip88_polls: Bool @Setting(key: "notification_indicators", default_value: NewEventsBits.all.rawValue) var notification_indicators: Int diff --git a/damus/Features/Timeline/Models/HomeModel.swift b/damus/Features/Timeline/Models/HomeModel.swift index 97dd7c48d..24e43bb54 100644 --- a/damus/Features/Timeline/Models/HomeModel.swift +++ b/damus/Features/Timeline/Models/HomeModel.swift @@ -101,6 +101,10 @@ class HomeModel: ContactsDelegate { var dms: DirectMessagesModel { return damus_state.dms } + + var pollsFeatureEnabled: Bool { + damus_state.settings.enable_nip88_polls + } func has_sub_id_event(sub_id: String, ev_id: NoteId) -> Bool { if !has_event.keys.contains(sub_id) { @@ -193,9 +197,15 @@ class HomeModel: ContactsDelegate { case .chat, .longform, .text, .highlight: handle_text_event(sub_id: sub_id, ev) case .poll: - handle_poll_event(sub_id: sub_id, ev) + if pollsFeatureEnabled { + handle_poll_event(sub_id: sub_id, ev) + } else { + handle_text_event(sub_id: sub_id, ev) + } case .poll_response: - handle_poll_response(ev) + if pollsFeatureEnabled { + handle_poll_response(ev) + } case .contacts: handle_contact_event(sub_id: sub_id, relay_id: relay_id, ev: ev) case .metadata: