feat: add sign out debug menu
This commit is contained in:
parent
f066e736eb
commit
1b3c9b2099
|
@ -11,7 +11,7 @@
|
|||
2D04F42525C255B9003F936F /* APIService+PublicTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */; };
|
||||
2D152A8C25C295CC009AA50C /* TimelinePostView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D152A8B25C295CC009AA50C /* TimelinePostView.swift */; };
|
||||
2D152A9225C2980C009AA50C /* UIFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D152A9125C2980C009AA50C /* UIFont.swift */; };
|
||||
2D42FF6125C8177C004A627A /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 2D42FF6025C8177C004A627A /* SwiftPackageProductDependency */; };
|
||||
2D42FF6125C8177C004A627A /* ActiveLabel in Frameworks */ = {isa = PBXBuildFile; productRef = 2D42FF6025C8177C004A627A /* ActiveLabel */; };
|
||||
2D42FF6B25C817D2004A627A /* MastodonContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF6A25C817D2004A627A /* MastodonContent.swift */; };
|
||||
2D42FF7E25C82218004A627A /* ActionToolBarContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF7D25C82218004A627A /* ActionToolBarContainer.swift */; };
|
||||
2D42FF8525C8224F004A627A /* HitTestExpandedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D42FF8425C8224F004A627A /* HitTestExpandedButton.swift */; };
|
||||
|
@ -21,7 +21,7 @@
|
|||
2D46976425C2A71500CF4AA9 /* UIIamge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D46976325C2A71500CF4AA9 /* UIIamge.swift */; };
|
||||
2D61335825C188A000CAE157 /* APIService+Persist+Timeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335725C188A000CAE157 /* APIService+Persist+Timeline.swift */; };
|
||||
2D61335E25C1894B00CAE157 /* APIService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D61335D25C1894B00CAE157 /* APIService.swift */; };
|
||||
2D61336925C18A4F00CAE157 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 2D61336825C18A4F00CAE157 /* SwiftPackageProductDependency */; };
|
||||
2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */ = {isa = PBXBuildFile; productRef = 2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */; };
|
||||
2D69CFF425CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69CFF325CA9E2200C3A1B2 /* LoadMoreConfigurableTableViewContainer.swift */; };
|
||||
2D69D00A25CAA00300C3A1B2 /* APIService+CoreData+Toot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D69D00925CAA00300C3A1B2 /* APIService+CoreData+Toot.swift */; };
|
||||
2D76316525C14BD100929FB9 /* PublicTimelineViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2D76316425C14BD100929FB9 /* PublicTimelineViewController.swift */; };
|
||||
|
@ -40,17 +40,19 @@
|
|||
2DA7D05725CA693F00804E11 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DA7D05625CA693F00804E11 /* Application.swift */; };
|
||||
2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2DF123A625C3B0210020F248 /* ActiveLabel.swift */; };
|
||||
45B49097460EDE530AD5AA72 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; };
|
||||
5D526FE225BE9AC400460CB9 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = 5D526FE125BE9AC400460CB9 /* SwiftPackageProductDependency */; };
|
||||
5D526FE225BE9AC400460CB9 /* MastodonSDK in Frameworks */ = {isa = PBXBuildFile; productRef = 5D526FE125BE9AC400460CB9 /* MastodonSDK */; };
|
||||
5E0DEC05797A7E6933788DDB /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */; };
|
||||
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */; };
|
||||
DB01409625C40B6700F9F3CF /* AuthenticationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB01409525C40B6700F9F3CF /* AuthenticationViewController.swift */; };
|
||||
DB0140A125C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140A025C40C0600F9F3CF /* MastodonPinBasedAuthenticationViewController.swift */; };
|
||||
DB0140A825C40C1500F9F3CF /* MastodonPinBasedAuthenticationViewModelNavigationDelegateShim.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140A725C40C1500F9F3CF /* MastodonPinBasedAuthenticationViewModelNavigationDelegateShim.swift */; };
|
||||
DB0140AE25C40C7300F9F3CF /* MastodonPinBasedAuthenticationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140AD25C40C7300F9F3CF /* MastodonPinBasedAuthenticationViewModel.swift */; };
|
||||
DB0140BD25C40D7500F9F3CF /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = DB0140BC25C40D7500F9F3CF /* SwiftPackageProductDependency */; };
|
||||
DB0140BD25C40D7500F9F3CF /* CommonOSLog in Frameworks */ = {isa = PBXBuildFile; productRef = DB0140BC25C40D7500F9F3CF /* CommonOSLog */; };
|
||||
DB0140CF25C42AEE00F9F3CF /* OSLog.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0140CE25C42AEE00F9F3CF /* OSLog.swift */; };
|
||||
DB084B5725CBC56C00F898ED /* Toot.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB084B5625CBC56C00F898ED /* Toot.swift */; };
|
||||
DB3D0FF325BAA61700EAA174 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = DB3D0FF225BAA61700EAA174 /* SwiftPackageProductDependency */; };
|
||||
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */; };
|
||||
DB0AC70A25CD2E0300D75117 /* HomeViewController+DebugAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB0AC70925CD2E0300D75117 /* HomeViewController+DebugAction.swift */; };
|
||||
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */ = {isa = PBXBuildFile; productRef = DB3D0FF225BAA61700EAA174 /* AlamofireImage */; };
|
||||
DB3D100D25BAA75E00EAA174 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = DB3D100F25BAA75E00EAA174 /* Localizable.strings */; };
|
||||
DB427DD625BAA00100D1B89D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DD525BAA00100D1B89D /* AppDelegate.swift */; };
|
||||
DB427DD825BAA00100D1B89D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB427DD725BAA00100D1B89D /* SceneDelegate.swift */; };
|
||||
|
@ -69,7 +71,7 @@
|
|||
DB45FB1D25CA9D23005A8AC7 /* APIService+HomeTimeline.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB45FB1C25CA9D23005A8AC7 /* APIService+HomeTimeline.swift */; };
|
||||
DB5086A525CC0B7000C2C187 /* AvatarBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086A425CC0B7000C2C187 /* AvatarBarButtonItem.swift */; };
|
||||
DB5086AB25CC0BBB00C2C187 /* AvatarConfigurableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086AA25CC0BBB00C2C187 /* AvatarConfigurableView.swift */; };
|
||||
DB5086B825CC0D6400C2C187 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; productRef = DB5086B725CC0D6400C2C187 /* SwiftPackageProductDependency */; };
|
||||
DB5086B825CC0D6400C2C187 /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = DB5086B725CC0D6400C2C187 /* Kingfisher */; };
|
||||
DB5086BE25CC0D9900C2C187 /* SplashPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB5086BD25CC0D9900C2C187 /* SplashPreference.swift */; };
|
||||
DB89B9F725C10FD0008580ED /* CoreDataStack.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DB89B9EE25C10FD0008580ED /* CoreDataStack.framework */; };
|
||||
DB89B9FE25C10FD0008580ED /* CoreDataStackTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB89B9FD25C10FD0008580ED /* CoreDataStackTests.swift */; };
|
||||
|
@ -202,6 +204,8 @@
|
|||
DB0140AD25C40C7300F9F3CF /* MastodonPinBasedAuthenticationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MastodonPinBasedAuthenticationViewModel.swift; sourceTree = "<group>"; };
|
||||
DB0140CE25C42AEE00F9F3CF /* OSLog.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSLog.swift; sourceTree = "<group>"; };
|
||||
DB084B5625CBC56C00F898ED /* Toot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toot.swift; sourceTree = "<group>"; };
|
||||
DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+Instance.swift"; sourceTree = "<group>"; };
|
||||
DB0AC70925CD2E0300D75117 /* HomeViewController+DebugAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HomeViewController+DebugAction.swift"; sourceTree = "<group>"; };
|
||||
DB3D0FED25BAA42200EAA174 /* MastodonSDK */ = {isa = PBXFileReference; lastKnownFileType = folder; path = MastodonSDK; sourceTree = "<group>"; };
|
||||
DB3D100E25BAA75E00EAA174 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
DB427DD225BAA00100D1B89D /* Mastodon.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Mastodon.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
|
@ -271,13 +275,13 @@
|
|||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
DB0140BD25C40D7500F9F3CF /* BuildFile in Frameworks */,
|
||||
DB0140BD25C40D7500F9F3CF /* CommonOSLog in Frameworks */,
|
||||
DB89BA0325C10FD0008580ED /* CoreDataStack.framework in Frameworks */,
|
||||
2D42FF6125C8177C004A627A /* BuildFile in Frameworks */,
|
||||
5D526FE225BE9AC400460CB9 /* BuildFile in Frameworks */,
|
||||
DB5086B825CC0D6400C2C187 /* BuildFile in Frameworks */,
|
||||
2D61336925C18A4F00CAE157 /* BuildFile in Frameworks */,
|
||||
DB3D0FF325BAA61700EAA174 /* BuildFile in Frameworks */,
|
||||
2D42FF6125C8177C004A627A /* ActiveLabel in Frameworks */,
|
||||
5D526FE225BE9AC400460CB9 /* MastodonSDK in Frameworks */,
|
||||
DB5086B825CC0D6400C2C187 /* Kingfisher in Frameworks */,
|
||||
2D61336925C18A4F00CAE157 /* AlamofireNetworkActivityIndicator in Frameworks */,
|
||||
DB3D0FF325BAA61700EAA174 /* AlamofireImage in Frameworks */,
|
||||
45B49097460EDE530AD5AA72 /* Pods_Mastodon.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -586,6 +590,7 @@
|
|||
DB98339B25C96DE600AD9700 /* APIService+Account.swift */,
|
||||
2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */,
|
||||
DB45FB1C25CA9D23005A8AC7 /* APIService+HomeTimeline.swift */,
|
||||
DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */,
|
||||
);
|
||||
path = APIService;
|
||||
sourceTree = "<group>";
|
||||
|
@ -745,6 +750,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
DB8AF55625C137A8002E6C99 /* HomeViewController.swift */,
|
||||
DB0AC70925CD2E0300D75117 /* HomeViewController+DebugAction.swift */,
|
||||
DBD4ED1025CC0FEB0041B741 /* HomeViewModel.swift */,
|
||||
);
|
||||
path = HomeTimeline;
|
||||
|
@ -783,12 +789,12 @@
|
|||
);
|
||||
name = Mastodon;
|
||||
packageProductDependencies = (
|
||||
DB3D0FF225BAA61700EAA174 /* SwiftPackageProductDependency */,
|
||||
5D526FE125BE9AC400460CB9 /* SwiftPackageProductDependency */,
|
||||
2D61336825C18A4F00CAE157 /* SwiftPackageProductDependency */,
|
||||
2D42FF6025C8177C004A627A /* SwiftPackageProductDependency */,
|
||||
DB0140BC25C40D7500F9F3CF /* SwiftPackageProductDependency */,
|
||||
DB5086B725CC0D6400C2C187 /* SwiftPackageProductDependency */,
|
||||
DB3D0FF225BAA61700EAA174 /* AlamofireImage */,
|
||||
5D526FE125BE9AC400460CB9 /* MastodonSDK */,
|
||||
2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */,
|
||||
2D42FF6025C8177C004A627A /* ActiveLabel */,
|
||||
DB0140BC25C40D7500F9F3CF /* CommonOSLog */,
|
||||
DB5086B725CC0D6400C2C187 /* Kingfisher */,
|
||||
);
|
||||
productName = Mastodon;
|
||||
productReference = DB427DD225BAA00100D1B89D /* Mastodon.app */;
|
||||
|
@ -911,11 +917,11 @@
|
|||
);
|
||||
mainGroup = DB427DC925BAA00100D1B89D;
|
||||
packageReferences = (
|
||||
DB3D0FF125BAA61700EAA174 /* RemoteSwiftPackageReference */,
|
||||
2D61336725C18A4F00CAE157 /* RemoteSwiftPackageReference */,
|
||||
2D42FF5F25C8177C004A627A /* RemoteSwiftPackageReference */,
|
||||
DB0140BB25C40D7500F9F3CF /* RemoteSwiftPackageReference */,
|
||||
DB5086B625CC0D6400C2C187 /* RemoteSwiftPackageReference */,
|
||||
DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */,
|
||||
2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */,
|
||||
2D42FF5F25C8177C004A627A /* XCRemoteSwiftPackageReference "ActiveLabel" */,
|
||||
DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */,
|
||||
DB5086B625CC0D6400C2C187 /* XCRemoteSwiftPackageReference "Kingfisher" */,
|
||||
);
|
||||
productRefGroup = DB427DD325BAA00100D1B89D /* Products */;
|
||||
projectDirPath = "";
|
||||
|
@ -1108,9 +1114,11 @@
|
|||
2D42FF8F25C8228A004A627A /* UIButton.swift in Sources */,
|
||||
2D61335825C188A000CAE157 /* APIService+Persist+Timeline.swift in Sources */,
|
||||
DB45FAE325CA7181005A8AC7 /* MastodonUser.swift in Sources */,
|
||||
DB0AC6FC25CD02E600D75117 /* APIService+Instance.swift in Sources */,
|
||||
2D69D00A25CAA00300C3A1B2 /* APIService+CoreData+Toot.swift in Sources */,
|
||||
DB98338825C945ED00AD9700 /* Assets.swift in Sources */,
|
||||
2DA7D04425CA52B200804E11 /* TimelineLoaderTableViewCell.swift in Sources */,
|
||||
DB0AC70A25CD2E0300D75117 /* HomeViewController+DebugAction.swift in Sources */,
|
||||
DB8AF52F25C13561002E6C99 /* DocumentStore.swift in Sources */,
|
||||
DB98337F25C9452D00AD9700 /* APIService+APIError.swift in Sources */,
|
||||
2DF123A725C3B0210020F248 /* ActiveLabel.swift in Sources */,
|
||||
|
@ -1665,7 +1673,7 @@
|
|||
/* End XCConfigurationList section */
|
||||
|
||||
/* Begin XCRemoteSwiftPackageReference section */
|
||||
2D42FF5F25C8177C004A627A /* RemoteSwiftPackageReference */ = {
|
||||
2D42FF5F25C8177C004A627A /* XCRemoteSwiftPackageReference "ActiveLabel" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/TwidereProject/ActiveLabel.swift";
|
||||
requirement = {
|
||||
|
@ -1673,7 +1681,7 @@
|
|||
minimumVersion = 4.0.0;
|
||||
};
|
||||
};
|
||||
2D61336725C18A4F00CAE157 /* RemoteSwiftPackageReference */ = {
|
||||
2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/Alamofire/AlamofireNetworkActivityIndicator";
|
||||
requirement = {
|
||||
|
@ -1681,7 +1689,7 @@
|
|||
minimumVersion = 3.1.0;
|
||||
};
|
||||
};
|
||||
DB0140BB25C40D7500F9F3CF /* RemoteSwiftPackageReference */ = {
|
||||
DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/MainasuK/CommonOSLog";
|
||||
requirement = {
|
||||
|
@ -1689,7 +1697,7 @@
|
|||
minimumVersion = 0.1.1;
|
||||
};
|
||||
};
|
||||
DB3D0FF125BAA61700EAA174 /* RemoteSwiftPackageReference */ = {
|
||||
DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/Alamofire/AlamofireImage.git";
|
||||
requirement = {
|
||||
|
@ -1697,7 +1705,7 @@
|
|||
minimumVersion = 4.1.0;
|
||||
};
|
||||
};
|
||||
DB5086B625CC0D6400C2C187 /* RemoteSwiftPackageReference */ = {
|
||||
DB5086B625CC0D6400C2C187 /* XCRemoteSwiftPackageReference "Kingfisher" */ = {
|
||||
isa = XCRemoteSwiftPackageReference;
|
||||
repositoryURL = "https://github.com/onevcat/Kingfisher.git";
|
||||
requirement = {
|
||||
|
@ -1708,33 +1716,33 @@
|
|||
/* End XCRemoteSwiftPackageReference section */
|
||||
|
||||
/* Begin XCSwiftPackageProductDependency section */
|
||||
2D42FF6025C8177C004A627A /* SwiftPackageProductDependency */ = {
|
||||
2D42FF6025C8177C004A627A /* ActiveLabel */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 2D42FF5F25C8177C004A627A /* RemoteSwiftPackageReference */;
|
||||
package = 2D42FF5F25C8177C004A627A /* XCRemoteSwiftPackageReference "ActiveLabel" */;
|
||||
productName = ActiveLabel;
|
||||
};
|
||||
2D61336825C18A4F00CAE157 /* SwiftPackageProductDependency */ = {
|
||||
2D61336825C18A4F00CAE157 /* AlamofireNetworkActivityIndicator */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = 2D61336725C18A4F00CAE157 /* RemoteSwiftPackageReference */;
|
||||
package = 2D61336725C18A4F00CAE157 /* XCRemoteSwiftPackageReference "AlamofireNetworkActivityIndicator" */;
|
||||
productName = AlamofireNetworkActivityIndicator;
|
||||
};
|
||||
5D526FE125BE9AC400460CB9 /* SwiftPackageProductDependency */ = {
|
||||
5D526FE125BE9AC400460CB9 /* MastodonSDK */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
productName = MastodonSDK;
|
||||
};
|
||||
DB0140BC25C40D7500F9F3CF /* SwiftPackageProductDependency */ = {
|
||||
DB0140BC25C40D7500F9F3CF /* CommonOSLog */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB0140BB25C40D7500F9F3CF /* RemoteSwiftPackageReference */;
|
||||
package = DB0140BB25C40D7500F9F3CF /* XCRemoteSwiftPackageReference "CommonOSLog" */;
|
||||
productName = CommonOSLog;
|
||||
};
|
||||
DB3D0FF225BAA61700EAA174 /* SwiftPackageProductDependency */ = {
|
||||
DB3D0FF225BAA61700EAA174 /* AlamofireImage */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB3D0FF125BAA61700EAA174 /* RemoteSwiftPackageReference */;
|
||||
package = DB3D0FF125BAA61700EAA174 /* XCRemoteSwiftPackageReference "AlamofireImage" */;
|
||||
productName = AlamofireImage;
|
||||
};
|
||||
DB5086B725CC0D6400C2C187 /* SwiftPackageProductDependency */ = {
|
||||
DB5086B725CC0D6400C2C187 /* Kingfisher */ = {
|
||||
isa = XCSwiftPackageProductDependency;
|
||||
package = DB5086B625CC0D6400C2C187 /* RemoteSwiftPackageReference */;
|
||||
package = DB5086B625CC0D6400C2C187 /* XCRemoteSwiftPackageReference "Kingfisher" */;
|
||||
productName = Kingfisher;
|
||||
};
|
||||
/* End XCSwiftPackageProductDependency section */
|
||||
|
|
|
@ -41,6 +41,7 @@ final class AuthenticationViewController: UIViewController, NeedsDependency {
|
|||
let button = UIButton(type: .system)
|
||||
button.titleLabel?.font = .preferredFont(forTextStyle: .headline)
|
||||
button.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.Background.secondarySystemBackground.color), for: .normal)
|
||||
button.setBackgroundImage(UIImage.placeholder(color: Asset.Colors.Background.secondarySystemBackground.color.withAlphaComponent(0.8)), for: .disabled)
|
||||
button.setTitleColor(Asset.Colors.Label.primary.color, for: .normal)
|
||||
button.setTitle("Sign in", for: .normal)
|
||||
button.layer.masksToBounds = true
|
||||
|
@ -53,6 +54,7 @@ final class AuthenticationViewController: UIViewController, NeedsDependency {
|
|||
let button = UIButton(type: .system)
|
||||
button.titleLabel?.font = .preferredFont(forTextStyle: .subheadline)
|
||||
button.setTitleColor(Asset.Colors.Button.highlight.color, for: .normal)
|
||||
button.setTitleColor(.systemGray, for: .disabled)
|
||||
button.setTitle("Sign up", for: .normal)
|
||||
return button
|
||||
}()
|
||||
|
@ -126,6 +128,9 @@ extension AuthenticationViewController {
|
|||
.sink { [weak self] isAuthenticating in
|
||||
guard let self = self else { return }
|
||||
isAuthenticating ? self.activityIndicatorView.startAnimating() : self.activityIndicatorView.stopAnimating()
|
||||
self.signInButton.setTitle(isAuthenticating ? "" : "Sign in", for: .normal)
|
||||
self.signInButton.isEnabled = !isAuthenticating
|
||||
self.signUpButton.isEnabled = !isAuthenticating
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
|
@ -171,6 +176,8 @@ extension AuthenticationViewController {
|
|||
.store(in: &disposeBag)
|
||||
|
||||
signInButton.addTarget(self, action: #selector(AuthenticationViewController.signInButtonPressed(_:)), for: .touchUpInside)
|
||||
signUpButton.addTarget(self, action: #selector(AuthenticationViewController.signUpButtonPressed(_:)), for: .touchUpInside)
|
||||
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
@ -194,18 +201,10 @@ extension AuthenticationViewController {
|
|||
context.apiService.createApplication(domain: domain)
|
||||
.tryMap { response -> AuthenticationViewModel.AuthenticateInfo in
|
||||
let application = response.value
|
||||
guard let clientID = application.clientID,
|
||||
let clientSecret = application.clientSecret else {
|
||||
guard let info = AuthenticationViewModel.AuthenticateInfo(domain: domain, application: application) else {
|
||||
throw APIService.APIError.explicit(.badResponse)
|
||||
}
|
||||
let query = Mastodon.API.OAuth.AuthorizeQuery(clientID: clientID)
|
||||
let url = Mastodon.API.OAuth.authorizeURL(domain: domain, query: query)
|
||||
return AuthenticationViewModel.AuthenticateInfo(
|
||||
domain: domain,
|
||||
clientID: clientID,
|
||||
clientSecret: clientSecret,
|
||||
url: url
|
||||
)
|
||||
return info
|
||||
}
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] completion in
|
||||
|
@ -222,7 +221,7 @@ extension AuthenticationViewController {
|
|||
}
|
||||
} receiveValue: { [weak self] info in
|
||||
guard let self = self else { return }
|
||||
let mastodonPinBasedAuthenticationViewModel = MastodonPinBasedAuthenticationViewModel(authenticateURL: info.url)
|
||||
let mastodonPinBasedAuthenticationViewModel = MastodonPinBasedAuthenticationViewModel(authenticateURL: info.authorizeURL)
|
||||
self.viewModel.authenticate(
|
||||
info: info,
|
||||
pinCodePublisher: mastodonPinBasedAuthenticationViewModel.pinCodePublisher
|
||||
|
@ -236,6 +235,50 @@ extension AuthenticationViewController {
|
|||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
@objc private func signUpButtonPressed(_ sender: UIButton) {
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
guard viewModel.isDomainValid.value, let domain = viewModel.domain.value else {
|
||||
domainTextField.shake()
|
||||
return
|
||||
}
|
||||
guard !viewModel.isAuthenticating.value else { return }
|
||||
|
||||
context.apiService.instance(domain: domain)
|
||||
.compactMap { [weak self] response -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Application>, Error>? in
|
||||
guard let self = self else { return nil }
|
||||
guard response.value.registrations != false else {
|
||||
return Fail(error: AuthenticationViewModel.AuthenticationError.registrationClosed).eraseToAnyPublisher()
|
||||
}
|
||||
return self.context.apiService.createApplication(domain: domain)
|
||||
}
|
||||
.switchToLatest()
|
||||
.tryMap { response -> AuthenticationViewModel.AuthenticateInfo in
|
||||
let application = response.value
|
||||
guard let authenticateInfo = AuthenticationViewModel.AuthenticateInfo(domain: domain, application: application) else {
|
||||
throw APIService.APIError.explicit(.badResponse)
|
||||
}
|
||||
return authenticateInfo
|
||||
}
|
||||
.compactMap { [weak self] authenticateInfo -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Token>, Error>? in
|
||||
guard let self = self else { return nil }
|
||||
return self.context.apiService.applicationAccessToken(domain: domain, clientID: authenticateInfo.clientID, clientSecret: authenticateInfo.clientSecret)
|
||||
}
|
||||
.switchToLatest()
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { completion in
|
||||
switch completion {
|
||||
case .failure(let error):
|
||||
break
|
||||
case .finished:
|
||||
break
|
||||
}
|
||||
} receiveValue: { [weak self] response in
|
||||
guard let self = self else { return }
|
||||
print(response)
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// MARK: - UIAdaptivePresentationControllerDelegate
|
||||
|
|
|
@ -67,13 +67,54 @@ final class AuthenticationViewModel {
|
|||
|
||||
}
|
||||
|
||||
extension AuthenticationViewModel {
|
||||
enum AuthenticationError: Error, LocalizedError {
|
||||
case badCredentials
|
||||
case registrationClosed
|
||||
|
||||
var errorDescription: String? {
|
||||
switch self {
|
||||
case .badCredentials: return "Bad Credentials"
|
||||
case .registrationClosed: return "Registration Closed"
|
||||
}
|
||||
}
|
||||
|
||||
var failureReason: String? {
|
||||
switch self {
|
||||
case .badCredentials: return "Credentials invalid."
|
||||
case .registrationClosed: return "Server disallow registration."
|
||||
}
|
||||
}
|
||||
|
||||
var helpAnchor: String? {
|
||||
switch self {
|
||||
case .badCredentials: return "Please try again."
|
||||
case .registrationClosed: return "Please try another domain."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension AuthenticationViewModel {
|
||||
|
||||
struct AuthenticateInfo {
|
||||
let domain: String
|
||||
let clientID: String
|
||||
let clientSecret: String
|
||||
let url: URL
|
||||
let authorizeURL: URL
|
||||
|
||||
init?(domain: String, application: Mastodon.Entity.Application) {
|
||||
self.domain = domain
|
||||
guard let clientID = application.clientID,
|
||||
let clientSecret = application.clientSecret else { return nil }
|
||||
self.clientID = clientID
|
||||
self.clientSecret = clientSecret
|
||||
self.authorizeURL = {
|
||||
let query = Mastodon.API.OAuth.AuthorizeQuery(clientID: clientID)
|
||||
let url = Mastodon.API.OAuth.authorizeURL(domain: domain, query: query)
|
||||
return url
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
func authenticate(info: AuthenticateInfo, pinCodePublisher: PassthroughSubject<String, Never>) {
|
||||
|
@ -144,7 +185,7 @@ extension AuthenticationViewModel {
|
|||
mastodonUserRequest.predicate = MastodonUser.predicate(domain: info.domain, id: account.id)
|
||||
mastodonUserRequest.fetchLimit = 1
|
||||
guard let mastodonUser = try? managedObjectContext.fetch(mastodonUserRequest).first else {
|
||||
return Fail(error: APIService.APIError.explicit(.badCredentials)).eraseToAnyPublisher()
|
||||
return Fail(error: AuthenticationError.badCredentials).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
let property = MastodonAuthentication.Property(
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// HomeViewController+DebugAction.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-2-5.
|
||||
//
|
||||
|
||||
import os.log
|
||||
import UIKit
|
||||
|
||||
#if DEBUG
|
||||
extension HomeViewController {
|
||||
var debugMenu: UIMenu {
|
||||
let menu = UIMenu(
|
||||
title: "Debug Tools",
|
||||
image: nil,
|
||||
identifier: nil,
|
||||
options: .displayInline,
|
||||
children: [
|
||||
UIAction(title: "Sign Out", image: UIImage(systemName: "escape"), attributes: .destructive) { [weak self] action in
|
||||
guard let self = self else { return }
|
||||
self.signOutAction(action)
|
||||
}
|
||||
]
|
||||
)
|
||||
return menu
|
||||
}
|
||||
}
|
||||
|
||||
extension HomeViewController {
|
||||
|
||||
@objc private func signOutAction(_ sender: UIAction) {
|
||||
guard let activeMastodonAuthenticationBox = context.authenticationService.activeMastodonAuthenticationBox.value else {
|
||||
return
|
||||
}
|
||||
let currentAccountCount = context.authenticationService.mastodonAuthentications.value.count
|
||||
let isAuthenticationExistWhenSignOut = currentAccountCount - 1 > 0
|
||||
// prepare advance
|
||||
let authenticationViewModel = AuthenticationViewModel(context: context, coordinator: coordinator, isAuthenticationExist: isAuthenticationExistWhenSignOut)
|
||||
|
||||
context.authenticationService.signOutMastodonUser(
|
||||
domain: activeMastodonAuthenticationBox.domain,
|
||||
userID: activeMastodonAuthenticationBox.userID
|
||||
)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { [weak self] result in
|
||||
guard let self = self else { return }
|
||||
switch result {
|
||||
case .failure(let error):
|
||||
assertionFailure(error.localizedDescription)
|
||||
case .success(let isSignOut):
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: sign out %s", ((#file as NSString).lastPathComponent), #line, #function, isSignOut ? "success" : "fail")
|
||||
guard isSignOut else { return }
|
||||
if !isAuthenticationExistWhenSignOut {
|
||||
self.coordinator.present(scene: .authentication(viewModel: authenticationViewModel), from: nil, transition: .modal(animated: true, completion: nil))
|
||||
}
|
||||
}
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
|
@ -31,6 +31,10 @@ extension HomeViewController {
|
|||
view.backgroundColor = Asset.Colors.Background.systemBackground.color
|
||||
navigationItem.leftBarButtonItem = avatarBarButtonItem
|
||||
avatarBarButtonItem.avatarButton.addTarget(self, action: #selector(HomeViewController.avatarBarButtonItemDidPressed(_:)), for: .touchUpInside)
|
||||
#if DEBUG
|
||||
avatarBarButtonItem.avatarButton.menu = debugMenu
|
||||
avatarBarButtonItem.avatarButton.showsMenuAsPrimaryAction = true
|
||||
#endif
|
||||
|
||||
Publishers.CombineLatest(
|
||||
context.authenticationService.activeMastodonAuthentication.eraseToAnyPublisher(),
|
||||
|
|
|
@ -17,7 +17,6 @@ extension APIService {
|
|||
enum ErrorReason {
|
||||
// application internal error
|
||||
case authenticationMissing
|
||||
case badCredentials
|
||||
case badRequest
|
||||
case badResponse
|
||||
case requestThrottle
|
||||
|
@ -42,7 +41,6 @@ extension APIService.APIError: LocalizedError {
|
|||
var errorDescription: String? {
|
||||
switch errorReason {
|
||||
case .authenticationMissing: return "Fail to Authenticatie"
|
||||
case .badCredentials: return "Bad Credentials"
|
||||
case .badRequest: return "Bad Request"
|
||||
case .badResponse: return "Bad Response"
|
||||
case .requestThrottle: return "Request Throttled"
|
||||
|
@ -61,7 +59,6 @@ extension APIService.APIError: LocalizedError {
|
|||
var failureReason: String? {
|
||||
switch errorReason {
|
||||
case .authenticationMissing: return "Account credential not found."
|
||||
case .badCredentials: return "Credentials invalid."
|
||||
case .badRequest: return "Request invalid."
|
||||
case .badResponse: return "Response invalid."
|
||||
case .requestThrottle: return "Request too frequency."
|
||||
|
@ -76,7 +73,6 @@ extension APIService.APIError: LocalizedError {
|
|||
var helpAnchor: String? {
|
||||
switch errorReason {
|
||||
case .authenticationMissing: return "Please request after authenticated."
|
||||
case .badCredentials: return "Please try again.."
|
||||
case .badRequest: return "Please try again."
|
||||
case .badResponse: return "Please try again."
|
||||
case .requestThrottle: return "Please try again later."
|
||||
|
|
|
@ -32,4 +32,22 @@ extension APIService {
|
|||
)
|
||||
}
|
||||
|
||||
func applicationAccessToken(
|
||||
domain: String,
|
||||
clientID: String,
|
||||
clientSecret: String
|
||||
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Token>, Error> {
|
||||
let query = Mastodon.API.OAuth.AccessTokenQuery(
|
||||
clientID: clientID,
|
||||
clientSecret: clientSecret,
|
||||
code: nil,
|
||||
grantType: "client_credentials"
|
||||
)
|
||||
return Mastodon.API.OAuth.accessToken(
|
||||
session: session,
|
||||
domain: domain,
|
||||
query: query
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
//
|
||||
// APIService+Instance.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-2-5.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import CoreData
|
||||
import CoreDataStack
|
||||
import CommonOSLog
|
||||
import DateToolsSwift
|
||||
import MastodonSDK
|
||||
|
||||
extension APIService {
|
||||
|
||||
func instance(
|
||||
domain: String
|
||||
) -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Instance>, Error> {
|
||||
return Mastodon.API.Instance.instance(session: session, domain: domain)
|
||||
}
|
||||
|
||||
}
|
|
@ -12,6 +12,18 @@
|
|||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id" : "9DA3EAE9-A502-49E9-BC74-5ED71250F4A8",
|
||||
"name" : "mastodon.social",
|
||||
"options" : {
|
||||
"environmentVariableEntries" : [
|
||||
{
|
||||
"key" : "domain",
|
||||
"value" : "mastodon.social"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id" : "C5184AF3-B83B-4A7E-949C-6B1AA3ABE7D1",
|
||||
"name" : "pawoo.net",
|
||||
|
@ -23,6 +35,18 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"id" : "71C5BF3D-A8CE-468B-B22E-E6DA4AD5AF4E",
|
||||
"name" : "freespeechextremist.com",
|
||||
"options" : {
|
||||
"environmentVariableEntries" : [
|
||||
{
|
||||
"key" : "domain",
|
||||
"value" : "freespeechextremist.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"defaultOptions" : {
|
||||
|
|
|
@ -29,7 +29,7 @@ extension MastodonSDKTests {
|
|||
break
|
||||
}
|
||||
} receiveValue: { response in
|
||||
XCTAssertEqual(response.value.uri, domain)
|
||||
XCTAssertNotEqual(response.value.uri, "")
|
||||
print(response.value)
|
||||
theExpectation.fulfill()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue