Add link to account settings

This commit is contained in:
Justin Mazzocchi 2022-11-08 14:04:34 -08:00
parent 2497dae088
commit dd47dc62b2
17 changed files with 79 additions and 8 deletions

View file

@ -160,6 +160,7 @@
"registration.agree-to-server-rules-and-terms-of-service" = "Ich stimme den Serverregeln und Nutzungsbedingungen zu"; "registration.agree-to-server-rules-and-terms-of-service" = "Ich stimme den Serverregeln und Nutzungsbedingungen zu";
"registration.password-confirmation-mismatch" = "Das Passwort und die Passwortbestätigung stimmen nicht überein"; "registration.password-confirmation-mismatch" = "Das Passwort und die Passwortbestätigung stimmen nicht überein";
"secondary-navigation.about" = "Über diese App"; "secondary-navigation.about" = "Über diese App";
"secondary-navigation.account-settings" = "Kontoeinstellungen";
"secondary-navigation.accounts" = "Accounts"; "secondary-navigation.accounts" = "Accounts";
"secondary-navigation.lists" = "Listen"; "secondary-navigation.lists" = "Listen";
"secondary-navigation.my-profile" = "Mein Profil"; "secondary-navigation.my-profile" = "Mein Profil";

View file

@ -160,6 +160,7 @@
"registration.agree-to-server-rules-and-terms-of-service" = "I agree to the server rules and terms of service"; "registration.agree-to-server-rules-and-terms-of-service" = "I agree to the server rules and terms of service";
"registration.password-confirmation-mismatch" = "Password and password confirmation do not match"; "registration.password-confirmation-mismatch" = "Password and password confirmation do not match";
"secondary-navigation.about" = "About This App"; "secondary-navigation.about" = "About This App";
"secondary-navigation.account-settings" = "Account Settings";
"secondary-navigation.accounts" = "Accounts"; "secondary-navigation.accounts" = "Accounts";
"secondary-navigation.lists" = "Lists"; "secondary-navigation.lists" = "Lists";
"secondary-navigation.my-profile" = "My Profile"; "secondary-navigation.my-profile" = "My Profile";

View file

@ -160,6 +160,7 @@
"registration.agree-to-server-rules-and-terms-of-service" = "Estoy de acuerdo con las reglas del servidor y los términos del servicio"; "registration.agree-to-server-rules-and-terms-of-service" = "Estoy de acuerdo con las reglas del servidor y los términos del servicio";
"registration.password-confirmation-mismatch" = "La contraseña no coincide con su confirmación"; "registration.password-confirmation-mismatch" = "La contraseña no coincide con su confirmación";
"secondary-navigation.about" = "Acerca de esta aplicación"; "secondary-navigation.about" = "Acerca de esta aplicación";
"secondary-navigation.account-settings" = "Configuración de Cuenta";
"secondary-navigation.accounts" = "Cuentas"; "secondary-navigation.accounts" = "Cuentas";
"secondary-navigation.lists" = "Listas"; "secondary-navigation.lists" = "Listas";
"secondary-navigation.my-profile" = "Mi perfil"; "secondary-navigation.my-profile" = "Mi perfil";

View file

@ -160,6 +160,7 @@
"registration.agree-to-server-rules-and-terms-of-service" = "サーバーのルールとプライバシーポリシーに同意します"; "registration.agree-to-server-rules-and-terms-of-service" = "サーバーのルールとプライバシーポリシーに同意します";
"registration.password-confirmation-mismatch" = "パスワードと確認用パスワードが一致しません"; "registration.password-confirmation-mismatch" = "パスワードと確認用パスワードが一致しません";
"secondary-navigation.about" = "このアプリについて"; "secondary-navigation.about" = "このアプリについて";
"secondary-navigation.account-settings" = "アカウント設定";
"secondary-navigation.accounts" = "アカウント"; "secondary-navigation.accounts" = "アカウント";
"secondary-navigation.lists" = "リスト"; "secondary-navigation.lists" = "リスト";
"secondary-navigation.my-profile" = "マイプロフィール"; "secondary-navigation.my-profile" = "マイプロフィール";

View file

@ -160,6 +160,7 @@
"registration.agree-to-server-rules-and-terms-of-service" = "서버 규칙 및 개인정보처리방침에 동의해요"; "registration.agree-to-server-rules-and-terms-of-service" = "서버 규칙 및 개인정보처리방침에 동의해요";
"registration.password-confirmation-mismatch" = "입력한 비밀번호가 일치하지 않아요"; "registration.password-confirmation-mismatch" = "입력한 비밀번호가 일치하지 않아요";
"secondary-navigation.about" = "이 앱에 대해서"; "secondary-navigation.about" = "이 앱에 대해서";
"secondary-navigation.account-settings" = "계정 설정";
"secondary-navigation.accounts" = "계정"; "secondary-navigation.accounts" = "계정";
"secondary-navigation.lists" = "목록"; "secondary-navigation.lists" = "목록";
"secondary-navigation.my-profile" = "내 프로필"; "secondary-navigation.my-profile" = "내 프로필";

View file

@ -160,6 +160,7 @@
"registration.agree-to-server-rules-and-terms-of-service" = "Zgadzam się na zasady stosowane na serwerze i warunki świadczenia usługi"; "registration.agree-to-server-rules-and-terms-of-service" = "Zgadzam się na zasady stosowane na serwerze i warunki świadczenia usługi";
"registration.password-confirmation-mismatch" = "Hasło i powtórzone hasło się nie zgadzają"; "registration.password-confirmation-mismatch" = "Hasło i powtórzone hasło się nie zgadzają";
"secondary-navigation.about" = "O aplikacji"; "secondary-navigation.about" = "O aplikacji";
"secondary-navigation.account-settings" = "Ustawienia konta";
"secondary-navigation.accounts" = "Konta"; "secondary-navigation.accounts" = "Konta";
"secondary-navigation.lists" = "Listy"; "secondary-navigation.lists" = "Listy";
"secondary-navigation.my-profile" = "Mój profil"; "secondary-navigation.my-profile" = "Mój profil";

View file

@ -160,6 +160,7 @@
"registration.agree-to-server-rules-and-terms-of-service" = "Я принимаю правила сервера и условия предоставления услуг"; "registration.agree-to-server-rules-and-terms-of-service" = "Я принимаю правила сервера и условия предоставления услуг";
"registration.password-confirmation-mismatch" = "Пароли не совпадают"; "registration.password-confirmation-mismatch" = "Пароли не совпадают";
"secondary-navigation.about" = "О приложении"; "secondary-navigation.about" = "О приложении";
"secondary-navigation.account-settings" = "Настройки аккаунта";
"secondary-navigation.accounts" = "Аккаунты"; "secondary-navigation.accounts" = "Аккаунты";
"secondary-navigation.lists" = "Списки"; "secondary-navigation.lists" = "Списки";
"secondary-navigation.my-profile" = "Профиль"; "secondary-navigation.my-profile" = "Профиль";

View file

@ -160,6 +160,7 @@
"registration.agree-to-server-rules-and-terms-of-service" = "我同意实例规则和服务条款"; "registration.agree-to-server-rules-and-terms-of-service" = "我同意实例规则和服务条款";
"registration.password-confirmation-mismatch" = "密码和确认密码不匹配"; "registration.password-confirmation-mismatch" = "密码和确认密码不匹配";
"secondary-navigation.about" = "关于这个应用"; "secondary-navigation.about" = "关于这个应用";
"secondary-navigation.account-settings" = "账号设置";
"secondary-navigation.accounts" = "账户"; "secondary-navigation.accounts" = "账户";
"secondary-navigation.lists" = "列表"; "secondary-navigation.lists" = "列表";
"secondary-navigation.my-profile" = "我的个人资料"; "secondary-navigation.my-profile" = "我的个人资料";

View file

@ -0,0 +1,41 @@
//
// File.swift
//
//
// Created by Justin Mazzocchi on 11/8/22.
//
import Combine
import Foundation
public struct AccountSettingsService {
private let instanceURI: String
private let webAuthSessionType: WebAuthSession.Type
private let webAuthSessionContextProvider = WebAuthSessionContextProvider()
public init(instanceURI: String, environment: AppEnvironment) {
self.instanceURI = instanceURI
webAuthSessionType = environment.webAuthSessionType
}
}
public extension AccountSettingsService {
func openAccountSettings() -> AnyPublisher<URL, Error> {
guard let url = URL(string: "https://\(instanceURI)/auth/edit") else {
return Fail(error: URLError(.badURL)).eraseToAnyPublisher()
}
print(webAuthSessionContextProvider)
return webAuthSessionType.publisher(
url: url,
callbackURLScheme: nil,
presentationContextProvider: webAuthSessionContextProvider)
}
}
private extension AccountSettingsService {
func accountSettingsURL(instanceURI: String) -> URL? {
URL(string: "https://\(instanceURI)/auth/edit")
}
}

View file

@ -30,9 +30,8 @@ extension WebAuthSession {
} }
} }
webAuthSession.presentationContextProvider = presentationContextProvider
DispatchQueue.main.async { DispatchQueue.main.async {
webAuthSession.presentationContextProvider = presentationContextProvider
webAuthSession.start() webAuthSession.start()
} }
} }

View file

@ -56,6 +56,10 @@ extension ContentDatabase {
keychain: MockKeychain.self) keychain: MockKeychain.self)
} }
public extension AppEnvironment {
static let preview = environment
}
public extension URL { public extension URL {
static let previewInstanceURL = URL(string: "https://mastodon.social")! static let previewInstanceURL = URL(string: "https://mastodon.social")!
} }

View file

@ -16,10 +16,12 @@ public final class NavigationViewModel: ObservableObject {
@Published public var alertItem: AlertItem? @Published public var alertItem: AlertItem?
private let navigationsSubject = PassthroughSubject<Navigation, Never>() private let navigationsSubject = PassthroughSubject<Navigation, Never>()
private let environment: AppEnvironment
private var cancellables = Set<AnyCancellable>() private var cancellables = Set<AnyCancellable>()
public init(identityContext: IdentityContext) { public init(identityContext: IdentityContext, environment: AppEnvironment) {
self.identityContext = identityContext self.identityContext = identityContext
self.environment = environment
navigations = navigationsSubject.eraseToAnyPublisher() navigations = navigationsSubject.eraseToAnyPublisher()
identityContext.$identity identityContext.$identity
@ -104,6 +106,12 @@ public extension NavigationViewModel {
navigationsSubject.send(.profile(identityContext.service.navigationService.profileService(id: id))) navigationsSubject.send(.profile(identityContext.service.navigationService.profileService(id: id)))
} }
func navigateToAccountSettings(instanceURI: String) {
AccountSettingsService(instanceURI: instanceURI, environment: environment).openAccountSettings()
.sink { _ in } receiveValue: { _ in }
.store(in: &cancellables)
}
func navigate(timeline: Timeline) { func navigate(timeline: Timeline) {
presentingSecondaryNavigation = false presentingSecondaryNavigation = false
presentedNewStatusViewModel = nil presentedNewStatusViewModel = nil

View file

@ -143,7 +143,7 @@ private extension RootViewModel {
self.notifyIdentityChange(identityContext: identityContext) self.notifyIdentityChange(identityContext: identityContext)
} }
return NavigationViewModel(identityContext: identityContext) return NavigationViewModel(identityContext: identityContext, environment: self.environment)
} }
.assign(to: &$navigationViewModel) .assign(to: &$navigationViewModel)
} }

View file

@ -88,7 +88,7 @@ import PreviewViewModels
struct AboutView_Previews: PreviewProvider { struct AboutView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
AboutView(viewModel: NavigationViewModel(identityContext: .preview)) AboutView(viewModel: NavigationViewModel(identityContext: .preview, environment: .preview))
} }
} }
#endif #endif

View file

@ -64,7 +64,7 @@ import PreviewViewModels
struct ListsView_Previews: PreviewProvider { struct ListsView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
ListsView(viewModel: .init(identityContext: .preview)) ListsView(viewModel: .init(identityContext: .preview))
.environmentObject(NavigationViewModel(identityContext: .preview)) .environmentObject(NavigationViewModel(identityContext: .preview, environment: .preview))
} }
} }
#endif #endif

View file

@ -22,6 +22,17 @@ struct SecondaryNavigationView: View {
} }
} }
} }
if let instanceURI = viewModel.identityContext.identity.instance?.uri {
Button {
viewModel.navigateToAccountSettings(instanceURI: instanceURI)
} label: {
Label {
Text("secondary-navigation.account-settings").foregroundColor(.primary)
} icon: {
Image(systemName: "person.crop.square")
}
}
}
NavigationLink( NavigationLink(
destination: IdentitiesView { .init(identityContext: viewModel.identityContext) } destination: IdentitiesView { .init(identityContext: viewModel.identityContext) }
.environmentObject(rootViewModel)) { .environmentObject(rootViewModel)) {
@ -84,7 +95,7 @@ import PreviewViewModels
struct SecondaryNavigationView_Previews: PreviewProvider { struct SecondaryNavigationView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
SecondaryNavigationView(viewModel: NavigationViewModel(identityContext: .preview)) SecondaryNavigationView(viewModel: NavigationViewModel(identityContext: .preview, environment: .preview))
.environmentObject(RootViewModel.preview) .environmentObject(RootViewModel.preview)
} }
} }

View file

@ -23,7 +23,7 @@ import PreviewViewModels
struct MainNavigationView_Previews: PreviewProvider { struct MainNavigationView_Previews: PreviewProvider {
static var previews: some View { static var previews: some View {
MainNavigationView { NavigationViewModel(identityContext: .preview) } MainNavigationView { NavigationViewModel(identityContext: .preview, environment: .preview) }
.environmentObject(RootViewModel.preview) .environmentObject(RootViewModel.preview)
} }
} }