forked from zelo72/mastodon-ios
Merge branch 'release/0.8.8' into main
This commit is contained in:
commit
28c64e2ebb
|
@ -191,6 +191,7 @@
|
|||
<attribute name="domain" attributeType="String"/>
|
||||
<attribute name="preferredStaticAvatar" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="preferredTrueBlackDarkMode" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="preferredUsingDefaultBrowser" attributeType="Boolean" defaultValueString="NO" usesScalarValueType="YES"/>
|
||||
<attribute name="updatedAt" attributeType="Date" usesScalarValueType="NO"/>
|
||||
<attribute name="userID" attributeType="String"/>
|
||||
<relationship name="subscriptions" optional="YES" toMany="YES" deletionRule="Nullify" destinationEntity="Subscription" inverseName="setting" inverseEntity="Subscription"/>
|
||||
|
@ -282,7 +283,7 @@
|
|||
<element name="PollOption" positionX="0" positionY="0" width="128" height="134"/>
|
||||
<element name="PrivateNote" positionX="0" positionY="0" width="128" height="89"/>
|
||||
<element name="SearchHistory" positionX="0" positionY="0" width="128" height="104"/>
|
||||
<element name="Setting" positionX="72" positionY="162" width="128" height="149"/>
|
||||
<element name="Setting" positionX="72" positionY="162" width="128" height="164"/>
|
||||
<element name="Status" positionX="0" positionY="0" width="128" height="599"/>
|
||||
<element name="Subscription" positionX="81" positionY="171" width="128" height="179"/>
|
||||
<element name="SubscriptionAlerts" positionX="72" positionY="162" width="128" height="14"/>
|
||||
|
|
|
@ -16,6 +16,7 @@ public final class Setting: NSManagedObject {
|
|||
@NSManaged public var appearanceRaw: String
|
||||
@NSManaged public var preferredTrueBlackDarkMode: Bool
|
||||
@NSManaged public var preferredStaticAvatar: Bool
|
||||
@NSManaged public var preferredUsingDefaultBrowser: Bool
|
||||
|
||||
@NSManaged public private(set) var createdAt: Date
|
||||
@NSManaged public private(set) var updatedAt: Date
|
||||
|
@ -62,6 +63,12 @@ extension Setting {
|
|||
self.preferredStaticAvatar = preferredStaticAvatar
|
||||
didUpdate(at: Date())
|
||||
}
|
||||
|
||||
public func update(preferredUsingDefaultBrowser: Bool) {
|
||||
guard preferredUsingDefaultBrowser != self.preferredUsingDefaultBrowser else { return }
|
||||
self.preferredUsingDefaultBrowser = preferredUsingDefaultBrowser
|
||||
didUpdate(at: Date())
|
||||
}
|
||||
|
||||
public func didUpdate(at networkDate: Date) {
|
||||
self.updatedAt = networkDate
|
||||
|
|
|
@ -495,12 +495,8 @@
|
|||
"dark": "Always Dark"
|
||||
},
|
||||
"appearance_settings": {
|
||||
"dark_mode": {
|
||||
"title": "True black Dark Mode"
|
||||
},
|
||||
"avatar_animation": {
|
||||
"title": "Disable avatar animation"
|
||||
}
|
||||
"true_black_dark_mode": "True black Dark Mode",
|
||||
"disable_avatar_animation": "Disable avatar animation"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Notifications",
|
||||
|
@ -516,6 +512,10 @@
|
|||
"title": "Notify me when"
|
||||
}
|
||||
},
|
||||
"preference": {
|
||||
"title": "Preference",
|
||||
"using_default_browser": "Using default browser open link"
|
||||
},
|
||||
"boringzone": {
|
||||
"title": "The Boring zone",
|
||||
"terms": "Terms of Service",
|
||||
|
|
|
@ -415,6 +415,8 @@
|
|||
DBA0A10925FB3C2B0079C110 /* RoundedEdgesButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA0A10825FB3C2B0079C110 /* RoundedEdgesButton.swift */; };
|
||||
DBA0A11325FB3FC10079C110 /* ComposeToolbarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */; };
|
||||
DBA1DB80268F84F80052DB59 /* NotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA1DB7F268F84F80052DB59 /* NotificationType.swift */; };
|
||||
DBA465932696B495002B41DB /* APIService+WebFinger.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA465922696B495002B41DB /* APIService+WebFinger.swift */; };
|
||||
DBA465952696E387002B41DB /* AppPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA465942696E387002B41DB /* AppPreference.swift */; };
|
||||
DBA5E7A3263AD0A3004598BB /* PhotoLibraryService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA5E7A2263AD0A3004598BB /* PhotoLibraryService.swift */; };
|
||||
DBA5E7A5263BD28C004598BB /* ContextMenuImagePreviewViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA5E7A4263BD28C004598BB /* ContextMenuImagePreviewViewModel.swift */; };
|
||||
DBA5E7A9263BD3A4004598BB /* ContextMenuImagePreviewViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBA5E7A8263BD3A4004598BB /* ContextMenuImagePreviewViewController.swift */; };
|
||||
|
@ -1044,6 +1046,8 @@
|
|||
DBA0A10825FB3C2B0079C110 /* RoundedEdgesButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoundedEdgesButton.swift; sourceTree = "<group>"; };
|
||||
DBA0A11225FB3FC10079C110 /* ComposeToolbarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeToolbarView.swift; sourceTree = "<group>"; };
|
||||
DBA1DB7F268F84F80052DB59 /* NotificationType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationType.swift; sourceTree = "<group>"; };
|
||||
DBA465922696B495002B41DB /* APIService+WebFinger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "APIService+WebFinger.swift"; sourceTree = "<group>"; };
|
||||
DBA465942696E387002B41DB /* AppPreference.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppPreference.swift; sourceTree = "<group>"; };
|
||||
DBA5E7A2263AD0A3004598BB /* PhotoLibraryService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PhotoLibraryService.swift; sourceTree = "<group>"; };
|
||||
DBA5E7A4263BD28C004598BB /* ContextMenuImagePreviewViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuImagePreviewViewModel.swift; sourceTree = "<group>"; };
|
||||
DBA5E7A8263BD3A4004598BB /* ContextMenuImagePreviewViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContextMenuImagePreviewViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -1935,6 +1939,7 @@
|
|||
2D04F42425C255B9003F936F /* APIService+PublicTimeline.swift */,
|
||||
DB45FB1C25CA9D23005A8AC7 /* APIService+HomeTimeline.swift */,
|
||||
DB482A4A261340A7008AE74C /* APIService+UserTimeline.swift */,
|
||||
DBA465922696B495002B41DB /* APIService+WebFinger.swift */,
|
||||
DB0AC6FB25CD02E600D75117 /* APIService+Instance.swift */,
|
||||
DB59F10D25EF724F001F1DAB /* APIService+Poll.swift */,
|
||||
DB71FD5125F8CCAA00512AE1 /* APIService+Status.swift */,
|
||||
|
@ -1984,6 +1989,7 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
DB5086BD25CC0D9900C2C187 /* SplashPreference.swift */,
|
||||
DBA465942696E387002B41DB /* AppPreference.swift */,
|
||||
DB6D1B3C2636857500ACB481 /* AppearancePreference.swift */,
|
||||
DBE54AC52636C89F004E7C0B /* NotificationPreference.swift */,
|
||||
DB1D842F26566512000346B3 /* KeyboardPreference.swift */,
|
||||
|
@ -3225,6 +3231,7 @@
|
|||
DBAC649B267DF8C8007FE9FD /* ActivityIndicatorNode.swift in Sources */,
|
||||
DB45FAD725CA6C76005A8AC7 /* UIBarButtonItem.swift in Sources */,
|
||||
2DA504692601ADE7008F4E6C /* SawToothView.swift in Sources */,
|
||||
DBA465952696E387002B41DB /* AppPreference.swift in Sources */,
|
||||
DB87D4572609DD5300D12C0D /* DeleteBackwardResponseTextField.swift in Sources */,
|
||||
2D8434F525FF465D00EECE90 /* HomeTimelineNavigationBarTitleViewModel.swift in Sources */,
|
||||
DB938F0F2624119800E5B6C1 /* ThreadViewModel+LoadThreadState.swift in Sources */,
|
||||
|
@ -3430,6 +3437,7 @@
|
|||
DB6D9F8426358EEC008423CD /* SettingsItem.swift in Sources */,
|
||||
2D364F7825E66D8300204FDC /* MastodonResendEmailViewModel.swift in Sources */,
|
||||
DBCBCC052680AFB9000F5B51 /* AsyncHomeTimelineViewController+Provider.swift in Sources */,
|
||||
DBA465932696B495002B41DB /* APIService+WebFinger.swift in Sources */,
|
||||
DB8AF54525C13647002E6C99 /* NeedsDependency.swift in Sources */,
|
||||
DB9D6BF825E4F5690051B173 /* NotificationViewController.swift in Sources */,
|
||||
2DAC9E46262FC9FD0062E1A6 /* SuggestionAccountTableViewCell.swift in Sources */,
|
||||
|
@ -3898,7 +3906,7 @@
|
|||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 33;
|
||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||
|
@ -3906,7 +3914,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 0.8.7;
|
||||
MARKETING_VERSION = 0.8.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@ -3925,7 +3933,7 @@
|
|||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 33;
|
||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||
|
@ -3933,7 +3941,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 0.8.7;
|
||||
MARKETING_VERSION = 0.8.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@ -4253,7 +4261,7 @@
|
|||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 33;
|
||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||
|
@ -4261,7 +4269,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 0.8.7;
|
||||
MARKETING_VERSION = 0.8.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@ -4367,7 +4375,7 @@
|
|||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 33;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -4375,7 +4383,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 0.8.7;
|
||||
MARKETING_VERSION = 0.8.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -4486,7 +4494,7 @@
|
|||
CLANG_ENABLE_MODULES = YES;
|
||||
CODE_SIGN_ENTITLEMENTS = Mastodon/Mastodon.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 33;
|
||||
DEVELOPMENT_ASSET_PATHS = "Mastodon/Resources/Preview\\ Assets.xcassets";
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = Mastodon/Info.plist;
|
||||
|
@ -4494,7 +4502,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 0.8.7;
|
||||
MARKETING_VERSION = 0.8.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
@ -4600,7 +4608,7 @@
|
|||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 33;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -4608,7 +4616,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 0.8.7;
|
||||
MARKETING_VERSION = 0.8.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -4654,7 +4662,7 @@
|
|||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 33;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -4662,7 +4670,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 0.8.7;
|
||||
MARKETING_VERSION = 0.8.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -4677,7 +4685,7 @@
|
|||
buildSettings = {
|
||||
CODE_SIGN_ENTITLEMENTS = NotificationService/NotificationService.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 32;
|
||||
CURRENT_PROJECT_VERSION = 33;
|
||||
DEVELOPMENT_TEAM = 5Z4GVSS33P;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
|
@ -4685,7 +4693,7 @@
|
|||
"@executable_path/Frameworks",
|
||||
"@executable_path/../../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 0.8.7;
|
||||
MARKETING_VERSION = 0.8.8;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = org.joinmastodon.app.NotificationService;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SKIP_INSTALL = YES;
|
||||
|
@ -4833,7 +4841,7 @@
|
|||
repositoryURL = "https://github.com/TwidereProject/MetaTextView.git";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 1.3.0;
|
||||
version = 1.3.1;
|
||||
};
|
||||
};
|
||||
DB0E2D2C26833FF600865C3C /* XCRemoteSwiftPackageReference "Nuke-FLAnimatedImage-Plugin" */ = {
|
||||
|
|
|
@ -114,8 +114,8 @@
|
|||
"repositoryURL": "https://github.com/TwidereProject/MetaTextView.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "e2049e14ef411c6810d53c1baf553b5161c6678f",
|
||||
"version": "1.3.0"
|
||||
"revision": "9021b330dd72898583f62ee7f4c98768d72e7654",
|
||||
"version": "1.3.1"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
@ -192,8 +192,12 @@ extension SceneCoordinator {
|
|||
sender?.navigationController?.pushViewController(viewController, animated: true)
|
||||
|
||||
case .safariPresent(let animated, let completion):
|
||||
viewController.modalPresentationCapturesStatusBarAppearance = true
|
||||
presentingViewController.present(viewController, animated: animated, completion: completion)
|
||||
if UserDefaults.shared.preferredUsingDefaultBrowser, case let .safari(url) = scene {
|
||||
UIApplication.shared.open(url, options: [:], completionHandler: nil)
|
||||
} else {
|
||||
viewController.modalPresentationCapturesStatusBarAppearance = true
|
||||
presentingViewController.present(viewController, animated: animated, completion: completion)
|
||||
}
|
||||
|
||||
case .alertController(let animated, let completion):
|
||||
viewController.modalPresentationCapturesStatusBarAppearance = true
|
||||
|
|
|
@ -13,6 +13,7 @@ enum SettingsItem: Hashable {
|
|||
case appearanceDarkMode(settingObjectID: NSManagedObjectID)
|
||||
case appearanceDisableAvatarAnimation(settingObjectID: NSManagedObjectID)
|
||||
case notification(settingObjectID: NSManagedObjectID, switchMode: NotificationSwitchMode)
|
||||
case preferenceUsingDefaultBrowser(settingObjectID: NSManagedObjectID)
|
||||
case boringZone(item: Link)
|
||||
case spicyZone(item: Link)
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ enum SettingsSection: Hashable {
|
|||
case appearance
|
||||
case appearanceSettings
|
||||
case notifications
|
||||
case preference
|
||||
case boringZone
|
||||
case spicyZone
|
||||
|
||||
|
@ -19,6 +20,7 @@ enum SettingsSection: Hashable {
|
|||
case .appearance: return L10n.Scene.Settings.Section.Appearance.title
|
||||
case .appearanceSettings: return ""
|
||||
case .notifications: return L10n.Scene.Settings.Section.Notifications.title
|
||||
case .preference: return L10n.Scene.Settings.Section.Preference.title
|
||||
case .boringZone: return L10n.Scene.Settings.Section.Boringzone.title
|
||||
case .spicyZone: return L10n.Scene.Settings.Section.Spicyzone.title
|
||||
}
|
||||
|
|
|
@ -934,14 +934,10 @@ internal enum L10n {
|
|||
internal static let title = L10n.tr("Localizable", "Scene.Settings.Section.Appearance.Title")
|
||||
}
|
||||
internal enum AppearanceSettings {
|
||||
internal enum AvatarAnimation {
|
||||
/// Disable avatar animation
|
||||
internal static let title = L10n.tr("Localizable", "Scene.Settings.Section.AppearanceSettings.AvatarAnimation.Title")
|
||||
}
|
||||
internal enum DarkMode {
|
||||
/// True black Dark Mode
|
||||
internal static let title = L10n.tr("Localizable", "Scene.Settings.Section.AppearanceSettings.DarkMode.Title")
|
||||
}
|
||||
/// Disable avatar animation
|
||||
internal static let disableAvatarAnimation = L10n.tr("Localizable", "Scene.Settings.Section.AppearanceSettings.DisableAvatarAnimation")
|
||||
/// True black Dark Mode
|
||||
internal static let trueBlackDarkMode = L10n.tr("Localizable", "Scene.Settings.Section.AppearanceSettings.TrueBlackDarkMode")
|
||||
}
|
||||
internal enum Boringzone {
|
||||
/// Privacy Policy
|
||||
|
@ -975,6 +971,12 @@ internal enum L10n {
|
|||
internal static let title = L10n.tr("Localizable", "Scene.Settings.Section.Notifications.Trigger.Title")
|
||||
}
|
||||
}
|
||||
internal enum Preference {
|
||||
/// Preference
|
||||
internal static let title = L10n.tr("Localizable", "Scene.Settings.Section.Preference.Title")
|
||||
/// Using default browser open link
|
||||
internal static let usingDefaultBrowser = L10n.tr("Localizable", "Scene.Settings.Section.Preference.UsingDefaultBrowser")
|
||||
}
|
||||
internal enum Spicyzone {
|
||||
/// Clear Media Cache
|
||||
internal static let clear = L10n.tr("Localizable", "Scene.Settings.Section.Spicyzone.Clear")
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
//
|
||||
// AppPreference.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-7-8.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UserDefaults {
|
||||
|
||||
@objc dynamic var preferredUsingDefaultBrowser: Bool {
|
||||
get {
|
||||
register(defaults: [#function: false])
|
||||
return bool(forKey: #function)
|
||||
}
|
||||
set { self[#function] = newValue }
|
||||
}
|
||||
|
||||
}
|
|
@ -128,12 +128,10 @@ extension StatusProviderFacade {
|
|||
|
||||
static func responseToStatusActiveLabelAction(provider: StatusProvider, cell: UITableViewCell, activeLabel: ActiveLabel, didTapEntity entity: ActiveEntity) {
|
||||
switch entity.type {
|
||||
case .hashtag(let text, _):
|
||||
let hashtagTimelienViewModel = HashtagTimelineViewModel(context: provider.context, hashtag: text)
|
||||
provider.coordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelienViewModel), from: provider, transition: .show)
|
||||
case .mention(let text, _):
|
||||
coordinateToStatusMentionProfileScene(for: .primary, provider: provider, cell: cell, mention: text)
|
||||
case .url(_, _, let url, _):
|
||||
case .url(_, _, let url, _),
|
||||
.mention(let url, _) where url.lowercased().hasPrefix("http"):
|
||||
// note:
|
||||
// some server mark the normal url as "u-url" class. :
|
||||
guard let url = URL(string: url) else { return }
|
||||
if let domain = provider.context.authenticationService.activeMastodonAuthenticationBox.value?.domain, url.host == domain,
|
||||
url.pathComponents.count >= 4,
|
||||
|
@ -146,6 +144,12 @@ extension StatusProviderFacade {
|
|||
} else {
|
||||
provider.coordinator.present(scene: .safari(url: url), from: nil, transition: .safariPresent(animated: true, completion: nil))
|
||||
}
|
||||
case .hashtag(let text, _):
|
||||
let hashtagTimelienViewModel = HashtagTimelineViewModel(context: provider.context, hashtag: text)
|
||||
provider.coordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelienViewModel), from: provider, transition: .show)
|
||||
case .mention(let text, let userInfo):
|
||||
let href = userInfo?["href"] as? String
|
||||
coordinateToStatusMentionProfileScene(for: .primary, provider: provider, cell: cell, mention: text, href: href)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -153,7 +157,10 @@ extension StatusProviderFacade {
|
|||
|
||||
static func responseToStatusMetaTextAction(provider: StatusProvider, cell: UITableViewCell, metaText: MetaText, didSelectMeta meta: Meta) {
|
||||
switch meta {
|
||||
case .url(_, _, let url, _):
|
||||
case .url(_, _, let url, _),
|
||||
.mention(_, let url, _) where url.lowercased().hasPrefix("http"):
|
||||
// note:
|
||||
// some server mark the normal url as "u-url" class. highlighted content is a URL
|
||||
guard let url = URL(string: url) else { return }
|
||||
if let domain = provider.context.authenticationService.activeMastodonAuthenticationBox.value?.domain, url.host == domain,
|
||||
url.pathComponents.count >= 4,
|
||||
|
@ -169,8 +176,9 @@ extension StatusProviderFacade {
|
|||
case .hashtag(_, let hashtag, _):
|
||||
let hashtagTimelineViewModel = HashtagTimelineViewModel(context: provider.context, hashtag: hashtag)
|
||||
provider.coordinator.present(scene: .hashtagTimeline(viewModel: hashtagTimelineViewModel), from: provider, transition: .show)
|
||||
case .mention(_, let mention, _):
|
||||
coordinateToStatusMentionProfileScene(for: .primary, provider: provider, cell: cell, mention: mention)
|
||||
case .mention(_, let mention, let userInfo):
|
||||
let href = userInfo?["href"] as? String
|
||||
coordinateToStatusMentionProfileScene(for: .primary, provider: provider, cell: cell, mention: mention, href: href)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
@ -208,17 +216,17 @@ extension StatusProviderFacade {
|
|||
}
|
||||
#endif
|
||||
|
||||
private static func coordinateToStatusMentionProfileScene(for target: Target, provider: StatusProvider, cell: UITableViewCell, mention: String) {
|
||||
private static func coordinateToStatusMentionProfileScene(for target: Target, provider: StatusProvider, cell: UITableViewCell, mention: String, href: String?) {
|
||||
provider.status(for: cell, indexPath: nil)
|
||||
.sink { [weak provider] status in
|
||||
guard let provider = provider else { return }
|
||||
guard let status = status else { return }
|
||||
coordinateToStatusMentionProfileScene(for: target, provider: provider, status: status, mention: mention)
|
||||
coordinateToStatusMentionProfileScene(for: target, provider: provider, status: status, mention: mention, href: href)
|
||||
}
|
||||
.store(in: &provider.disposeBag)
|
||||
}
|
||||
|
||||
private static func coordinateToStatusMentionProfileScene(for target: Target, provider: StatusProvider, status: Status, mention: String) {
|
||||
private static func coordinateToStatusMentionProfileScene(for target: Target, provider: StatusProvider, status: Status, mention: String, href: String?) {
|
||||
guard let activeMastodonAuthenticationBox = provider.context.authenticationService.activeMastodonAuthenticationBox.value else { return }
|
||||
let domain = activeMastodonAuthenticationBox.domain
|
||||
|
||||
|
@ -230,7 +238,13 @@ extension StatusProviderFacade {
|
|||
}()
|
||||
|
||||
// cannot continue without meta
|
||||
guard let mentionMeta = (status.mentions ?? Set()).first(where: { $0.username == mention }) else { return }
|
||||
guard let mentionMeta = (status.mentions ?? Set()).first(where: { $0.username == mention }) else {
|
||||
// present web page if possible
|
||||
if let url = href.flatMap({ URL(string: $0) }) {
|
||||
provider.coordinator.present(scene: .safari(url: url), from: provider, transition: .safariPresent(animated: true, completion: nil))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
let userID = mentionMeta.id
|
||||
|
||||
|
|
|
@ -317,8 +317,8 @@ any server.";
|
|||
"Scene.Settings.Section.Appearance.Dark" = "Always Dark";
|
||||
"Scene.Settings.Section.Appearance.Light" = "Always Light";
|
||||
"Scene.Settings.Section.Appearance.Title" = "Appearance";
|
||||
"Scene.Settings.Section.AppearanceSettings.AvatarAnimation.Title" = "Disable avatar animation";
|
||||
"Scene.Settings.Section.AppearanceSettings.DarkMode.Title" = "True black Dark Mode";
|
||||
"Scene.Settings.Section.AppearanceSettings.DisableAvatarAnimation" = "Disable avatar animation";
|
||||
"Scene.Settings.Section.AppearanceSettings.TrueBlackDarkMode" = "True black Dark Mode";
|
||||
"Scene.Settings.Section.Boringzone.Privacy" = "Privacy Policy";
|
||||
"Scene.Settings.Section.Boringzone.Terms" = "Terms of Service";
|
||||
"Scene.Settings.Section.Boringzone.Title" = "The Boring zone";
|
||||
|
@ -332,6 +332,8 @@ any server.";
|
|||
"Scene.Settings.Section.Notifications.Trigger.Follower" = "a follower";
|
||||
"Scene.Settings.Section.Notifications.Trigger.Noone" = "no one";
|
||||
"Scene.Settings.Section.Notifications.Trigger.Title" = "Notify me when";
|
||||
"Scene.Settings.Section.Preference.Title" = "Preference";
|
||||
"Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Using default browser open link";
|
||||
"Scene.Settings.Section.Spicyzone.Clear" = "Clear Media Cache";
|
||||
"Scene.Settings.Section.Spicyzone.Signout" = "Sign Out";
|
||||
"Scene.Settings.Section.Spicyzone.Title" = "The spicy zone";
|
||||
|
|
|
@ -317,8 +317,8 @@ any server.";
|
|||
"Scene.Settings.Section.Appearance.Dark" = "Always Dark";
|
||||
"Scene.Settings.Section.Appearance.Light" = "Always Light";
|
||||
"Scene.Settings.Section.Appearance.Title" = "Appearance";
|
||||
"Scene.Settings.Section.AppearanceSettings.AvatarAnimation.Title" = "Disable avatar animation";
|
||||
"Scene.Settings.Section.AppearanceSettings.DarkMode.Title" = "True black Dark Mode";
|
||||
"Scene.Settings.Section.AppearanceSettings.DisableAvatarAnimation" = "Disable avatar animation";
|
||||
"Scene.Settings.Section.AppearanceSettings.TrueBlackDarkMode" = "True black Dark Mode";
|
||||
"Scene.Settings.Section.Boringzone.Privacy" = "Privacy Policy";
|
||||
"Scene.Settings.Section.Boringzone.Terms" = "Terms of Service";
|
||||
"Scene.Settings.Section.Boringzone.Title" = "The Boring zone";
|
||||
|
@ -332,6 +332,8 @@ any server.";
|
|||
"Scene.Settings.Section.Notifications.Trigger.Follower" = "a follower";
|
||||
"Scene.Settings.Section.Notifications.Trigger.Noone" = "no one";
|
||||
"Scene.Settings.Section.Notifications.Trigger.Title" = "Notify me when";
|
||||
"Scene.Settings.Section.Preference.Title" = "Preference";
|
||||
"Scene.Settings.Section.Preference.UsingDefaultBrowser" = "Using default browser open link";
|
||||
"Scene.Settings.Section.Spicyzone.Clear" = "Clear Media Cache";
|
||||
"Scene.Settings.Section.Spicyzone.Signout" = "Sign Out";
|
||||
"Scene.Settings.Section.Spicyzone.Title" = "The spicy zone";
|
||||
|
|
|
@ -188,10 +188,17 @@ extension MastodonPickServerViewModel {
|
|||
return Just(Result.failure(APIService.APIError.implicit(.badRequest))).eraseToAnyPublisher()
|
||||
}
|
||||
self.unindexedServers.value = nil
|
||||
return self.context.apiService.instance(domain: domain)
|
||||
.map { response -> Result<Mastodon.Response.Content<[Mastodon.Entity.Server]>, Error>in
|
||||
let newResponse = response.map { [Mastodon.Entity.Server(instance: $0)] }
|
||||
return Result.success(newResponse)
|
||||
return self.context.apiService.webFinger(domain: domain)
|
||||
.flatMap { domain -> AnyPublisher<Result<Mastodon.Response.Content<[Mastodon.Entity.Server]>, Error>, Never> in
|
||||
return self.context.apiService.instance(domain: domain)
|
||||
.map { response -> Result<Mastodon.Response.Content<[Mastodon.Entity.Server]>, Error>in
|
||||
let newResponse = response.map { [Mastodon.Entity.Server(domain: domain, instance: $0)] }
|
||||
return Result.success(newResponse)
|
||||
}
|
||||
.catch { error in
|
||||
return Just(Result.failure(error))
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
.catch { error in
|
||||
return Just(Result.failure(error))
|
||||
|
|
|
@ -364,6 +364,9 @@ extension SettingsViewController: UITableViewDelegate {
|
|||
case .notification:
|
||||
// do nothing
|
||||
break
|
||||
case .preferenceUsingDefaultBrowser:
|
||||
// do nothing
|
||||
break
|
||||
case .boringZone(let link), .spicyZone(let link):
|
||||
switch link {
|
||||
case .termsOfService, .privacyPolicy:
|
||||
|
@ -501,7 +504,24 @@ extension SettingsViewController: SettingsToggleCellDelegate {
|
|||
// do nothing
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
case .preferenceUsingDefaultBrowser(let settingObjectID):
|
||||
let managedObjectContext = context.backgroundManagedObjectContext
|
||||
managedObjectContext.performChanges {
|
||||
let setting = managedObjectContext.object(with: settingObjectID) as! Setting
|
||||
setting.update(preferredUsingDefaultBrowser: isOn)
|
||||
}
|
||||
.sink { result in
|
||||
switch result {
|
||||
case .success:
|
||||
UserDefaults.shared.preferredUsingDefaultBrowser = isOn
|
||||
case .failure(let error):
|
||||
assertionFailure(error.localizedDescription)
|
||||
break
|
||||
}
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
default:
|
||||
assertionFailure()
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -102,13 +102,18 @@ extension SettingsViewModel {
|
|||
]
|
||||
snapshot.appendSections([.appearanceSettings])
|
||||
snapshot.appendItems(appearanceSettingItems, toSection: .appearanceSettings)
|
||||
|
||||
|
||||
// notification
|
||||
let notificationItems = SettingsItem.NotificationSwitchMode.allCases.map { mode in
|
||||
SettingsItem.notification(settingObjectID: setting.objectID, switchMode: mode)
|
||||
}
|
||||
snapshot.appendSections([.notifications])
|
||||
snapshot.appendItems(notificationItems, toSection: .notifications)
|
||||
|
||||
// preference
|
||||
snapshot.appendSections([.preference])
|
||||
snapshot.appendItems([.preferenceUsingDefaultBrowser(settingObjectID: setting.objectID)], toSection: .preference)
|
||||
|
||||
// boring zone
|
||||
let boringZoneSettingsItems: [SettingsItem] = {
|
||||
let links: [SettingsItem.Link] = [
|
||||
|
@ -170,7 +175,8 @@ extension SettingsViewModel {
|
|||
cell.delegate = settingsAppearanceTableViewCellDelegate
|
||||
return cell
|
||||
case .appearanceDarkMode(let objectID),
|
||||
.appearanceDisableAvatarAnimation(let objectID):
|
||||
.appearanceDisableAvatarAnimation(let objectID),
|
||||
.preferenceUsingDefaultBrowser(let objectID):
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: String(describing: SettingsToggleTableViewCell.self), for: indexPath) as! SettingsToggleTableViewCell
|
||||
cell.delegate = settingsToggleCellDelegate
|
||||
self.context.managedObjectContext.performAndWait {
|
||||
|
@ -231,11 +237,14 @@ extension SettingsViewModel {
|
|||
) {
|
||||
switch item {
|
||||
case .appearanceDarkMode:
|
||||
cell.textLabel?.text = L10n.Scene.Settings.Section.AppearanceSettings.DarkMode.title
|
||||
cell.textLabel?.text = L10n.Scene.Settings.Section.AppearanceSettings.trueBlackDarkMode
|
||||
cell.switchButton.isOn = setting.preferredTrueBlackDarkMode
|
||||
case .appearanceDisableAvatarAnimation:
|
||||
cell.textLabel?.text = L10n.Scene.Settings.Section.AppearanceSettings.AvatarAnimation.title
|
||||
cell.textLabel?.text = L10n.Scene.Settings.Section.AppearanceSettings.disableAvatarAnimation
|
||||
cell.switchButton.isOn = setting.preferredStaticAvatar
|
||||
case .preferenceUsingDefaultBrowser:
|
||||
cell.textLabel?.text = L10n.Scene.Settings.Section.Preference.usingDefaultBrowser
|
||||
cell.switchButton.isOn = setting.preferredUsingDefaultBrowser
|
||||
default:
|
||||
assertionFailure()
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ final class SawToothView: UIView {
|
|||
}
|
||||
bezierPath.addLine(to: CGPoint(x: 0, y: bottomY))
|
||||
bezierPath.close()
|
||||
ThemeService.shared.currentTheme.value.systemBackgroundColor.setFill()
|
||||
ThemeService.shared.currentTheme.value.tableViewCellBackgroundColor.setFill()
|
||||
bezierPath.fill()
|
||||
bezierPath.lineWidth = 0
|
||||
bezierPath.stroke()
|
||||
|
|
|
@ -86,7 +86,7 @@ class TimelineLoaderTableViewCell: UITableViewCell {
|
|||
loadMoreButton.heightAnchor.constraint(equalToConstant: TimelineLoaderTableViewCell.buttonHeight).priority(.required - 1),
|
||||
])
|
||||
|
||||
// use stack view to alignlment content center
|
||||
// use stack view to alignment content center
|
||||
stackView.spacing = 4
|
||||
stackView.axis = .horizontal
|
||||
stackView.alignment = .center
|
||||
|
@ -127,7 +127,7 @@ class TimelineLoaderTableViewCell: UITableViewCell {
|
|||
}
|
||||
|
||||
private func setupBackgroundColor(theme: Theme) {
|
||||
loadMoreButton.backgroundColor = theme.systemBackgroundColor
|
||||
loadMoreButton.backgroundColor = theme.tableViewCellBackgroundColor
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,9 +18,9 @@ extension MediaPreviewableViewController {
|
|||
case .mosaic(let mosaicImageViewContainer):
|
||||
guard index < mosaicImageViewContainer.imageViews.count else { return nil }
|
||||
let imageView = mosaicImageViewContainer.imageViews[index]
|
||||
return imageView.superview!.convert(imageView.frame, to: nil)
|
||||
return imageView.superview?.convert(imageView.frame, to: nil)
|
||||
case .profileAvatar(let profileHeaderView):
|
||||
return profileHeaderView.avatarImageView.superview!.convert(profileHeaderView.avatarImageView.frame, to: nil)
|
||||
return profileHeaderView.avatarImageView.superview?.convert(profileHeaderView.avatarImageView.frame, to: nil)
|
||||
case .profileBanner:
|
||||
return nil // fallback to snapshot.frame
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// APIService+WebFinger.swift
|
||||
// Mastodon
|
||||
//
|
||||
// Created by MainasuK Cirno on 2021-7-8.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Combine
|
||||
import CoreData
|
||||
import CoreDataStack
|
||||
import CommonOSLog
|
||||
import DateToolsSwift
|
||||
import MastodonSDK
|
||||
|
||||
extension APIService {
|
||||
|
||||
private static func webFingerEndpointURL(domain: String) -> URL {
|
||||
return URL(string: "https://\(domain)/")!
|
||||
.appendingPathComponent(".well-known")
|
||||
.appendingPathComponent("webfinger")
|
||||
}
|
||||
|
||||
func webFinger(
|
||||
domain: String
|
||||
) -> AnyPublisher<String, Error> {
|
||||
let url = APIService.webFingerEndpointURL(domain: domain)
|
||||
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 3)
|
||||
return session.dataTaskPublisher(for: request)
|
||||
.tryMap { data, response in
|
||||
return response.url?.host ?? domain
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
}
|
|
@ -81,26 +81,6 @@ final class AuthenticationService: NSObject {
|
|||
.assign(to: \.value, on: activeMastodonAuthenticationBox)
|
||||
.store(in: &disposeBag)
|
||||
|
||||
activeMastodonAuthenticationBox
|
||||
.receive(on: RunLoop.main)
|
||||
.sink { [weak self] authenticationBox in
|
||||
guard let _ = self else { return }
|
||||
guard let authenticationBox = authenticationBox else { return }
|
||||
let request = Setting.sortedFetchRequest
|
||||
request.predicate = Setting.predicate(domain: authenticationBox.domain, userID: authenticationBox.userID)
|
||||
guard let setting = managedObjectContext.safeFetch(request).first else { return }
|
||||
|
||||
let themeName: ThemeName = setting.preferredTrueBlackDarkMode ? .system : .mastodon
|
||||
if UserDefaults.shared.currentThemeNameRawValue != themeName.rawValue {
|
||||
ThemeService.shared.set(themeName: themeName)
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: update theme style", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
}
|
||||
if UserDefaults.shared.preferredStaticAvatar != setting.preferredStaticAvatar {
|
||||
UserDefaults.shared.preferredStaticAvatar = setting.preferredStaticAvatar
|
||||
}
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
||||
do {
|
||||
try mastodonAuthenticationFetchedResultsController.performFetch()
|
||||
mastodonAuthentications.value = mastodonAuthenticationFetchedResultsController.fetchedObjects ?? []
|
||||
|
|
|
@ -91,20 +91,16 @@ final class SettingService {
|
|||
self.currentSettingUpdateSubscription = nil
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
SettingService.updatePreference(setting: setting)
|
||||
self.currentSettingUpdateSubscription = ManagedObjectObserver.observe(object: setting)
|
||||
.sink(receiveCompletion: { _ in
|
||||
// do nothing
|
||||
}, receiveValue: { change in
|
||||
guard case .update(let object) = change.changeType,
|
||||
let setting = object as? Setting else { return }
|
||||
|
||||
// observe apparance mode
|
||||
switch setting.appearance {
|
||||
case .automatic: UserDefaults.shared.customUserInterfaceStyle = .unspecified
|
||||
case .light: UserDefaults.shared.customUserInterfaceStyle = .light
|
||||
case .dark: UserDefaults.shared.customUserInterfaceStyle = .dark
|
||||
}
|
||||
|
||||
SettingService.updatePreference(setting: setting)
|
||||
})
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
|
@ -187,3 +183,37 @@ extension SettingService {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extension SettingService {
|
||||
|
||||
static func updatePreference(setting: Setting) {
|
||||
// set appearance
|
||||
let userInterfaceStyle: UIUserInterfaceStyle = {
|
||||
switch setting.appearance {
|
||||
case .automatic: return .unspecified
|
||||
case .light: return .light
|
||||
case .dark: return .dark
|
||||
}
|
||||
}()
|
||||
if UserDefaults.shared.customUserInterfaceStyle != userInterfaceStyle {
|
||||
UserDefaults.shared.customUserInterfaceStyle = userInterfaceStyle
|
||||
}
|
||||
|
||||
// set theme
|
||||
let themeName: ThemeName = setting.preferredTrueBlackDarkMode ? .system : .mastodon
|
||||
if UserDefaults.shared.currentThemeNameRawValue != themeName.rawValue {
|
||||
ThemeService.shared.set(themeName: themeName)
|
||||
os_log(.info, log: .debug, "%{public}s[%{public}ld], %{public}s: update theme style", ((#file as NSString).lastPathComponent), #line, #function)
|
||||
}
|
||||
|
||||
// set avatar mode
|
||||
if UserDefaults.shared.preferredStaticAvatar != setting.preferredStaticAvatar {
|
||||
UserDefaults.shared.preferredStaticAvatar = setting.preferredStaticAvatar
|
||||
}
|
||||
|
||||
// set browser
|
||||
if UserDefaults.shared.preferredUsingDefaultBrowser != setting.preferredUsingDefaultBrowser {
|
||||
UserDefaults.shared.preferredUsingDefaultBrowser = setting.preferredUsingDefaultBrowser
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,8 +38,8 @@ extension Mastodon.Entity {
|
|||
case category
|
||||
}
|
||||
|
||||
public init(instance: Instance) {
|
||||
self.domain = instance.uri
|
||||
public init(domain: String, instance: Instance) {
|
||||
self.domain = domain // make domain configurable for WebFinger
|
||||
self.version = instance.version ?? ""
|
||||
self.description = instance.shortDescription ?? instance.description
|
||||
self.language = instance.languages?.first ?? ""
|
||||
|
|
|
@ -21,6 +21,7 @@ extension MastodonSDKTests {
|
|||
|
||||
let query = Mastodon.API.App.CreateQuery(
|
||||
clientName: "XCTest",
|
||||
redirectURIs: "mastodon://joinmastodon.org/oauth",
|
||||
website: nil
|
||||
)
|
||||
Mastodon.API.App.create(session: session, domain: domain, query: query)
|
||||
|
|
|
@ -17,12 +17,12 @@ extension MastodonSDKTests {
|
|||
}
|
||||
|
||||
func _testOAuthAuthorize(domain: String) throws {
|
||||
let query = Mastodon.API.OAuth.AuthorizeQuery(clientID: "StubClientID")
|
||||
let query = Mastodon.API.OAuth.AuthorizeQuery(clientID: "StubClientID", redirectURI: "mastodon://joinmastodon.org/oauth")
|
||||
let authorizeURL = Mastodon.API.OAuth.authorizeURL(domain: domain, query: query)
|
||||
os_log("%{public}s[%{public}ld], %{public}s: (%s) authorizeURL %s", ((#file as NSString).lastPathComponent), #line, #function, domain, authorizeURL.absoluteString)
|
||||
XCTAssertEqual(
|
||||
authorizeURL.absoluteString,
|
||||
"https://\(domain)/oauth/authorize?response_type=code&client_id=StubClientID&redirect_uri=urn:ietf:wg:oauth:2.0:oob&scope=read%20write%20follow%20push"
|
||||
"https://\(domain)/oauth/authorize?response_type=code&client_id=StubClientID&redirect_uri=mastodon://joinmastodon.org/oauth&scope=read%20write%20follow%20push"
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ extension MastodonSDKTests {
|
|||
}
|
||||
|
||||
func _testRevokeTokenFail() {
|
||||
let theExpectation = expectation(description: "Revoke Instance Infomation")
|
||||
let theExpectation = expectation(description: "Revoke Instance Information")
|
||||
let query = Mastodon.API.OAuth.RevokeTokenQuery(clientID: "StubClientID", clientSecret: "", token: "")
|
||||
Mastodon.API.OAuth.revokeToken(session: session, domain: domain, query: query)
|
||||
.receive(on: DispatchQueue.main)
|
||||
|
|
|
@ -31,3 +31,16 @@ class MastodonTests: XCTestCase {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extension MastodonTests {
|
||||
func testWebFinger() {
|
||||
let expectation = expectation(description: "webfinger")
|
||||
let cancellable = AppContext.shared.apiService.webFinger(domain: "pawoo.net")
|
||||
.sink { completion in
|
||||
expectation.fulfill()
|
||||
} receiveValue: { domain in
|
||||
expectation.fulfill()
|
||||
}
|
||||
wait(for: [expectation], timeout: 10)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue