Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions ios/Keep/Services/KeepAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,16 @@ actor KeepAPI {
_ = try await request("/api/notes/\(id)", method: "DELETE", as: OkResponse.self)
}

/// Mints a public share token (or returns the existing one — the server
/// COALESCEs) for the note.
func share(id: String) async throws -> Note {
try await request("/api/notes/\(id)/share", method: "POST", as: NoteResponse.self).note
}

func unshare(id: String) async throws -> Note {
try await request("/api/notes/\(id)/share", method: "DELETE", as: NoteResponse.self).note
}

// MARK: - Plumbing

private func request<T: Decodable>(
Expand Down
20 changes: 20 additions & 0 deletions ios/Keep/Services/NotesStore.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,26 @@ final class NotesStore {
await update(note.id, patch: ["color": key ?? NSNull()])
}

/// Ensures the note has a public share link; returns the updated note.
@discardableResult
func share(_ note: Note) async -> Note? {
do {
let updated = try await api.share(id: note.id)
if let i = notes.firstIndex(where: { $0.id == note.id }) { notes[i] = updated }
return updated
} catch {
handle(error)
return nil
}
}

func unshare(_ note: Note) async {
do {
let updated = try await api.unshare(id: note.id)
if let i = notes.firstIndex(where: { $0.id == note.id }) { notes[i] = updated }
} catch { handle(error) }
}

// MARK: - Auth

/// Signs in, then reloads. Returns an error message to show, or nil on success.
Expand Down
12 changes: 12 additions & 0 deletions ios/KeepMac/KeepMacApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,18 @@ struct NoteCommands: Commands {

Divider()

Button("Copy Share Link") {
if let note { Task { await store.copyShareLink(note) } }
}
.disabled(note == nil || note?.trashed == true)

Button("Stop Sharing") {
if let note { Task { await store.unshare(note) } }
}
.disabled(note?.shareToken == nil)

Divider()

Button("Move to Trash") {
if let note { Task { await store.trash(note) } }
}
Expand Down
10 changes: 10 additions & 0 deletions ios/KeepMac/MacRootView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,11 @@ struct MacRootView: View {
}
}
Divider()
Button("Copy Share Link") { Task { await store.copyShareLink(note) } }
if note.shareToken != nil {
Button("Stop Sharing") { Task { await store.unshare(note) } }
}
Divider()
Button("Move to Trash", role: .destructive) { Task { await store.trash(note) } }
}
}
Expand Down Expand Up @@ -233,6 +238,11 @@ private struct MacNoteRow: View {
}
}
Spacer()
if note.shareToken != nil {
Image(systemName: "link")
.font(.caption2)
.foregroundStyle(.secondary)
}
if note.pinned {
Image(systemName: "pin.fill")
.font(.caption2)
Expand Down
13 changes: 13 additions & 0 deletions ios/KeepMac/ShareLink.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import AppKit

/// Mac-side share helper: makes sure the public link exists, then puts it on
/// the pasteboard. Lives in the Mac target because of NSPasteboard.
extension NotesStore {
func copyShareLink(_ note: Note) async {
guard let token = (await share(note))?.shareToken else { return }
let url = Config.baseURL.appendingPathComponent("p/\(token)")
let pasteboard = NSPasteboard.general
pasteboard.clearContents()
pasteboard.setString(url.absoluteString, forType: .string)
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading