From 079e611f330d092d2c8ef0de74d4c4d1325334a4 Mon Sep 17 00:00:00 2001 From: CMK Date: Fri, 16 Jul 2021 21:21:18 +0800 Subject: [PATCH] feat: add compose view --- Mastodon.xcodeproj/project.pbxproj | 42 +++++++++- .../xcschemes/xcschememanagement.plist | 14 ++-- .../xcshareddata/swiftpm/Package.resolved | 8 +- ...meTimelineViewController+DebugAction.swift | 19 ++++- MastodonSDK/Package.swift | 10 ++- .../Sources/MastodonUI/AnimatedImage.swift | 56 +++++++++++++ .../MastodonUI/Compose/ComposeView.swift | 68 ++++++++++++++++ .../MastodonUI/Compose/ComposeViewModel.swift | 46 +++++++++++ .../MastodonUI/Compose/StatusAuthorView.swift | 44 ++++++++++ .../MastodonUI/Compose/TextEditorView.swift | 80 +++++++++++++++++++ ShareActionExtension/Info.plist | 26 +++--- .../ShareViewController.swift | 27 ++++--- ShareActionExtension/ShareViewModel.swift | 2 + 13 files changed, 399 insertions(+), 43 deletions(-) create mode 100644 MastodonSDK/Sources/MastodonUI/AnimatedImage.swift create mode 100644 MastodonSDK/Sources/MastodonUI/Compose/ComposeView.swift create mode 100644 MastodonSDK/Sources/MastodonUI/Compose/ComposeViewModel.swift create mode 100644 MastodonSDK/Sources/MastodonUI/Compose/StatusAuthorView.swift create mode 100644 MastodonSDK/Sources/MastodonUI/Compose/TextEditorView.swift diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj index 423886e1..ae5393fe 100644 --- a/Mastodon.xcodeproj/project.pbxproj +++ b/Mastodon.xcodeproj/project.pbxproj @@ -491,6 +491,8 @@ DBC6462926A1736700B0E31B /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338525C945ED00AD9700 /* Strings.swift */; }; DBC6462B26A1738900B0E31B /* MastodonUI in Frameworks */ = {isa = PBXBuildFile; productRef = DBC6462A26A1738900B0E31B /* MastodonUI */; }; DBC6462C26A176B000B0E31B /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338625C945ED00AD9700 /* Assets.swift */; }; + DBC6463326A195DB00B0E31B /* AppShared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB68047F2637CD4C00430867 /* AppShared.framework */; }; + DBC6463726A195DB00B0E31B /* CoreDataStack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB89B9EE25C10FD0008580ED /* CoreDataStack.framework */; }; DBC7A672260C897100E57475 /* StatusContentWarningEditorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */; }; DBC7A67C260DFADE00E57475 /* StatusPublishService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC7A67B260DFADE00E57475 /* StatusPublishService.swift */; }; DBCBCBF4267CB070000F5B51 /* Decode85.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBCBCBF3267CB070000F5B51 /* Decode85.swift */; }; @@ -615,6 +617,20 @@ remoteGlobalIDString = DBC6461126A170AB00B0E31B; remoteInfo = ShareActionExtension; }; + DBC6463526A195DB00B0E31B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DB427DCA25BAA00100D1B89D /* Project object */; + proxyType = 1; + remoteGlobalIDString = DB68047E2637CD4C00430867; + remoteInfo = AppShared; + }; + DBC6463926A195DB00B0E31B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DB427DCA25BAA00100D1B89D /* Project object */; + proxyType = 1; + remoteGlobalIDString = DB89B9ED25C10FD0008580ED; + remoteInfo = CoreDataStack; + }; DBF8AE18263293E400C9C23C /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = DB427DCA25BAA00100D1B89D /* Project object */; @@ -1281,6 +1297,8 @@ buildActionMask = 2147483647; files = ( DBC6462526A1720B00B0E31B /* MastodonUI in Frameworks */, + DBC6463726A195DB00B0E31B /* CoreDataStack.framework in Frameworks */, + DBC6463326A195DB00B0E31B /* AppShared.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3012,6 +3030,8 @@ buildRules = ( ); dependencies = ( + DBC6463626A195DB00B0E31B /* PBXTargetDependency */, + DBC6463A26A195DB00B0E31B /* PBXTargetDependency */, ); name = ShareActionExtension; packageProductDependencies = ( @@ -3955,6 +3975,16 @@ target = DBC6461126A170AB00B0E31B /* ShareActionExtension */; targetProxy = DBC6461A26A170AB00B0E31B /* PBXContainerItemProxy */; }; + DBC6463626A195DB00B0E31B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DB68047E2637CD4C00430867 /* AppShared */; + targetProxy = DBC6463526A195DB00B0E31B /* PBXContainerItemProxy */; + }; + DBC6463A26A195DB00B0E31B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = DB89B9ED25C10FD0008580ED /* CoreDataStack */; + targetProxy = DBC6463926A195DB00B0E31B /* PBXContainerItemProxy */; + }; DBF8AE19263293E400C9C23C /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = DBF8AE12263293E400C9C23C /* NotificationService */; @@ -4434,14 +4464,15 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 40; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); + MARKETING_VERSION = 0.9.0; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -4454,14 +4485,15 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 40; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); + MARKETING_VERSION = 0.9.0; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -4474,14 +4506,15 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 40; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); + MARKETING_VERSION = 0.9.0; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; @@ -4494,14 +4527,15 @@ isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 40; DEVELOPMENT_TEAM = 5Z4GVSS33P; INFOPLIST_FILE = ShareActionExtension/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 14.5; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); + MARKETING_VERSION = 0.9.0; PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist index 4c04247e..e417a0d4 100644 --- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -12,37 +12,37 @@ CoreDataStack.xcscheme_^#shared#^_ orderHint - 21 + 20 Mastodon - ASDK.xcscheme_^#shared#^_ orderHint - 2 + 5 Mastodon - RTL.xcscheme_^#shared#^_ orderHint - 3 + 7 Mastodon - Release.xcscheme_^#shared#^_ orderHint - 1 + 3 Mastodon.xcscheme_^#shared#^_ orderHint - 0 + 1 NotificationService.xcscheme_^#shared#^_ orderHint - 22 + 21 ShareActionExtension.xcscheme_^#shared#^_ orderHint - 30 + 22 SuppressBuildableAutocreation diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved index edf6e564..78b4a755 100644 --- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -105,8 +105,8 @@ "repositoryURL": "https://github.com/onevcat/Kingfisher.git", "state": { "branch": null, - "revision": "15d199e84677303a7004ed2c5ecaa1a90f3863f8", - "version": "6.2.1" + "revision": "44450a8f564d7c0165f736ba2250649ff8d3e556", + "version": "6.3.0" } }, { @@ -123,8 +123,8 @@ "repositoryURL": "https://github.com/kean/Nuke.git", "state": { "branch": null, - "revision": "69ae6d5b8c4b898450432f94bd35f863d3830cfc", - "version": "10.3.0" + "revision": "83e1edaa5a30c567eb129c21c6d00f2f552d2c6f", + "version": "10.3.1" } }, { diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift index 7c1f79db..0b439753 100644 --- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift +++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewController+DebugAction.swift @@ -5,13 +5,15 @@ // Created by MainasuK Cirno on 2021-2-5. // + +#if DEBUG import os.log import UIKit import CoreData import CoreDataStack - -#if DEBUG import FLEX +import SwiftUI +import MastodonUI extension HomeTimelineViewController { var debugMenu: UIMenu { @@ -55,6 +57,10 @@ extension HomeTimelineViewController { guard let self = self else { return } self.showThreadAction(action) }, + UIAction(title: "Show Share Action Compose", image: UIImage(systemName: "square.and.arrow.up"), attributes: []) { [weak self] action in + guard let self = self else { return } + self.showShareActionExtensionComposeView(action) + }, UIAction(title: "Settings", image: UIImage(systemName: "gear"), attributes: []) { [weak self] action in guard let self = self else { return } self.showSettings(action) @@ -363,5 +369,14 @@ extension HomeTimelineViewController { transition: .modal(animated: true, completion: nil) ) } + + @objc private func showShareActionExtensionComposeView(_ sender: UIAction) { + let viewController = UIHostingController( + rootView: ComposeView().environmentObject(MastodonUI.ComposeViewModel()) + ) + let navigationController = UINavigationController(rootViewController: viewController) + present(navigationController, animated: true, completion: nil) + } + } #endif diff --git a/MastodonSDK/Package.swift b/MastodonSDK/Package.swift index 23b5015f..4b3ba9d4 100644 --- a/MastodonSDK/Package.swift +++ b/MastodonSDK/Package.swift @@ -6,7 +6,7 @@ import PackageDescription let package = Package( name: "MastodonSDK", platforms: [ - .iOS(.v13), + .iOS(.v14), ], products: [ .library( @@ -22,6 +22,8 @@ let package = Package( dependencies: [ .package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "5.0.0"), .package(url: "https://github.com/apple/swift-nio.git", from: "1.0.0"), + .package(url: "https://github.com/kean/Nuke.git", from: "10.3.1"), + .package(name: "NukeFLAnimatedImagePlugin", url: "https://github.com/kean/Nuke-FLAnimatedImage-Plugin.git", from: "8.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. @@ -35,7 +37,11 @@ let package = Package( ), .target( name: "MastodonUI", - dependencies: ["MastodonExtension"] + dependencies: [ + "MastodonExtension", + "Nuke", + "NukeFLAnimatedImagePlugin" + ] ), .target( name: "MastodonExtension", diff --git a/MastodonSDK/Sources/MastodonUI/AnimatedImage.swift b/MastodonSDK/Sources/MastodonUI/AnimatedImage.swift new file mode 100644 index 00000000..d6c91678 --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/AnimatedImage.swift @@ -0,0 +1,56 @@ +// +// AnimatedImage.swift +// +// +// Created by MainasuK Cirno on 2021-7-16. +// + +import SwiftUI +import Nuke +import FLAnimatedImage + +struct AnimatedImage: UIViewRepresentable { + + let imageURL: URL? + + func makeUIView(context: Context) -> FLAnimatedImageViewProxy { + let proxy = FLAnimatedImageViewProxy(frame: .zero) + Nuke.loadImage(with: imageURL, into: proxy.imageView) + return proxy + } + + func updateUIView(_ proxy: FLAnimatedImageViewProxy, context: Context) { + Nuke.cancelRequest(for: proxy.imageView) + Nuke.loadImage(with: imageURL, into: proxy.imageView) + } +} + +final class FLAnimatedImageViewProxy: UIView { + let imageView = FLAnimatedImageView() + + override init(frame: CGRect) { + super.init(frame: frame) + + imageView.translatesAutoresizingMaskIntoConstraints = false + addSubview(imageView) + NSLayoutConstraint.activate([ + imageView.topAnchor.constraint(equalTo: topAnchor), + imageView.leadingAnchor.constraint(equalTo: leadingAnchor), + imageView.trailingAnchor.constraint(equalTo: trailingAnchor), + imageView.bottomAnchor.constraint(equalTo: bottomAnchor), + ]) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } +} + +struct AnimatedImage_Previews: PreviewProvider { + static var previews: some View { + AnimatedImage( + imageURL: URL(string: "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif") + ) + .frame(width: 300, height: 300) + } +} diff --git a/MastodonSDK/Sources/MastodonUI/Compose/ComposeView.swift b/MastodonSDK/Sources/MastodonUI/Compose/ComposeView.swift new file mode 100644 index 00000000..10ae383d --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Compose/ComposeView.swift @@ -0,0 +1,68 @@ +// +// ComposeView.swift +// +// +// Created by MainasuK Cirno on 2021-7-16. +// + +import SwiftUI + +public struct ComposeView: View { + + @EnvironmentObject public var viewModel: ComposeViewModel + + public init() { } + + public var body: some View { + GeometryReader { proxy in + ScrollView(.vertical) { + StatusAuthorView( + avatarImageURL: viewModel.avatarImageURL, + name: viewModel.authorName, + username: viewModel.authorUsername + ) + TextEditorView( + string: $viewModel.statusContent, + width: viewModel.frame.width, + attributedString: viewModel.statusContentAttributedString + ) + .frame(width: viewModel.frame.width) + .frame(minHeight: 100) + ForEach(viewModel.attachments, id: \.self) { image in + Image(uiImage: image) + .resizable() + .aspectRatio(16.0/9.0, contentMode: .fill) + .frame(maxWidth: .infinity) + .background(Color.gray) + .cornerRadius(4) + } + } // end ScrollView + .preference( + key: ComposeViewFramePreferenceKey.self, + value: proxy.frame(in: .local) + ) + .onPreferenceChange(ComposeViewFramePreferenceKey.self) { frame in + viewModel.frame = frame + print(frame) + } + } + } +} + +struct ComposeViewFramePreferenceKey: PreferenceKey { + static var defaultValue: CGRect = .zero + static func reduce(value: inout CGRect, nextValue: () -> CGRect) { } +} + +struct ComposeView_Previews: PreviewProvider { + + static let viewModel: ComposeViewModel = { + let viewModel = ComposeViewModel() + return viewModel + }() + + static var previews: some View { + ComposeView().environmentObject(viewModel) + } + +} diff --git a/MastodonSDK/Sources/MastodonUI/Compose/ComposeViewModel.swift b/MastodonSDK/Sources/MastodonUI/Compose/ComposeViewModel.swift new file mode 100644 index 00000000..4679c61c --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Compose/ComposeViewModel.swift @@ -0,0 +1,46 @@ +// +// ComposeViewModel.swift +// ShareActionExtension +// +// Created by MainasuK Cirno on 2021-7-16. +// + +import Foundation +import SwiftUI +import Combine + +public class ComposeViewModel: ObservableObject { + + var disposeBag = Set() + + @Published var frame: CGRect = .zero + + @Published var avatarImageURL: URL? + @Published var authorName: String = "" + @Published var authorUsername: String = "" + + @Published var statusContent = "" + @Published var statusContentAttributedString = NSAttributedString() + @Published var contentWarningContent = "" + + @Published var attachments: [UIImage] = [] + + public init() { + $statusContent + .map { NSAttributedString(string: $0) } + .assign(to: &$statusContentAttributedString) + + #if DEBUG + avatarImageURL = URL(string: "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif") + authorName = "Alice" + authorUsername = "alice" + attachments = [ + UIImage(systemName: "photo")!, + UIImage(systemName: "photo")!, + UIImage(systemName: "photo")!, + UIImage(systemName: "photo")!, + ] + #endif + } + +} diff --git a/MastodonSDK/Sources/MastodonUI/Compose/StatusAuthorView.swift b/MastodonSDK/Sources/MastodonUI/Compose/StatusAuthorView.swift new file mode 100644 index 00000000..110dfb7f --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Compose/StatusAuthorView.swift @@ -0,0 +1,44 @@ +// +// StatusAuthorView.swift +// +// +// Created by MainasuK Cirno on 2021-7-16. +// + +import SwiftUI +import Nuke +import NukeFLAnimatedImagePlugin +import FLAnimatedImage + +struct StatusAuthorView: View { + + let avatarImageURL: URL? + let name: String + let username: String + + var body: some View { + HStack(spacing: 5) { + AnimatedImage(imageURL: avatarImageURL) + .frame(width: 42, height: 42) + .cornerRadius(4) + VStack(alignment: .leading) { + Text(name) + .font(.headline) + Text("@" + username) + .font(.subheadline) + .foregroundColor(.secondary) + } + Spacer() + } + } +} + +struct StatusAuthorView_Previews: PreviewProvider { + static var previews: some View { + StatusAuthorView( + avatarImageURL: URL(string: "https://upload.wikimedia.org/wikipedia/commons/2/2c/Rotating_earth_%28large%29.gif"), + name: "Alice", + username: "alice" + ) + } +} diff --git a/MastodonSDK/Sources/MastodonUI/Compose/TextEditorView.swift b/MastodonSDK/Sources/MastodonUI/Compose/TextEditorView.swift new file mode 100644 index 00000000..4f087f6b --- /dev/null +++ b/MastodonSDK/Sources/MastodonUI/Compose/TextEditorView.swift @@ -0,0 +1,80 @@ +// +// TextEditorView.swift +// +// +// Created by MainasuK Cirno on 2021-7-16. +// + +import UIKit +import SwiftUI + +public struct TextEditorView: UIViewRepresentable { + + @Binding var string: String + + let width: CGFloat + let attributedString: NSAttributedString + + public init( + string: Binding, + width: CGFloat, + attributedString: NSAttributedString + ) { + self._string = string + self.width = width + self.attributedString = attributedString + } + + public func makeUIView(context: Context) -> UITextView { + let textView = UITextView(frame: .zero) + + textView.isScrollEnabled = false + textView.font = .preferredFont(forTextStyle: .body) + textView.textColor = .label + + textView.delegate = context.coordinator + + textView.translatesAutoresizingMaskIntoConstraints = false + let widthLayoutConstraint = textView.widthAnchor.constraint(equalToConstant: 100) + widthLayoutConstraint.priority = .required - 1 + context.coordinator.widthLayoutConstraint = widthLayoutConstraint + + + return textView + } + + public func updateUIView(_ textView: UITextView, context: Context) { + // update content + // textView.attributedText = attributedString + textView.text = string + + // update layout + context.coordinator.updateLayout(width: width) + } + + public func makeCoordinator() -> Coordinator { + Coordinator(self) + } + + public class Coordinator: NSObject, UITextViewDelegate { + var parent: TextEditorView + var widthLayoutConstraint: NSLayoutConstraint? + + init(_ parent: TextEditorView) { + self.parent = parent + } + + public func textViewDidChange(_ textView: UITextView) { + parent.string = textView.text + } + + func updateLayout(width: CGFloat) { + guard let widthLayoutConstraint = widthLayoutConstraint else { return } + widthLayoutConstraint.constant = width + widthLayoutConstraint.isActive = true + } + } + +} + + diff --git a/ShareActionExtension/Info.plist b/ShareActionExtension/Info.plist index ea226b26..52924bee 100644 --- a/ShareActionExtension/Info.plist +++ b/ShareActionExtension/Info.plist @@ -17,24 +17,24 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.0 + $(MARKETING_VERSION) CFBundleVersion - 1 + $(CURRENT_PROJECT_VERSION) NSExtension NSExtensionAttributes - NSExtensionActivationRule - - NSExtensionActivationSupportsImageWithMaxCount - 4 - NSExtensionActivationSupportsMovieWithMaxCount - 1 - NSExtensionActivationSupportsText - - NSExtensionActivationSupportsWebURLWithMaxCount - 1 - + NSExtensionActivationRule + + NSExtensionActivationSupportsImageWithMaxCount + 4 + NSExtensionActivationSupportsMovieWithMaxCount + 1 + NSExtensionActivationSupportsText + + NSExtensionActivationSupportsWebURLWithMaxCount + 1 + NSExtensionMainStoryboard MainInterface diff --git a/ShareActionExtension/ShareViewController.swift b/ShareActionExtension/ShareViewController.swift index c0479c96..e44e3f9f 100644 --- a/ShareActionExtension/ShareViewController.swift +++ b/ShareActionExtension/ShareViewController.swift @@ -9,6 +9,7 @@ import os.log import UIKit import Combine import MastodonUI +import SwiftUI class ShareViewController: UIViewController { @@ -45,19 +46,8 @@ class ShareViewController: UIViewController { return barButtonItem }() -// let tableView: ComposeTableView = { -// let tableView = ComposeTableView() -// tableView.register(ComposeStatusContentTableViewCell.self, forCellReuseIdentifier: String(describing: ComposeStatusContentTableViewCell.self)) -// tableView.register(ComposeStatusAttachmentTableViewCell.self, forCellReuseIdentifier: String(describing: ComposeStatusAttachmentTableViewCell.self)) -// tableView.alwaysBounceVertical = true -// tableView.separatorStyle = .none -// tableView.tableFooterView = UIView() -// return tableView -// }() - } - extension ShareViewController { override func viewDidLoad() { @@ -74,6 +64,21 @@ extension ShareViewController { } .store(in: &disposeBag) + let hostingViewController = UIHostingController( + rootView: ComposeView().environmentObject(viewModel.composeViewModel) + ) + addChild(hostingViewController) + view.addSubview(hostingViewController.view) + hostingViewController.view.translatesAutoresizingMaskIntoConstraints = false + view.addSubview(hostingViewController.view) + NSLayoutConstraint.activate([ + hostingViewController.view.topAnchor.constraint(equalTo: view.topAnchor), + hostingViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor), + hostingViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor), + hostingViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), + ]) + hostingViewController.didMove(toParent: self) + // viewModel.authentication // .receive(on: DispatchQueue.main) // .sink { [weak self] result in diff --git a/ShareActionExtension/ShareViewModel.swift b/ShareActionExtension/ShareViewModel.swift index bea00c51..8384eb12 100644 --- a/ShareActionExtension/ShareViewModel.swift +++ b/ShareActionExtension/ShareViewModel.swift @@ -10,6 +10,7 @@ import Foundation import Combine import CoreData import CoreDataStack +import MastodonUI final class ShareViewModel { @@ -27,6 +28,7 @@ final class ShareViewModel { let isFetchAuthentication = CurrentValueSubject(true) let isBusy = CurrentValueSubject(true) let isValid = CurrentValueSubject(false) + let composeViewModel = ComposeViewModel() init() { viewDidAppear.receive(on: DispatchQueue.main)