diff --git a/Base.lproj/Intents.intentdefinition b/Base.lproj/Intents.intentdefinition
new file mode 100644
index 000000000..df98e3ab2
--- /dev/null
+++ b/Base.lproj/Intents.intentdefinition
@@ -0,0 +1,402 @@
+
+
+
+
+ INEnums
+
+
+ INEnumDisplayName
+ Post Visibility
+ INEnumDisplayNameID
+ Zo4jgJ
+ INEnumGeneratesHeader
+
+ INEnumName
+ PostVisibility
+ INEnumType
+ Regular
+ INEnumValues
+
+
+ INEnumValueDisplayName
+ unknown
+ INEnumValueDisplayNameID
+ cQxbPW
+ INEnumValueName
+ unknown
+
+
+ INEnumValueDisplayName
+ Public
+ INEnumValueDisplayNameID
+ dYQ5NN
+ INEnumValueIndex
+ 1
+ INEnumValueName
+ public
+
+
+ INEnumValueDisplayName
+ Followers Only
+ INEnumValueDisplayNameID
+ ehFLjY
+ INEnumValueIndex
+ 2
+ INEnumValueName
+ followersOnly
+
+
+
+
+ INIntentDefinitionModelVersion
+ 1.2
+ INIntentDefinitionNamespace
+ BvMBE4
+ INIntentDefinitionSystemVersion
+ 20G71
+ INIntentDefinitionToolsBuildVersion
+ 12E507
+ INIntentDefinitionToolsVersion
+ 12.5.1
+ INIntents
+
+
+ INIntentCategory
+ share
+ INIntentConfigurable
+
+ INIntentDescription
+ Send Post with text content
+ INIntentDescriptionID
+ RHxKOw
+ INIntentInput
+ content
+ INIntentKeyParameter
+ content
+ INIntentLastParameterTag
+ 3
+ INIntentManagedParameterCombinations
+
+ content,visibility
+
+ INIntentParameterCombinationSupportsBackgroundExecution
+
+ INIntentParameterCombinationTitle
+ Post ${content} on Mastodon
+ INIntentParameterCombinationTitleID
+ WCIR3D
+ INIntentParameterCombinationUpdatesLinked
+
+
+
+ INIntentName
+ SendPost
+ INIntentParameterCombinations
+
+ content
+
+ INIntentParameterCombinationSubtitle
+ ${content}
+ INIntentParameterCombinationSubtitleID
+ ZS1XaK
+ INIntentParameterCombinationSupportsBackgroundExecution
+
+ INIntentParameterCombinationTitle
+ Post
+ INIntentParameterCombinationTitleID
+ CsR7G2
+
+ content,visibility
+
+ INIntentParameterCombinationIsPrimary
+
+ INIntentParameterCombinationSubtitle
+ ${content}, ${visibility}
+ INIntentParameterCombinationSubtitleID
+ ayoYEb
+ INIntentParameterCombinationSupportsBackgroundExecution
+
+ INIntentParameterCombinationTitle
+ Post
+ INIntentParameterCombinationTitleID
+ dUyuGg
+
+
+ INIntentParameters
+
+
+ INIntentParameterConfigurable
+
+ INIntentParameterCustomDisambiguation
+
+ INIntentParameterDisplayName
+ Text Content
+ INIntentParameterDisplayNameID
+ 751xkl
+ INIntentParameterDisplayPriority
+ 1
+ INIntentParameterMetadata
+
+ INIntentParameterMetadataCapitalization
+ Sentences
+ INIntentParameterMetadataDefaultValueID
+ odzH7f
+ INIntentParameterMetadataMultiline
+
+
+ INIntentParameterName
+ content
+ INIntentParameterPromptDialogs
+
+
+ INIntentParameterPromptDialogCustom
+
+ INIntentParameterPromptDialogType
+ Configuration
+
+
+ INIntentParameterPromptDialogCustom
+
+ INIntentParameterPromptDialogFormatString
+ What content to post?
+ INIntentParameterPromptDialogFormatStringID
+ HZSGTr
+ INIntentParameterPromptDialogType
+ Primary
+
+
+ INIntentParameterSupportsResolution
+
+ INIntentParameterTag
+ 1
+ INIntentParameterType
+ String
+
+
+ INIntentParameterConfigurable
+
+ INIntentParameterCustomDisambiguation
+
+ INIntentParameterDisplayName
+ Visibility
+ INIntentParameterDisplayNameID
+ ZbSjzC
+ INIntentParameterDisplayPriority
+ 2
+ INIntentParameterEnumType
+ PostVisibility
+ INIntentParameterEnumTypeNamespace
+ BvMBE4
+ INIntentParameterMetadata
+
+ INIntentParameterMetadataDefaultValue
+ public
+
+ INIntentParameterName
+ visibility
+ INIntentParameterPromptDialogs
+
+
+ INIntentParameterPromptDialogCustom
+
+ INIntentParameterPromptDialogType
+ Configuration
+
+
+ INIntentParameterPromptDialogCustom
+
+ INIntentParameterPromptDialogType
+ Primary
+
+
+ INIntentParameterPromptDialogCustom
+
+ INIntentParameterPromptDialogFormatString
+ There are ${count} options matching ‘${visibility}’.
+ INIntentParameterPromptDialogFormatStringID
+ apSxMG
+ INIntentParameterPromptDialogType
+ DisambiguationIntroduction
+
+
+ INIntentParameterPromptDialogCustom
+
+ INIntentParameterPromptDialogFormatString
+ Just to confirm, you wanted ‘${visibility}’?
+ INIntentParameterPromptDialogFormatStringID
+ oGiqmY
+ INIntentParameterPromptDialogType
+ Confirmation
+
+
+ INIntentParameterSupportsResolution
+
+ INIntentParameterTag
+ 3
+ INIntentParameterType
+ Integer
+
+
+ INIntentResponse
+
+ INIntentResponseCodes
+
+
+ INIntentResponseCodeConciseFormatString
+ Post was sent successfully.
+ INIntentResponseCodeConciseFormatStringID
+ k7dbKQ
+ INIntentResponseCodeFormatString
+ Post was sent successfully.
+ INIntentResponseCodeFormatStringID
+ ryJLwG
+ INIntentResponseCodeName
+ success
+ INIntentResponseCodeSuccess
+
+
+
+ INIntentResponseCodeConciseFormatString
+ Posting failed
+ INIntentResponseCodeConciseFormatStringID
+ HdGikU
+ INIntentResponseCodeFormatString
+ Posting failed. ${failureReason}
+ INIntentResponseCodeFormatStringID
+ gfePDu
+ INIntentResponseCodeName
+ failure
+
+
+ INIntentResponseLastParameterTag
+ 7
+ INIntentResponseOutput
+ post
+ INIntentResponseParameters
+
+
+ INIntentResponseParameterDisplayName
+ Post
+ INIntentResponseParameterDisplayNameID
+ ZKJSNu
+ INIntentResponseParameterDisplayPriority
+ 1
+ INIntentResponseParameterName
+ post
+ INIntentResponseParameterObjectType
+ Post
+ INIntentResponseParameterObjectTypeNamespace
+ BvMBE4
+ INIntentResponseParameterTag
+ 6
+ INIntentResponseParameterType
+ Object
+
+
+ INIntentResponseParameterDisplayName
+ Failure Reason
+ INIntentResponseParameterDisplayNameID
+ KDNTJ4
+ INIntentResponseParameterDisplayPriority
+ 2
+ INIntentResponseParameterName
+ failureReason
+ INIntentResponseParameterTag
+ 7
+ INIntentResponseParameterType
+ String
+
+
+
+ INIntentTitle
+ Post on Mastodon
+ INIntentTitleID
+ 16wxgf
+ INIntentType
+ Custom
+ INIntentVerb
+ Post
+
+
+ INTypes
+
+
+ INTypeDisplayName
+ Post
+ INTypeDisplayNameID
+ RxSqsb
+ INTypeLastPropertyTag
+ 102
+ INTypeName
+ Post
+ INTypeProperties
+
+
+ INTypePropertyDefault
+
+ INTypePropertyDisplayPriority
+ 1
+ INTypePropertyName
+ identifier
+ INTypePropertyTag
+ 1
+ INTypePropertyType
+ String
+
+
+ INTypePropertyDefault
+
+ INTypePropertyDisplayPriority
+ 2
+ INTypePropertyName
+ displayString
+ INTypePropertyTag
+ 2
+ INTypePropertyType
+ String
+
+
+ INTypePropertyDefault
+
+ INTypePropertyDisplayPriority
+ 3
+ INTypePropertyName
+ pronunciationHint
+ INTypePropertyTag
+ 3
+ INTypePropertyType
+ String
+
+
+ INTypePropertyDefault
+
+ INTypePropertyDisplayPriority
+ 4
+ INTypePropertyName
+ alternativeSpeakableMatches
+ INTypePropertySupportsMultipleValues
+
+ INTypePropertyTag
+ 4
+ INTypePropertyType
+ SpeakableString
+
+
+ INTypePropertyDisplayName
+ URL
+ INTypePropertyDisplayNameID
+ rM6dvp
+ INTypePropertyDisplayPriority
+ 5
+ INTypePropertyName
+ url
+ INTypePropertyTag
+ 101
+ INTypePropertyType
+ URL
+
+
+
+
+
+
diff --git a/CoreDataStack/Entity/HomeTimelineIndex.swift b/CoreDataStack/Entity/HomeTimelineIndex.swift
index 10b00aaa0..d52d0c3cd 100644
--- a/CoreDataStack/Entity/HomeTimelineIndex.swift
+++ b/CoreDataStack/Entity/HomeTimelineIndex.swift
@@ -65,7 +65,7 @@ extension HomeTimelineIndex {
public let domain: String
public let userID: String
- public init(domain: String,userID: String) {
+ public init(domain: String, userID: String) {
self.identifier = UUID().uuidString + "@" + domain
self.domain = domain
self.userID = userID
@@ -80,10 +80,20 @@ extension HomeTimelineIndex: Managed {
}
extension HomeTimelineIndex {
- public static func predicate(userID: String) -> NSPredicate {
+ static func predicate(domain: String) -> NSPredicate {
+ return NSPredicate(format: "%K == %@", #keyPath(HomeTimelineIndex.domain), domain)
+ }
+
+ static func predicate(userID: MastodonUser.ID) -> NSPredicate {
return NSPredicate(format: "%K == %@", #keyPath(HomeTimelineIndex.userID), userID)
}
-
+
+ public static func predicate(domain: String, userID: MastodonUser.ID) -> NSPredicate {
+ return NSCompoundPredicate(andPredicateWithSubpredicates: [
+ predicate(domain: domain),
+ predicate(userID: userID)
+ ])
+ }
public static func notDeleted() -> NSPredicate {
return NSPredicate(format: "%K == nil", #keyPath(HomeTimelineIndex.deletedAt))
diff --git a/Localization/ios-infoPlist.json b/Localization/ios-infoPlist.json
index f25dbcc0e..c6db73de0 100644
--- a/Localization/ios-infoPlist.json
+++ b/Localization/ios-infoPlist.json
@@ -1,4 +1,6 @@
{
"NSCameraUsageDescription": "Used to take photo for post status",
- "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library"
-}
\ No newline at end of file
+ "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library",
+ "NewPostShortcutItemTitle": "New Post",
+ "SearchShortcutItemTitle": "Search"
+}
diff --git a/Mastodon.xcodeproj/project.pbxproj b/Mastodon.xcodeproj/project.pbxproj
index f1351b859..e4b6635c0 100644
--- a/Mastodon.xcodeproj/project.pbxproj
+++ b/Mastodon.xcodeproj/project.pbxproj
@@ -175,6 +175,9 @@
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */; };
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; };
B914FC6B0B8AF18573C0B291 /* Pods_NotificationService.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 374AA339A20E0FAC75BCDA6D /* Pods_NotificationService.framework */; };
+ BBAC710E327AF1EE1DB36A4E /* Pods_MastodonIntent.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F4C94BD75C96D0EFF5F6D961 /* Pods_MastodonIntent.framework */; };
+ DB0009A626AEE5DC009B9D2D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */; settings = {ATTRIBUTES = (no_codegen, ); }; };
+ DB0009A726AEE5DC009B9D2D /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */; };
DB00CA972632DDB600A54956 /* CommonOSLog in Frameworks */ = {isa = PBXBuildFile; productRef = DB00CA962632DDB600A54956 /* CommonOSLog */; };
DB0140BD25C40D7500F9F3CF /* CommonOSLog in Frameworks */ = {isa = PBXBuildFile; productRef = DB0140BC25C40D7500F9F3CF /* CommonOSLog */; };
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140CE25C42AEE00F9F3CF /* OSLog.swift */; };
@@ -374,6 +377,11 @@
DB8AF55025C13703002E6C99 /* MainTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF54F25C13703002E6C99 /* MainTabBarController.swift */; };
DB8AF55D25C138B7002E6C99 /* UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF55C25C138B7002E6C99 /* UIViewController.swift */; };
DB8AF56825C13E2A002E6C99 /* HomeTimelineIndex.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8AF56725C13E2A002E6C99 /* HomeTimelineIndex.swift */; };
+ DB8FABC726AEC7B2008E5AF4 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB8FAB9E26AEC3A2008E5AF4 /* Intents.framework */; };
+ DB8FABCA26AEC7B2008E5AF4 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB8FABC926AEC7B2008E5AF4 /* IntentHandler.swift */; };
+ DB8FABCE26AEC7B2008E5AF4 /* MastodonIntent.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = DB8FABC626AEC7B2008E5AF4 /* MastodonIntent.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
+ DB8FABD726AEC873008E5AF4 /* AppShared.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB68047F2637CD4C00430867 /* AppShared.framework */; };
+ DB8FABDC26AEC87B008E5AF4 /* CoreDataStack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB89B9EE25C10FD0008580ED /* CoreDataStack.framework */; };
DB9282B225F3222800823B15 /* PickServerEmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB9282B125F3222800823B15 /* PickServerEmptyStateView.swift */; };
DB92CF7225E7BB98002C1017 /* PollOptionTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB92CF7125E7BB98002C1017 /* PollOptionTableViewCell.swift */; };
DB938EE62623F50700E5B6C1 /* ThreadViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB938EE52623F50700E5B6C1 /* ThreadViewController.swift */; };
@@ -455,6 +463,17 @@
DBB525642612C988002F1F29 /* MeProfileViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB525632612C988002F1F29 /* MeProfileViewModel.swift */; };
DBB5256E2612D5A1002F1F29 /* ProfileStatusDashboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB5256D2612D5A1002F1F29 /* ProfileStatusDashboardView.swift */; };
DBB525852612D6DD002F1F29 /* ProfileStatusDashboardMeterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB525842612D6DD002F1F29 /* ProfileStatusDashboardMeterView.swift */; };
+ DBB8AB4626AECDE200F6D281 /* SendPostIntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB8AB4526AECDE200F6D281 /* SendPostIntentHandler.swift */; };
+ DBB8AB4826AED09C00F6D281 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DBB8AB4726AED09C00F6D281 /* MastodonSDK */; };
+ DBB8AB4A26AED0B500F6D281 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB8AB4926AED0B500F6D281 /* APIService.swift */; };
+ DBB8AB4C26AED11300F6D281 /* APIService+APIError.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98337E25C9452D00AD9700 /* APIService+APIError.swift */; };
+ DBB8AB4D26AED12B00F6D281 /* Strings.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338525C945ED00AD9700 /* Strings.swift */; };
+ DBB8AB4E26AED12E00F6D281 /* Assets.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB98338625C945ED00AD9700 /* Assets.swift */; };
+ DBB8AB4F26AED13F00F6D281 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DB427DDE25BAA00100D1B89D /* Assets.xcassets */; };
+ DBB8AB5026AED14400F6D281 /* Localizable.stringsdict in Resources */ = {isa = PBXBuildFile; fileRef = DB564BCE269F2F83001E39A7 /* Localizable.stringsdict */; };
+ DBB8AB5126AED14600F6D281 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB3D100F25BAA75E00EAA174 /* Localizable.strings */; };
+ DBB8AB5226AED1B300F6D281 /* APIService+Status+Publish.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF07A26A6BCE8006D7ED1 /* APIService+Status+Publish.swift */; };
+ DBB8AB5326AED25100F6D281 /* MastodonAuthenticationBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBFEF07626A691FB006D7ED1 /* MastodonAuthenticationBox.swift */; };
DBB9759C262462E1004620BD /* ThreadMetaView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBB9759B262462E1004620BD /* ThreadMetaView.swift */; };
DBBC24A826A52F9000398BB9 /* ComposeToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBBC24A726A52F9000398BB9 /* ComposeToolbarView.swift */; };
DBBC24AA26A5301B00398BB9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = DBBC24A926A5301B00398BB9 /* MastodonSDK */; };
@@ -624,6 +643,27 @@
remoteGlobalIDString = DB89B9ED25C10FD0008580ED;
remoteInfo = CoreDataStack;
};
+ DB8FABCC26AEC7B2008E5AF4 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DB8FABC526AEC7B2008E5AF4;
+ remoteInfo = MastodonIntent;
+ };
+ DB8FABD926AEC873008E5AF4 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DB68047E2637CD4C00430867;
+ remoteInfo = AppShared;
+ };
+ DB8FABDE26AEC87B008E5AF4 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = DB89B9ED25C10FD0008580ED;
+ remoteInfo = CoreDataStack;
+ };
DBC6461A26A170AB00B0E31B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
@@ -673,6 +713,7 @@
dstPath = "";
dstSubfolderSpec = 13;
files = (
+ DB8FABCE26AEC7B2008E5AF4 /* MastodonIntent.appex in Embed App Extensions */,
DBC6461C26A170AB00B0E31B /* ShareActionExtension.appex in Embed App Extensions */,
DBF8AE1A263293E400C9C23C /* NotificationService.appex in Embed App Extensions */,
);
@@ -703,6 +744,7 @@
0FB3D31D25E534C700AAD544 /* PickServerCategoryCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCategoryCollectionViewCell.swift; sourceTree = ""; };
0FB3D33125E5F50E00AAD544 /* PickServerSearchCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerSearchCell.swift; sourceTree = ""; };
0FB3D33725E6401400AAD544 /* PickServerCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerCell.swift; sourceTree = ""; };
+ 159AC43EFE0A1F95FCB358A4 /* Pods-MastodonIntent.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.release.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.release.xcconfig"; sourceTree = ""; };
164F0EBB267D4FE400249499 /* BoopSound.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = BoopSound.caf; sourceTree = ""; };
1D6D967E77A5357E2C6110D9 /* Pods-Mastodon.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - debug.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - debug.xcconfig"; sourceTree = ""; };
2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+PublicTimeline.swift"; sourceTree = ""; };
@@ -856,6 +898,7 @@
77EE917BC055E6621C0452B6 /* Pods-ShareActionExtension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShareActionExtension.debug.xcconfig"; path = "Target Support Files/Pods-ShareActionExtension/Pods-ShareActionExtension.debug.xcconfig"; sourceTree = ""; };
7CEFFAE9AF9284B13C0A758D /* Pods-MastodonTests.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.asdk - debug.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.asdk - debug.xcconfig"; sourceTree = ""; };
819CEC9DCAD8E8E7BD85A7BB /* Pods-Mastodon.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk.xcconfig"; sourceTree = ""; };
+ 861BE60ED27430771CFD578D /* Pods-MastodonIntent.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.debug.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.debug.xcconfig"; sourceTree = ""; };
8850E70A1D5FF51432E43653 /* Pods-Mastodon-MastodonUITests.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.asdk - release.xcconfig"; sourceTree = ""; };
8ED8C4B1F1BA2DCFF2926BB1 /* Pods-Mastodon-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-NotificationService/Pods-Mastodon-NotificationService.debug.xcconfig"; sourceTree = ""; };
9553C689FFA9EBC880CAB78D /* Pods-NotificationService.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.debug.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.debug.xcconfig"; sourceTree = ""; };
@@ -872,8 +915,12 @@
B44342AC2B6585F8295F1DDF /* Pods-Mastodon-NotificationService.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-NotificationService.release.xcconfig"; path = "Target Support Files/Pods-Mastodon-NotificationService/Pods-Mastodon-NotificationService.release.xcconfig"; sourceTree = ""; };
BB482D32A7B9825BF5327C4F /* Pods-Mastodon-MastodonUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-MastodonUITests.release.xcconfig"; path = "Target Support Files/Pods-Mastodon-MastodonUITests/Pods-Mastodon-MastodonUITests.release.xcconfig"; sourceTree = ""; };
BD7598A87F4497045EDEF252 /* Pods-Mastodon.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.asdk - release.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.asdk - release.xcconfig"; sourceTree = ""; };
+ C3789232A52F43529CA67E95 /* Pods-MastodonIntent.asdk - debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.asdk - debug.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.asdk - debug.xcconfig"; sourceTree = ""; };
CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D7D7CF93E262178800077512 /* Pods-Mastodon-AppShared.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon-AppShared.debug.xcconfig"; path = "Target Support Files/Pods-Mastodon-AppShared/Pods-Mastodon-AppShared.debug.xcconfig"; sourceTree = ""; };
+ DB0009A826AEE5DC009B9D2D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = Base; path = Base.lproj/Intents.intentdefinition; sourceTree = ""; };
+ DB0009AB26AEE5E3009B9D2D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Intents.strings; sourceTree = ""; };
+ DB0009AD26AEE5E4009B9D2D /* ar */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ar; path = ar.lproj/Intents.strings; sourceTree = ""; };
DB0140CE25C42AEE00F9F3CF /* OSLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSLog.swift; sourceTree = ""; };
DB023294267F0AB800031745 /* ASMetaEditableTextNode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ASMetaEditableTextNode.swift; sourceTree = ""; };
DB029E94266A20430062874E /* MastodonAuthenticationController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonAuthenticationController.swift; sourceTree = ""; };
@@ -923,7 +970,6 @@
DB3667A7268AE2900027D07F /* ComposeStatusPollItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusPollItem.swift; sourceTree = ""; };
DB3D0FED25BAA42200EAA174 /* MastodonSDK */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MastodonSDK; sourceTree = ""; };
DB3D100E25BAA75E00EAA174 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; };
- DB3F693926AA97BD00C883AB /* MetaTextKit */ = {isa = PBXFileReference; lastKnownFileType = folder; name = MetaTextKit; path = ../MetaTextKit; sourceTree = ""; };
DB427DD225BAA00100D1B89D /* Mastodon.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Mastodon.app; sourceTree = BUILT_PRODUCTS_DIR; };
DB427DD525BAA00100D1B89D /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
DB427DD725BAA00100D1B89D /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
@@ -1075,6 +1121,12 @@
DB8AF54F25C13703002E6C99 /* MainTabBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainTabBarController.swift; sourceTree = ""; };
DB8AF55C25C138B7002E6C99 /* UIViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIViewController.swift; sourceTree = ""; };
DB8AF56725C13E2A002E6C99 /* HomeTimelineIndex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeTimelineIndex.swift; sourceTree = ""; };
+ DB8FAB9E26AEC3A2008E5AF4 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; };
+ DB8FABA926AEC3A2008E5AF4 /* IntentsUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IntentsUI.framework; path = System/Library/Frameworks/IntentsUI.framework; sourceTree = SDKROOT; };
+ DB8FABC626AEC7B2008E5AF4 /* MastodonIntent.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = MastodonIntent.appex; sourceTree = BUILT_PRODUCTS_DIR; };
+ DB8FABC926AEC7B2008E5AF4 /* IntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentHandler.swift; sourceTree = ""; };
+ DB8FABCB26AEC7B2008E5AF4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ DB8FABD626AEC864008E5AF4 /* MastodonIntent.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = MastodonIntent.entitlements; sourceTree = ""; };
DB9282B125F3222800823B15 /* PickServerEmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PickServerEmptyStateView.swift; sourceTree = ""; };
DB92CF7125E7BB98002C1017 /* PollOptionTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PollOptionTableViewCell.swift; sourceTree = ""; };
DB938EE52623F50700E5B6C1 /* ThreadViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadViewController.swift; sourceTree = ""; };
@@ -1150,6 +1202,8 @@
DBB525632612C988002F1F29 /* MeProfileViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MeProfileViewModel.swift; sourceTree = ""; };
DBB5256D2612D5A1002F1F29 /* ProfileStatusDashboardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileStatusDashboardView.swift; sourceTree = ""; };
DBB525842612D6DD002F1F29 /* ProfileStatusDashboardMeterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileStatusDashboardMeterView.swift; sourceTree = ""; };
+ DBB8AB4526AECDE200F6D281 /* SendPostIntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendPostIntentHandler.swift; sourceTree = ""; };
+ DBB8AB4926AED0B500F6D281 /* APIService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIService.swift; sourceTree = ""; };
DBB9759B262462E1004620BD /* ThreadMetaView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreadMetaView.swift; sourceTree = ""; };
DBBC24A726A52F9000398BB9 /* ComposeToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeToolbarView.swift; sourceTree = ""; };
DBBC24AB26A53D9300398BB9 /* ComposeStatusContentTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeStatusContentTableViewCell.swift; sourceTree = ""; };
@@ -1238,6 +1292,8 @@
EE13214BC0246BE5210CCC10 /* Pods-AppShared.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AppShared.asdk.xcconfig"; path = "Target Support Files/Pods-AppShared/Pods-AppShared.asdk.xcconfig"; sourceTree = ""; };
F31E7502A7E3945B98C6CBAF /* Pods-NotificationService.asdk.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-NotificationService.asdk.xcconfig"; path = "Target Support Files/Pods-NotificationService/Pods-NotificationService.asdk.xcconfig"; sourceTree = ""; };
F4A2A2D7000E477CA459ADA9 /* Pods_AppShared.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AppShared.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ F4C94BD75C96D0EFF5F6D961 /* Pods_MastodonIntent.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MastodonIntent.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ F920AD4EC23B0D00F5CCA58E /* Pods-MastodonIntent.asdk - release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonIntent.asdk - release.xcconfig"; path = "Target Support Files/Pods-MastodonIntent/Pods-MastodonIntent.asdk - release.xcconfig"; sourceTree = ""; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -1309,6 +1365,18 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ DB8FABC326AEC7B2008E5AF4 /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DB8FABC726AEC7B2008E5AF4 /* Intents.framework in Frameworks */,
+ DB8FABDC26AEC87B008E5AF4 /* CoreDataStack.framework in Frameworks */,
+ DBB8AB4826AED09C00F6D281 /* MastodonSDK in Frameworks */,
+ DB8FABD726AEC873008E5AF4 /* AppShared.framework in Frameworks */,
+ BBAC710E327AF1EE1DB36A4E /* Pods_MastodonIntent.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
DBC6460F26A170AB00B0E31B /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@@ -1442,6 +1510,10 @@
6130CBE4B26E3C976ACC1688 /* Pods-ShareActionExtension.asdk - debug.xcconfig */,
5CE45680252519F42FEA2D13 /* Pods-ShareActionExtension.asdk - release.xcconfig */,
95AD0663479892A2109EEFD0 /* Pods-ShareActionExtension.release.xcconfig */,
+ 861BE60ED27430771CFD578D /* Pods-MastodonIntent.debug.xcconfig */,
+ C3789232A52F43529CA67E95 /* Pods-MastodonIntent.asdk - debug.xcconfig */,
+ F920AD4EC23B0D00F5CCA58E /* Pods-MastodonIntent.asdk - release.xcconfig */,
+ 159AC43EFE0A1F95FCB358A4 /* Pods-MastodonIntent.release.xcconfig */,
);
path = Pods;
sourceTree = "";
@@ -1789,6 +1861,9 @@
F4A2A2D7000E477CA459ADA9 /* Pods_AppShared.framework */,
374AA339A20E0FAC75BCDA6D /* Pods_NotificationService.framework */,
A32B0CACBF35F4CC3CFAA043 /* Pods_ShareActionExtension.framework */,
+ DB8FAB9E26AEC3A2008E5AF4 /* Intents.framework */,
+ DB8FABA926AEC3A2008E5AF4 /* IntentsUI.framework */,
+ F4C94BD75C96D0EFF5F6D961 /* Pods_MastodonIntent.framework */,
);
name = Frameworks;
sourceTree = "";
@@ -1958,9 +2033,9 @@
DB427DC925BAA00100D1B89D = {
isa = PBXGroup;
children = (
+ DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */,
DBF53F5F25C14E88008AAC7B /* Mastodon.xctestplan */,
DBF53F6025C14E9D008AAC7B /* MastodonSDK.xctestplan */,
- DB3F693926AA97BD00C883AB /* MetaTextKit */,
DB3D0FED25BAA42200EAA174 /* MastodonSDK */,
DB427DD425BAA00100D1B89D /* Mastodon */,
DB427DEB25BAA00100D1B89D /* MastodonTests */,
@@ -1970,6 +2045,7 @@
DB89B9FC25C10FD0008580ED /* CoreDataStackTests */,
DBF8AE14263293E400C9C23C /* NotificationService */,
DBC6461326A170AB00B0E31B /* ShareActionExtension */,
+ DB8FABC826AEC7B2008E5AF4 /* MastodonIntent */,
DB427DD325BAA00100D1B89D /* Products */,
1EBA4F56E920856A3FC84ACB /* Pods */,
3FE14AD363ED19AE7FF210A6 /* Frameworks */,
@@ -1988,6 +2064,7 @@
DBF8AE13263293E400C9C23C /* NotificationService.appex */,
DB68047F2637CD4C00430867 /* AppShared.framework */,
DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */,
+ DB8FABC626AEC7B2008E5AF4 /* MastodonIntent.appex */,
);
name = Products;
sourceTree = "";
@@ -2519,6 +2596,18 @@
path = Extension;
sourceTree = "";
};
+ DB8FABC826AEC7B2008E5AF4 /* MastodonIntent */ = {
+ isa = PBXGroup;
+ children = (
+ DB8FABD626AEC864008E5AF4 /* MastodonIntent.entitlements */,
+ DB8FABC926AEC7B2008E5AF4 /* IntentHandler.swift */,
+ DBB8AB4526AECDE200F6D281 /* SendPostIntentHandler.swift */,
+ DBB8AB4B26AED0B800F6D281 /* Service */,
+ DB8FABCB26AEC7B2008E5AF4 /* Info.plist */,
+ );
+ path = MastodonIntent;
+ sourceTree = "";
+ };
DB938EEB2623F52600E5B6C1 /* Thread */ = {
isa = PBXGroup;
children = (
@@ -2742,6 +2831,14 @@
path = View;
sourceTree = "";
};
+ DBB8AB4B26AED0B800F6D281 /* Service */ = {
+ isa = PBXGroup;
+ children = (
+ DBB8AB4926AED0B500F6D281 /* APIService.swift */,
+ );
+ path = Service;
+ sourceTree = "";
+ };
DBBC24BD26A5441A00398BB9 /* ThemeService */ = {
isa = PBXGroup;
children = (
@@ -2965,6 +3062,7 @@
DB6804852637CD4C00430867 /* PBXTargetDependency */,
DB6804CA2637CE3000430867 /* PBXTargetDependency */,
DBC6461B26A170AB00B0E31B /* PBXTargetDependency */,
+ DB8FABCD26AEC7B2008E5AF4 /* PBXTargetDependency */,
);
name = Mastodon;
packageProductDependencies = (
@@ -3087,6 +3185,29 @@
productReference = DB89B9F625C10FD0008580ED /* CoreDataStackTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
+ DB8FABC526AEC7B2008E5AF4 /* MastodonIntent */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = DB8FABCF26AEC7B2008E5AF4 /* Build configuration list for PBXNativeTarget "MastodonIntent" */;
+ buildPhases = (
+ 625308CC94CCF528BD373740 /* [CP] Check Pods Manifest.lock */,
+ DB8FABC226AEC7B2008E5AF4 /* Sources */,
+ DB8FABC326AEC7B2008E5AF4 /* Frameworks */,
+ DB8FABC426AEC7B2008E5AF4 /* Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ DB8FABDA26AEC873008E5AF4 /* PBXTargetDependency */,
+ DB8FABDF26AEC87B008E5AF4 /* PBXTargetDependency */,
+ );
+ name = MastodonIntent;
+ packageProductDependencies = (
+ DBB8AB4726AED09C00F6D281 /* MastodonSDK */,
+ );
+ productName = MastodonIntent;
+ productReference = DB8FABC626AEC7B2008E5AF4 /* MastodonIntent.appex */;
+ productType = "com.apple.product-type.app-extension";
+ };
DBC6461126A170AB00B0E31B /* ShareActionExtension */ = {
isa = PBXNativeTarget;
buildConfigurationList = DBC6462126A170AB00B0E31B /* Build configuration list for PBXNativeTarget "ShareActionExtension" */;
@@ -3171,6 +3292,9 @@
CreatedOnToolsVersion = 12.4;
TestTargetID = DB427DD125BAA00100D1B89D;
};
+ DB8FABC526AEC7B2008E5AF4 = {
+ CreatedOnToolsVersion = 12.5.1;
+ };
DBC6461126A170AB00B0E31B = {
CreatedOnToolsVersion = 12.5.1;
};
@@ -3217,6 +3341,7 @@
DB89B9F525C10FD0008580ED /* CoreDataStackTests */,
DBF8AE12263293E400C9C23C /* NotificationService */,
DBC6461126A170AB00B0E31B /* ShareActionExtension */,
+ DB8FABC526AEC7B2008E5AF4 /* MastodonIntent */,
);
};
/* End PBXProject section */
@@ -3273,6 +3398,16 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ DB8FABC426AEC7B2008E5AF4 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DBB8AB4F26AED13F00F6D281 /* Assets.xcassets in Resources */,
+ DBB8AB5126AED14600F6D281 /* Localizable.strings in Resources */,
+ DBB8AB5026AED14400F6D281 /* Localizable.stringsdict in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
DBC6461026A170AB00B0E31B /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
@@ -3333,6 +3468,28 @@
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Mastodon/Pods-Mastodon-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
+ 625308CC94CCF528BD373740 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-MastodonIntent-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
641DEA63EE5B048C9A551302 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -3700,6 +3857,7 @@
DB4481CC25EE2AFE00BEFB67 /* PollItem.swift in Sources */,
DB44767B260B3B8C00B66B82 /* CustomEmojiPickerInputView.swift in Sources */,
0F20222D261457EE000C64BF /* HashtagTimelineViewModel+LoadOldestState.swift in Sources */,
+ DB0009A626AEE5DC009B9D2D /* Intents.intentdefinition in Sources */,
5B90C462262599800002E742 /* SettingsSectionHeader.swift in Sources */,
DB44768B260B3F2100B66B82 /* CustomEmojiPickerItem.swift in Sources */,
2DF75BA125D0E29D00694EC8 /* StatusProvider+StatusTableViewCellDelegate.swift in Sources */,
@@ -3982,6 +4140,22 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
+ DB8FABC226AEC7B2008E5AF4 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ DB0009A726AEE5DC009B9D2D /* Intents.intentdefinition in Sources */,
+ DBB8AB4E26AED12E00F6D281 /* Assets.swift in Sources */,
+ DBB8AB4626AECDE200F6D281 /* SendPostIntentHandler.swift in Sources */,
+ DBB8AB5326AED25100F6D281 /* MastodonAuthenticationBox.swift in Sources */,
+ DBB8AB4A26AED0B500F6D281 /* APIService.swift in Sources */,
+ DBB8AB4C26AED11300F6D281 /* APIService+APIError.swift in Sources */,
+ DBB8AB4D26AED12B00F6D281 /* Strings.swift in Sources */,
+ DBB8AB5226AED1B300F6D281 /* APIService+Status+Publish.swift in Sources */,
+ DB8FABCA26AEC7B2008E5AF4 /* IntentHandler.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
DBC6460E26A170AB00B0E31B /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@@ -4077,6 +4251,21 @@
target = DB89B9ED25C10FD0008580ED /* CoreDataStack */;
targetProxy = DB89BA0125C10FD0008580ED /* PBXContainerItemProxy */;
};
+ DB8FABCD26AEC7B2008E5AF4 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DB8FABC526AEC7B2008E5AF4 /* MastodonIntent */;
+ targetProxy = DB8FABCC26AEC7B2008E5AF4 /* PBXContainerItemProxy */;
+ };
+ DB8FABDA26AEC873008E5AF4 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DB68047E2637CD4C00430867 /* AppShared */;
+ targetProxy = DB8FABD926AEC873008E5AF4 /* PBXContainerItemProxy */;
+ };
+ DB8FABDF26AEC87B008E5AF4 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = DB89B9ED25C10FD0008580ED /* CoreDataStack */;
+ targetProxy = DB8FABDE26AEC87B008E5AF4 /* PBXContainerItemProxy */;
+ };
DBC6461B26A170AB00B0E31B /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DBC6461126A170AB00B0E31B /* ShareActionExtension */;
@@ -4100,6 +4289,16 @@
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
+ DB0009A926AEE5DC009B9D2D /* Intents.intentdefinition */ = {
+ isa = PBXVariantGroup;
+ children = (
+ DB0009A826AEE5DC009B9D2D /* Base */,
+ DB0009AB26AEE5E3009B9D2D /* en */,
+ DB0009AD26AEE5E4009B9D2D /* ar */,
+ );
+ name = Intents.intentdefinition;
+ sourceTree = "";
+ };
DB2B3ABE25E37E15007045F9 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
@@ -4206,6 +4405,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ INTENTS_CODEGEN_LANGUAGE = Swift;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
@@ -4262,6 +4462,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ INTENTS_CODEGEN_LANGUAGE = Swift;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
@@ -4281,7 +4482,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@@ -4289,7 +4490,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -4308,7 +4509,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@@ -4316,7 +4517,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -4530,7 +4731,6 @@
DB89BA0A25C10FD0008580ED /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = CoreDataStackTests/Info.plist;
@@ -4550,7 +4750,6 @@
DB89BA0B25C10FD0008580ED /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = CoreDataStackTests/Info.plist;
@@ -4567,13 +4766,109 @@
};
name = Release;
};
+ DB8FABD026AEC7B2008E5AF4 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 861BE60ED27430771CFD578D /* Pods-MastodonIntent.debug.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 47;
+ DEVELOPMENT_TEAM = 5Z4GVSS33P;
+ INFOPLIST_FILE = MastodonIntent/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ MARKETING_VERSION = 0.9.4;
+ PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.MastodonIntent;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 1;
+ };
+ name = Debug;
+ };
+ DB8FABD126AEC7B2008E5AF4 /* ASDK - Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = C3789232A52F43529CA67E95 /* Pods-MastodonIntent.asdk - debug.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 47;
+ DEVELOPMENT_TEAM = 5Z4GVSS33P;
+ INFOPLIST_FILE = MastodonIntent/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ MARKETING_VERSION = 0.9.4;
+ PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.MastodonIntent;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 1;
+ };
+ name = "ASDK - Debug";
+ };
+ DB8FABD226AEC7B2008E5AF4 /* ASDK - Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = F920AD4EC23B0D00F5CCA58E /* Pods-MastodonIntent.asdk - release.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 47;
+ DEVELOPMENT_TEAM = 5Z4GVSS33P;
+ INFOPLIST_FILE = MastodonIntent/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ MARKETING_VERSION = 0.9.4;
+ PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.MastodonIntent;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 1;
+ };
+ name = "ASDK - Release";
+ };
+ DB8FABD326AEC7B2008E5AF4 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 159AC43EFE0A1F95FCB358A4 /* Pods-MastodonIntent.release.xcconfig */;
+ buildSettings = {
+ CODE_SIGN_ENTITLEMENTS = MastodonIntent/MastodonIntent.entitlements;
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 47;
+ DEVELOPMENT_TEAM = 5Z4GVSS33P;
+ INFOPLIST_FILE = MastodonIntent/Info.plist;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ "@executable_path/../../Frameworks",
+ );
+ MARKETING_VERSION = 0.9.4;
+ PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.MastodonIntent;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SKIP_INSTALL = YES;
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = "APP_EXTENSION $(inherited)";
+ SWIFT_VERSION = 5.0;
+ TARGETED_DEVICE_FAMILY = 1;
+ };
+ name = Release;
+ };
DBC6461D26A170AB00B0E31B /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 77EE917BC055E6621C0452B6 /* Pods-ShareActionExtension.debug.xcconfig */;
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4581,7 +4876,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -4597,7 +4892,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4605,7 +4900,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -4621,7 +4916,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4629,7 +4924,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -4645,7 +4940,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = ShareActionExtension/ShareActionExtension.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = ShareActionExtension/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4653,7 +4948,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.ShareActionExtension;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -4715,6 +5010,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ INTENTS_CODEGEN_LANGUAGE = Swift;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
@@ -4735,7 +5031,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@@ -4743,7 +5039,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -4827,7 +5123,6 @@
DBCBCC132680BE3E000F5B51 /* ASDK - Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = CoreDataStackTests/Info.plist;
@@ -4850,7 +5145,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -4858,7 +5153,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -4950,6 +5245,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
+ INTENTS_CODEGEN_LANGUAGE = Swift;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
@@ -4969,7 +5265,7 @@
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = Mastodon/Info.plist;
@@ -4977,7 +5273,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -5061,7 +5357,6 @@
DBCBCC2326818F6F000F5B51 /* ASDK - Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
- ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
CODE_SIGN_STYLE = Automatic;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = CoreDataStackTests/Info.plist;
@@ -5084,7 +5379,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -5092,7 +5387,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -5138,7 +5433,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -5146,7 +5441,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -5161,7 +5456,7 @@
buildSettings = {
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 45;
+ CURRENT_PROJECT_VERSION = 47;
DEVELOPMENT_TEAM = 5Z4GVSS33P;
INFOPLIST_FILE = NotificationService/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
@@ -5169,7 +5464,7 @@
"@executable_path/Frameworks",
"@executable_path/../../Frameworks",
);
- MARKETING_VERSION = 0.9.3;
+ MARKETING_VERSION = 0.9.4;
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
@@ -5258,6 +5553,17 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ DB8FABCF26AEC7B2008E5AF4 /* Build configuration list for PBXNativeTarget "MastodonIntent" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ DB8FABD026AEC7B2008E5AF4 /* Debug */,
+ DB8FABD126AEC7B2008E5AF4 /* ASDK - Debug */,
+ DB8FABD226AEC7B2008E5AF4 /* ASDK - Release */,
+ DB8FABD326AEC7B2008E5AF4 /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
DBC6462126A170AB00B0E31B /* Build configuration list for PBXNativeTarget "ShareActionExtension" */ = {
isa = XCConfigurationList;
buildConfigurations = (
@@ -5482,6 +5788,10 @@
package = DBB525062611EAC0002F1F29 /* XCRemoteSwiftPackageReference "Tabman" */;
productName = Tabman;
};
+ DBB8AB4726AED09C00F6D281 /* MastodonSDK */ = {
+ isa = XCSwiftPackageProductDependency;
+ productName = MastodonSDK;
+ };
DBBC24A926A5301B00398BB9 /* MastodonSDK */ = {
isa = XCSwiftPackageProductDependency;
productName = MastodonSDK;
diff --git a/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - ASDK.xcscheme b/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - ASDK.xcscheme
new file mode 100644
index 000000000..4ce52bd58
--- /dev/null
+++ b/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - ASDK.xcscheme
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - Release.xcscheme b/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - Release.xcscheme
new file mode 100644
index 000000000..15ecdcbe9
--- /dev/null
+++ b/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon - Release.xcscheme
@@ -0,0 +1,110 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon.xcscheme b/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon.xcscheme
new file mode 100644
index 000000000..70507b96c
--- /dev/null
+++ b/Mastodon.xcodeproj/xcshareddata/xcschemes/Mastodon.xcscheme
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Mastodon.xcodeproj/xcshareddata/xcschemes/NotificationService.xcscheme b/Mastodon.xcodeproj/xcshareddata/xcschemes/NotificationService.xcscheme
new file mode 100644
index 000000000..b64bfc894
--- /dev/null
+++ b/Mastodon.xcodeproj/xcshareddata/xcschemes/NotificationService.xcscheme
@@ -0,0 +1,96 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist
index d28d5cdd8..d5b0a1e96 100644
--- a/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist
+++ b/Mastodon.xcodeproj/xcuserdata/mainasuk.xcuserdatad/xcschemes/xcschememanagement.plist
@@ -7,12 +7,12 @@
AppShared.xcscheme_^#shared#^_
orderHint
- 20
+ 31
CoreDataStack.xcscheme_^#shared#^_
orderHint
- 22
+ 30
Mastodon - ASDK.xcscheme_^#shared#^_
@@ -34,15 +34,30 @@
orderHint
0
+ MastodonIntent.xcscheme_^#shared#^_
+
+ orderHint
+ 29
+
+ MastodonIntents.xcscheme_^#shared#^_
+
+ orderHint
+ 35
+
+ MastodonIntentsUI.xcscheme_^#shared#^_
+
+ orderHint
+ 34
+
NotificationService.xcscheme_^#shared#^_
orderHint
- 24
+ 3
ShareActionExtension.xcscheme_^#shared#^_
orderHint
- 23
+ 28
SuppressBuildableAutocreation
diff --git a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved
index dc848b695..c6a46992b 100644
--- a/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved
+++ b/Mastodon.xcworkspace/xcshareddata/swiftpm/Package.resolved
@@ -91,6 +91,15 @@
"version": "4.2.2"
}
},
+ {
+ "package": "MetaTextKit",
+ "repositoryURL": "https://github.com/TwidereProject/MetaTextKit.git",
+ "state": {
+ "branch": null,
+ "revision": "ccb54189b31d13868d979c33d43566912b765bbd",
+ "version": "2.1.0"
+ }
+ },
{
"package": "Nuke",
"repositoryURL": "https://github.com/kean/Nuke.git",
diff --git a/Mastodon/Coordinator/SceneCoordinator.swift b/Mastodon/Coordinator/SceneCoordinator.swift
index 5aac2b1b9..04804dde3 100644
--- a/Mastodon/Coordinator/SceneCoordinator.swift
+++ b/Mastodon/Coordinator/SceneCoordinator.swift
@@ -13,7 +13,7 @@ final public class SceneCoordinator {
private weak var scene: UIScene!
private weak var sceneDelegate: SceneDelegate!
private weak var appContext: AppContext!
- private weak var tabBarController: MainTabBarController!
+ private(set) weak var tabBarController: MainTabBarController!
let id = UUID().uuidString
diff --git a/Mastodon/Extension/CoreDataStack/Status.swift b/Mastodon/Extension/CoreDataStack/Status.swift
index 7b64e6a9d..1c329c852 100644
--- a/Mastodon/Extension/CoreDataStack/Status.swift
+++ b/Mastodon/Extension/CoreDataStack/Status.swift
@@ -24,7 +24,7 @@ extension Status.Property {
reblogsCount: NSNumber(value: entity.reblogsCount),
favouritesCount: NSNumber(value: entity.favouritesCount),
repliesCount: entity.repliesCount.flatMap { NSNumber(value: $0) },
- url: entity.uri,
+ url: entity.url ?? entity.uri,
inReplyToID: entity.inReplyToID,
inReplyToAccountID: entity.inReplyToAccountID,
language: entity.language,
diff --git a/Mastodon/Extension/MetaLabel.swift b/Mastodon/Extension/MetaLabel.swift
index 27f04e068..e5a588e15 100644
--- a/Mastodon/Extension/MetaLabel.swift
+++ b/Mastodon/Extension/MetaLabel.swift
@@ -26,7 +26,8 @@ extension MetaLabel {
layer.masksToBounds = true
textContainer.lineBreakMode = .byTruncatingTail
-
+ textContainer.lineFragmentPadding = 0
+
let font: UIFont
let textColor: UIColor
diff --git a/Mastodon/Info.plist b/Mastodon/Info.plist
index cbb93eabf..0201333cc 100644
--- a/Mastodon/Info.plist
+++ b/Mastodon/Info.plist
@@ -44,6 +44,10 @@
LSRequiresIPhoneOS
+ NSUserActivityTypes
+
+ SendPostIntent
+
UIApplicationSceneManifest
UIApplicationSupportsMultipleScenes
@@ -63,6 +67,25 @@
+ UIApplicationShortcutItems
+
+
+ UIApplicationShortcutItemIconSymbolName
+ square.and.pencil
+ UIApplicationShortcutItemTitle
+ NewPostShortcutItemTitle
+ UIApplicationShortcutItemType
+ org.joinmastodon.app.new-post
+
+
+ UIApplicationShortcutItemIconSymbolName
+ magnifyingglass
+ UIApplicationShortcutItemTitle
+ SearchShortcutItemTitle
+ UIApplicationShortcutItemType
+ org.joinmastodon.app.search
+
+
UIApplicationSupportsIndirectInputEvents
UILaunchStoryboardName
diff --git a/Mastodon/Mastodon.entitlements b/Mastodon/Mastodon.entitlements
index 0135ecdd2..153b958a3 100644
--- a/Mastodon/Mastodon.entitlements
+++ b/Mastodon/Mastodon.entitlements
@@ -4,6 +4,8 @@
aps-environment
development
+ com.apple.developer.siri
+
com.apple.security.application-groups
group.org.joinmastodon.app
diff --git a/Mastodon/Resources/ar.lproj/InfoPlist.strings b/Mastodon/Resources/ar.lproj/InfoPlist.strings
index 48566ae36..710865573 100644
--- a/Mastodon/Resources/ar.lproj/InfoPlist.strings
+++ b/Mastodon/Resources/ar.lproj/InfoPlist.strings
@@ -1,2 +1,4 @@
"NSCameraUsageDescription" = "Used to take photo for post status";
-"NSPhotoLibraryAddUsageDescription" = "Used to save photo into the Photo Library";
\ No newline at end of file
+"NSPhotoLibraryAddUsageDescription" = "Used to save photo into the Photo Library";
+"NewPostShortcutItemTitle" = "New Post";
+"SearchShortcutItemTitle" = "Search";
\ No newline at end of file
diff --git a/Mastodon/Resources/en.lproj/InfoPlist.strings b/Mastodon/Resources/en.lproj/InfoPlist.strings
index 48566ae36..710865573 100644
--- a/Mastodon/Resources/en.lproj/InfoPlist.strings
+++ b/Mastodon/Resources/en.lproj/InfoPlist.strings
@@ -1,2 +1,4 @@
"NSCameraUsageDescription" = "Used to take photo for post status";
-"NSPhotoLibraryAddUsageDescription" = "Used to save photo into the Photo Library";
\ No newline at end of file
+"NSPhotoLibraryAddUsageDescription" = "Used to save photo into the Photo Library";
+"NewPostShortcutItemTitle" = "New Post";
+"SearchShortcutItemTitle" = "Search";
\ No newline at end of file
diff --git a/Mastodon/Resources/en.lproj/infoPlist.strings b/Mastodon/Resources/en.lproj/infoPlist.strings
deleted file mode 100644
index 48566ae36..000000000
--- a/Mastodon/Resources/en.lproj/infoPlist.strings
+++ /dev/null
@@ -1,2 +0,0 @@
-"NSCameraUsageDescription" = "Used to take photo for post status";
-"NSPhotoLibraryAddUsageDescription" = "Used to save photo into the Photo Library";
\ No newline at end of file
diff --git a/Mastodon/Scene/Compose/ComposeViewModel.swift b/Mastodon/Scene/Compose/ComposeViewModel.swift
index 52af2cb67..9964dd2ba 100644
--- a/Mastodon/Scene/Compose/ComposeViewModel.swift
+++ b/Mastodon/Scene/Compose/ComposeViewModel.swift
@@ -18,6 +18,8 @@ final class ComposeViewModel: NSObject {
static let composeContentLimit: Int = 500
var disposeBag = Set()
+
+ let id = UUID()
// input
let context: AppContext
diff --git a/Mastodon/Scene/Compose/View/ReplicaStatusView.swift b/Mastodon/Scene/Compose/View/ReplicaStatusView.swift
index 8948a2f6a..cb34f3ded 100644
--- a/Mastodon/Scene/Compose/View/ReplicaStatusView.swift
+++ b/Mastodon/Scene/Compose/View/ReplicaStatusView.swift
@@ -99,6 +99,21 @@ final class ReplicaStatusView: UIView {
metaText.textView.textContainer.lineFragmentPadding = 0
metaText.textView.textContainerInset = .zero
metaText.textView.layer.masksToBounds = false
+
+ metaText.paragraphStyle = {
+ let style = NSMutableParagraphStyle()
+ style.lineSpacing = 5
+ style.paragraphSpacing = 8
+ return style
+ }()
+ metaText.textAttributes = [
+ .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 17, weight: .regular)),
+ .foregroundColor: Asset.Colors.Label.primary.color,
+ ]
+ metaText.linkAttributes = [
+ .font: UIFontMetrics(forTextStyle: .body).scaledFont(for: .systemFont(ofSize: 17, weight: .semibold)),
+ .foregroundColor: Asset.Colors.brandBlue.color,
+ ]
return metaText
}()
diff --git a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift
index 611e95368..0bf1e1041 100644
--- a/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift
+++ b/Mastodon/Scene/HomeTimeline/HomeTimelineViewModel.swift
@@ -120,9 +120,10 @@ final class HomeTimelineViewModel: NSObject {
.sink { [weak self] activeMastodonAuthentication in
guard let self = self else { return }
guard let mastodonAuthentication = activeMastodonAuthentication else { return }
- let activeMastodonUserID = mastodonAuthentication.userID
+ let domain = mastodonAuthentication.domain
+ let userID = mastodonAuthentication.userID
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: [
- HomeTimelineIndex.predicate(userID: activeMastodonUserID),
+ HomeTimelineIndex.predicate(domain: domain, userID: userID),
HomeTimelineIndex.notDeleted()
])
self.timelinePredicate.value = predicate
diff --git a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift
index eb6e06a04..c45a0f648 100644
--- a/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift
+++ b/Mastodon/Scene/Profile/Header/View/ProfileHeaderView.swift
@@ -440,6 +440,7 @@ extension ProfileHeaderView {
bringSubviewToFront(bannerContainerView)
bringSubviewToFront(nameContainerStackView)
+ bioMetaText.textView.delegate = self
bioMetaText.textView.linkDelegate = self
let avatarImageViewSingleTapGestureRecognizer = UITapGestureRecognizer.singleTapGestureRecognizer
@@ -522,6 +523,19 @@ extension ProfileHeaderView {
}
}
+// MARK: - UITextViewDelegate
+extension ProfileHeaderView: UITextViewDelegate {
+ func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
+ switch textView {
+ case bioMetaText.textView:
+ return false
+ default:
+ assertionFailure()
+ return true
+ }
+ }
+}
+
// MARK: - MetaTextViewDelegate
extension ProfileHeaderView: MetaTextViewDelegate {
func metaTextView(_ metaTextView: MetaTextView, didSelectMeta meta: Meta) {
diff --git a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift
index 0445ee017..dba71b50e 100644
--- a/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift
+++ b/Mastodon/Scene/Search/SearchDetail/SearchResult/SearchResultViewModel+State.swift
@@ -101,7 +101,7 @@ extension SearchResultViewModel.State {
maxID: nil,
minID: nil,
excludeUnreviewed: nil,
- resolve: nil,
+ resolve: true,
limit: nil,
offset: _offset,
following: nil
diff --git a/Mastodon/Scene/Search/SearchDetail/TableViewCell/SearchResultTableViewCell.swift b/Mastodon/Scene/Search/SearchDetail/TableViewCell/SearchResultTableViewCell.swift
index 4c1753ff0..d0106a334 100644
--- a/Mastodon/Scene/Search/SearchDetail/TableViewCell/SearchResultTableViewCell.swift
+++ b/Mastodon/Scene/Search/SearchDetail/TableViewCell/SearchResultTableViewCell.swift
@@ -160,7 +160,7 @@ extension SearchResultTableViewCell {
let metaContent = PlaintextMetaContent(string: name)
_titleLabel.configure(content: metaContent)
}
- _subTitleLabel.text = account.acct
+ _subTitleLabel.text = "@" + account.acct
}
func config(with account: MastodonUser) {
@@ -173,14 +173,15 @@ extension SearchResultTableViewCell {
let metaContent = PlaintextMetaContent(string: account.displayNameWithFallback)
_titleLabel.configure(content: metaContent)
}
- _subTitleLabel.text = account.acct
+ _subTitleLabel.text = "@" + account.acct
}
func config(with tag: Mastodon.Entity.Tag) {
configure(with: AvatarConfigurableViewConfiguration(avatarImageURL: nil))
let image = UIImage(systemName: "number.circle.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 34, weight: .regular))!.withRenderingMode(.alwaysTemplate)
_imageView.image = image
- _titleLabel.text = "#" + tag.name
+ let metaContent = PlaintextMetaContent(string: "#" + tag.name)
+ _titleLabel.configure(content: metaContent)
guard let histories = tag.history else {
_subTitleLabel.text = ""
return
@@ -195,7 +196,8 @@ extension SearchResultTableViewCell {
configure(with: AvatarConfigurableViewConfiguration(avatarImageURL: nil))
let image = UIImage(systemName: "number.circle.fill", withConfiguration: UIImage.SymbolConfiguration(pointSize: 34, weight: .regular))!.withRenderingMode(.alwaysTemplate)
_imageView.image = image
- _titleLabel.text = "# " + tag.name
+ let metaContent = PlaintextMetaContent(string: "#" + tag.name)
+ _titleLabel.configure(content: metaContent)
guard let histories = tag.histories?.sorted(by: {
$0.createAt.compare($1.createAt) == .orderedAscending
}) else {
diff --git a/Mastodon/Service/APIService/APIService+APIError.swift b/Mastodon/Service/APIService/APIService+APIError.swift
index 37235c2cb..352be4ff4 100644
--- a/Mastodon/Service/APIService/APIService+APIError.swift
+++ b/Mastodon/Service/APIService/APIService+APIError.swift
@@ -40,7 +40,7 @@ extension APIService {
// MARK: - LocalizedError
extension APIService.APIError: LocalizedError {
- var errorDescription: String? {
+ public var errorDescription: String? {
switch errorReason {
case .authenticationMissing: return "Fail to Authenticatie"
case .badRequest: return "Bad Request"
diff --git a/Mastodon/Service/APIService/APIService+App.swift b/Mastodon/Service/APIService/APIService+App.swift
index b5b1d8686..1575e6561 100644
--- a/Mastodon/Service/APIService/APIService+App.swift
+++ b/Mastodon/Service/APIService/APIService+App.swift
@@ -19,11 +19,13 @@ extension APIService {
private static let clientName = "Mastodon for iOS"
#endif
+ private static let appWebsite = "https://joinmastodon.org/apps"
+
func createApplication(domain: String) -> AnyPublisher, Error> {
let query = Mastodon.API.App.CreateQuery(
clientName: APIService.clientName,
redirectURIs: MastodonAuthenticationController.callbackURL,
- website: nil
+ website: APIService.appWebsite
)
return Mastodon.API.App.create(
session: session,
diff --git a/Mastodon/Service/APIService/APIService+Reblog.swift b/Mastodon/Service/APIService/APIService+Reblog.swift
index fd0206145..88da60f25 100644
--- a/Mastodon/Service/APIService/APIService+Reblog.swift
+++ b/Mastodon/Service/APIService/APIService+Reblog.swift
@@ -104,7 +104,17 @@ extension APIService {
APIService.CoreData.merge(status: oldStatus, entity: entity.reblog ?? entity, requestMastodonUser: requestMastodonUser, domain: mastodonAuthenticationBox.domain, networkDate: response.networkDate)
switch reblogKind {
case .undoReblog:
+ // update reblogged status
oldStatus.update(reblogsCount: NSNumber(value: max(0, oldStatus.reblogsCount.intValue - 1)))
+
+ // remove reblog from statuses
+ let reblogFroms = oldStatus.reblogFrom?.filter { status in
+ return status.author.domain == domain && status.author.id == requestMastodonUserID
+ } ?? Set()
+ reblogFroms.forEach { reblogFrom in
+ managedObjectContext.delete(reblogFrom)
+ }
+
default:
break
}
diff --git a/Mastodon/Service/AuthenticationService.swift b/Mastodon/Service/AuthenticationService.swift
index f6ece0440..0b3c3fa11 100644
--- a/Mastodon/Service/AuthenticationService.swift
+++ b/Mastodon/Service/AuthenticationService.swift
@@ -130,6 +130,19 @@ extension AuthenticationService {
appAuthorization: Mastodon.API.OAuth.Authorization(accessToken: mastodonAuthentication.appAccessToken),
userAuthorization: Mastodon.API.OAuth.Authorization(accessToken: mastodonAuthentication.userAccessToken)
)
+
+ // remove home timeline indexes
+ let homeTimelineIndexRequest = HomeTimelineIndex.sortedFetchRequest
+ homeTimelineIndexRequest.predicate = HomeTimelineIndex.predicate(
+ domain: mastodonAuthentication.domain,
+ userID: mastodonAuthentication.userID
+ )
+ let homeTimelineIndexes = managedObjectContext.safeFetch(homeTimelineIndexRequest)
+ for homeTimelineIndex in homeTimelineIndexes {
+ managedObjectContext.delete(homeTimelineIndex)
+ }
+
+ // remove user authentication
managedObjectContext.delete(mastodonAuthentication)
isSignOut = true
}
diff --git a/Mastodon/Service/StatusPublishService.swift b/Mastodon/Service/StatusPublishService.swift
index f797d9f6a..ed894f933 100644
--- a/Mastodon/Service/StatusPublishService.swift
+++ b/Mastodon/Service/StatusPublishService.swift
@@ -7,6 +7,7 @@
import os.log
import Foundation
+import Intents
import Combine
import CoreData
import CoreDataStack
@@ -52,7 +53,7 @@ extension StatusPublishService {
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: composeViewModelDidUpdate", ((#file as NSString).lastPathComponent), #line, #function)
self.composeViewModelDidUpdatePublisher.send()
-
+
switch state {
case is ComposeViewModel.PublishState.Finish:
self.remove(composeViewModel: composeViewModel)
diff --git a/Mastodon/Supporting Files/SceneDelegate.swift b/Mastodon/Supporting Files/SceneDelegate.swift
index 6964eef91..05ff8850a 100644
--- a/Mastodon/Supporting Files/SceneDelegate.swift
+++ b/Mastodon/Supporting Files/SceneDelegate.swift
@@ -5,6 +5,7 @@
// Created by MainasuK Cirno on 2021/1/22.
//
+import os.log
import UIKit
import Combine
import CoreDataStack
@@ -25,6 +26,9 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var fpsIndicator: FPSIndicator?
#endif
+ var savedShortCutItem: UIApplicationShortcutItem?
+
+ let logger = Logger(subsystem: "SceneDelegate", category: "logic")
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
@@ -55,6 +59,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
sceneCoordinator.setup()
sceneCoordinator.setupOnboardingIfNeeds(animated: false)
window.makeKeyAndVisible()
+
+ if let shortcutItem = connectionOptions.shortcutItem {
+ // Save it off for later when we become active.
+ savedShortCutItem = shortcutItem
+ }
UserDefaults.shared.observe(\.customUserInterfaceStyle, options: [.initial, .new]) { [weak self] defaults, _ in
guard let self = self else { return }
@@ -84,6 +93,11 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// trigger status filter update
AppContext.shared.statusFilterService.filterUpdatePublisher.send()
+
+ if let shortcutItem = savedShortCutItem {
+ _ = handler(shortcutItem: shortcutItem)
+ savedShortCutItem = nil
+ }
}
func sceneWillResignActive(_ scene: UIScene) {
@@ -103,7 +117,40 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
AppContext.shared.audioPlaybackService.pauseIfNeed()
}
+}
+extension SceneDelegate {
+ func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
+ completionHandler(handler(shortcutItem: shortcutItem))
+ }
+
+ private func handler(shortcutItem: UIApplicationShortcutItem) -> Bool {
+ logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): \(shortcutItem.type)")
+
+ switch shortcutItem.type {
+ case "org.joinmastodon.app.new-post":
+ if coordinator?.tabBarController.topMost is ComposeViewController {
+ logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): composing…")
+ } else {
+ let composeViewModel = ComposeViewModel(context: AppContext.shared, composeKind: .post)
+ coordinator?.present(scene: .compose(viewModel: composeViewModel), from: nil, transition: .modal(animated: true, completion: nil))
+ logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): present compose scene")
+ }
+ case "org.joinmastodon.app.search":
+ coordinator?.switchToTabBar(tab: .search)
+ logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): select search tab")
+
+ if let searchViewController = coordinator?.tabBarController.topMost as? SearchViewController {
+ searchViewController.searchBarTapPublisher.send()
+ logger.debug("\((#file as NSString).lastPathComponent, privacy: .public)[\(#line, privacy: .public)], \(#function, privacy: .public): trigger search")
+ }
+ default:
+ assertionFailure()
+ break
+ }
+
+ return true
+ }
}
#if DEBUG
diff --git a/MastodonIntent/Info.plist b/MastodonIntent/Info.plist
new file mode 100644
index 000000000..3c4a6e453
--- /dev/null
+++ b/MastodonIntent/Info.plist
@@ -0,0 +1,42 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ MastodonIntent
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ $(PRODUCT_BUNDLE_PACKAGE_TYPE)
+ CFBundleShortVersionString
+ $(MARKETING_VERSION)
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ NSExtension
+
+ NSExtensionAttributes
+
+ IntentsRestrictedWhileLocked
+
+ IntentsRestrictedWhileProtectedDataUnavailable
+
+ IntentsSupported
+
+ SendPostIntent
+
+
+ NSExtensionPointIdentifier
+ com.apple.intents-service
+ NSExtensionPrincipalClass
+ $(PRODUCT_MODULE_NAME).IntentHandler
+
+
+
diff --git a/MastodonIntent/IntentHandler.swift b/MastodonIntent/IntentHandler.swift
new file mode 100644
index 000000000..cb8588d67
--- /dev/null
+++ b/MastodonIntent/IntentHandler.swift
@@ -0,0 +1,23 @@
+//
+// IntentHandler.swift
+// MastodonIntent
+//
+// Created by Cirno MainasuK on 2021-7-26.
+//
+
+import Intents
+
+class IntentHandler: INExtension {
+
+ override func handler(for intent: INIntent) -> Any {
+ // This is the default implementation. If you want different objects to handle different intents,
+ // you can override this and return the handler you want for that particular intent.
+ switch intent {
+ case is SendPostIntent:
+ return SendPostIntentHandler()
+ default:
+ return self
+ }
+ }
+
+}
diff --git a/MastodonIntent/MastodonIntent.entitlements b/MastodonIntent/MastodonIntent.entitlements
new file mode 100644
index 000000000..c3bc3f816
--- /dev/null
+++ b/MastodonIntent/MastodonIntent.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.security.application-groups
+
+ group.org.joinmastodon.app
+
+
+
diff --git a/MastodonIntent/SendPostIntentHandler.swift b/MastodonIntent/SendPostIntentHandler.swift
new file mode 100644
index 000000000..6d5f739fb
--- /dev/null
+++ b/MastodonIntent/SendPostIntentHandler.swift
@@ -0,0 +1,99 @@
+//
+// SendPostIntentHandler.swift
+// MastodonIntent
+//
+// Created by Cirno MainasuK on 2021-7-26.
+//
+
+import Foundation
+import Intents
+import Combine
+import CoreData
+import CoreDataStack
+import MastodonSDK
+
+final class SendPostIntentHandler: NSObject, SendPostIntentHandling {
+
+ var disposeBag = Set()
+
+ lazy var coreDataStack = CoreDataStack()
+ lazy var managedObjectContext = coreDataStack.persistentContainer.viewContext
+
+ func handle(intent: SendPostIntent, completion: @escaping (SendPostIntentResponse) -> Void) {
+ managedObjectContext.performAndWait {
+ let request = MastodonAuthentication.sortedFetchRequest
+ let authentications = (try? self.managedObjectContext.fetch(request)) ?? []
+ let _authentication = authentications.sorted(by: { $0.activedAt > $1.activedAt }).first
+
+ guard let authentication = _authentication else {
+ let failureReason = APIService.APIError.implicit(.authenticationMissing).errorDescription ?? "Fail to Send Post"
+ completion(SendPostIntentResponse.failure(failureReason: failureReason))
+ return
+ }
+
+ let box = MastodonAuthenticationBox(
+ domain: authentication.domain,
+ userID: authentication.userID,
+ appAuthorization: .init(accessToken: authentication.appAccessToken),
+ userAuthorization: .init(accessToken: authentication.userAccessToken)
+ )
+
+ let visibility: Mastodon.Entity.Status.Visibility = {
+ switch intent.visibility {
+ case .unknown: return .public
+ case .public: return .public
+ case .followersOnly: return .private
+ }
+ }()
+ let query = Mastodon.API.Statuses.PublishStatusQuery(
+ status: intent.content,
+ mediaIDs: nil,
+ pollOptions: nil,
+ pollExpiresIn: nil,
+ inReplyToID: nil,
+ sensitive: nil,
+ spoilerText: nil,
+ visibility: visibility
+ )
+
+ APIService.shared.publishStatus(
+ domain: box.domain,
+ query: query,
+ mastodonAuthenticationBox: box
+ )
+ .sink { _completion in
+ switch _completion {
+ case .failure(let error):
+ let failureReason = error.localizedDescription
+ completion(SendPostIntentResponse.failure(failureReason: failureReason))
+ case .finished:
+ break
+ }
+ } receiveValue: { response in
+ let post = Post(identifier: response.value.id, display: intent.content ?? "")
+ post.url = URL(string: response.value.url ?? response.value.uri)
+ let result = SendPostIntentResponse(code: .success, userActivity: nil)
+ result.post = post
+ completion(result)
+ }
+ .store(in: &disposeBag)
+ }
+
+ }
+
+ func resolveContent(for intent: SendPostIntent, with completion: @escaping (INStringResolutionResult) -> Void) {
+ guard let content = intent.content, !content.isEmpty else {
+ completion(.needsValue())
+ return
+ }
+
+ completion(.success(with: content))
+ }
+
+ func resolveVisibility(for intent: SendPostIntent, with completion: @escaping (PostVisibilityResolutionResult) -> Void) {
+ completion(.success(with: intent.visibility))
+ }
+
+
+
+}
diff --git a/MastodonIntent/Service/APIService.swift b/MastodonIntent/Service/APIService.swift
new file mode 100644
index 000000000..0733c08d4
--- /dev/null
+++ b/MastodonIntent/Service/APIService.swift
@@ -0,0 +1,33 @@
+//
+// APIService.swift
+// MastodonIntent
+//
+// Created by Cirno MainasuK on 2021-7-26.
+//
+
+import os.log
+import Foundation
+import Combine
+import CoreData
+import CoreDataStack
+import MastodonSDK
+
+// Replica APIService for share extension
+final class APIService {
+
+ var disposeBag = Set()
+
+ static let shared = APIService()
+
+ // internal
+ let session: URLSession
+
+ // output
+ let error = PassthroughSubject()
+
+ private init() {
+ self.session = URLSession(configuration: .default)
+ }
+
+}
+
diff --git a/Podfile b/Podfile
index cd7dbfd62..b976556b9 100644
--- a/Podfile
+++ b/Podfile
@@ -39,6 +39,11 @@ target 'ShareActionExtension' do
use_frameworks!
end
+target 'MastodonIntent' do
+ # Comment the next line if you don't want to use dynamic frameworks
+ use_frameworks!
+end
+
target 'AppShared' do
# Comment the next line if you don't want to use dynamic frameworks
use_frameworks!
diff --git a/Podfile.lock b/Podfile.lock
index 516d109e8..c59f13a9b 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -78,6 +78,6 @@ SPEC CHECKSUMS:
Texture: 2f109e937850d94d1d07232041c9c7313ccddb81
"UITextField+Shake": 298ac5a0f239d731bdab999b19b628c956ca0ac3
-PODFILE CHECKSUM: adf1bf30957525fcafb99001323d1c6ad9995b9d
+PODFILE CHECKSUM: 1ea006302c191ee52b6206e4957aa78fb66fe690
COCOAPODS: 1.10.1
diff --git a/ar.lproj/Intents.strings b/ar.lproj/Intents.strings
new file mode 100644
index 000000000..770b74bb9
--- /dev/null
+++ b/ar.lproj/Intents.strings
@@ -0,0 +1,52 @@
+"16wxgf" = "Post on Mastodon";
+
+"751xkl" = "Text Content";
+
+"CsR7G2" = "Post";
+
+"HZSGTr" = "What content to post?";
+
+"HdGikU" = "Posting failed";
+
+"KDNTJ4" = "Failure Reason";
+
+"RHxKOw" = "Send Post with text content";
+
+"RxSqsb" = "Post";
+
+"WCIR3D" = "Post ${content} on Mastodon";
+
+"ZKJSNu" = "Post";
+
+"ZS1XaK" = "${content}";
+
+"ZbSjzC" = "Visibility";
+
+"Zo4jgJ" = "Post Visibility";
+
+"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’.";
+
+"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’.";
+
+"ayoYEb-dYQ5NN" = "${content}, Public";
+
+"ayoYEb-ehFLjY" = "${content}, Followers Only";
+
+"dUyuGg" = "Post";
+
+"dYQ5NN" = "Public";
+
+"ehFLjY" = "Followers Only";
+
+"gfePDu" = "Posting failed. ${failureReason}";
+
+"k7dbKQ" = "Post was sent successfully.";
+
+"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?";
+
+"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?";
+
+"rM6dvp" = "URL";
+
+"ryJLwG" = "Post was sent successfully. ";
+
diff --git a/en.lproj/Intents.strings b/en.lproj/Intents.strings
new file mode 100644
index 000000000..770b74bb9
--- /dev/null
+++ b/en.lproj/Intents.strings
@@ -0,0 +1,52 @@
+"16wxgf" = "Post on Mastodon";
+
+"751xkl" = "Text Content";
+
+"CsR7G2" = "Post";
+
+"HZSGTr" = "What content to post?";
+
+"HdGikU" = "Posting failed";
+
+"KDNTJ4" = "Failure Reason";
+
+"RHxKOw" = "Send Post with text content";
+
+"RxSqsb" = "Post";
+
+"WCIR3D" = "Post ${content} on Mastodon";
+
+"ZKJSNu" = "Post";
+
+"ZS1XaK" = "${content}";
+
+"ZbSjzC" = "Visibility";
+
+"Zo4jgJ" = "Post Visibility";
+
+"apSxMG-dYQ5NN" = "There are ${count} options matching ‘Public’.";
+
+"apSxMG-ehFLjY" = "There are ${count} options matching ‘Followers Only’.";
+
+"ayoYEb-dYQ5NN" = "${content}, Public";
+
+"ayoYEb-ehFLjY" = "${content}, Followers Only";
+
+"dUyuGg" = "Post";
+
+"dYQ5NN" = "Public";
+
+"ehFLjY" = "Followers Only";
+
+"gfePDu" = "Posting failed. ${failureReason}";
+
+"k7dbKQ" = "Post was sent successfully.";
+
+"oGiqmY-dYQ5NN" = "Just to confirm, you wanted ‘Public’?";
+
+"oGiqmY-ehFLjY" = "Just to confirm, you wanted ‘Followers Only’?";
+
+"rM6dvp" = "URL";
+
+"ryJLwG" = "Post was sent successfully. ";
+