mirror of
https://github.com/metabolist/metatext.git
synced 2024-11-21 15:50:59 +00:00
Extraction from extension context
This commit is contained in:
parent
358aebf0f0
commit
d127eb51f2
6 changed files with 94 additions and 53 deletions
|
@ -27,13 +27,11 @@
|
|||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||
<integer>4</integer>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsText</key>
|
||||
<true/>
|
||||
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsWebPageWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
|
|
|
@ -11,13 +11,14 @@ class ShareExtensionNavigationViewController: UINavigationController {
|
|||
environment: .live(
|
||||
userNotificationCenter: .current(),
|
||||
reduceMotion: { UIAccessibility.isReduceMotionEnabled }))
|
||||
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
|
||||
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let newStatusViewModel: NewStatusViewModel
|
||||
|
||||
do {
|
||||
newStatusViewModel = try viewModel.newStatusViewModel()
|
||||
newStatusViewModel = try viewModel.newStatusViewModel(extensionContext: extensionContext)
|
||||
} catch {
|
||||
setViewControllers([ShareErrorViewController(error: error)], animated: false)
|
||||
|
||||
|
@ -28,9 +29,4 @@ class ShareExtensionNavigationViewController: UINavigationController {
|
|||
[UIHostingController(rootView: NewStatusView { newStatusViewModel })],
|
||||
animated: false)
|
||||
}
|
||||
|
||||
@available(*, unavailable)
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,19 +4,20 @@ import Combine
|
|||
import Foundation
|
||||
import Mastodon
|
||||
import ServiceLayer
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
public final class CompositionViewModel: AttachmentsRenderingViewModel, ObservableObject, Identifiable {
|
||||
public let id = Id()
|
||||
public var isPosted = false
|
||||
@Published public var text: String
|
||||
@Published public var contentWarning: String
|
||||
@Published public var displayContentWarning: Bool
|
||||
@Published public var sensitive: Bool
|
||||
@Published public var displayPoll: Bool
|
||||
@Published public var pollMultipleChoice: Bool
|
||||
@Published public var text = ""
|
||||
@Published public var contentWarning = ""
|
||||
@Published public var displayContentWarning = false
|
||||
@Published public var sensitive = false
|
||||
@Published public var displayPoll = false
|
||||
@Published public var pollMultipleChoice = false
|
||||
@Published public var pollExpiresIn = PollExpiry.oneDay
|
||||
@Published public private(set) var pollOptions: [PollOption]
|
||||
@Published public private(set) var attachmentViewModels: [AttachmentViewModel]
|
||||
@Published public private(set) var pollOptions = [PollOption(text: ""), PollOption(text: "")]
|
||||
@Published public private(set) var attachmentViewModels = [AttachmentViewModel]()
|
||||
@Published public private(set) var attachmentUpload: AttachmentUpload?
|
||||
@Published public private(set) var isPostable = false
|
||||
@Published public private(set) var canAddAttachment = true
|
||||
|
@ -27,24 +28,8 @@ public final class CompositionViewModel: AttachmentsRenderingViewModel, Observab
|
|||
private let eventsSubject: PassthroughSubject<Event, Never>
|
||||
private var attachmentUploadCancellable: AnyCancellable?
|
||||
|
||||
init(eventsSubject: PassthroughSubject<Event, Never>,
|
||||
redraft: (status: Status, identification: Identification)? = nil) {
|
||||
init(eventsSubject: PassthroughSubject<Event, Never>) {
|
||||
self.eventsSubject = eventsSubject
|
||||
text = redraft?.status.text ?? ""
|
||||
contentWarning = redraft?.status.spoilerText ?? ""
|
||||
displayContentWarning = !(redraft?.status.spoilerText.isEmpty ?? true)
|
||||
sensitive = redraft?.status.sensitive ?? false
|
||||
displayPoll = redraft?.status.poll != nil
|
||||
pollMultipleChoice = redraft?.status.poll?.multiple ?? false
|
||||
pollOptions = redraft?.status.poll?.options.map { PollOption(text: $0.title) }
|
||||
?? [PollOption(text: ""), PollOption(text: "")]
|
||||
if let redraft = redraft {
|
||||
attachmentViewModels = redraft.status.mediaAttachments.map {
|
||||
AttachmentViewModel(attachment: $0, identification: redraft.identification)
|
||||
}
|
||||
} else {
|
||||
attachmentViewModels = [AttachmentViewModel]()
|
||||
}
|
||||
|
||||
$text.map { !$0.isEmpty }
|
||||
.removeDuplicates()
|
||||
|
@ -111,6 +96,58 @@ public extension CompositionViewModel {
|
|||
|
||||
typealias Id = UUID
|
||||
|
||||
convenience init(eventsSubject: PassthroughSubject<Event, Never>, redraft: Status, identification: Identification) {
|
||||
self.init(eventsSubject: eventsSubject)
|
||||
|
||||
if let text = redraft.text {
|
||||
self.text = text
|
||||
}
|
||||
|
||||
contentWarning = redraft.spoilerText
|
||||
displayContentWarning = redraft.spoilerText.isEmpty
|
||||
sensitive = redraft.sensitive
|
||||
displayPoll = redraft.poll != nil
|
||||
attachmentViewModels = redraft.mediaAttachments.map {
|
||||
AttachmentViewModel(attachment: $0, identification: identification)
|
||||
}
|
||||
|
||||
if let poll = redraft.poll {
|
||||
pollMultipleChoice = poll.multiple
|
||||
pollOptions = poll.options.map { PollOption(text: $0.title) }
|
||||
}
|
||||
}
|
||||
|
||||
convenience init(eventsSubject: PassthroughSubject<Event, Never>,
|
||||
extensionContext: NSExtensionContext,
|
||||
parentViewModel: NewStatusViewModel) {
|
||||
self.init(eventsSubject: eventsSubject)
|
||||
|
||||
guard let inputItem = extensionContext.inputItems.first as? NSExtensionItem,
|
||||
let itemProvider = inputItem.attachments?.first
|
||||
else { return }
|
||||
|
||||
if itemProvider.hasItemConformingToTypeIdentifier(UTType.plainText.identifier) {
|
||||
itemProvider.loadItem(forTypeIdentifier: UTType.plainText.identifier, options: nil) { result, _ in
|
||||
guard let text = result as? String else { return }
|
||||
|
||||
self.text = text
|
||||
}
|
||||
} else if itemProvider.hasItemConformingToTypeIdentifier(UTType.url.identifier) {
|
||||
itemProvider.loadItem(forTypeIdentifier: UTType.url.identifier, options: nil) { result, _ in
|
||||
guard let url = result as? URL else { return }
|
||||
|
||||
if let contentText = inputItem.attributedContentText?.string {
|
||||
self.text.append(contentText)
|
||||
self.text.append("\n\n")
|
||||
}
|
||||
|
||||
self.text.append(url.absoluteString)
|
||||
}
|
||||
} else {
|
||||
attach(itemProvider: itemProvider, parentViewModel: parentViewModel)
|
||||
}
|
||||
}
|
||||
|
||||
func components(inReplyToId: Status.Id?, visibility: Status.Visibility) -> StatusComponents {
|
||||
StatusComponents(
|
||||
inReplyToId: inReplyToId,
|
||||
|
|
|
@ -7,7 +7,7 @@ import ServiceLayer
|
|||
|
||||
public final class NewStatusViewModel: ObservableObject {
|
||||
@Published public var visibility: Status.Visibility
|
||||
@Published public private(set) var compositionViewModels: [CompositionViewModel]
|
||||
@Published public private(set) var compositionViewModels = [CompositionViewModel]()
|
||||
@Published public private(set) var identification: Identification
|
||||
@Published public private(set) var authenticatedIdentities = [Identity]()
|
||||
@Published public var canPost = false
|
||||
|
@ -27,25 +27,33 @@ public final class NewStatusViewModel: ObservableObject {
|
|||
identification: Identification,
|
||||
environment: AppEnvironment,
|
||||
inReplyTo: StatusViewModel?,
|
||||
redraft: Status?) {
|
||||
redraft: Status?,
|
||||
extensionContext: NSExtensionContext?) {
|
||||
self.allIdentitiesService = allIdentitiesService
|
||||
self.identification = identification
|
||||
self.environment = environment
|
||||
inReplyToViewModel = inReplyTo
|
||||
|
||||
let redraftAndIdentification: (status: Status, identification: Identification)?
|
||||
|
||||
if let redraft = redraft {
|
||||
redraftAndIdentification = (status: redraft, identification: identification)
|
||||
} else {
|
||||
redraftAndIdentification = nil
|
||||
}
|
||||
|
||||
compositionViewModels = [CompositionViewModel(
|
||||
eventsSubject: compositionEventsSubject,
|
||||
redraft: redraftAndIdentification)]
|
||||
events = eventsSubject.eraseToAnyPublisher()
|
||||
visibility = identification.identity.preferences.postingDefaultVisibility
|
||||
|
||||
let compositionViewModel: CompositionViewModel
|
||||
|
||||
if let redraft = redraft {
|
||||
compositionViewModel = CompositionViewModel(
|
||||
eventsSubject: compositionEventsSubject,
|
||||
redraft: redraft,
|
||||
identification: identification)
|
||||
} else if let extensionContext = extensionContext {
|
||||
compositionViewModel = CompositionViewModel(
|
||||
eventsSubject: compositionEventsSubject,
|
||||
extensionContext: extensionContext,
|
||||
parentViewModel: self)
|
||||
} else {
|
||||
compositionViewModel = CompositionViewModel(eventsSubject: compositionEventsSubject)
|
||||
}
|
||||
|
||||
compositionViewModels = [compositionViewModel]
|
||||
|
||||
allIdentitiesService.authenticatedIdentitiesPublisher()
|
||||
.assignErrorsToAlertItem(to: \.alertItem, on: self)
|
||||
.assign(to: &$authenticatedIdentities)
|
||||
|
|
|
@ -68,7 +68,8 @@ public extension RootViewModel {
|
|||
identification: identification,
|
||||
environment: environment,
|
||||
inReplyTo: inReplyTo,
|
||||
redraft: redraft)
|
||||
redraft: redraft,
|
||||
extensionContext: nil)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ public final class ShareExtensionNavigationViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
public extension ShareExtensionNavigationViewModel {
|
||||
func newStatusViewModel() throws -> NewStatusViewModel {
|
||||
func newStatusViewModel(extensionContext: NSExtensionContext?) throws -> NewStatusViewModel {
|
||||
let allIdentitiesService = try AllIdentitiesService(environment: environment)
|
||||
|
||||
guard let identity = try allIdentitiesService.mostRecentAuthenticatedIdentity()
|
||||
|
@ -38,6 +38,7 @@ public extension ShareExtensionNavigationViewModel {
|
|||
identification: identification,
|
||||
environment: environment,
|
||||
inReplyTo: nil,
|
||||
redraft: nil)
|
||||
redraft: nil,
|
||||
extensionContext: extensionContext)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue