Allow authoring local-only posts on Akkoma

Closes #332
This commit is contained in:
Shadowfacts 2023-09-25 21:23:28 -04:00
parent 6821f1b9a0
commit bf1ed57180
5 changed files with 33 additions and 7 deletions

View File

@ -72,12 +72,12 @@ class PostService: ObservableObject {
mediaIDs: uploadedAttachments,
sensitive: sensitive,
spoilerText: contentWarning,
visibility: draft.visibility,
visibility: draft.localOnly && mastodonController.instanceFeatures.localOnlyPostsVisibility ? Status.localPostVisibility : draft.visibility.rawValue,
language: mastodonController.instanceFeatures.createStatusWithLanguage ? draft.language : nil,
pollOptions: draft.poll?.pollOptions.map(\.text),
pollExpiresIn: draft.poll == nil ? nil : Int(draft.poll!.duration),
pollMultiple: draft.poll?.multiple,
localOnly: mastodonController.instanceFeatures.localOnlyPosts ? draft.localOnly : nil,
localOnly: mastodonController.instanceFeatures.localOnlyPosts && !mastodonController.instanceFeatures.localOnlyPostsVisibility ? draft.localOnly : nil,
idempotencyKey: draft.id.uuidString
)
}

View File

@ -53,10 +53,11 @@ class ToolbarController: ViewController {
HStack(spacing: 0) {
cwButton
MenuPicker(selection: $draft.visibility, options: visibilityOptions, buttonStyle: .iconOnly)
MenuPicker(selection: visibilityBinding, options: visibilityOptions, buttonStyle: .iconOnly)
// the button has a bunch of extra space by default, but combined with what we add it's too much
.padding(.horizontal, -8)
.disabled(draft.editedStatusID != nil)
.disabled(composeController.mastodonController.instanceFeatures.localOnlyPostsVisibility && draft.localOnly)
if composeController.mastodonController.instanceFeatures.localOnlyPosts {
localOnlyPicker
@ -118,9 +119,20 @@ class ToolbarController: ViewController {
.hoverEffect()
}
private var visibilityBinding: Binding<Pachyderm.Visibility> {
// On instances that conflate visibliity and local only, we still show two separate controls but don't allow
// changing the visibility when local-only.
if draft.localOnly,
composeController.mastodonController.instanceFeatures.localOnlyPostsVisibility {
return .constant(.public)
} else {
return $draft.visibility
}
}
private var visibilityOptions: [MenuPicker<Pachyderm.Visibility>.Option] {
let visibilities: [Pachyderm.Visibility]
if !controller.parent.mastodonController.instanceFeatures.composeDirectStatuses {
if !composeController.mastodonController.instanceFeatures.composeDirectStatuses {
visibilities = [.public, .unlisted, .private]
} else {
visibilities = Pachyderm.Visibility.allCases

View File

@ -27,11 +27,22 @@ public class InstanceFeatures: ObservableObject {
switch instanceType {
case .mastodon(.hometown(_), _), .mastodon(.glitch, _):
return true
case .pleroma(.akkoma(_)):
return true
default:
return false
}
}
/// Instance types that use a separate visibility to indicate local-only posts.
public var localOnlyPostsVisibility: Bool {
if case .pleroma(.akkoma(_)) = instanceType {
return true
} else {
return false
}
}
public var mastodonAttachmentRestrictions: Bool {
instanceType.isMastodon
}

View File

@ -396,7 +396,7 @@ public class Client {
mediaIDs: [String]? = nil,
sensitive: Bool? = nil,
spoilerText: String? = nil,
visibility: Visibility? = nil,
visibility: String? = nil,
language: String? = nil, // language supported by mastodon and akkoma
pollOptions: [String]? = nil,
pollExpiresIn: Int? = nil,
@ -409,7 +409,7 @@ public class Client {
"in_reply_to_id" => inReplyTo,
"sensitive" => sensitive,
"spoiler_text" => spoilerText,
"visibility" => visibility?.rawValue,
"visibility" => visibility,
"language" => language,
"poll[expires_in]" => pollExpiresIn,
"poll[multiple]" => pollMultiple,

View File

@ -10,6 +10,9 @@ import Foundation
import WebURL
public final class Status: StatusProtocol, Decodable, Sendable {
/// The pseudo-visibility used by instance types (Akkoma) that overload the visibility for local-only posts.
public static let localPostVisibility: String = "local"
public let id: String
public let uri: String
public let url: WebURL?
@ -77,7 +80,7 @@ public final class Status: StatusProtocol, Decodable, Sendable {
self.visibility = visibility
self.localOnly = try container.decodeIfPresent(Bool.self, forKey: .localOnly)
} else if let s = try? container.decode(String.self, forKey: .visibility),
s == "local" {
s == Status.localPostVisibility {
// hacky workaround for #332, akkoma describes local posts with a separate visibility
self.visibility = .public
self.localOnly = true