Skip to content

Commit

Permalink
Add support for NIP-36 Sensitive Content / Content Warning (#196)
Browse files Browse the repository at this point in the history
  • Loading branch information
tyiu authored Nov 3, 2024
1 parent 88593b6 commit 43978e1
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ The following [NIPs](https://github.com/nostr-protocol/nips) are implemented:
- [x] [NIP-32: Labeling](https://github.com/nostr-protocol/nips/blob/master/32.md)
- [ ] [NIP-34: `git` stuff](https://github.com/nostr-protocol/nips/blob/master/34.md)
- [ ] [NIP-35: Torrents](https://github.com/nostr-protocol/nips/blob/master/35.md)
- [ ] [NIP-36: Sensitive Content](https://github.com/nostr-protocol/nips/blob/master/36.md)
- [x] [NIP-36: Sensitive Content](https://github.com/nostr-protocol/nips/blob/master/36.md)
- [ ] [NIP-38: User Statuses](https://github.com/nostr-protocol/nips/blob/master/38.md)
- [ ] [NIP-39: External Identities in Profiles](https://github.com/nostr-protocol/nips/blob/master/39.md)
- [x] [NIP-40: Expiration Timestamp](https://github.com/nostr-protocol/nips/blob/master/40.md)
Expand Down
4 changes: 2 additions & 2 deletions Sources/NostrSDK/Events/NostrEvent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import Foundation
/// A structure that describes a Nostr event.
///
/// > Note: [NIP-01 Specification](https://github.com/nostr-protocol/nips/blob/master/01.md#events-and-signatures)
public class NostrEvent: Codable, Equatable, Hashable, LabelTagInterpreting {
public class NostrEvent: Codable, Equatable, Hashable, ContentWarningTagInterpreting, LabelTagInterpreting {
public static func == (lhs: NostrEvent, rhs: NostrEvent) -> Bool {
lhs.id == rhs.id &&
lhs.pubkey == rhs.pubkey &&
Expand Down Expand Up @@ -318,7 +318,7 @@ public protocol NostrEventBuilding {

public extension NostrEvent {
/// Builder of a ``NostrEvent`` of type `T`.
class Builder<T: NostrEvent>: NostrEventBuilding, LabelBuilding {
class Builder<T: NostrEvent>: NostrEventBuilding, ContentWarningTagBuilding, LabelBuilding {
public typealias EventType = T

/// The event kind.
Expand Down
31 changes: 31 additions & 0 deletions Sources/NostrSDK/Events/Tags/ContentWarningTag.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// ContentWarningTag.swift
// NostrSDK
//
// Created by Terry Yiu on 11/3/24.
//

import Foundation

/// Interprets the content-warning tag.
///
/// See [NIP-36 Sensitive Content / Content Warning](https://github.com/nostr-protocol/nips/blob/master/36.md).
public protocol ContentWarningTagInterpreting: NostrEvent {}
public extension ContentWarningTagInterpreting {
/// Content warning to indicate that the event's content needs to be approved by readers to be shown. Clients can hide the content until the user acts on it.
var contentWarning: String? {
firstValueForRawTagName("content-warning")
}
}

/// Builder that adds a content warning to an event.
///
/// See [NIP-36 Sensitive Content / Content Warning](https://github.com/nostr-protocol/nips/blob/master/36.md).
public protocol ContentWarningTagBuilding: NostrEventBuilding {}
public extension ContentWarningTagBuilding {
/// Adds a content warning to indicate that the event's content needs to be approved by readers to be shown. Clients can hide the content until the user acts on it.
@discardableResult
func contentWarning(_ contentWarning: String) -> Self {
appendTags(Tag(name: "content-warning", value: contentWarning))
}
}
29 changes: 29 additions & 0 deletions Tests/NostrSDKTests/Events/Tags/ContentWarningTagTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// ContentWarningTagTests.swift
// NostrSDK
//
// Created by Terry Yiu on 11/3/24.
//

@testable import NostrSDK
import XCTest

final class ContentWarningTagTests: XCTestCase, EventVerifying {

func testCreateContentWarningTaggedEvent() throws {
let event = try NostrEvent.Builder(kind: .textNote)
.contentWarning("Trigger warning.")
.content("Pineapple goes great on pizza.")
.build(signedBy: .test)

XCTAssertEqual(event.contentWarning, "Trigger warning.")

XCTAssertEqual(event.tags.count, 1)
let tag = try XCTUnwrap(event.tags.first)
XCTAssertEqual(tag.name, "content-warning")
XCTAssertEqual(tag.value, "Trigger warning.")

try verifyEvent(event)
}

}

0 comments on commit 43978e1

Please sign in to comment.