Merge pull request #878 from mastodon/IOS-31_ActionExtension
Feature: Action Extension
This commit is contained in:
commit
37678caed5
|
@ -805,5 +805,10 @@
|
||||||
"unfollow": "Unfollow"
|
"unfollow": "Unfollow"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"extension": {
|
||||||
|
"open_in": {
|
||||||
|
"invalid_link_error": "This doesn't seem to be a valid Mastodon link."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,14 @@
|
||||||
2A3F6FE5292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */; };
|
2A3F6FE5292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */; };
|
||||||
2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */; };
|
2A506CF4292CD85800059C37 /* FollowedTagsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */; };
|
||||||
2A506CF6292D040100059C37 /* HashtagTimelineHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */; };
|
2A506CF6292D040100059C37 /* HashtagTimelineHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */; };
|
||||||
|
2A64515E29642A8A00CD8B8A /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2A6451022964223800CD8B8A /* UniformTypeIdentifiers.framework */; };
|
||||||
|
2A64516929642A8B00CD8B8A /* OpenInActionExtension.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 2A64515D29642A8A00CD8B8A /* OpenInActionExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
|
2A71F541296DBDA80049F54A /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2A71F53D296DBDA80049F54A /* Media.xcassets */; };
|
||||||
|
2A71F542296DBDA80049F54A /* Action.js in Resources */ = {isa = PBXBuildFile; fileRef = 2A71F53E296DBDA80049F54A /* Action.js */; };
|
||||||
|
2A71F543296DBDA80049F54A /* ActionRequestHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A71F53F296DBDA80049F54A /* ActionRequestHandler.swift */; };
|
||||||
2A76F75C2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */; };
|
2A76F75C2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */; };
|
||||||
2A82294F29262EE000D2A1F7 /* AppContext+NextAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */; };
|
2A82294F29262EE000D2A1F7 /* AppContext+NextAccount.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */; };
|
||||||
|
2A90A157296EEE500026C155 /* MastodonSDKDynamic in Frameworks */ = {isa = PBXBuildFile; productRef = 2A90A156296EEE500026C155 /* MastodonSDKDynamic */; };
|
||||||
2AB12E4629362F27006BC925 /* DataSourceFacade+Translate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB12E4529362F27006BC925 /* DataSourceFacade+Translate.swift */; };
|
2AB12E4629362F27006BC925 /* DataSourceFacade+Translate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AB12E4529362F27006BC925 /* DataSourceFacade+Translate.swift */; };
|
||||||
2AE244482927831100BDBF7C /* UIImage+SFSymbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */; };
|
2AE244482927831100BDBF7C /* UIImage+SFSymbols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2AE244472927831100BDBF7C /* UIImage+SFSymbols.swift */; };
|
||||||
2D198643261BF09500F0B013 /* SearchResultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198642261BF09500F0B013 /* SearchResultItem.swift */; };
|
2D198643261BF09500F0B013 /* SearchResultItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D198642261BF09500F0B013 /* SearchResultItem.swift */; };
|
||||||
|
@ -454,6 +460,13 @@
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXContainerItemProxy section */
|
/* Begin PBXContainerItemProxy section */
|
||||||
|
2A64516729642A8B00CD8B8A /* PBXContainerItemProxy */ = {
|
||||||
|
isa = PBXContainerItemProxy;
|
||||||
|
containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
|
||||||
|
proxyType = 1;
|
||||||
|
remoteGlobalIDString = 2A64515C29642A8A00CD8B8A;
|
||||||
|
remoteInfo = FollowActionExtension;
|
||||||
|
};
|
||||||
DB427DE925BAA00100D1B89D /* PBXContainerItemProxy */ = {
|
DB427DE925BAA00100D1B89D /* PBXContainerItemProxy */ = {
|
||||||
isa = PBXContainerItemProxy;
|
isa = PBXContainerItemProxy;
|
||||||
containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
|
containerPortal = DB427DCA25BAA00100D1B89D /* Project object */;
|
||||||
|
@ -492,6 +505,16 @@
|
||||||
/* End PBXContainerItemProxy section */
|
/* End PBXContainerItemProxy section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
2A90A159296EEE500026C155 /* Embed Frameworks */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 10;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
name = "Embed Frameworks";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
9E44C7212967AD17004B2A72 /* Embed Frameworks */ = {
|
9E44C7212967AD17004B2A72 /* Embed Frameworks */ = {
|
||||||
isa = PBXCopyFilesBuildPhase;
|
isa = PBXCopyFilesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -521,6 +544,7 @@
|
||||||
dstSubfolderSpec = 13;
|
dstSubfolderSpec = 13;
|
||||||
files = (
|
files = (
|
||||||
DB8FABCE26AEC7B2008E5AF4 /* MastodonIntent.appex in Embed Foundation Extensions */,
|
DB8FABCE26AEC7B2008E5AF4 /* MastodonIntent.appex in Embed Foundation Extensions */,
|
||||||
|
2A64516929642A8B00CD8B8A /* OpenInActionExtension.appex in Embed Foundation Extensions */,
|
||||||
DBC6461C26A170AB00B0E31B /* ShareActionExtension.appex in Embed Foundation Extensions */,
|
DBC6461C26A170AB00B0E31B /* ShareActionExtension.appex in Embed Foundation Extensions */,
|
||||||
DBF8AE1A263293E400C9C23C /* NotificationService.appex in Embed Foundation Extensions */,
|
DBF8AE1A263293E400C9C23C /* NotificationService.appex in Embed Foundation Extensions */,
|
||||||
);
|
);
|
||||||
|
@ -553,6 +577,12 @@
|
||||||
2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsTableViewCell.swift; sourceTree = "<group>"; };
|
2A3F6FE4292F6E44002E6DA7 /* FollowedTagsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewController.swift; sourceTree = "<group>"; };
|
2A506CF3292CD85800059C37 /* FollowedTagsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowedTagsViewController.swift; sourceTree = "<group>"; };
|
||||||
2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderView.swift; sourceTree = "<group>"; };
|
2A506CF5292D040100059C37 /* HashtagTimelineHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderView.swift; sourceTree = "<group>"; };
|
||||||
|
2A6451022964223800CD8B8A /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; };
|
||||||
|
2A64515D29642A8A00CD8B8A /* OpenInActionExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = OpenInActionExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
2A71F53D296DBDA80049F54A /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = "<group>"; };
|
||||||
|
2A71F53E296DBDA80049F54A /* Action.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = Action.js; sourceTree = "<group>"; };
|
||||||
|
2A71F53F296DBDA80049F54A /* ActionRequestHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionRequestHandler.swift; sourceTree = "<group>"; };
|
||||||
|
2A71F540296DBDA80049F54A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderViewActionButton.swift; sourceTree = "<group>"; };
|
2A76F75B2930D94700B3388D /* HashtagTimelineHeaderViewActionButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HashtagTimelineHeaderViewActionButton.swift; sourceTree = "<group>"; };
|
||||||
2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+NextAccount.swift"; sourceTree = "<group>"; };
|
2A82294E29262EE000D2A1F7 /* AppContext+NextAccount.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppContext+NextAccount.swift"; sourceTree = "<group>"; };
|
||||||
2AB12E4529362F27006BC925 /* DataSourceFacade+Translate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Translate.swift"; sourceTree = "<group>"; };
|
2AB12E4529362F27006BC925 /* DataSourceFacade+Translate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DataSourceFacade+Translate.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -1108,6 +1138,15 @@
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
2A64515A29642A8A00CD8B8A /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
2A90A157296EEE500026C155 /* MastodonSDKDynamic in Frameworks */,
|
||||||
|
2A64515E29642A8A00CD8B8A /* UniformTypeIdentifiers.framework in Frameworks */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
DB427DCF25BAA00100D1B89D /* Frameworks */ = {
|
DB427DCF25BAA00100D1B89D /* Frameworks */ = {
|
||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -1291,6 +1330,17 @@
|
||||||
path = FollowedTags;
|
path = FollowedTags;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
2A71F53C296DBDA80049F54A /* OpenInActionExtension */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
2A71F53D296DBDA80049F54A /* Media.xcassets */,
|
||||||
|
2A71F53E296DBDA80049F54A /* Action.js */,
|
||||||
|
2A71F53F296DBDA80049F54A /* ActionRequestHandler.swift */,
|
||||||
|
2A71F540296DBDA80049F54A /* Info.plist */,
|
||||||
|
);
|
||||||
|
path = OpenInActionExtension;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
2D152A8A25C295B8009AA50C /* Content */ = {
|
2D152A8A25C295B8009AA50C /* Content */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
@ -1509,6 +1559,7 @@
|
||||||
F4A2A2D7000E477CA459ADA9 /* Pods_AppShared.framework */,
|
F4A2A2D7000E477CA459ADA9 /* Pods_AppShared.framework */,
|
||||||
DB8FAB9E26AEC3A2008E5AF4 /* Intents.framework */,
|
DB8FAB9E26AEC3A2008E5AF4 /* Intents.framework */,
|
||||||
DB8FABA926AEC3A2008E5AF4 /* IntentsUI.framework */,
|
DB8FABA926AEC3A2008E5AF4 /* IntentsUI.framework */,
|
||||||
|
2A6451022964223800CD8B8A /* UniformTypeIdentifiers.framework */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -1826,6 +1877,7 @@
|
||||||
DBF8AE14263293E400C9C23C /* NotificationService */,
|
DBF8AE14263293E400C9C23C /* NotificationService */,
|
||||||
DBC6461326A170AB00B0E31B /* ShareActionExtension */,
|
DBC6461326A170AB00B0E31B /* ShareActionExtension */,
|
||||||
DB8FABC826AEC7B2008E5AF4 /* MastodonIntent */,
|
DB8FABC826AEC7B2008E5AF4 /* MastodonIntent */,
|
||||||
|
2A71F53C296DBDA80049F54A /* OpenInActionExtension */,
|
||||||
DB427DD325BAA00100D1B89D /* Products */,
|
DB427DD325BAA00100D1B89D /* Products */,
|
||||||
1EBA4F56E920856A3FC84ACB /* Pods */,
|
1EBA4F56E920856A3FC84ACB /* Pods */,
|
||||||
3FE14AD363ED19AE7FF210A6 /* Frameworks */,
|
3FE14AD363ED19AE7FF210A6 /* Frameworks */,
|
||||||
|
@ -1843,6 +1895,7 @@
|
||||||
DBF8AE13263293E400C9C23C /* NotificationService.appex */,
|
DBF8AE13263293E400C9C23C /* NotificationService.appex */,
|
||||||
DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */,
|
DBC6461226A170AB00B0E31B /* ShareActionExtension.appex */,
|
||||||
DB8FABC626AEC7B2008E5AF4 /* MastodonIntent.appex */,
|
DB8FABC626AEC7B2008E5AF4 /* MastodonIntent.appex */,
|
||||||
|
2A64515D29642A8A00CD8B8A /* OpenInActionExtension.appex */,
|
||||||
);
|
);
|
||||||
name = Products;
|
name = Products;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -2784,6 +2837,27 @@
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
|
2A64515C29642A8A00CD8B8A /* OpenInActionExtension */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = 2A64516A29642A8B00CD8B8A /* Build configuration list for PBXNativeTarget "OpenInActionExtension" */;
|
||||||
|
buildPhases = (
|
||||||
|
2A64515929642A8A00CD8B8A /* Sources */,
|
||||||
|
2A64515A29642A8A00CD8B8A /* Frameworks */,
|
||||||
|
2A64515B29642A8A00CD8B8A /* Resources */,
|
||||||
|
2A90A159296EEE500026C155 /* Embed Frameworks */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = OpenInActionExtension;
|
||||||
|
packageProductDependencies = (
|
||||||
|
2A90A156296EEE500026C155 /* MastodonSDKDynamic */,
|
||||||
|
);
|
||||||
|
productName = FollowActionExtension;
|
||||||
|
productReference = 2A64515D29642A8A00CD8B8A /* OpenInActionExtension.appex */;
|
||||||
|
productType = "com.apple.product-type.app-extension";
|
||||||
|
};
|
||||||
DB427DD125BAA00100D1B89D /* Mastodon */ = {
|
DB427DD125BAA00100D1B89D /* Mastodon */ = {
|
||||||
isa = PBXNativeTarget;
|
isa = PBXNativeTarget;
|
||||||
buildConfigurationList = DB427DFC25BAA00100D1B89D /* Build configuration list for PBXNativeTarget "Mastodon" */;
|
buildConfigurationList = DB427DFC25BAA00100D1B89D /* Build configuration list for PBXNativeTarget "Mastodon" */;
|
||||||
|
@ -2805,6 +2879,7 @@
|
||||||
DBF8AE19263293E400C9C23C /* PBXTargetDependency */,
|
DBF8AE19263293E400C9C23C /* PBXTargetDependency */,
|
||||||
DBC6461B26A170AB00B0E31B /* PBXTargetDependency */,
|
DBC6461B26A170AB00B0E31B /* PBXTargetDependency */,
|
||||||
DB8FABCD26AEC7B2008E5AF4 /* PBXTargetDependency */,
|
DB8FABCD26AEC7B2008E5AF4 /* PBXTargetDependency */,
|
||||||
|
2A64516829642A8B00CD8B8A /* PBXTargetDependency */,
|
||||||
);
|
);
|
||||||
name = Mastodon;
|
name = Mastodon;
|
||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
|
@ -2923,9 +2998,12 @@
|
||||||
DB427DCA25BAA00100D1B89D /* Project object */ = {
|
DB427DCA25BAA00100D1B89D /* Project object */ = {
|
||||||
isa = PBXProject;
|
isa = PBXProject;
|
||||||
attributes = {
|
attributes = {
|
||||||
LastSwiftUpdateCheck = 1250;
|
LastSwiftUpdateCheck = 1420;
|
||||||
LastUpgradeCheck = 1400;
|
LastUpgradeCheck = 1400;
|
||||||
TargetAttributes = {
|
TargetAttributes = {
|
||||||
|
2A64515C29642A8A00CD8B8A = {
|
||||||
|
CreatedOnToolsVersion = 14.2;
|
||||||
|
};
|
||||||
DB427DD125BAA00100D1B89D = {
|
DB427DD125BAA00100D1B89D = {
|
||||||
CreatedOnToolsVersion = 12.4;
|
CreatedOnToolsVersion = 12.4;
|
||||||
LastSwiftMigration = 1300;
|
LastSwiftMigration = 1300;
|
||||||
|
@ -2995,11 +3073,21 @@
|
||||||
DBF8AE12263293E400C9C23C /* NotificationService */,
|
DBF8AE12263293E400C9C23C /* NotificationService */,
|
||||||
DBC6461126A170AB00B0E31B /* ShareActionExtension */,
|
DBC6461126A170AB00B0E31B /* ShareActionExtension */,
|
||||||
DB8FABC526AEC7B2008E5AF4 /* MastodonIntent */,
|
DB8FABC526AEC7B2008E5AF4 /* MastodonIntent */,
|
||||||
|
2A64515C29642A8A00CD8B8A /* OpenInActionExtension */,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
/* End PBXProject section */
|
/* End PBXProject section */
|
||||||
|
|
||||||
/* Begin PBXResourcesBuildPhase section */
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
2A64515B29642A8A00CD8B8A /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
2A71F541296DBDA80049F54A /* Media.xcassets in Resources */,
|
||||||
|
2A71F542296DBDA80049F54A /* Action.js in Resources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
DB427DD025BAA00100D1B89D /* Resources */ = {
|
DB427DD025BAA00100D1B89D /* Resources */ = {
|
||||||
isa = PBXResourcesBuildPhase;
|
isa = PBXResourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -3218,6 +3306,14 @@
|
||||||
/* End PBXShellScriptBuildPhase section */
|
/* End PBXShellScriptBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXSourcesBuildPhase section */
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
2A64515929642A8A00CD8B8A /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
2A71F543296DBDA80049F54A /* ActionRequestHandler.swift in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
DB427DCE25BAA00100D1B89D /* Sources */ = {
|
DB427DCE25BAA00100D1B89D /* Sources */ = {
|
||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
|
@ -3678,6 +3774,11 @@
|
||||||
/* End PBXSourcesBuildPhase section */
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
/* Begin PBXTargetDependency section */
|
/* Begin PBXTargetDependency section */
|
||||||
|
2A64516829642A8B00CD8B8A /* PBXTargetDependency */ = {
|
||||||
|
isa = PBXTargetDependency;
|
||||||
|
target = 2A64515C29642A8A00CD8B8A /* OpenInActionExtension */;
|
||||||
|
targetProxy = 2A64516729642A8B00CD8B8A /* PBXContainerItemProxy */;
|
||||||
|
};
|
||||||
DB427DEA25BAA00100D1B89D /* PBXTargetDependency */ = {
|
DB427DEA25BAA00100D1B89D /* PBXTargetDependency */ = {
|
||||||
isa = PBXTargetDependency;
|
isa = PBXTargetDependency;
|
||||||
target = DB427DD125BAA00100D1B89D /* Mastodon */;
|
target = DB427DD125BAA00100D1B89D /* Mastodon */;
|
||||||
|
@ -3833,6 +3934,123 @@
|
||||||
/* End PBXVariantGroup section */
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
/* Begin XCBuildConfiguration section */
|
/* Begin XCBuildConfiguration section */
|
||||||
|
2A64516B29642A8B00CD8B8A /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = Icon;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||||
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = OpenInActionExtension/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Open using Mastodon";
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.OpenInActionExtension;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
2A64516C29642A8B00CD8B8A /* Profile */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = Icon;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = OpenInActionExtension/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Open using Mastodon";
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.OpenInActionExtension;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Profile;
|
||||||
|
};
|
||||||
|
2A64516D29642A8B00CD8B8A /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = Icon;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = OpenInActionExtension/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Open using Mastodon";
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.OpenInActionExtension;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
2A64516E29642A8B00CD8B8A /* Release Snapshot */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = Icon;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
|
||||||
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
|
CODE_SIGN_STYLE = Automatic;
|
||||||
|
CURRENT_PROJECT_VERSION = 1;
|
||||||
|
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||||
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_FILE = OpenInActionExtension/Info.plist;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Open using Mastodon";
|
||||||
|
INFOPLIST_KEY_NSHumanReadableCopyright = "";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
"@executable_path/../../Frameworks",
|
||||||
|
);
|
||||||
|
MARKETING_VERSION = 1.0;
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.OpenInActionExtension;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
|
SWIFT_VERSION = 5.0;
|
||||||
|
TARGETED_DEVICE_FAMILY = "1,2";
|
||||||
|
};
|
||||||
|
name = "Release Snapshot";
|
||||||
|
};
|
||||||
DB427DFA25BAA00100D1B89D /* Debug */ = {
|
DB427DFA25BAA00100D1B89D /* Debug */ = {
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
@ -3959,6 +4177,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 2E1F6A67FDF9771D3E064FDC /* Pods-Mastodon.debug.xcconfig */;
|
baseConfigurationReference = 2E1F6A67FDF9771D3E064FDC /* Pods-Mastodon.debug.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
@ -3989,6 +4208,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 75E3471C898DDD9631729B6E /* Pods-Mastodon.release.xcconfig */;
|
baseConfigurationReference = 75E3471C898DDD9631729B6E /* Pods-Mastodon.release.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
@ -4176,6 +4396,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 7CB58D292DA7ACEF179A9050 /* Pods-Mastodon.profile.xcconfig */;
|
baseConfigurationReference = 7CB58D292DA7ACEF179A9050 /* Pods-Mastodon.profile.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
@ -4466,6 +4687,7 @@
|
||||||
isa = XCBuildConfiguration;
|
isa = XCBuildConfiguration;
|
||||||
baseConfigurationReference = 0655B257371274BEB7EB1C19 /* Pods-Mastodon.release snapshot.xcconfig */;
|
baseConfigurationReference = 0655B257371274BEB7EB1C19 /* Pods-Mastodon.release snapshot.xcconfig */;
|
||||||
buildSettings = {
|
buildSettings = {
|
||||||
|
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
|
||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
@ -4651,6 +4873,17 @@
|
||||||
/* End XCBuildConfiguration section */
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
/* Begin XCConfigurationList section */
|
/* Begin XCConfigurationList section */
|
||||||
|
2A64516A29642A8B00CD8B8A /* Build configuration list for PBXNativeTarget "OpenInActionExtension" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
2A64516B29642A8B00CD8B8A /* Debug */,
|
||||||
|
2A64516C29642A8B00CD8B8A /* Profile */,
|
||||||
|
2A64516D29642A8B00CD8B8A /* Release */,
|
||||||
|
2A64516E29642A8B00CD8B8A /* Release Snapshot */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
DB427DCD25BAA00100D1B89D /* Build configuration list for PBXProject "Mastodon" */ = {
|
DB427DCD25BAA00100D1B89D /* Build configuration list for PBXProject "Mastodon" */ = {
|
||||||
isa = XCConfigurationList;
|
isa = XCConfigurationList;
|
||||||
buildConfigurations = (
|
buildConfigurations = (
|
||||||
|
@ -4731,6 +4964,10 @@
|
||||||
/* End XCConfigurationList section */
|
/* End XCConfigurationList section */
|
||||||
|
|
||||||
/* Begin XCSwiftPackageProductDependency section */
|
/* Begin XCSwiftPackageProductDependency section */
|
||||||
|
2A90A156296EEE500026C155 /* MastodonSDKDynamic */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
productName = MastodonSDKDynamic;
|
||||||
|
};
|
||||||
357FEEAE29523D470021C9DC /* MastodonSDKDynamic */ = {
|
357FEEAE29523D470021C9DC /* MastodonSDKDynamic */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
productName = MastodonSDKDynamic;
|
productName = MastodonSDKDynamic;
|
||||||
|
|
|
@ -242,41 +242,56 @@ extension SceneDelegate {
|
||||||
|
|
||||||
if !UIApplication.shared.canOpenURL(url) { return }
|
if !UIApplication.shared.canOpenURL(url) { return }
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
print("source application = \(sendingAppID ?? "Unknown")")
|
print("source application = \(sendingAppID ?? "Unknown")")
|
||||||
print("url = \(url)")
|
print("url = \(url)")
|
||||||
|
#endif
|
||||||
|
|
||||||
switch url.host {
|
switch url.host {
|
||||||
case "post":
|
case "post":
|
||||||
showComposeViewController()
|
showComposeViewController()
|
||||||
case "profile":
|
case "profile":
|
||||||
let components = url.pathComponents
|
let components = url.pathComponents
|
||||||
if components.count == 2 && components[0] == "/" {
|
guard
|
||||||
let addr = components[1]
|
components.count == 2,
|
||||||
if let authContext = coordinator?.authContext {
|
components[0] == "/",
|
||||||
let profileViewModel = RemoteProfileViewModel(
|
let authContext = coordinator?.authContext
|
||||||
context: AppContext.shared,
|
else { return }
|
||||||
authContext: authContext,
|
|
||||||
acct: components[1]
|
let profileViewModel = RemoteProfileViewModel(
|
||||||
)
|
context: AppContext.shared,
|
||||||
self.coordinator?.present(
|
authContext: authContext,
|
||||||
scene: .profile(viewModel: profileViewModel),
|
acct: components[1]
|
||||||
from: nil,
|
)
|
||||||
transition: .show
|
self.coordinator?.present(
|
||||||
)
|
scene: .profile(viewModel: profileViewModel),
|
||||||
}
|
from: nil,
|
||||||
}
|
transition: .show
|
||||||
|
)
|
||||||
case "status":
|
case "status":
|
||||||
let components = url.pathComponents
|
let components = url.pathComponents
|
||||||
if components.count == 2 && components[0] == "/" {
|
guard
|
||||||
let statusId = components[1]
|
components.count == 2,
|
||||||
// View post from user
|
components[0] == "/",
|
||||||
if let authContext = coordinator?.authContext {
|
let authContext = coordinator?.authContext
|
||||||
let threadViewModel = RemoteThreadViewModel(context: AppContext.shared,
|
else { return }
|
||||||
authContext: authContext,
|
let statusId = components[1]
|
||||||
statusID: statusId)
|
// View post from user
|
||||||
coordinator?.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show)
|
let threadViewModel = RemoteThreadViewModel(
|
||||||
}
|
context: AppContext.shared,
|
||||||
}
|
authContext: authContext,
|
||||||
|
statusID: statusId
|
||||||
|
)
|
||||||
|
coordinator?.present(scene: .thread(viewModel: threadViewModel), from: nil, transition: .show)
|
||||||
|
case "search":
|
||||||
|
let queryItems = URLComponents(url: url, resolvingAgainstBaseURL: false)?.queryItems
|
||||||
|
guard
|
||||||
|
let authContext = coordinator?.authContext,
|
||||||
|
let searchQuery = queryItems?.first(where: { $0.name == "query" })?.value
|
||||||
|
else { return }
|
||||||
|
|
||||||
|
let viewModel = SearchDetailViewModel(authContext: authContext, initialSearchText: searchQuery)
|
||||||
|
coordinator?.present(scene: .searchDetail(viewModel: viewModel), from: nil, transition: .show)
|
||||||
default:
|
default:
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -469,6 +469,12 @@ public enum L10n {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
public enum Extension {
|
||||||
|
public enum OpenIn {
|
||||||
|
/// This doesn't seem to be a valid Mastodon link.
|
||||||
|
public static let invalidLinkError = L10n.tr("Localizable", "Extension.OpenIn.InvalidLinkError", fallback: "This doesn't seem to be a valid Mastodon link.")
|
||||||
|
}
|
||||||
|
}
|
||||||
public enum Scene {
|
public enum Scene {
|
||||||
public enum AccountList {
|
public enum AccountList {
|
||||||
/// Add Account
|
/// Add Account
|
||||||
|
|
|
@ -513,3 +513,4 @@ You can’t go wrong with any of our recommend servers, so regardless of which o
|
||||||
"Scene.Privacy.Button.confirm" = "I agree";
|
"Scene.Privacy.Button.confirm" = "I agree";
|
||||||
"Scene.Privacy.Policy.Ios" = "Privacy Policy - Mastodon for iOS";
|
"Scene.Privacy.Policy.Ios" = "Privacy Policy - Mastodon for iOS";
|
||||||
"Scene.Privacy.Policy.Server" = "Privacy Policy - %@";
|
"Scene.Privacy.Policy.Server" = "Privacy Policy - %@";
|
||||||
|
"Extension.OpenIn.InvalidLinkError" = "This doesn't seem to be a valid Mastodon link.";
|
||||||
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
//
|
||||||
|
// Action.js
|
||||||
|
// OpenInActionExtension
|
||||||
|
//
|
||||||
|
// Created by Marcus Kida on 03.01.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
var Action = function() {};
|
||||||
|
|
||||||
|
Action.prototype = {
|
||||||
|
|
||||||
|
run: function(arguments) {
|
||||||
|
var payload = {
|
||||||
|
"username": detectUsername(),
|
||||||
|
"url": document.documentURI
|
||||||
|
}
|
||||||
|
|
||||||
|
arguments.completionFunction(payload)
|
||||||
|
},
|
||||||
|
|
||||||
|
finalize: function(arguments) {
|
||||||
|
let alertMessage = arguments["alert"]
|
||||||
|
if (alertMessage) {
|
||||||
|
alert(alertMessage)
|
||||||
|
} else {
|
||||||
|
window.location = arguments["openURL"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
function detectUsername() {
|
||||||
|
var uriUsername = document.documentURI.match("(?:@([a-zA-Z0-9_]+)(@[a-zA-Z0-9_.-]+)?|#([^\\s.]+))")
|
||||||
|
|
||||||
|
if (Array.isArray(uriUsername)) {
|
||||||
|
return uriUsername[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
var querySelector = document.head.querySelector('[property="profile:username"]')
|
||||||
|
if (querySelector !== null && typeof querySelector === "object") {
|
||||||
|
return querySelector.content
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
var ExtensionPreprocessingJS = new Action
|
|
@ -0,0 +1,115 @@
|
||||||
|
//
|
||||||
|
// ActionRequestHandler.swift
|
||||||
|
// OpenInActionExtension
|
||||||
|
//
|
||||||
|
// Created by Marcus Kida on 03.01.23.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import UIKit
|
||||||
|
import MobileCoreServices
|
||||||
|
import UniformTypeIdentifiers
|
||||||
|
import MastodonSDK
|
||||||
|
import MastodonLocalization
|
||||||
|
|
||||||
|
class ActionRequestHandler: NSObject, NSExtensionRequestHandling {
|
||||||
|
var extensionContext: NSExtensionContext?
|
||||||
|
var cancellables = [AnyCancellable]()
|
||||||
|
|
||||||
|
func beginRequest(with context: NSExtensionContext) {
|
||||||
|
// Do not call super in an Action extension with no user interface
|
||||||
|
self.extensionContext = context
|
||||||
|
|
||||||
|
let itemProvider = context.inputItems
|
||||||
|
.compactMap({ $0 as? NSExtensionItem })
|
||||||
|
.reduce([NSItemProvider](), { partialResult, acc in
|
||||||
|
var nextResult = partialResult
|
||||||
|
nextResult += acc.attachments ?? []
|
||||||
|
return nextResult
|
||||||
|
})
|
||||||
|
.filter({ $0.hasItemConformingToTypeIdentifier(UTType.propertyList.identifier) })
|
||||||
|
.first
|
||||||
|
|
||||||
|
guard let itemProvider = itemProvider else {
|
||||||
|
return doneWithInvalidLink()
|
||||||
|
}
|
||||||
|
|
||||||
|
itemProvider.loadItem(forTypeIdentifier: UTType.propertyList.identifier, options: nil, completionHandler: { [weak self] item, error in
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
guard
|
||||||
|
let dictionary = item as? NSDictionary,
|
||||||
|
let results = dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as? NSDictionary
|
||||||
|
else {
|
||||||
|
self?.doneWithInvalidLink()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let username = results["username"] as? String {
|
||||||
|
self?.completeWithOpenUserProfile(username)
|
||||||
|
} else if let url = results["url"] as? String {
|
||||||
|
self?.continueWithSearch(url)
|
||||||
|
} else {
|
||||||
|
self?.doneWithInvalidLink()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private extension ActionRequestHandler {
|
||||||
|
func completeWithOpenUserProfile(_ username: String) {
|
||||||
|
doneWithResults([
|
||||||
|
"openURL": "mastodon://profile/\(username)"
|
||||||
|
])
|
||||||
|
}
|
||||||
|
|
||||||
|
func continueWithSearch(_ query: String) {
|
||||||
|
guard
|
||||||
|
let url = URL(string: query),
|
||||||
|
let host = url.host
|
||||||
|
else {
|
||||||
|
return doneWithInvalidLink()
|
||||||
|
}
|
||||||
|
|
||||||
|
Mastodon.API
|
||||||
|
.Instance
|
||||||
|
.instance(
|
||||||
|
session: .shared,
|
||||||
|
domain: host
|
||||||
|
)
|
||||||
|
.receive(on: DispatchQueue.main)
|
||||||
|
.sink { _ in
|
||||||
|
// no-op
|
||||||
|
} receiveValue: { [weak self] response in
|
||||||
|
guard response.value.version != nil else {
|
||||||
|
self?.doneWithInvalidLink()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
guard let query = query.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
|
||||||
|
self?.doneWithInvalidLink()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self?.doneWithResults(
|
||||||
|
["openURL": "mastodon://search?query=\(query)"]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.store(in: &cancellables)
|
||||||
|
}
|
||||||
|
|
||||||
|
func doneWithInvalidLink() {
|
||||||
|
doneWithResults(["alert": L10n.Extension.OpenIn.invalidLinkError])
|
||||||
|
}
|
||||||
|
|
||||||
|
func doneWithResults(_ resultsForJavaScriptFinalizeArg: [String: Any]?) {
|
||||||
|
if let resultsForJavaScriptFinalize = resultsForJavaScriptFinalizeArg {
|
||||||
|
let resultsDictionary = [NSExtensionJavaScriptFinalizeArgumentKey: resultsForJavaScriptFinalize]
|
||||||
|
let resultsProvider = NSItemProvider(item: resultsDictionary as NSDictionary, typeIdentifier: UTType.propertyList.identifier)
|
||||||
|
let resultsItem = NSExtensionItem()
|
||||||
|
resultsItem.attachments = [resultsProvider]
|
||||||
|
self.extensionContext!.completeRequest(returningItems: [resultsItem], completionHandler: nil)
|
||||||
|
} else {
|
||||||
|
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
|
||||||
|
}
|
||||||
|
self.extensionContext = nil
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?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>NSExtension</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionAttributes</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionActivationRule</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSExtensionActivationSupportsFileWithMaxCount</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>NSExtensionActivationSupportsImageWithMaxCount</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>NSExtensionActivationSupportsMovieWithMaxCount</key>
|
||||||
|
<integer>0</integer>
|
||||||
|
<key>NSExtensionActivationSupportsText</key>
|
||||||
|
<false/>
|
||||||
|
<key>NSExtensionActivationSupportsWebURLWithMaxCount</key>
|
||||||
|
<integer>1</integer>
|
||||||
|
</dict>
|
||||||
|
<key>NSExtensionJavaScriptPreprocessingFile</key>
|
||||||
|
<string>Action</string>
|
||||||
|
<key>NSExtensionServiceAllowsFinderPreviewItem</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSExtensionServiceAllowsTouchBarItem</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSExtensionServiceFinderPreviewIconName</key>
|
||||||
|
<string>NSActionTemplate</string>
|
||||||
|
<key>NSExtensionServiceTouchBarBezelColorName</key>
|
||||||
|
<string>TouchBarBezel</string>
|
||||||
|
<key>NSExtensionServiceTouchBarIconName</key>
|
||||||
|
<string>NSActionTemplate</string>
|
||||||
|
</dict>
|
||||||
|
<key>NSExtensionPointIdentifier</key>
|
||||||
|
<string>com.apple.services</string>
|
||||||
|
<key>NSExtensionPrincipalClass</key>
|
||||||
|
<string>$(PRODUCT_MODULE_NAME).ActionRequestHandler</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "MastodonActionExtensionIcon@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 86 KiB |
|
@ -0,0 +1,38 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.733",
|
||||||
|
"green" : "0.110",
|
||||||
|
"red" : "0.263"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "1.000",
|
||||||
|
"green" : "0.600",
|
||||||
|
"red" : "0.600"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue