feat: add share action extension
This commit is contained in:
parent
9a19001df9
commit
8e749fd75b
|
@ -7,12 +7,14 @@
|
|||
|
||||
import os
|
||||
import Foundation
|
||||
import Combine
|
||||
import CoreData
|
||||
import AppShared
|
||||
|
||||
public final class CoreDataStack {
|
||||
|
||||
private(set) var storeDescriptions: [NSPersistentStoreDescription]
|
||||
public let didFinishLoad = CurrentValueSubject<Bool, Never>(false)
|
||||
|
||||
init(persistentStoreDescriptions storeDescriptions: [NSPersistentStoreDescription]) {
|
||||
self.storeDescriptions = storeDescriptions
|
||||
|
@ -33,7 +35,10 @@ public final class CoreDataStack {
|
|||
*/
|
||||
let container = CoreDataStack.persistentContainer()
|
||||
CoreDataStack.configure(persistentContainer: container, storeDescriptions: storeDescriptions)
|
||||
CoreDataStack.load(persistentContainer: container)
|
||||
CoreDataStack.load(persistentContainer: container) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.didFinishLoad.value = true
|
||||
}
|
||||
|
||||
return container
|
||||
}()
|
||||
|
@ -52,7 +57,7 @@ public final class CoreDataStack {
|
|||
container.persistentStoreDescriptions = storeDescriptions
|
||||
}
|
||||
|
||||
static func load(persistentContainer container: NSPersistentContainer) {
|
||||
static func load(persistentContainer container: NSPersistentContainer, callback: @escaping () -> Void) {
|
||||
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
|
||||
if let error = error as NSError? {
|
||||
// Replace this implementation with code to handle the error appropriately.
|
||||
|
@ -85,6 +90,8 @@ public final class CoreDataStack {
|
|||
container.viewContext.automaticallyMergesChangesFromParent = true
|
||||
|
||||
os_log("%{public}s[%{public}ld], %{public}s: %s", ((#file as NSString).lastPathComponent), #line, #function, storeDescription.debugDescription)
|
||||
|
||||
callback()
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -96,7 +103,10 @@ extension CoreDataStack {
|
|||
let oldStoreURL = persistentContainer.persistentStoreCoordinator.url(for: persistentContainer.persistentStoreCoordinator.persistentStores.first!)
|
||||
try! persistentContainer.persistentStoreCoordinator.destroyPersistentStore(at: oldStoreURL, ofType: NSSQLiteStoreType, options: nil)
|
||||
|
||||
CoreDataStack.load(persistentContainer: persistentContainer)
|
||||
CoreDataStack.load(persistentContainer: persistentContainer) { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.didFinishLoad.value = true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -423,7 +423,6 @@
|
|||
DB9D7C21269824B80054B3DF /* APIService+Filter.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9D7C20269824B80054B3DF /* APIService+Filter.swift */; };
|
||||
DB9E0D6F25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */; };
|
||||
DBA088DF26958164003EB4B2 /* UserFetchedResultsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA088DE26958164003EB4B2 /* UserFetchedResultsController.swift */; };
|
||||
DBA0A10925FB3C2B0079C110 /* RoundedEdgesButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA0A10825FB3C2B0079C110 /* RoundedEdgesButton.swift */; };
|
||||
DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */; };
|
||||
DBA1DB80268F84F80052DB59 /* NotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA1DB7F268F84F80052DB59 /* NotificationType.swift */; };
|
||||
DBA465932696B495002B41DB /* APIService+WebFinger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA465922696B495002B41DB /* APIService+WebFinger.swift */; };
|
||||
|
@ -481,6 +480,17 @@
|
|||
DBBF1DC7265251D400E5B703 /* AutoCompleteViewModel+State.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBF1DC6265251D400E5B703 /* AutoCompleteViewModel+State.swift */; };
|
||||
DBBF1DC92652538500E5B703 /* AutoCompleteSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBF1DC82652538500E5B703 /* AutoCompleteSection.swift */; };
|
||||
DBBF1DCB2652539E00E5B703 /* AutoCompleteItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBF1DCA2652539E00E5B703 /* AutoCompleteItem.swift */; };
|
||||
DBC6461526A170AB00B0E31B /* ShareViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC6461426A170AB00B0E31B /* ShareViewController.swift */; };
|
||||
DBC6461826A170AB00B0E31B /* MainInterface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = DBC6461626A170AB00B0E31B /* MainInterface.storyboard */; };
|
||||
DBC6461C26A170AB00B0E31B /* ShareActionExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||
DBC6462326A1712000B0E31B /* ShareViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC6462226A1712000B0E31B /* ShareViewModel.swift */; };
|
||||
DBC6462526A1720B00B0E31B /* MastodonUI in Frameworks */ = {isa = PBXBuildFile; productRef = DBC6462426A1720B00B0E31B /* MastodonUI */; };
|
||||
DBC6462626A1736000B0E31B /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DB564BCE269F2F83001E39A7 /* Localizable.stringsdict */; };
|
||||
DBC6462726A1736000B0E31B /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB3D100F25BAA75E00EAA174 /* Localizable.strings */; };
|
||||
DBC6462826A1736300B0E31B /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB427DDE25BAA00100D1B89D /* Assets.xcassets */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
|
@ -598,6 +608,13 @@
|
|||
remoteGlobalIDString = DB89B9ED25C10FD0008580ED;
|
||||
remoteInfo = CoreDataStack;
|
||||
};
|
||||
DBC6461A26A170AB00B0E31B /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = DBC6461126A170AB00B0E31B;
|
||||
remoteInfo = ShareActionExtension;
|
||||
};
|
||||
DBF8AE18263293E400C9C23C /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
|
||||
|
@ -627,6 +644,7 @@
|
|||
dstPath = "";
|
||||
dstSubfolderSpec = 13;
|
||||
files = (
|
||||
DBC6461C26A170AB00B0E31B /* ShareActionExtension.appex in Embed App Extensions */,
|
||||
DBF8AE1A263293E400C9C23C /* NotificationService.appex in Embed App Extensions */,
|
||||
);
|
||||
name = "Embed App Extensions";
|
||||
|
@ -1068,7 +1086,6 @@
|
|||
DB9D7C20269824B80054B3DF /* APIService+Filter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Filter.swift"; sourceTree = "<group>"; };
|
||||
DB9E0D6E25EE008500CFDD76 /* UIInterpolatingMotionEffect.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIInterpolatingMotionEffect.swift; sourceTree = "<group>"; };
|
||||
DBA088DE26958164003EB4B2 /* UserFetchedResultsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserFetchedResultsController.swift; sourceTree = "<group>"; };
|
||||
DBA0A10825FB3C2B0079C110 /* RoundedEdgesButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedEdgesButton.swift; sourceTree = "<group>"; };
|
||||
DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeToolbarView.swift; sourceTree = "<group>"; };
|
||||
DBA1DB7F268F84F80052DB59 /* NotificationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationType.swift; sourceTree = "<group>"; };
|
||||
DBA465922696B495002B41DB /* APIService+WebFinger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+WebFinger.swift"; sourceTree = "<group>"; };
|
||||
|
@ -1121,6 +1138,11 @@
|
|||
DBBF1DC6265251D400E5B703 /* AutoCompleteViewModel+State.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AutoCompleteViewModel+State.swift"; sourceTree = "<group>"; };
|
||||
DBBF1DC82652538500E5B703 /* AutoCompleteSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoCompleteSection.swift; sourceTree = "<group>"; };
|
||||
DBBF1DCA2652539E00E5B703 /* AutoCompleteItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoCompleteItem.swift; sourceTree = "<group>"; };
|
||||
DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = ShareActionExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DBC6461426A170AB00B0E31B /* ShareViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareViewController.swift; sourceTree = "<group>"; };
|
||||
DBC6461726A170AB00B0E31B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/MainInterface.storyboard; sourceTree = "<group>"; };
|
||||
DBC6461926A170AB00B0E31B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
DBC6462226A1712000B0E31B /* ShareViewModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareViewModel.swift; sourceTree = "<group>"; };
|
||||
DBC7A671260C897100E57475 /* StatusContentWarningEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusContentWarningEditorView.swift; sourceTree = "<group>"; };
|
||||
DBC7A67B260DFADE00E57475 /* StatusPublishService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatusPublishService.swift; sourceTree = "<group>"; };
|
||||
DBCBCBF3267CB070000F5B51 /* Decode85.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Decode85.swift; sourceTree = "<group>"; };
|
||||
|
@ -1190,6 +1212,7 @@
|
|||
DB0140BD25C40D7500F9F3CF /* CommonOSLog in Frameworks */,
|
||||
DB03F7ED268976B5007B274C /* MetaTextView in Frameworks */,
|
||||
DB89BA0325C10FD0008580ED /* CoreDataStack.framework in Frameworks */,
|
||||
DBC6462B26A1738900B0E31B /* MastodonUI in Frameworks */,
|
||||
2D42FF6125C8177C004A627A /* ActiveLabel in Frameworks */,
|
||||
DB9A487E2603456B008B817C /* UITextView+Placeholder in Frameworks */,
|
||||
2D939AC825EE14620076FA61 /* CropViewController in Frameworks */,
|
||||
|
@ -1253,6 +1276,14 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DBC6460F26A170AB00B0E31B /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DBC6462526A1720B00B0E31B /* MastodonUI in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DBF8AE10263293E400C9C23C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -1458,7 +1489,6 @@
|
|||
2D42FF8425C8224F004A627A /* HitTestExpandedButton.swift */,
|
||||
DB118A8B25E4BFB500FAB162 /* HighlightDimmableButton.swift */,
|
||||
0FAA101125E105390017CCDE /* PrimaryActionButton.swift */,
|
||||
DBA0A10825FB3C2B0079C110 /* RoundedEdgesButton.swift */,
|
||||
);
|
||||
path = Button;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1876,10 +1906,11 @@
|
|||
DB427DD425BAA00100D1B89D /* Mastodon */,
|
||||
DB427DEB25BAA00100D1B89D /* MastodonTests */,
|
||||
DB427DF625BAA00100D1B89D /* MastodonUITests */,
|
||||
DB6804802637CD4C00430867 /* AppShared */,
|
||||
DB89B9EF25C10FD0008580ED /* CoreDataStack */,
|
||||
DB89B9FC25C10FD0008580ED /* CoreDataStackTests */,
|
||||
DBF8AE14263293E400C9C23C /* NotificationService */,
|
||||
DB6804802637CD4C00430867 /* AppShared */,
|
||||
DBC6461326A170AB00B0E31B /* ShareActionExtension */,
|
||||
DB427DD325BAA00100D1B89D /* Products */,
|
||||
1EBA4F56E920856A3FC84ACB /* Pods */,
|
||||
3FE14AD363ED19AE7FF210A6 /* Frameworks */,
|
||||
|
@ -1897,6 +1928,7 @@
|
|||
DB89B9F625C10FD0008580ED /* CoreDataStackTests.xctest */,
|
||||
DBF8AE13263293E400C9C23C /* NotificationService.appex */,
|
||||
DB68047F2637CD4C00430867 /* AppShared.framework */,
|
||||
DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -2682,6 +2714,17 @@
|
|||
path = Cell;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DBC6461326A170AB00B0E31B /* ShareActionExtension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
DBC6462226A1712000B0E31B /* ShareViewModel.swift */,
|
||||
DBC6461426A170AB00B0E31B /* ShareViewController.swift */,
|
||||
DBC6461626A170AB00B0E31B /* MainInterface.storyboard */,
|
||||
DBC6461926A170AB00B0E31B /* Info.plist */,
|
||||
);
|
||||
path = ShareActionExtension;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DBCBCBFD2680ADBA000F5B51 /* AsyncHomeTimeline */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -2831,6 +2874,7 @@
|
|||
DBF8AE19263293E400C9C23C /* PBXTargetDependency */,
|
||||
DB6804852637CD4C00430867 /* PBXTargetDependency */,
|
||||
DB6804CA2637CE3000430867 /* PBXTargetDependency */,
|
||||
DBC6461B26A170AB00B0E31B /* PBXTargetDependency */,
|
||||
);
|
||||
name = Mastodon;
|
||||
packageProductDependencies = (
|
||||
|
@ -2852,6 +2896,7 @@
|
|||
DB0E2D2D26833FF700865C3C /* NukeFLAnimatedImagePlugin */,
|
||||
DB03F7EA268976B5007B274C /* MastodonMeta */,
|
||||
DB03F7EC268976B5007B274C /* MetaTextView */,
|
||||
DBC6462A26A1738900B0E31B /* MastodonUI */,
|
||||
);
|
||||
productName = Mastodon;
|
||||
productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */;
|
||||
|
@ -2956,6 +3001,26 @@
|
|||
productReference = DB89B9F625C10FD0008580ED /* CoreDataStackTests.xctest */;
|
||||
productType = "com.apple.product-type.bundle.unit-test";
|
||||
};
|
||||
DBC6461126A170AB00B0E31B /* ShareActionExtension */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = DBC6462126A170AB00B0E31B /* Build configuration list for PBXNativeTarget "ShareActionExtension" */;
|
||||
buildPhases = (
|
||||
DBC6460E26A170AB00B0E31B /* Sources */,
|
||||
DBC6460F26A170AB00B0E31B /* Frameworks */,
|
||||
DBC6461026A170AB00B0E31B /* Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ShareActionExtension;
|
||||
packageProductDependencies = (
|
||||
DBC6462426A1720B00B0E31B /* MastodonUI */,
|
||||
);
|
||||
productName = ShareActionExtension;
|
||||
productReference = DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */;
|
||||
productType = "com.apple.product-type.app-extension";
|
||||
};
|
||||
DBF8AE12263293E400C9C23C /* NotificationService */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = DBF8AE1E263293E400C9C23C /* Build configuration list for PBXNativeTarget "NotificationService" */;
|
||||
|
@ -2985,7 +3050,7 @@
|
|||
DB427DCA25BAA00100D1B89D /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastSwiftUpdateCheck = 1240;
|
||||
LastSwiftUpdateCheck = 1250;
|
||||
LastUpgradeCheck = 1240;
|
||||
TargetAttributes = {
|
||||
DB427DD125BAA00100D1B89D = {
|
||||
|
@ -3012,6 +3077,9 @@
|
|||
CreatedOnToolsVersion = 12.4;
|
||||
TestTargetID = DB427DD125BAA00100D1B89D;
|
||||
};
|
||||
DBC6461126A170AB00B0E31B = {
|
||||
CreatedOnToolsVersion = 12.5.1;
|
||||
};
|
||||
DBF8AE12263293E400C9C23C = {
|
||||
CreatedOnToolsVersion = 12.4;
|
||||
};
|
||||
|
@ -3053,10 +3121,11 @@
|
|||
DB427DD125BAA00100D1B89D /* Mastodon */,
|
||||
DB427DE725BAA00100D1B89D /* MastodonTests */,
|
||||
DB427DF225BAA00100D1B89D /* MastodonUITests */,
|
||||
DB68047E2637CD4C00430867 /* AppShared */,
|
||||
DB89B9ED25C10FD0008580ED /* CoreDataStack */,
|
||||
DB89B9F525C10FD0008580ED /* CoreDataStackTests */,
|
||||
DBF8AE12263293E400C9C23C /* NotificationService */,
|
||||
DB68047E2637CD4C00430867 /* AppShared */,
|
||||
DBC6461126A170AB00B0E31B /* ShareActionExtension */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
@ -3113,6 +3182,17 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DBC6461026A170AB00B0E31B /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DBC6461826A170AB00B0E31B /* MainInterface.storyboard in Resources */,
|
||||
DBC6462726A1736000B0E31B /* Localizable.strings in Resources */,
|
||||
DBC6462826A1736300B0E31B /* Assets.xcassets in Resources */,
|
||||
DBC6462626A1736000B0E31B /* Localizable.stringsdict in Resources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DBF8AE11263293E400C9C23C /* Resources */ = {
|
||||
isa = PBXResourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -3364,7 +3444,6 @@
|
|||
5DDDF1932617442700311060 /* Mastodon+Entity+Account.swift in Sources */,
|
||||
DBAE3F882615DDF4004B8251 /* UserProviderFacade.swift in Sources */,
|
||||
2D607AD826242FC500B70763 /* NotificationViewModel.swift in Sources */,
|
||||
DBA0A10925FB3C2B0079C110 /* RoundedEdgesButton.swift in Sources */,
|
||||
DBABE3EC25ECAC4B00879EE5 /* WelcomeIllustrationView.swift in Sources */,
|
||||
DB564BD3269F3B35001E39A7 /* StatusFilterService.swift in Sources */,
|
||||
DB71FD4625F8C6D200512AE1 /* StatusProvider+UITableViewDataSourcePrefetching.swift in Sources */,
|
||||
|
@ -3798,6 +3877,17 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DBC6460E26A170AB00B0E31B /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DBC6462326A1712000B0E31B /* ShareViewModel.swift in Sources */,
|
||||
DBC6462926A1736700B0E31B /* Strings.swift in Sources */,
|
||||
DBC6462C26A176B000B0E31B /* Assets.swift in Sources */,
|
||||
DBC6461526A170AB00B0E31B /* ShareViewController.swift in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
DBF8AE0F263293E400C9C23C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -3860,6 +3950,11 @@
|
|||
target = DB89B9ED25C10FD0008580ED /* CoreDataStack */;
|
||||
targetProxy = DB89BA0125C10FD0008580ED /* PBXContainerItemProxy */;
|
||||
};
|
||||
DBC6461B26A170AB00B0E31B /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = DBC6461126A170AB00B0E31B /* ShareActionExtension */;
|
||||
targetProxy = DBC6461A26A170AB00B0E31B /* PBXContainerItemProxy */;
|
||||
};
|
||||
DBF8AE19263293E400C9C23C /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = DBF8AE12263293E400C9C23C /* NotificationService */;
|
||||
|
@ -3911,6 +4006,14 @@
|
|||
name = Localizable.stringsdict;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
DBC6461626A170AB00B0E31B /* MainInterface.storyboard */ = {
|
||||
isa = PBXVariantGroup;
|
||||
children = (
|
||||
DBC6461726A170AB00B0E31B /* Base */,
|
||||
);
|
||||
name = MainInterface.storyboard;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXVariantGroup section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
|
@ -4036,6 +4139,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 2E1F6A67FDF9771D3E064FDC /* Pods-Mastodon.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
|
@ -4063,6 +4167,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 75E3471C898DDD9631729B6E /* Pods-Mastodon.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
|
@ -4325,6 +4430,86 @@
|
|||
};
|
||||
name = Release;
|
||||
};
|
||||
DBC6461D26A170AB00B0E31B /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
DBC6461E26A170AB00B0E31B /* ASDK - Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = "ASDK - Debug";
|
||||
};
|
||||
DBC6461F26A170AB00B0E31B /* ASDK - Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = "ASDK - Release";
|
||||
};
|
||||
DBC6462026A170AB00B0E31B /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = ShareActionExtension/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 14.5;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
SWIFT_VERSION = 5.0;
|
||||
TARGETED_DEVICE_FAMILY = "1,2";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
DBCBCC0E2680BE3E000F5B51 /* ASDK - Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -4391,6 +4576,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = BD7598A87F4497045EDEF252 /* Pods-Mastodon.asdk - release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
|
@ -4624,6 +4810,7 @@
|
|||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
|
@ -4917,6 +5104,17 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
DBC6462126A170AB00B0E31B /* Build configuration list for PBXNativeTarget "ShareActionExtension" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
DBC6461D26A170AB00B0E31B /* Debug */,
|
||||
DBC6461E26A170AB00B0E31B /* ASDK - Debug */,
|
||||
DBC6461F26A170AB00B0E31B /* ASDK - Release */,
|
||||
DBC6462026A170AB00B0E31B /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
DBF8AE1E263293E400C9C23C /* Build configuration list for PBXNativeTarget "NotificationService" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
|
@ -5169,6 +5367,14 @@
|
|||
package = DBB525062611EAC0002F1F29 /* XCRemoteSwiftPackageReference "Tabman" */;
|
||||
productName = Tabman;
|
||||
};
|
||||
DBC6462426A1720B00B0E31B /* MastodonUI */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = MastodonUI;
|
||||
};
|
||||
DBC6462A26A1738900B0E31B /* MastodonUI */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = MastodonUI;
|
||||
};
|
||||
DBF7A0FB26830C33004176A2 /* FPSIndicator */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DBF7A0FA26830C33004176A2 /* XCRemoteSwiftPackageReference "FPSIndicator" */;
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<key>CoreDataStack.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>20</integer>
|
||||
<integer>21</integer>
|
||||
</dict>
|
||||
<key>Mastodon - ASDK.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
|
@ -37,7 +37,12 @@
|
|||
<key>NotificationService.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>21</integer>
|
||||
<integer>22</integer>
|
||||
</dict>
|
||||
<key>ShareActionExtension.xcscheme_^#shared#^_</key>
|
||||
<dict>
|
||||
<key>orderHint</key>
|
||||
<integer>30</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>SuppressBuildableAutocreation</key>
|
||||
|
|
|
@ -9,17 +9,6 @@ import CoreImage
|
|||
import CoreImage.CIFilterBuiltins
|
||||
import UIKit
|
||||
|
||||
extension UIImage {
|
||||
static func placeholder(size: CGSize = CGSize(width: 1, height: 1), color: UIColor) -> UIImage {
|
||||
let render = UIGraphicsImageRenderer(size: size)
|
||||
|
||||
return render.image { (context: UIGraphicsImageRendererContext) in
|
||||
context.cgContext.setFillColor(color.cgColor)
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// refs: https://www.hackingwithswift.com/example-code/media/how-to-read-the-average-color-of-a-uiimage-using-ciareaaverage
|
||||
extension UIImage {
|
||||
@available(iOS 14.0, *)
|
||||
|
|
|
@ -14,6 +14,7 @@ import MetaTextView
|
|||
import MastodonMeta
|
||||
import Meta
|
||||
import Nuke
|
||||
import MastodonUI
|
||||
|
||||
final class ComposeViewController: UIViewController, NeedsDependency {
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import os.log
|
||||
import UIKit
|
||||
import MastodonUI
|
||||
|
||||
protocol HomeTimelineNavigationBarTitleViewDelegate: AnyObject {
|
||||
func homeTimelineNavigationBarTitleView(_ titleView: HomeTimelineNavigationBarTitleView, logoButtonDidPressed sender: UIButton)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
//
|
||||
|
||||
import UIKit
|
||||
import MastodonUI
|
||||
|
||||
final class ProfileRelationshipActionButton: RoundedEdgesButton {
|
||||
|
||||
|
|
|
@ -12,6 +12,12 @@ let package = Package(
|
|||
.library(
|
||||
name: "MastodonSDK",
|
||||
targets: ["MastodonSDK"]),
|
||||
.library(
|
||||
name: "MastodonUI",
|
||||
targets: ["MastodonUI"]),
|
||||
.library(
|
||||
name: "MastodonExtension",
|
||||
targets: ["MastodonExtension"]),
|
||||
],
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/SwiftyJSON/SwiftyJSON.git", from: "5.0.0"),
|
||||
|
@ -27,6 +33,14 @@ let package = Package(
|
|||
.product(name: "NIOHTTP1", package: "swift-nio"),
|
||||
]
|
||||
),
|
||||
.target(
|
||||
name: "MastodonUI",
|
||||
dependencies: ["MastodonExtension"]
|
||||
),
|
||||
.target(
|
||||
name: "MastodonExtension",
|
||||
dependencies: []
|
||||
),
|
||||
.testTarget(
|
||||
name: "MastodonSDKTests",
|
||||
dependencies: ["MastodonSDK"]
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// UIImage.swift
|
||||
//
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-7-16.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UIImage {
|
||||
public static func placeholder(size: CGSize = CGSize(width: 1, height: 1), color: UIColor) -> UIImage {
|
||||
let render = UIGraphicsImageRenderer(size: size)
|
||||
|
||||
return render.image { (context: UIGraphicsImageRendererContext) in
|
||||
context.cgContext.setFillColor(color.cgColor)
|
||||
context.fill(CGRect(origin: .zero, size: size))
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
//
|
||||
// RoundedEdgesButton.swift
|
||||
// Mastodon
|
||||
// MastodonUI
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-3-12.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class RoundedEdgesButton: UIButton {
|
||||
open class RoundedEdgesButton: UIButton {
|
||||
|
||||
override func layoutSubviews() {
|
||||
open override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
layer.masksToBounds = true
|
|
@ -0,0 +1 @@
|
|||
@_exported import MastodonExtension
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="18122" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="jKX-MD-OMs">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="18093"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Share View Controller-->
|
||||
<scene sceneID="ceB-am-kn3">
|
||||
<objects>
|
||||
<viewController id="j1y-V4-xli" customClass="ShareViewController" customModule="ShareActionExtension" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" opaque="NO" contentMode="scaleToFill" id="wbc-yd-nQP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<viewLayoutGuide key="safeArea" id="1Xd-am-t49"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="uKc-xP-YOE"/>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="CEy-Cv-SGf" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1042.0289855072465" y="116.51785714285714"/>
|
||||
</scene>
|
||||
<!--Navigation Controller-->
|
||||
<scene sceneID="hJg-46-PMP">
|
||||
<objects>
|
||||
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="jKX-MD-OMs" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<navigationBar key="navigationBar" contentMode="scaleToFill" id="ERE-s0-7dc">
|
||||
<rect key="frame" x="0.0" y="44" width="414" height="44"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
</navigationBar>
|
||||
<nil name="viewControllers"/>
|
||||
<connections>
|
||||
<segue destination="j1y-V4-xli" kind="relationship" relationship="rootViewController" id="sD9-c7-jnh"/>
|
||||
</connections>
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="bwB-yX-sdw" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="131.8840579710145" y="116.51785714285714"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>ShareActionExtension</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationRule</key>
|
||||
<dict>
|
||||
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||
<integer>4</integer>
|
||||
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
<key>NSExtensionActivationSupportsText</key>
|
||||
<true/>
|
||||
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</dict>
|
||||
<key>NSExtensionMainStoryboard</key>
|
||||
<string>MainInterface</string>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.share-services</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,102 @@
|
|||
//
|
||||
// ShareViewController.swift
|
||||
// MastodonShareAction
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-7-16.
|
||||
//
|
||||
|
||||
import os.log
|
||||
import UIKit
|
||||
import Combine
|
||||
import MastodonUI
|
||||
|
||||
class ShareViewController: UIViewController {
|
||||
|
||||
let logger = Logger(subsystem: "ShareViewController", category: "UI")
|
||||
|
||||
var disposeBag = Set<AnyCancellable>()
|
||||
let viewModel = ShareViewModel()
|
||||
|
||||
let publishButton: UIButton = {
|
||||
let button = RoundedEdgesButton(type: .custom)
|
||||
button.setTitle(L10n.Scene.Compose.composeAction, for: .normal)
|
||||
button.titleLabel?.font = .systemFont(ofSize: 14, weight: .bold)
|
||||
button.setBackgroundImage(.placeholder(color: Asset.Colors.brandBlue.color), for: .normal)
|
||||
button.setBackgroundImage(.placeholder(color: Asset.Colors.brandBlue.color.withAlphaComponent(0.5)), for: .highlighted)
|
||||
button.setBackgroundImage(.placeholder(color: Asset.Colors.Button.disabled.color), for: .disabled)
|
||||
button.setTitleColor(.white, for: .normal)
|
||||
button.contentEdgeInsets = UIEdgeInsets(top: 6, left: 16, bottom: 5, right: 16) // set 28pt height
|
||||
button.adjustsImageWhenHighlighted = false
|
||||
return button
|
||||
}()
|
||||
|
||||
private(set) lazy var cancelBarButtonItem = UIBarButtonItem(title: L10n.Common.Controls.Actions.cancel, style: .plain, target: self, action: #selector(ShareViewController.cancelBarButtonItemPressed(_:)))
|
||||
private(set) lazy var publishBarButtonItem: UIBarButtonItem = {
|
||||
let barButtonItem = UIBarButtonItem(customView: publishButton)
|
||||
barButtonItem.target = self
|
||||
barButtonItem.action = #selector(ShareViewController.publishBarButtonItemPressed(_:))
|
||||
return barButtonItem
|
||||
}()
|
||||
|
||||
let activityIndicatorBarButtonItem: UIBarButtonItem = {
|
||||
let indicatorView = UIActivityIndicatorView(style: .medium)
|
||||
let barButtonItem = UIBarButtonItem(customView: indicatorView)
|
||||
indicatorView.startAnimating()
|
||||
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() {
|
||||
super.viewDidLoad()
|
||||
|
||||
view.backgroundColor = Asset.Colors.Background.systemBackground.color
|
||||
|
||||
navigationItem.leftBarButtonItem = cancelBarButtonItem
|
||||
viewModel.isBusy
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] isBusy in
|
||||
guard let self = self else { return }
|
||||
self.navigationItem.rightBarButtonItem = isBusy ? self.activityIndicatorBarButtonItem : self.publishBarButtonItem
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
// viewModel.authentication
|
||||
// .receive(on: DispatchQueue.main)
|
||||
// .sink { [weak self] result in
|
||||
// guard let self = self else { return }
|
||||
// }
|
||||
}
|
||||
|
||||
override func viewDidAppear(_ animated: Bool) {
|
||||
super.viewDidAppear(animated)
|
||||
|
||||
viewModel.viewDidAppear.value = true
|
||||
// extensionContext
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ShareViewController {
|
||||
@objc private func cancelBarButtonItemPressed(_ sender: UIBarButtonItem) {
|
||||
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||
extensionContext?.cancelRequest(withError: ShareViewModel.ShareError.userCancelShare)
|
||||
}
|
||||
|
||||
@objc private func publishBarButtonItemPressed(_ sender: UIBarButtonItem) {
|
||||
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
//
|
||||
// ShareViewModel.swift
|
||||
// MastodonShareAction
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-7-16.
|
||||
//
|
||||
|
||||
import os.log
|
||||
import Foundation
|
||||
import Combine
|
||||
import CoreData
|
||||
import CoreDataStack
|
||||
|
||||
final class ShareViewModel {
|
||||
|
||||
let logger = Logger(subsystem: "ShareViewModel", category: "logic")
|
||||
|
||||
var disposeBag = Set<AnyCancellable>()
|
||||
|
||||
// input
|
||||
let viewDidAppear = CurrentValueSubject<Bool, Never>(false)
|
||||
private var coreDataStack: CoreDataStack?
|
||||
var managedObjectContext: NSManagedObjectContext?
|
||||
|
||||
// output
|
||||
let authentication = CurrentValueSubject<Result<MastodonAuthentication, Error>?, Never>(nil)
|
||||
let isFetchAuthentication = CurrentValueSubject<Bool, Never>(true)
|
||||
let isBusy = CurrentValueSubject<Bool, Never>(true)
|
||||
let isValid = CurrentValueSubject<Bool, Never>(false)
|
||||
|
||||
init() {
|
||||
viewDidAppear.receive(on: DispatchQueue.main)
|
||||
.removeDuplicates()
|
||||
.sink { [weak self] viewDidAppear in
|
||||
guard let self = self else { return }
|
||||
guard viewDidAppear else { return }
|
||||
self.setupCoreData()
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
authentication
|
||||
.map { result in result == nil }
|
||||
.assign(to: \.value, on: isFetchAuthentication)
|
||||
.store(in: &disposeBag)
|
||||
|
||||
isFetchAuthentication
|
||||
.receive(on: DispatchQueue.main)
|
||||
.assign(to: \.value, on: isBusy)
|
||||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ShareViewModel {
|
||||
enum ShareError: Error {
|
||||
case `internal`(error: Error)
|
||||
case userCancelShare
|
||||
case missingAuthentication
|
||||
}
|
||||
}
|
||||
|
||||
extension ShareViewModel {
|
||||
private func setupCoreData() {
|
||||
logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public)")
|
||||
DispatchQueue.global().async {
|
||||
let _coreDataStack = CoreDataStack()
|
||||
self.coreDataStack = _coreDataStack
|
||||
self.managedObjectContext = _coreDataStack.persistentContainer.viewContext
|
||||
|
||||
_coreDataStack.didFinishLoad
|
||||
.receive(on: RunLoop.main)
|
||||
.sink { [weak self] didFinishLoad in
|
||||
guard let self = self else { return }
|
||||
guard didFinishLoad else { return }
|
||||
guard let managedObjectContext = self.managedObjectContext else { return }
|
||||
|
||||
self.logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch authentication…")
|
||||
managedObjectContext.perform {
|
||||
do {
|
||||
let request = MastodonAuthentication.sortedFetchRequest
|
||||
let authentications = try managedObjectContext.fetch(request)
|
||||
let authentication = authentications.sorted(by: { $0.activedAt > $1.activedAt }).first
|
||||
guard let activeAuthentication = authentication else {
|
||||
self.authentication.value = .failure(ShareError.missingAuthentication)
|
||||
return
|
||||
}
|
||||
self.authentication.value = .success(activeAuthentication)
|
||||
self.logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch authentication success \(activeAuthentication.userID)")
|
||||
} catch {
|
||||
self.authentication.value = .failure(ShareError.internal(error: error))
|
||||
self.logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): fetch authentication fail \(error.localizedDescription)")
|
||||
assertionFailure(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &self.disposeBag)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue