mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-05 11:58:32 +00:00
Use strings from Localazy (#718)
* Adopt strings from Localazy. * Remove all old Android strings. * Disable german snapshot tests for now. * Rebase and add latest strings.
This commit is contained in:
@@ -38,15 +38,15 @@ struct AnalyticsPromptViewState: BindableState {
|
||||
/// A collection of strings for the UI that need to be parsed from HTML
|
||||
struct AnalyticsPromptStrings {
|
||||
let optInContent: AttributedString
|
||||
let point1 = AttributedStringBuilder().fromHTML(ElementL10n.analyticsOptInListItem1) ?? AttributedString(ElementL10n.analyticsOptInListItem1)
|
||||
let point2 = AttributedStringBuilder().fromHTML(ElementL10n.analyticsOptInListItem2) ?? AttributedString(ElementL10n.analyticsOptInListItem2)
|
||||
let point1 = AttributedStringBuilder().fromHTML(UntranslatedL10n.analyticsOptInListItem1) ?? AttributedString(UntranslatedL10n.analyticsOptInListItem1)
|
||||
let point2 = AttributedStringBuilder().fromHTML(UntranslatedL10n.analyticsOptInListItem2) ?? AttributedString(UntranslatedL10n.analyticsOptInListItem2)
|
||||
|
||||
init() {
|
||||
// Create the opt in content with a placeholder.
|
||||
let linkPlaceholder = "{link}"
|
||||
var optInContent = AttributedString(ElementL10n.analyticsOptInContent(InfoPlistReader.main.bundleDisplayName, linkPlaceholder))
|
||||
var optInContent = AttributedString(UntranslatedL10n.analyticsOptInContent(InfoPlistReader.main.bundleDisplayName, linkPlaceholder))
|
||||
optInContent.replace(linkPlaceholder,
|
||||
with: ElementL10n.analyticsOptInContentLink,
|
||||
with: UntranslatedL10n.analyticsOptInContentLink,
|
||||
asLinkTo: ServiceLocator.shared.settings.analyticsConfiguration.termsURL)
|
||||
self.optInContent = optInContent
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ struct AnalyticsPrompt: View {
|
||||
Image(uiImage: Asset.Images.analyticsLogo.image)
|
||||
.padding(.bottom, 25)
|
||||
|
||||
Text(ElementL10n.analyticsOptInTitle(InfoPlistReader.main.bundleDisplayName))
|
||||
Text(UntranslatedL10n.analyticsOptInTitle(InfoPlistReader.main.bundleDisplayName))
|
||||
.font(.element.title2Bold)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
@@ -84,7 +84,7 @@ struct AnalyticsPrompt: View {
|
||||
VStack(alignment: .leading) {
|
||||
AnalyticsPromptCheckmarkItem(attributedString: context.viewState.strings.point1)
|
||||
AnalyticsPromptCheckmarkItem(attributedString: context.viewState.strings.point1)
|
||||
AnalyticsPromptCheckmarkItem(string: ElementL10n.analyticsOptInListItem3)
|
||||
AnalyticsPromptCheckmarkItem(string: UntranslatedL10n.analyticsOptInListItem3)
|
||||
}
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.font(.element.body)
|
||||
@@ -96,13 +96,13 @@ struct AnalyticsPrompt: View {
|
||||
private var buttons: some View {
|
||||
VStack {
|
||||
Button { context.send(viewAction: .enable) } label: {
|
||||
Text(ElementL10n.actionEnable)
|
||||
Text(L10n.actionEnable)
|
||||
.font(.element.bodyBold)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
|
||||
Button { context.send(viewAction: .disable) } label: {
|
||||
Text(ElementL10n.actionNotNow)
|
||||
Text(L10n.actionNotNow)
|
||||
.font(.element.bodyBold)
|
||||
.padding(12)
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ class AuthenticationCoordinator: CoordinatorProtocol {
|
||||
private func startLoading() {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
title: ElementL10n.loading,
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
}
|
||||
|
||||
|
||||
@@ -95,7 +95,7 @@ final class LoginCoordinator: CoordinatorProtocol {
|
||||
if isInteractionBlocking {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
title: ElementL10n.loading,
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
} else {
|
||||
viewModel.update(isLoading: true)
|
||||
@@ -108,11 +108,11 @@ final class LoginCoordinator: CoordinatorProtocol {
|
||||
}
|
||||
|
||||
private func indicateSuccess() {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: ElementL10n.dialogTitleSuccess))
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonSuccess))
|
||||
}
|
||||
|
||||
private func indicateFailure() {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: ElementL10n.dialogTitleError))
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonError))
|
||||
}
|
||||
|
||||
/// Processes an error to either update the flow or display it to the user.
|
||||
@@ -121,13 +121,13 @@ final class LoginCoordinator: CoordinatorProtocol {
|
||||
|
||||
switch error {
|
||||
case .invalidCredentials:
|
||||
viewModel.displayError(.alert(ElementL10n.authInvalidLoginParam))
|
||||
viewModel.displayError(.alert(L10n.screenLoginErrorInvalidCredentials))
|
||||
case .accountDeactivated:
|
||||
viewModel.displayError(.alert(ElementL10n.authInvalidLoginDeactivatedAccount))
|
||||
viewModel.displayError(.alert(L10n.screenLoginErrorDeactivatedAccount))
|
||||
case .slidingSyncNotAvailable:
|
||||
viewModel.displayError(.slidingSyncAlert)
|
||||
default:
|
||||
viewModel.displayError(.alert(ElementL10n.unknownError))
|
||||
viewModel.displayError(.alert(L10n.errorUnknown))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ final class LoginCoordinator: CoordinatorProtocol {
|
||||
Task {
|
||||
switch await authenticationService.login(username: username,
|
||||
password: password,
|
||||
initialDeviceName: UIDevice.current.initialDisplayName,
|
||||
initialDeviceName: UIDevice.current.initialDeviceName,
|
||||
deviceId: nil) {
|
||||
case .success(let userSession):
|
||||
callback?(.signedIn(userSession))
|
||||
|
||||
@@ -56,19 +56,19 @@ class LoginViewModel: LoginViewModelType, LoginViewModelProtocol {
|
||||
switch type {
|
||||
case .alert(let message):
|
||||
state.bindings.alertInfo = AlertInfo(id: type,
|
||||
title: ElementL10n.dialogTitleError,
|
||||
title: L10n.commonError,
|
||||
message: message)
|
||||
case .invalidHomeserver:
|
||||
state.bindings.alertInfo = AlertInfo(id: type,
|
||||
title: ElementL10n.dialogTitleError,
|
||||
message: ElementL10n.loginSigninMatrixIdErrorInvalidMatrixId)
|
||||
title: L10n.commonError,
|
||||
message: L10n.screenLoginErrorInvalidUserId)
|
||||
case .slidingSyncAlert:
|
||||
let openURL = { UIApplication.shared.open(ServiceLocator.shared.settings.slidingSyncLearnMoreURL) }
|
||||
state.bindings.alertInfo = AlertInfo(id: .slidingSyncAlert,
|
||||
title: ElementL10n.serverSelectionSlidingSyncAlertTitle,
|
||||
message: ElementL10n.serverSelectionSlidingSyncAlertMessage,
|
||||
primaryButton: .init(title: ElementL10n.actionLearnMore, role: .cancel, action: openURL),
|
||||
secondaryButton: .init(title: ElementL10n.actionCancel, action: nil))
|
||||
title: L10n.commonServerNotSupported,
|
||||
message: L10n.screenChangeServerErrorNoSlidingSyncMessage,
|
||||
primaryButton: .init(title: L10n.actionLearnMore, role: .cancel, action: openURL),
|
||||
secondaryButton: .init(title: L10n.actionCancel, action: nil))
|
||||
|
||||
// Clear out the invalid username to avoid an attempted login to matrix.org
|
||||
state.bindings.username = ""
|
||||
|
||||
@@ -53,7 +53,7 @@ struct LoginScreen: View {
|
||||
|
||||
/// The header containing a Welcome Back title.
|
||||
var header: some View {
|
||||
Text(ElementL10n.ftueAuthWelcomeBackTitle)
|
||||
Text(L10n.screenLoginTitle)
|
||||
.font(.element.title1Bold)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
@@ -69,16 +69,16 @@ struct LoginScreen: View {
|
||||
/// The form with text fields for username and password, along with a submit button.
|
||||
var loginForm: some View {
|
||||
VStack(alignment: .leading, spacing: 0) {
|
||||
Text(ElementL10n.ftueAuthSignInEnterDetails)
|
||||
Text(L10n.screenLoginFormHeader)
|
||||
.font(.element.footnote)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
.padding(.horizontal, 16)
|
||||
.padding(.bottom, 8)
|
||||
|
||||
TextField(ElementL10n.username,
|
||||
TextField(L10n.commonUsername,
|
||||
text: $context.username,
|
||||
// Prompt colour fixes a flicker that occurs before the text field style introspects the field.
|
||||
prompt: Text(ElementL10n.username).foregroundColor(.element.tertiaryContent))
|
||||
prompt: Text(L10n.commonUsername).foregroundColor(.element.tertiaryContent))
|
||||
.focused($isUsernameFocused)
|
||||
.textFieldStyle(.elementInput(accessibilityIdentifier: A11yIdentifiers.loginScreen.emailUsername))
|
||||
.disableAutocorrection(true)
|
||||
@@ -89,10 +89,10 @@ struct LoginScreen: View {
|
||||
.onSubmit { isPasswordFocused = true }
|
||||
.padding(.bottom, 20)
|
||||
|
||||
SecureField(ElementL10n.loginSignupPasswordHint,
|
||||
SecureField(L10n.commonPassword,
|
||||
text: $context.password,
|
||||
// Prompt colour fixes a flicker that occurs before the text field style introspects the field.
|
||||
prompt: Text(ElementL10n.loginSignupPasswordHint).foregroundColor(.element.tertiaryContent))
|
||||
prompt: Text(L10n.commonPassword).foregroundColor(.element.tertiaryContent))
|
||||
.focused($isPasswordFocused)
|
||||
.textFieldStyle(.elementInput(accessibilityIdentifier: A11yIdentifiers.loginScreen.password))
|
||||
.textContentType(.password)
|
||||
@@ -102,7 +102,7 @@ struct LoginScreen: View {
|
||||
Spacer().frame(height: 32)
|
||||
|
||||
Button(action: submit) {
|
||||
Text(ElementL10n.loginContinue)
|
||||
Text(L10n.actionContinue)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
.disabled(!context.viewState.canSubmit)
|
||||
@@ -113,7 +113,7 @@ struct LoginScreen: View {
|
||||
/// The OIDC button that can be used for login.
|
||||
var oidcButton: some View {
|
||||
Button { context.send(viewAction: .continueWithOIDC) } label: {
|
||||
Text(ElementL10n.loginContinue)
|
||||
Text(L10n.actionContinue)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
.accessibilityIdentifier(A11yIdentifiers.loginScreen.oidc)
|
||||
@@ -121,7 +121,7 @@ struct LoginScreen: View {
|
||||
|
||||
/// Text shown if neither password or OIDC login is supported.
|
||||
var loginUnavailableText: some View {
|
||||
Text(ElementL10n.autodiscoverWellKnownError)
|
||||
Text(L10n.screenLoginErrorUnsupportedAuthentication)
|
||||
.font(.body)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
@@ -156,9 +156,13 @@ struct Login_Previews: PreviewProvider {
|
||||
|
||||
static var previews: some View {
|
||||
screen(for: LoginViewModel(homeserver: .mockMatrixDotOrg))
|
||||
.previewDisplayName("matrix.org")
|
||||
screen(for: credentialsViewModel)
|
||||
screen(for: LoginViewModel(homeserver: .mockBasicServer))
|
||||
.previewDisplayName("Credentials Entered")
|
||||
screen(for: LoginViewModel(homeserver: .mockOIDC))
|
||||
.previewDisplayName("OIDC")
|
||||
screen(for: LoginViewModel(homeserver: .mockUnsupported))
|
||||
.previewDisplayName("Unsupported")
|
||||
}
|
||||
|
||||
static func screen(for viewModel: LoginViewModel) -> some View {
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ struct LoginServerInfoSection: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 8) {
|
||||
Text(ElementL10n.ftueAuthSignInChooseServerHeader)
|
||||
Text(L10n.screenLoginServerHeader)
|
||||
.font(.element.footnote)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
.padding(.horizontal, 16)
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ enum MockServerSelectionScreenState: CaseIterable {
|
||||
case .invalidAddress:
|
||||
let viewModel = ServerSelectionViewModel(homeserverAddress: "thisisbad",
|
||||
isModallyPresented: true)
|
||||
viewModel.displayError(.footerMessage(ElementL10n.unknownError))
|
||||
viewModel.displayError(.footerMessage(L10n.errorUnknown))
|
||||
return viewModel
|
||||
case .nonModal:
|
||||
return ServerSelectionViewModel(homeserverAddress: "https://matrix.org",
|
||||
|
||||
+3
-3
@@ -69,7 +69,7 @@ final class ServerSelectionCoordinator: CoordinatorProtocol {
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func startLoading(label: String = ElementL10n.loading) {
|
||||
private func startLoading(label: String = L10n.commonLoading) {
|
||||
userIndicatorController.submitIndicator(UserIndicator(type: .modal,
|
||||
title: label,
|
||||
persistent: true))
|
||||
@@ -101,11 +101,11 @@ final class ServerSelectionCoordinator: CoordinatorProtocol {
|
||||
private func handleError(_ error: AuthenticationServiceError) {
|
||||
switch error {
|
||||
case .invalidServer, .invalidHomeserverAddress:
|
||||
viewModel.displayError(.footerMessage(ElementL10n.loginErrorHomeserverNotFound))
|
||||
viewModel.displayError(.footerMessage(L10n.screenChangeServerErrorInvalidHomeserver))
|
||||
case .slidingSyncNotAvailable:
|
||||
viewModel.displayError(.slidingSyncAlert)
|
||||
default:
|
||||
viewModel.displayError(.footerMessage(ElementL10n.unknownError))
|
||||
viewModel.displayError(.footerMessage(L10n.errorUnknown))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,9 +27,9 @@ struct ServerSelectionViewState: BindableState {
|
||||
/// The message to be shown in the text field footer when no error has occurred.
|
||||
private let regularFooterMessage = {
|
||||
let linkPlaceholder = "{link}"
|
||||
var message = AttributedString(ElementL10n.serverSelectionServerFooter(linkPlaceholder))
|
||||
var message = AttributedString(L10n.screenChangeServerFormNotice(linkPlaceholder))
|
||||
message.replace(linkPlaceholder,
|
||||
with: ElementL10n.actionLearnMore,
|
||||
with: L10n.actionLearnMore,
|
||||
asLinkTo: ServiceLocator.shared.settings.slidingSyncLearnMoreURL)
|
||||
return message
|
||||
}()
|
||||
@@ -48,7 +48,7 @@ struct ServerSelectionViewState: BindableState {
|
||||
|
||||
/// The title shown on the confirm button.
|
||||
var buttonTitle: String {
|
||||
isModallyPresented ? ElementL10n.continue : ElementL10n.actionNext
|
||||
isModallyPresented ? L10n.actionContinue : L10n.actionNext
|
||||
}
|
||||
|
||||
/// The text field is showing an error.
|
||||
|
||||
+4
-4
@@ -48,10 +48,10 @@ class ServerSelectionViewModel: ServerSelectionViewModelType, ServerSelectionVie
|
||||
case .slidingSyncAlert:
|
||||
let openURL = { UIApplication.shared.open(ServiceLocator.shared.settings.slidingSyncLearnMoreURL) }
|
||||
state.bindings.alertInfo = AlertInfo(id: .slidingSyncAlert,
|
||||
title: ElementL10n.serverSelectionSlidingSyncAlertTitle,
|
||||
message: ElementL10n.serverSelectionSlidingSyncAlertMessage,
|
||||
primaryButton: .init(title: ElementL10n.actionLearnMore, role: .cancel, action: openURL),
|
||||
secondaryButton: .init(title: ElementL10n.actionCancel, action: nil))
|
||||
title: L10n.commonServerNotSupported,
|
||||
message: L10n.screenChangeServerErrorNoSlidingSyncMessage,
|
||||
primaryButton: .init(title: L10n.actionLearnMore, role: .cancel, action: openURL),
|
||||
secondaryButton: .init(title: L10n.actionCancel, action: nil))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-5
@@ -43,12 +43,12 @@ struct ServerSelectionScreen: View {
|
||||
AuthenticationIconImage(image: Image(asset: Asset.Images.serverSelectionIcon), insets: 19)
|
||||
.padding(.bottom, 8)
|
||||
|
||||
Text(ElementL10n.ftueAuthChooseServerTitle)
|
||||
Text(L10n.commonSelectYourServer)
|
||||
.font(.element.title2Bold)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
|
||||
Text(ElementL10n.ftueAuthChooseServerSignInSubtitle)
|
||||
Text(L10n.screenChangeServerSubtitle)
|
||||
.font(.element.subheadline)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.tertiaryContent)
|
||||
@@ -59,8 +59,8 @@ struct ServerSelectionScreen: View {
|
||||
/// The text field and confirm button where the user enters a server URL.
|
||||
var serverForm: some View {
|
||||
VStack(alignment: .leading, spacing: 24) {
|
||||
TextField(ElementL10n.ftueAuthChooseServerEntryHint, text: $context.homeserverAddress)
|
||||
.textFieldStyle(.elementInput(labelText: Text(ElementL10n.hsUrl),
|
||||
TextField(L10n.commonServerUrl, text: $context.homeserverAddress)
|
||||
.textFieldStyle(.elementInput(labelText: Text(L10n.screenChangeServerFormHeader),
|
||||
footerText: Text(context.viewState.footerMessage),
|
||||
isError: context.viewState.isShowingFooterError,
|
||||
accessibilityIdentifier: A11yIdentifiers.changeServerScreen.server))
|
||||
@@ -85,7 +85,7 @@ struct ServerSelectionScreen: View {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
if context.viewState.isModallyPresented {
|
||||
Button { context.send(viewAction: .dismiss) } label: {
|
||||
Text(ElementL10n.actionCancel)
|
||||
Text(L10n.actionCancel)
|
||||
}
|
||||
.accessibilityIdentifier(A11yIdentifiers.changeServerScreen.dismiss)
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ final class SoftLogoutCoordinator: CoordinatorProtocol {
|
||||
@MainActor private func startLoading() {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
title: ElementL10n.loading,
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ final class SoftLogoutCoordinator: CoordinatorProtocol {
|
||||
Task {
|
||||
switch await authenticationService.login(username: username,
|
||||
password: password,
|
||||
initialDeviceName: UIDevice.current.initialDisplayName,
|
||||
initialDeviceName: UIDevice.current.initialDeviceName,
|
||||
deviceId: parameters.credentials.deviceId) {
|
||||
case .success(let userSession):
|
||||
callback?(.signedIn(userSession))
|
||||
@@ -160,11 +160,11 @@ final class SoftLogoutCoordinator: CoordinatorProtocol {
|
||||
private func handleError(_ error: AuthenticationServiceError) {
|
||||
switch error {
|
||||
case .invalidCredentials:
|
||||
viewModel.displayError(.alert(ElementL10n.authInvalidLoginParam))
|
||||
viewModel.displayError(.alert(L10n.screenLoginErrorInvalidCredentials))
|
||||
case .accountDeactivated:
|
||||
viewModel.displayError(.alert(ElementL10n.authInvalidLoginDeactivatedAccount))
|
||||
viewModel.displayError(.alert(L10n.screenLoginErrorDeactivatedAccount))
|
||||
default:
|
||||
viewModel.displayError(.alert(ElementL10n.unknownError))
|
||||
viewModel.displayError(.alert(L10n.errorUnknown))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ class SoftLogoutViewModel: SoftLogoutViewModelType, SoftLogoutViewModelProtocol
|
||||
switch type {
|
||||
case .alert(let message):
|
||||
state.bindings.alertInfo = AlertInfo(id: type,
|
||||
title: ElementL10n.dialogTitleError,
|
||||
title: L10n.commonError,
|
||||
message: message)
|
||||
case .unknown:
|
||||
state.bindings.alertInfo = AlertInfo(id: type)
|
||||
|
||||
@@ -54,20 +54,20 @@ struct SoftLogoutScreen: View {
|
||||
/// The title, message and icon at the top of the screen.
|
||||
var header: some View {
|
||||
VStack(alignment: .leading, spacing: 16) {
|
||||
Text(ElementL10n.softLogoutSigninTitle)
|
||||
Text(UntranslatedL10n.softLogoutSigninTitle)
|
||||
.font(.element.title2Bold)
|
||||
.multilineTextAlignment(.leading)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
.accessibilityIdentifier(A11yIdentifiers.softLogoutScreen.title)
|
||||
|
||||
Text(ElementL10n.softLogoutSigninNotice(context.viewState.credentials.homeserverName, context.viewState.credentials.userDisplayName, context.viewState.credentials.userId))
|
||||
Text(UntranslatedL10n.softLogoutSigninNotice(context.viewState.credentials.homeserverName, context.viewState.credentials.userDisplayName, context.viewState.credentials.userId))
|
||||
.font(.element.body)
|
||||
.multilineTextAlignment(.leading)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
.accessibilityIdentifier(A11yIdentifiers.softLogoutScreen.message)
|
||||
|
||||
if context.viewState.showRecoverEncryptionKeysMessage {
|
||||
Text(ElementL10n.softLogoutSigninE2eWarningNotice)
|
||||
Text(UntranslatedL10n.softLogoutSigninE2eWarningNotice)
|
||||
.font(.element.body)
|
||||
.multilineTextAlignment(.leading)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
@@ -78,7 +78,7 @@ struct SoftLogoutScreen: View {
|
||||
/// The form with text fields for username and password, along with a submit button.
|
||||
var loginForm: some View {
|
||||
VStack(spacing: 14) {
|
||||
SecureField(ElementL10n.loginSignupPasswordHint, text: $context.password)
|
||||
SecureField(L10n.commonPassword, text: $context.password)
|
||||
.focused($isPasswordFocused)
|
||||
.textFieldStyle(.elementInput())
|
||||
.textContentType(.password)
|
||||
@@ -87,7 +87,7 @@ struct SoftLogoutScreen: View {
|
||||
.accessibilityIdentifier(A11yIdentifiers.softLogoutScreen.password)
|
||||
|
||||
Button { context.send(viewAction: .forgotPassword) } label: {
|
||||
Text(ElementL10n.ftueAuthForgotPassword)
|
||||
Text(UntranslatedL10n.softLogoutForgotPassword)
|
||||
.font(.element.body)
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .trailing)
|
||||
@@ -95,7 +95,7 @@ struct SoftLogoutScreen: View {
|
||||
.accessibilityIdentifier(A11yIdentifiers.softLogoutScreen.forgotPassword)
|
||||
|
||||
Button(action: submit) {
|
||||
Text(ElementL10n.loginSignupSubmit)
|
||||
Text(L10n.actionNext)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
.disabled(!context.viewState.canSubmit)
|
||||
@@ -106,14 +106,14 @@ struct SoftLogoutScreen: View {
|
||||
/// The OIDC button that can be used for login.
|
||||
var oidcButton: some View {
|
||||
Button { context.send(viewAction: .continueWithOIDC) } label: {
|
||||
Text(ElementL10n.loginContinue)
|
||||
Text(L10n.actionContinue)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
}
|
||||
|
||||
/// Text shown if neither password or OIDC login is supported.
|
||||
var loginUnavailableText: some View {
|
||||
Text(ElementL10n.autodiscoverWellKnownError)
|
||||
Text(L10n.screenLoginErrorUnsupportedAuthentication)
|
||||
.font(.body)
|
||||
.multilineTextAlignment(.center)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
@@ -123,13 +123,13 @@ struct SoftLogoutScreen: View {
|
||||
/// The text field and submit button where the user enters an email address.
|
||||
var clearDataForm: some View {
|
||||
VStack(alignment: .leading, spacing: 12) {
|
||||
Text(ElementL10n.softLogoutClearDataTitle)
|
||||
Text(UntranslatedL10n.softLogoutClearDataTitle)
|
||||
.font(.element.title2Bold)
|
||||
.multilineTextAlignment(.leading)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
.accessibilityIdentifier(A11yIdentifiers.softLogoutScreen.clearDataTitle)
|
||||
|
||||
Text(ElementL10n.softLogoutClearDataNotice)
|
||||
Text(UntranslatedL10n.softLogoutClearDataNotice)
|
||||
.font(.element.body)
|
||||
.multilineTextAlignment(.leading)
|
||||
.foregroundColor(.element.primaryContent)
|
||||
@@ -137,17 +137,17 @@ struct SoftLogoutScreen: View {
|
||||
.padding(.bottom, 12)
|
||||
|
||||
Button(action: clearData) {
|
||||
Text(ElementL10n.softLogoutClearDataSubmit)
|
||||
Text(UntranslatedL10n.softLogoutClearDataSubmit)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge, color: .element.alert))
|
||||
.accessibilityIdentifier(A11yIdentifiers.softLogoutScreen.clearData)
|
||||
.alert(ElementL10n.softLogoutClearDataDialogTitle,
|
||||
.alert(UntranslatedL10n.softLogoutClearDataDialogTitle,
|
||||
isPresented: $showingClearDataConfirmation) {
|
||||
Button(ElementL10n.actionSignOut,
|
||||
Button(L10n.screenSignoutConfirmationDialogSubmit,
|
||||
role: .destructive,
|
||||
action: clearData)
|
||||
} message: {
|
||||
Text(ElementL10n.softLogoutClearDataDialogContent)
|
||||
Text(UntranslatedL10n.softLogoutClearDataDialogContent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ final class BugReportCoordinator: CoordinatorProtocol {
|
||||
case .cancel:
|
||||
self.completion?(.cancel)
|
||||
case let .submitStarted(progressTracker):
|
||||
self.startLoading(label: ElementL10n.sending, progressPublisher: progressTracker)
|
||||
self.startLoading(label: L10n.commonSending, progressPublisher: progressTracker)
|
||||
case .submitFinished:
|
||||
self.stopLoading()
|
||||
self.completion?(.finish)
|
||||
@@ -80,7 +80,7 @@ final class BugReportCoordinator: CoordinatorProtocol {
|
||||
|
||||
static let loadingIndicatorIdentifier = "BugReportLoading"
|
||||
|
||||
private func startLoading(label: String = ElementL10n.loading, progressPublisher: ProgressPublisher) {
|
||||
private func startLoading(label: String = L10n.commonLoading, progressPublisher: ProgressPublisher) {
|
||||
parameters.userIndicatorController?.submitIndicator(
|
||||
UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
|
||||
@@ -33,7 +33,7 @@ struct BugReportScreen: View {
|
||||
}
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
.compoundForm()
|
||||
.navigationTitle(ElementL10n.bugReportScreenTitle)
|
||||
.navigationTitle(L10n.commonReportABug)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { toolbar }
|
||||
.interactiveDismissDisabled()
|
||||
@@ -51,15 +51,15 @@ struct BugReportScreen: View {
|
||||
|
||||
private var textFieldSection: some View {
|
||||
Section {
|
||||
TextField(ElementL10n.bugReportScreenEditorPlaceholder,
|
||||
TextField(L10n.screenBugReportEditorPlaceholder,
|
||||
text: $context.reportText,
|
||||
prompt: Text(ElementL10n.bugReportScreenEditorPlaceholder).compoundFormTextFieldPlaceholder(),
|
||||
prompt: Text(L10n.screenBugReportEditorPlaceholder).compoundFormTextFieldPlaceholder(),
|
||||
axis: .vertical)
|
||||
.lineLimit(4, reservesSpace: true)
|
||||
.textFieldStyle(.compoundForm)
|
||||
.accessibilityIdentifier(A11yIdentifiers.bugReportScreen.report)
|
||||
} footer: {
|
||||
Text(ElementL10n.bugReportScreenDescription)
|
||||
Text(L10n.screenBugReportEditorDescription)
|
||||
.compoundFormSectionFooter()
|
||||
}
|
||||
.compoundFormSection()
|
||||
@@ -67,11 +67,11 @@ struct BugReportScreen: View {
|
||||
|
||||
private var sendLogsSection: some View {
|
||||
Section {
|
||||
Toggle(ElementL10n.bugReportScreenIncludeLogs, isOn: $context.sendingLogsEnabled)
|
||||
Toggle(L10n.screenBugReportIncludeLogs, isOn: $context.sendingLogsEnabled)
|
||||
.toggleStyle(.compoundForm)
|
||||
.accessibilityIdentifier(A11yIdentifiers.bugReportScreen.sendLogs)
|
||||
} footer: {
|
||||
Text(ElementL10n.bugReportScreenLogsDescription)
|
||||
Text(L10n.screenBugReportLogsDescription)
|
||||
.compoundFormSectionFooter()
|
||||
}
|
||||
.compoundFormSection()
|
||||
@@ -83,7 +83,7 @@ struct BugReportScreen: View {
|
||||
PhotosPicker(selection: $selectedScreenshot,
|
||||
matching: .screenshots,
|
||||
photoLibrary: .shared()) {
|
||||
Label(context.viewState.screenshot == nil ? ElementL10n.bugReportScreenAttachScreenshot : ElementL10n.bugReportScreenEditScreenshot, systemImage: "camera")
|
||||
Label(context.viewState.screenshot == nil ? L10n.screenBugReportAttachScreenshot : L10n.screenBugReportEditScreenshot, systemImage: "camera")
|
||||
}
|
||||
.buttonStyle(.compoundForm())
|
||||
.accessibilityIdentifier(A11yIdentifiers.bugReportScreen.attachScreenshot)
|
||||
@@ -113,14 +113,14 @@ struct BugReportScreen: View {
|
||||
private var toolbar: some ToolbarContent {
|
||||
if context.viewState.isModallyPresented {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button(ElementL10n.actionCancel) {
|
||||
Button(L10n.actionCancel) {
|
||||
context.send(viewAction: .cancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .confirmationAction) {
|
||||
Button(ElementL10n.actionSend) {
|
||||
Button(L10n.actionSend) {
|
||||
context.send(viewAction: .submit)
|
||||
}
|
||||
.disabled(context.reportText.count < 5)
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ struct DeveloperOptionsScreenScreen: View {
|
||||
.overlay(effectsView)
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(Color.element.formBackground.ignoresSafeArea())
|
||||
.navigationTitle(ElementL10n.settingsDeveloperOptions)
|
||||
.navigationTitle(L10n.commonDeveloperOptions)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
}
|
||||
|
||||
|
||||
@@ -38,21 +38,21 @@ struct EmojiPickerEmojiCategoryViewData: Identifiable {
|
||||
var name: String {
|
||||
switch id {
|
||||
case "people":
|
||||
return ElementL10n.emojiPickerPeopleCategory
|
||||
return L10n.emojiPickerCategoryPeople
|
||||
case "nature":
|
||||
return ElementL10n.emojiPickerNatureCategory
|
||||
return L10n.emojiPickerCategoryNature
|
||||
case "foods":
|
||||
return ElementL10n.emojiPickerFoodsCategory
|
||||
return L10n.emojiPickerCategoryFoods
|
||||
case "activity":
|
||||
return ElementL10n.emojiPickerActivityCategory
|
||||
return L10n.emojiPickerCategoryActivity
|
||||
case "places":
|
||||
return ElementL10n.emojiPickerPlacesCategory
|
||||
return L10n.emojiPickerCategoryPlaces
|
||||
case "objects":
|
||||
return ElementL10n.emojiPickerObjectsCategory
|
||||
return L10n.emojiPickerCategoryObjects
|
||||
case "symbols":
|
||||
return ElementL10n.emojiPickerSymbolsCategory
|
||||
return L10n.emojiPickerCategorySymbols
|
||||
case "flags":
|
||||
return ElementL10n.emojiPickerFlagsCategory
|
||||
return L10n.emojiPickerCategoryFlags
|
||||
default:
|
||||
MXLog.failure("Missing translation for emoji category with id \(id)")
|
||||
return ""
|
||||
|
||||
@@ -41,7 +41,7 @@ struct EmojiPickerScreen: View {
|
||||
}
|
||||
.padding(.horizontal, 6)
|
||||
}
|
||||
.navigationTitle(ElementL10n.reactions)
|
||||
.navigationTitle(L10n.commonReactions)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { toolbar }
|
||||
.searchable(text: $searchString)
|
||||
@@ -55,7 +55,7 @@ struct EmojiPickerScreen: View {
|
||||
var toolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button { context.send(viewAction: .dismiss) } label: {
|
||||
Text(ElementL10n.actionCancel)
|
||||
Text(L10n.actionCancel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,9 +161,9 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
|
||||
|
||||
func presentCrashedLastRunAlert() {
|
||||
state.bindings.alertInfo = AlertInfo(id: UUID(),
|
||||
title: ElementL10n.sendBugReportAppCrashed,
|
||||
primaryButton: .init(title: ElementL10n.iosNo, action: nil),
|
||||
secondaryButton: .init(title: ElementL10n.iosYes) { [weak self] in
|
||||
title: L10n.crashDetectionDialogContent(InfoPlistReader.main.bundleDisplayName),
|
||||
primaryButton: .init(title: L10n.actionNo, action: nil),
|
||||
secondaryButton: .init(title: L10n.actionYes) { [weak self] in
|
||||
self?.callback?(.presentFeedbackScreen)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ struct HomeScreen: View {
|
||||
.animation(.elementDefault, value: context.viewState.showSessionVerificationBanner)
|
||||
.animation(.elementDefault, value: context.viewState.roomListMode)
|
||||
.alert(item: $context.alertInfo) { $0.alert }
|
||||
.navigationTitle(ElementL10n.allChats)
|
||||
.navigationTitle(L10n.screenRoomlistMainSpaceTitle)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarLeading) {
|
||||
userMenuButton
|
||||
@@ -118,22 +118,22 @@ struct HomeScreen: View {
|
||||
Menu {
|
||||
Section {
|
||||
Button(action: settings) {
|
||||
Label(ElementL10n.settings, systemImage: "gearshape")
|
||||
Label(L10n.commonSettings, systemImage: "gearshape")
|
||||
}
|
||||
}
|
||||
Section {
|
||||
Button(action: inviteFriends) {
|
||||
Label(ElementL10n.actionInvite, systemImage: "square.and.arrow.up")
|
||||
Label(L10n.actionInvite, systemImage: "square.and.arrow.up")
|
||||
}
|
||||
Button(action: feedback) {
|
||||
Label(ElementL10n.bugReportScreenTitle, systemImage: "questionmark.circle")
|
||||
Label(L10n.actionReportBug, systemImage: "questionmark.circle")
|
||||
}
|
||||
}
|
||||
Section {
|
||||
Button(role: .destructive) {
|
||||
showingLogoutConfirmation = true
|
||||
} label: {
|
||||
Label(ElementL10n.actionSignOut, systemImage: "rectangle.portrait.and.arrow.right")
|
||||
Label(L10n.screenSignoutPreferenceItem, systemImage: "rectangle.portrait.and.arrow.right")
|
||||
}
|
||||
}
|
||||
} label: {
|
||||
@@ -144,15 +144,15 @@ struct HomeScreen: View {
|
||||
imageProvider: context.imageProvider)
|
||||
.accessibilityIdentifier(A11yIdentifiers.homeScreen.userAvatar)
|
||||
}
|
||||
.alert(ElementL10n.actionSignOut,
|
||||
.alert(L10n.screenSignoutConfirmationDialogTitle,
|
||||
isPresented: $showingLogoutConfirmation) {
|
||||
Button(ElementL10n.actionSignOut,
|
||||
Button(L10n.screenSignoutConfirmationDialogSubmit,
|
||||
role: .destructive,
|
||||
action: signOut)
|
||||
} message: {
|
||||
Text(ElementL10n.actionSignOutConfirmationSimple)
|
||||
Text(L10n.screenSignoutConfirmationDialogContent)
|
||||
}
|
||||
.accessibilityLabel(ElementL10n.a11yAllChatsUserAvatarMenu)
|
||||
.accessibilityLabel(L10n.a11yUserMenu)
|
||||
}
|
||||
|
||||
private var newRoomButton: some View {
|
||||
@@ -165,7 +165,7 @@ struct HomeScreen: View {
|
||||
VStack(alignment: .leading, spacing: 16) {
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
HStack(spacing: 16) {
|
||||
Text(ElementL10n.sessionVerificationBannerTitle)
|
||||
Text(L10n.sessionVerificationBannerTitle)
|
||||
.font(.element.headline)
|
||||
.foregroundColor(.element.systemPrimaryLabel)
|
||||
|
||||
@@ -179,12 +179,12 @@ struct HomeScreen: View {
|
||||
.frame(width: 12, height: 12)
|
||||
}
|
||||
}
|
||||
Text(ElementL10n.sessionVerificationBannerMessage)
|
||||
Text(L10n.sessionVerificationBannerMessage)
|
||||
.font(.element.subheadline)
|
||||
.foregroundColor(.element.secondaryContent)
|
||||
}
|
||||
|
||||
Button(ElementL10n.continue) {
|
||||
Button(L10n.actionContinue) {
|
||||
context.send(viewAction: .verifySession)
|
||||
}
|
||||
.frame(maxWidth: .infinity)
|
||||
|
||||
@@ -138,7 +138,7 @@ struct HomeScreenRoomCell: View {
|
||||
.lastMessageFormatting()
|
||||
.redacted(reason: .placeholder)
|
||||
case .unknown:
|
||||
Text(ElementL10n.message)
|
||||
Text(L10n.commonMessage)
|
||||
.lastMessageFormatting()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ struct OnboardingViewState: BindableState {
|
||||
|
||||
init() {
|
||||
content = [
|
||||
OnboardingPageContent(title: ElementL10n.ftueAuthCarouselWelcomeTitle.tinting(".", color: .element.accent),
|
||||
message: ElementL10n.ftueAuthCarouselWelcomeBody(InfoPlistReader.main.bundleDisplayName),
|
||||
OnboardingPageContent(title: L10n.screenOnboardingWelcomeTitle.tinting(".", color: .element.accent),
|
||||
message: L10n.screenOnboardingWelcomeSubtitle(InfoPlistReader.main.bundleDisplayName),
|
||||
image: Asset.Images.onboardingAppLogo)
|
||||
]
|
||||
bindings = OnboardingBindings()
|
||||
|
||||
@@ -91,7 +91,7 @@ struct OnboardingScreen: View {
|
||||
var buttons: some View {
|
||||
VStack(spacing: 12) {
|
||||
Button { context.send(viewAction: .login) } label: {
|
||||
Text(ElementL10n.loginContinue)
|
||||
Text(L10n.actionContinue)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
.accessibilityIdentifier(A11yIdentifiers.onboardingScreen.signIn)
|
||||
|
||||
@@ -27,7 +27,7 @@ class InviteFriendsCoordinator: CoordinatorProtocol {
|
||||
guard let permalink = try? PermalinkBuilder.permalinkTo(userIdentifier: userId).absoluteString else {
|
||||
return AnyView(EmptyView())
|
||||
}
|
||||
let shareText = ElementL10n.inviteFriendsText(InfoPlistReader.main.bundleDisplayName, permalink)
|
||||
let shareText = L10n.inviteFriendsText(InfoPlistReader.main.bundleDisplayName, permalink)
|
||||
|
||||
return AnyView(UIActivityViewControllerWrapper(activityItems: [shareText])
|
||||
.presentationDetents([.medium])
|
||||
|
||||
@@ -75,7 +75,7 @@ final class ReportContentCoordinator: CoordinatorProtocol {
|
||||
parameters.userIndicatorController?.submitIndicator(
|
||||
UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
title: ElementL10n.sending,
|
||||
title: L10n.commonSending,
|
||||
persistent: true)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ struct ReportContentScreen: View {
|
||||
}
|
||||
.scrollDismissesKeyboard(.immediately)
|
||||
.background(Color.element.formBackground.ignoresSafeArea())
|
||||
.navigationTitle(ElementL10n.reportContent)
|
||||
.navigationTitle(L10n.actionReportContent)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar { toolbar }
|
||||
.interactiveDismissDisabled()
|
||||
@@ -48,25 +48,25 @@ struct ReportContentScreen: View {
|
||||
}
|
||||
|
||||
private var infoText: some View {
|
||||
Text(ElementL10n.reportContentInfo)
|
||||
Text(L10n.reportContentExplanation)
|
||||
.font(.element.body)
|
||||
.foregroundColor(Color.element.primaryContent)
|
||||
}
|
||||
|
||||
private var reasonTextEditor: some View {
|
||||
FormTextEditor(text: $context.reasonText, placeholder: ElementL10n.reportContentCustomHint)
|
||||
FormTextEditor(text: $context.reasonText, placeholder: L10n.reportContentHint)
|
||||
}
|
||||
|
||||
@ToolbarContentBuilder
|
||||
private var toolbar: some ToolbarContent {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button(ElementL10n.actionCancel) {
|
||||
Button(L10n.actionCancel) {
|
||||
context.send(viewAction: .cancel)
|
||||
}
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .confirmationAction) {
|
||||
Button(ElementL10n.actionSend) {
|
||||
Button(L10n.actionSend) {
|
||||
context.send(viewAction: .submit)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,15 +61,15 @@ struct LeaveRoomAlertItem: AlertItem {
|
||||
}
|
||||
|
||||
let state: RoomState
|
||||
let title = ElementL10n.roomProfileSectionMoreLeave
|
||||
let confirmationTitle = ElementL10n.actionLeave
|
||||
let cancelTitle = ElementL10n.actionCancel
|
||||
let title = L10n.actionLeaveRoom
|
||||
let confirmationTitle = L10n.actionLeave
|
||||
let cancelTitle = L10n.actionCancel
|
||||
|
||||
var subtitle: String {
|
||||
switch state {
|
||||
case .empty: return ElementL10n.roomDetailsLeaveEmptyRoomAlertSubtitle
|
||||
case .private: return ElementL10n.roomDetailsLeavePrivateRoomAlertSubtitle
|
||||
case .public: return ElementL10n.roomDetailsLeaveRoomAlertSubtitle
|
||||
case .empty: return L10n.leaveRoomAlertEmptySubtitle
|
||||
case .private: return L10n.leaveRoomAlertPrivateSubtitle
|
||||
case .public: return L10n.leaveRoomAlertSubtitle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class RoomDetailsViewModel: RoomDetailsViewModelType, RoomDetailsViewModelProtoc
|
||||
self.members = members
|
||||
case .failure(let error):
|
||||
MXLog.error("Failed retrieving room members: \(error)")
|
||||
state.bindings.alertInfo = AlertInfo(id: .alert(ElementL10n.unknownError))
|
||||
state.bindings.alertInfo = AlertInfo(id: .alert(L10n.errorUnknown))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,14 +80,14 @@ class RoomDetailsViewModel: RoomDetailsViewModelType, RoomDetailsViewModelProtoc
|
||||
private func copyRoomLink() {
|
||||
if let roomLink = state.permalink {
|
||||
UIPasteboard.general.url = roomLink
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: ElementL10n.linkCopiedToClipboard))
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonLinkCopiedToClipboard))
|
||||
} else {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: ElementL10n.unknownError))
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
|
||||
}
|
||||
}
|
||||
|
||||
private func leaveRoom() async {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.leaveRoomLoadingID, type: .modal, title: ElementL10n.loading, persistent: true))
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Self.leaveRoomLoadingID, type: .modal, title: L10n.commonLoading, persistent: true))
|
||||
let result = await roomProxy.leaveRoom()
|
||||
ServiceLocator.shared.userIndicatorController.retractIndicatorWithId(Self.leaveRoomLoadingID)
|
||||
switch result {
|
||||
|
||||
@@ -69,12 +69,12 @@ struct RoomDetailsScreen: View {
|
||||
Button { context.send(viewAction: .copyRoomLink) } label: {
|
||||
Image(systemName: "link")
|
||||
}
|
||||
.buttonStyle(FormActionButtonStyle(title: ElementL10n.actionCopyLink))
|
||||
.buttonStyle(FormActionButtonStyle(title: L10n.actionCopyLink))
|
||||
|
||||
ShareLink(item: permalink) {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
}
|
||||
.buttonStyle(FormActionButtonStyle(title: ElementL10n.inviteUsersToRoomActionInvite.capitalized))
|
||||
.buttonStyle(FormActionButtonStyle(title: L10n.actionInvite))
|
||||
}
|
||||
.padding(.top, 32)
|
||||
}
|
||||
@@ -91,7 +91,7 @@ struct RoomDetailsScreen: View {
|
||||
.foregroundColor(.element.secondaryContent)
|
||||
.font(.element.footnote)
|
||||
} header: {
|
||||
Text(ElementL10n.roomSettingsTopic)
|
||||
Text(L10n.commonTopic)
|
||||
.formSectionHeader()
|
||||
}
|
||||
.formSectionStyle()
|
||||
@@ -112,7 +112,7 @@ struct RoomDetailsScreen: View {
|
||||
.font(.element.body)
|
||||
}
|
||||
} label: {
|
||||
Label(ElementL10n.bottomActionPeople, systemImage: "person")
|
||||
Label(L10n.commonPeople, systemImage: "person")
|
||||
}
|
||||
}
|
||||
.buttonStyle(FormButtonStyle(accessory: context.viewState.isLoadingMembers ? nil : .navigationLink))
|
||||
@@ -120,7 +120,7 @@ struct RoomDetailsScreen: View {
|
||||
.accessibilityIdentifier(A11yIdentifiers.roomDetailsScreen.people)
|
||||
.disabled(context.viewState.isLoadingMembers)
|
||||
} header: {
|
||||
Text(ElementL10n.roomDetailsAboutSectionTitle)
|
||||
Text(L10n.commonAbout)
|
||||
.formSectionHeader()
|
||||
}
|
||||
.formSectionStyle()
|
||||
@@ -131,8 +131,8 @@ struct RoomDetailsScreen: View {
|
||||
HStack(alignment: .top) {
|
||||
Label {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
Text(ElementL10n.encryptionEnabled)
|
||||
Text(ElementL10n.encryptionEnabledTileDescription)
|
||||
Text(L10n.screenRoomDetailsEncryptionEnabledTitle)
|
||||
Text(L10n.screenRoomDetailsEncryptionEnabledSubtitle)
|
||||
.foregroundColor(.element.secondaryContent)
|
||||
.font(.element.footnote)
|
||||
}
|
||||
@@ -147,7 +147,7 @@ struct RoomDetailsScreen: View {
|
||||
.foregroundColor(.element.quaternaryContent)
|
||||
}
|
||||
} header: {
|
||||
Text(ElementL10n.roomProfileSectionSecurity)
|
||||
Text(L10n.commonSecurity)
|
||||
.formSectionHeader()
|
||||
}
|
||||
.formSectionStyle()
|
||||
@@ -158,7 +158,7 @@ struct RoomDetailsScreen: View {
|
||||
Button(role: .destructive) {
|
||||
context.send(viewAction: .processTapLeave)
|
||||
} label: {
|
||||
Label(ElementL10n.roomProfileSectionMoreLeave, systemImage: "door.right.hand.open")
|
||||
Label(L10n.actionLeaveRoom, systemImage: "door.right.hand.open")
|
||||
}
|
||||
.buttonStyle(FormButtonStyle(accessory: nil))
|
||||
}
|
||||
|
||||
@@ -41,26 +41,26 @@ struct IgnoreUserAlertItem: AlertItem {
|
||||
}
|
||||
|
||||
let action: Action
|
||||
let cancelTitle = ElementL10n.actionCancel
|
||||
let cancelTitle = L10n.actionCancel
|
||||
|
||||
var title: String {
|
||||
switch action {
|
||||
case .ignore: return ElementL10n.roomMemberDetailsBlockUser
|
||||
case .unignore: return ElementL10n.roomMemberDetailsUnblockUser
|
||||
case .ignore: return L10n.screenRoomMemberDetailsBlockUser
|
||||
case .unignore: return L10n.screenRoomMemberDetailsUnblockUser
|
||||
}
|
||||
}
|
||||
|
||||
var confirmationTitle: String {
|
||||
switch action {
|
||||
case .ignore: return ElementL10n.roomMemberDetailsBlockAlertAction
|
||||
case .unignore: return ElementL10n.roomMemberDetailsUnblockAlertAction
|
||||
case .ignore: return L10n.screenRoomMemberDetailsBlockAlertAction
|
||||
case .unignore: return L10n.screenRoomMemberDetailsUnblockAlertAction
|
||||
}
|
||||
}
|
||||
|
||||
var description: String {
|
||||
switch action {
|
||||
case .ignore: return ElementL10n.roomMemberDetailsBlockAlertDescription
|
||||
case .unignore: return ElementL10n.roomMemberDetailsUnblockAlertDescription
|
||||
case .ignore: return L10n.screenRoomMemberDetailsBlockAlertDescription
|
||||
case .unignore: return L10n.screenRoomMemberDetailsUnblockAlertDescription
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,9 +57,9 @@ class RoomMemberDetailsViewModel: RoomMemberDetailsViewModelType, RoomMemberDeta
|
||||
private func copyUserLink() {
|
||||
if let userLink = state.permalink {
|
||||
UIPasteboard.general.url = userLink
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: ElementL10n.linkCopiedToClipboard))
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: L10n.commonLinkCopiedToClipboard))
|
||||
} else {
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: ElementL10n.unknownError))
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(title: L10n.errorUnknown))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -59,12 +59,12 @@ struct RoomMemberDetailsScreen: View {
|
||||
Button { context.send(viewAction: .copyUserLink) } label: {
|
||||
Image(systemName: "link")
|
||||
}
|
||||
.buttonStyle(FormActionButtonStyle(title: ElementL10n.actionCopyLink))
|
||||
.buttonStyle(FormActionButtonStyle(title: L10n.actionCopyLink))
|
||||
|
||||
ShareLink(item: permalink) {
|
||||
Image(systemName: "square.and.arrow.up")
|
||||
}
|
||||
.buttonStyle(FormActionButtonStyle(title: ElementL10n.actionShareLink))
|
||||
.buttonStyle(FormActionButtonStyle(title: L10n.actionShareLink))
|
||||
}
|
||||
.padding(.top, 32)
|
||||
}
|
||||
@@ -79,14 +79,14 @@ struct RoomMemberDetailsScreen: View {
|
||||
Button {
|
||||
context.send(viewAction: .showUnblockAlert)
|
||||
} label: {
|
||||
Label(ElementL10n.roomMemberDetailsUnblockUser, systemImage: "slash.circle")
|
||||
Label(L10n.screenRoomMemberDetailsUnblockUser, systemImage: "slash.circle")
|
||||
}
|
||||
.buttonStyle(FormButtonStyle(accessory: nil))
|
||||
} else {
|
||||
Button(role: .destructive) {
|
||||
context.send(viewAction: .showBlockAlert)
|
||||
} label: {
|
||||
Label(ElementL10n.roomMemberDetailsBlockUser, systemImage: "slash.circle")
|
||||
Label(L10n.screenRoomMemberDetailsBlockUser, systemImage: "slash.circle")
|
||||
}
|
||||
.buttonStyle(FormButtonStyle(accessory: nil))
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ struct RoomMembersListScreen: View {
|
||||
.id(member.id)
|
||||
}
|
||||
} header: {
|
||||
Text(ElementL10n.roomTitleMembers(context.viewState.members.count))
|
||||
Text(L10n.commonMemberCount(context.viewState.members.count))
|
||||
.foregroundColor(.element.secondaryContent)
|
||||
.font(.element.body)
|
||||
.padding(.vertical, 12)
|
||||
@@ -41,7 +41,7 @@ struct RoomMembersListScreen: View {
|
||||
.searchable(text: $context.searchQuery, placement: .navigationBarDrawer(displayMode: .always))
|
||||
.searchableStyle(.list)
|
||||
.background(Color.element.background.ignoresSafeArea())
|
||||
.navigationTitle(ElementL10n.bottomActionPeople)
|
||||
.navigationTitle(L10n.commonPeople)
|
||||
.alert(item: $context.alertInfo) { $0.alert }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
||||
switch completion {
|
||||
case .cancel: break
|
||||
case .finish:
|
||||
self?.showSuccess(label: ElementL10n.reportContentSubmitted)
|
||||
self?.showSuccess(label: L10n.commonReportSubmitted)
|
||||
}
|
||||
}
|
||||
navigationCoordinator.setRootCoordinator(coordinator)
|
||||
|
||||
@@ -119,7 +119,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
private func paginateBackwards() async {
|
||||
switch await timelineController.paginateBackwards(requestSize: Constants.backPaginationEventLimit, untilNumberOfItems: Constants.backPaginationPageSize) {
|
||||
case .failure:
|
||||
displayError(.toast(ElementL10n.roomTimelineBackpaginationFailure))
|
||||
displayError(.toast(L10n.errorFailedLoadingMessages))
|
||||
default:
|
||||
break
|
||||
}
|
||||
@@ -224,7 +224,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
switch type {
|
||||
case .alert(let message):
|
||||
state.bindings.alertInfo = AlertInfo(id: type,
|
||||
title: ElementL10n.dialogTitleError,
|
||||
title: L10n.commonError,
|
||||
message: message)
|
||||
case .toast(let message):
|
||||
ServiceLocator.shared.userIndicatorController.submitIndicator(UserIndicator(id: Constants.toastErrorID,
|
||||
@@ -298,7 +298,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
|
||||
let permalink = try PermalinkBuilder.permalinkTo(eventIdentifier: item.id, roomIdentifier: timelineController.roomID)
|
||||
UIPasteboard.general.url = permalink
|
||||
} catch {
|
||||
displayError(.alert(ElementL10n.roomTimelinePermalinkCreationFailure))
|
||||
displayError(.alert(L10n.errorFailedCreatingThePermalink))
|
||||
}
|
||||
case .redact:
|
||||
Task {
|
||||
|
||||
@@ -34,7 +34,7 @@ struct MessageComposer: View {
|
||||
VStack(alignment: .leading, spacing: -6) {
|
||||
header
|
||||
HStack(alignment: .bottom) {
|
||||
MessageComposerTextField(placeholder: ElementL10n.roomMessagePlaceholder,
|
||||
MessageComposerTextField(placeholder: L10n.richTextEditorComposerPlaceholder,
|
||||
text: $text,
|
||||
focused: $focused,
|
||||
isMultiline: $isMultiline,
|
||||
@@ -94,14 +94,14 @@ struct MessageComposer: View {
|
||||
Image(systemName: "checkmark")
|
||||
.opacity(type.isEdit ? 1 : 0)
|
||||
.fontWeight(.medium)
|
||||
.accessibilityLabel(ElementL10n.actionConfirm)
|
||||
.accessibilityLabel(L10n.actionConfirm)
|
||||
.accessibilityHidden(!type.isEdit)
|
||||
Image(asset: Asset.Images.timelineComposerSendMessage)
|
||||
.resizable()
|
||||
.frame(width: sendButtonIconSize, height: sendButtonIconSize)
|
||||
.padding(EdgeInsets(top: 7, leading: 8, bottom: 7, trailing: 6))
|
||||
.opacity(type.isEdit ? 0 : 1)
|
||||
.accessibilityLabel(ElementL10n.actionSend)
|
||||
.accessibilityLabel(L10n.actionSend)
|
||||
.accessibilityHidden(type.isEdit)
|
||||
}
|
||||
}
|
||||
@@ -122,7 +122,7 @@ private struct MessageComposerReplyHeader: View {
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .center) {
|
||||
Label(ElementL10n.roomTimelineReplyingTo(displayName), systemImage: "arrowshape.turn.up.left")
|
||||
Label(L10n.commonReplyingTo(displayName), systemImage: "arrowshape.turn.up.left")
|
||||
.labelStyle(MessageComposerHeaderLabelStyle())
|
||||
Spacer()
|
||||
Button(action: action) {
|
||||
@@ -140,7 +140,7 @@ private struct MessageComposerEditHeader: View {
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: .center) {
|
||||
Label(ElementL10n.roomTimelineEditing, systemImage: "pencil.line")
|
||||
Label(L10n.commonEditing, systemImage: "pencil.line")
|
||||
.labelStyle(MessageComposerHeaderLabelStyle())
|
||||
Spacer()
|
||||
Button(action: action) {
|
||||
|
||||
@@ -111,7 +111,7 @@ struct TimelineItemBubbledStylerView<Content: View>: View {
|
||||
content()
|
||||
|
||||
if timelineItem.properties.isEdited {
|
||||
Text(ElementL10n.editedSuffix)
|
||||
Text(L10n.commonEditedSuffix)
|
||||
.font(.element.caption2)
|
||||
.foregroundColor(.element.tertiaryContent)
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ struct TimelineItemPlainStylerView<Content: View>: View {
|
||||
private var supplementaryViews: some View {
|
||||
VStack {
|
||||
if timelineItem.properties.isEdited {
|
||||
Text(ElementL10n.editedSuffix)
|
||||
Text(L10n.commonEditedSuffix)
|
||||
.font(.element.footnote)
|
||||
.foregroundColor(.element.tertiaryContent)
|
||||
}
|
||||
|
||||
@@ -28,8 +28,7 @@ struct CollapsibleRoomTimelineView: View {
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
DisclosureGroup(ElementL10n.roomTimelineStateChanges(timelineItem.items.count),
|
||||
isExpanded: $isExpanded) {
|
||||
DisclosureGroup(L10n.roomTimelineStateChanges(timelineItem.items.count), isExpanded: $isExpanded) {
|
||||
Group {
|
||||
ForEach(timelineViews) { timelineView in
|
||||
timelineView.body
|
||||
|
||||
@@ -41,7 +41,7 @@ struct ImageRoomTimelineView: View {
|
||||
.foregroundColor(.element.systemGray6)
|
||||
.opacity(0.3)
|
||||
|
||||
ProgressView(ElementL10n.loading)
|
||||
ProgressView(L10n.commonLoading)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
}
|
||||
@@ -49,7 +49,7 @@ struct ImageRoomTimelineView: View {
|
||||
@ViewBuilder
|
||||
var overlay: some View {
|
||||
if timelineItem.contentType == .gif {
|
||||
Text(ElementL10n.roomTimelineImageGif)
|
||||
Text(L10n.commonGif)
|
||||
.font(.element.bodyBold)
|
||||
.foregroundStyle(.primary)
|
||||
.padding(.horizontal, 10)
|
||||
|
||||
@@ -22,7 +22,7 @@ struct ReadMarkerRoomTimelineView: View {
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .trailing, spacing: 2) {
|
||||
Text(ElementL10n.roomTimelineReadMarkerTitle)
|
||||
Text(L10n.roomTimelineReadMarkerTitle)
|
||||
.textCase(.uppercase)
|
||||
.font(.element.caption2Bold)
|
||||
.foregroundColor(.element.quaternaryContent)
|
||||
|
||||
@@ -34,7 +34,7 @@ struct RedactedRoomTimelineView_Previews: PreviewProvider {
|
||||
|
||||
static var previews: some View {
|
||||
VStack(alignment: .leading, spacing: 20.0) {
|
||||
RedactedRoomTimelineView(timelineItem: itemWith(text: ElementL10n.eventRedacted,
|
||||
RedactedRoomTimelineView(timelineItem: itemWith(text: L10n.commonMessageRemoved,
|
||||
timestamp: "Later",
|
||||
senderId: "Anne"))
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ struct StickerRoomTimelineView: View {
|
||||
.foregroundColor(.element.systemGray6)
|
||||
.opacity(0.3)
|
||||
|
||||
ProgressView(ElementL10n.loading)
|
||||
ProgressView(L10n.commonLoading)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -28,9 +28,9 @@ struct TimelineStartRoomTimelineView: View {
|
||||
}
|
||||
|
||||
var title: String {
|
||||
var text = ElementL10n.thisIsTheBeginningOfRoomNoName
|
||||
var text = L10n.roomTimelineBeginningOfRoomNoName
|
||||
if let name = timelineItem.name {
|
||||
text = ElementL10n.thisIsTheBeginningOfRoom(name)
|
||||
text = L10n.roomTimelineBeginningOfRoom(name)
|
||||
}
|
||||
return text
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ struct VideoRoomTimelineView: View {
|
||||
.foregroundColor(.element.systemGray6)
|
||||
.opacity(0.3)
|
||||
|
||||
ProgressView(ElementL10n.loading)
|
||||
ProgressView(L10n.commonLoading)
|
||||
.frame(maxWidth: .infinity)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,43 +74,43 @@ public struct TimelineItemContextMenu: View {
|
||||
switch action {
|
||||
case .react:
|
||||
Button { send(action) } label: {
|
||||
Label(ElementL10n.reactions, systemImage: "face.smiling")
|
||||
Label(L10n.commonReactions, systemImage: "face.smiling")
|
||||
}
|
||||
case .copy:
|
||||
Button { send(action) } label: {
|
||||
Label(ElementL10n.actionCopy, systemImage: "doc.on.doc")
|
||||
Label(L10n.actionCopy, systemImage: "doc.on.doc")
|
||||
}
|
||||
case .edit:
|
||||
Button { send(action) } label: {
|
||||
Label(ElementL10n.edit, systemImage: "pencil.line")
|
||||
Label(L10n.actionEdit, systemImage: "pencil.line")
|
||||
}
|
||||
case .quote:
|
||||
Button { send(action) } label: {
|
||||
Label(ElementL10n.actionQuote, systemImage: "quote.bubble")
|
||||
Label(L10n.actionQuote, systemImage: "quote.bubble")
|
||||
}
|
||||
case .copyPermalink:
|
||||
Button { send(action) } label: {
|
||||
Label(ElementL10n.permalink, systemImage: "link")
|
||||
Label(L10n.commonPermalink, systemImage: "link")
|
||||
}
|
||||
case .reply:
|
||||
Button { send(action) } label: {
|
||||
Label(ElementL10n.reply, systemImage: "arrowshape.turn.up.left")
|
||||
Label(L10n.actionReply, systemImage: "arrowshape.turn.up.left")
|
||||
}
|
||||
case .redact:
|
||||
Button(role: .destructive) { send(action) } label: {
|
||||
Label(ElementL10n.actionRemove, systemImage: "trash")
|
||||
Label(L10n.actionRemove, systemImage: "trash")
|
||||
}
|
||||
case .viewSource:
|
||||
Button { send(action) } label: {
|
||||
Label(ElementL10n.viewSource, systemImage: "doc.text.below.ecg")
|
||||
Label(L10n.actionViewSource, systemImage: "doc.text.below.ecg")
|
||||
}
|
||||
case .retryDecryption:
|
||||
Button { send(action) } label: {
|
||||
Label(ElementL10n.roomTimelineContextMenuRetryDecryption, systemImage: "arrow.down.message")
|
||||
Label(L10n.actionRetryDecryption, systemImage: "arrow.down.message")
|
||||
}
|
||||
case .report:
|
||||
Button(role: .destructive) { send(action) } label: {
|
||||
Label(ElementL10n.reportContent, systemImage: "exclamationmark.bubble")
|
||||
Label(L10n.actionReportContent, systemImage: "exclamationmark.bubble")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,12 +40,12 @@ struct TimelineItemDebugView: View {
|
||||
.navigationTitle(info.title)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button(ElementL10n.actionCancel) {
|
||||
Button(L10n.actionCancel) {
|
||||
dismiss()
|
||||
}
|
||||
}
|
||||
ToolbarItem(placement: .secondaryAction) {
|
||||
Button(ElementL10n.actionCopy) {
|
||||
Button(L10n.actionCopy) {
|
||||
UIPasteboard.general.string = info.content
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,54 +26,54 @@ struct SessionVerificationViewState: BindableState {
|
||||
var title: String? {
|
||||
switch verificationState {
|
||||
case .initial:
|
||||
return ElementL10n.verificationOpenOtherToVerifyTitle
|
||||
return L10n.screenSessionVerificationOpenExistingSessionTitle
|
||||
case .requestingVerification:
|
||||
return ElementL10n.verificationRequestWaitingAcceptRequestTitle
|
||||
return L10n.screenSessionVerificationWaitingToAcceptTitle
|
||||
case .verificationRequestAccepted:
|
||||
return ElementL10n.verificationCompareEmojisTitle
|
||||
return L10n.screenSessionVerificationCompareEmojisTitle
|
||||
case .startingSasVerification:
|
||||
return nil
|
||||
case .sasVerificationStarted:
|
||||
return nil
|
||||
case .showingChallenge:
|
||||
return ElementL10n.verificationCompareEmojisTitle
|
||||
return L10n.screenSessionVerificationCompareEmojisTitle
|
||||
case .acceptingChallenge:
|
||||
return ElementL10n.verificationCompareEmojisTitle
|
||||
return L10n.screenSessionVerificationCompareEmojisTitle
|
||||
case .decliningChallenge:
|
||||
return nil
|
||||
case .verified:
|
||||
return ElementL10n.verificationConclusionOkSelfNoticeTitle
|
||||
return L10n.commonVerificationComplete
|
||||
case .cancelling:
|
||||
return nil
|
||||
case .cancelled:
|
||||
return ElementL10n.verificationCancelled
|
||||
return L10n.commonVerificationCancelled
|
||||
}
|
||||
}
|
||||
|
||||
var message: String {
|
||||
switch verificationState {
|
||||
case .initial:
|
||||
return ElementL10n.verificationOpenOtherToVerifyDetail
|
||||
return L10n.screenSessionVerificationOpenExistingSessionSubtitle
|
||||
case .requestingVerification:
|
||||
return ElementL10n.verificationRequestWaitingAcceptRequestDetail
|
||||
return L10n.screenSessionVerificationWaitingToAcceptSubtitle
|
||||
case .verificationRequestAccepted:
|
||||
return ElementL10n.verificationEmojiNotice
|
||||
return L10n.screenSessionVerificationRequestAcceptedSubtitle
|
||||
case .startingSasVerification:
|
||||
return ElementL10n.verificationRequestWaiting
|
||||
return L10n.commonWaiting
|
||||
case .sasVerificationStarted:
|
||||
return ElementL10n.verificationRequestWaiting
|
||||
return L10n.commonWaiting
|
||||
case .acceptingChallenge:
|
||||
return ElementL10n.verificationCompareEmojisDetail
|
||||
return L10n.screenSessionVerificationCompareEmojisSubtitle
|
||||
case .decliningChallenge:
|
||||
return ElementL10n.verificationRequestWaiting
|
||||
return L10n.commonWaiting
|
||||
case .cancelling:
|
||||
return ElementL10n.verificationRequestWaiting
|
||||
return L10n.commonWaiting
|
||||
case .showingChallenge:
|
||||
return ElementL10n.verificationCompareEmojisDetail
|
||||
return L10n.screenSessionVerificationCompareEmojisSubtitle
|
||||
case .verified:
|
||||
return ElementL10n.verificationConclusionOkSelfNotice
|
||||
return L10n.screenSessionVerificationCompleteSubtitle
|
||||
case .cancelled:
|
||||
return ElementL10n.verificationRequestCancelledDetail
|
||||
return L10n.screenSessionVerificationCancelledSubtitle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,14 +106,16 @@ struct SessionVerificationScreen: View {
|
||||
|
||||
@ViewBuilder
|
||||
private func emojisPanel(with emojis: [SessionVerificationEmoji]) -> some View {
|
||||
HStack(spacing: 16) {
|
||||
ForEach(emojis.prefix(4), id: \.self) { emoji in
|
||||
EmojiView(emoji: emoji)
|
||||
VStack(spacing: 32) {
|
||||
HStack(spacing: 16) {
|
||||
ForEach(emojis.prefix(4), id: \.self) { emoji in
|
||||
EmojiView(emoji: emoji)
|
||||
}
|
||||
}
|
||||
}
|
||||
HStack(spacing: 16) {
|
||||
ForEach(emojis.suffix(from: 4), id: \.self) { emoji in
|
||||
EmojiView(emoji: emoji)
|
||||
HStack(spacing: 16) {
|
||||
ForEach(emojis.suffix(from: 4), id: \.self) { emoji in
|
||||
EmojiView(emoji: emoji)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,20 +124,20 @@ struct SessionVerificationScreen: View {
|
||||
private var actionButtons: some View {
|
||||
switch context.viewState.verificationState {
|
||||
case .initial:
|
||||
Button(ElementL10n.startVerification) {
|
||||
Button(L10n.actionStartVerification) {
|
||||
context.send(viewAction: .requestVerification)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
.accessibilityIdentifier(A11yIdentifiers.sessionVerificationScreen.requestVerification)
|
||||
|
||||
case .cancelled:
|
||||
Button(ElementL10n.globalRetry) {
|
||||
Button(L10n.actionRetry) {
|
||||
context.send(viewAction: .restart)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
|
||||
case .verificationRequestAccepted:
|
||||
Button(ElementL10n.sessionVerificationStart) {
|
||||
Button(L10n.actionStart) {
|
||||
context.send(viewAction: .startSasVerification)
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
@@ -144,12 +146,12 @@ struct SessionVerificationScreen: View {
|
||||
case .showingChallenge:
|
||||
VStack(spacing: 30) {
|
||||
Button { context.send(viewAction: .accept) } label: {
|
||||
Label(ElementL10n.verificationSasMatch, systemImage: "checkmark")
|
||||
Label(L10n.screenSessionVerificationTheyMatch, systemImage: "checkmark")
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
.accessibilityIdentifier(A11yIdentifiers.sessionVerificationScreen.acceptChallenge)
|
||||
|
||||
Button(ElementL10n.verificationSasDoNotMatch) {
|
||||
Button(L10n.screenSessionVerificationTheyDontMatch) {
|
||||
context.send(viewAction: .decline)
|
||||
}
|
||||
.font(.element.bodyBold)
|
||||
@@ -162,14 +164,14 @@ struct SessionVerificationScreen: View {
|
||||
HStack(spacing: 16) {
|
||||
ProgressView()
|
||||
.tint(.element.background)
|
||||
Label(ElementL10n.verificationSasMatch, systemImage: "checkmark")
|
||||
Label(L10n.screenSessionVerificationTheyMatch, systemImage: "checkmark")
|
||||
}
|
||||
}
|
||||
.buttonStyle(.elementAction(.xLarge))
|
||||
.accessibilityIdentifier(A11yIdentifiers.sessionVerificationScreen.acceptChallenge)
|
||||
.disabled(true)
|
||||
|
||||
Button(ElementL10n.verificationSasDoNotMatch) {
|
||||
Button(L10n.screenSessionVerificationTheyDontMatch) {
|
||||
context.send(viewAction: .decline)
|
||||
}
|
||||
.font(.element.bodyBold)
|
||||
@@ -185,7 +187,7 @@ struct SessionVerificationScreen: View {
|
||||
@ToolbarContentBuilder
|
||||
private var toolbarContent: some ToolbarContent {
|
||||
ToolbarItem(placement: .cancellationAction) {
|
||||
Button(ElementL10n.actionCancel) {
|
||||
Button(L10n.actionCancel) {
|
||||
context.send(viewAction: .close)
|
||||
}
|
||||
.foregroundColor(.element.accent)
|
||||
@@ -227,11 +229,18 @@ struct SessionVerificationScreen: View {
|
||||
struct SessionVerification_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
sessionVerificationScreen(state: .initial)
|
||||
.previewDisplayName("Initial")
|
||||
sessionVerificationScreen(state: .requestingVerification)
|
||||
.previewDisplayName("Requesting Verification")
|
||||
sessionVerificationScreen(state: .verificationRequestAccepted)
|
||||
.previewDisplayName("Request Accepted")
|
||||
sessionVerificationScreen(state: .cancelled)
|
||||
.previewDisplayName("Cancelled")
|
||||
|
||||
sessionVerificationScreen(state: .showingChallenge(emojis: SessionVerificationControllerProxyMock.emojis))
|
||||
.previewDisplayName("Showing Challenge")
|
||||
sessionVerificationScreen(state: .verified)
|
||||
.previewDisplayName("Verified")
|
||||
}
|
||||
|
||||
static func sessionVerificationScreen(state: SessionVerificationStateMachine.State) -> some View {
|
||||
|
||||
@@ -87,7 +87,7 @@ final class SettingsScreenCoordinator: CoordinatorProtocol {
|
||||
coordinator.completion = { [weak self] result in
|
||||
switch result {
|
||||
case .finish:
|
||||
self?.showSuccess(label: ElementL10n.done)
|
||||
self?.showSuccess(label: L10n.actionDone)
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ struct SettingsScreen: View {
|
||||
signOutSection
|
||||
}
|
||||
.compoundForm()
|
||||
.navigationTitle(ElementL10n.settings)
|
||||
.navigationTitle(L10n.commonSettings)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .confirmationAction) {
|
||||
@@ -49,7 +49,7 @@ struct SettingsScreen: View {
|
||||
}
|
||||
|
||||
private var versionText: some View {
|
||||
Text(ElementL10n.settingsVersion + ": " + InfoPlistReader.main.bundleShortVersionString + " (" + InfoPlistReader.main.bundleVersion + ")")
|
||||
Text(L10n.settingsVersionNumber(InfoPlistReader.main.bundleShortVersionString, InfoPlistReader.main.bundleVersion))
|
||||
}
|
||||
|
||||
private var userSection: some View {
|
||||
@@ -79,7 +79,7 @@ struct SettingsScreen: View {
|
||||
private var sessionVerificationSection: some View {
|
||||
Section {
|
||||
Button { context.send(viewAction: .sessionVerification) } label: {
|
||||
Label(ElementL10n.settingsSessionVerification, systemImage: "checkmark.shield")
|
||||
Label(L10n.actionCompleteVerification, systemImage: "checkmark.shield")
|
||||
}
|
||||
.buttonStyle(.compoundForm())
|
||||
}
|
||||
@@ -89,7 +89,7 @@ struct SettingsScreen: View {
|
||||
private var developerOptionsSection: some View {
|
||||
Section {
|
||||
Button { context.send(viewAction: .developerOptions) } label: {
|
||||
Label(ElementL10n.settingsDeveloperOptions, systemImage: "hammer.circle")
|
||||
Label(L10n.commonDeveloperOptions, systemImage: "hammer.circle")
|
||||
}
|
||||
.buttonStyle(.compoundForm(accessory: .navigationLink))
|
||||
.accessibilityIdentifier("sessionVerificationButton")
|
||||
@@ -105,7 +105,7 @@ struct SettingsScreen: View {
|
||||
.tag(style)
|
||||
}
|
||||
} label: {
|
||||
Label(ElementL10n.settingsTimelineStyle, systemImage: "rectangle.grid.1x2")
|
||||
Label(L10n.commonMessageLayout, systemImage: "rectangle.grid.1x2")
|
||||
}
|
||||
.labelStyle(.compoundFormRow())
|
||||
.accessibilityIdentifier("timelineStylePicker")
|
||||
@@ -114,7 +114,7 @@ struct SettingsScreen: View {
|
||||
}
|
||||
|
||||
Button { context.send(viewAction: .reportBug) } label: {
|
||||
Label(ElementL10n.sendBugReport, systemImage: "questionmark.circle")
|
||||
Label(L10n.actionReportBug, systemImage: "questionmark.circle")
|
||||
}
|
||||
.buttonStyle(.compoundForm(accessory: .navigationLink))
|
||||
.accessibilityIdentifier("reportBugButton")
|
||||
@@ -125,16 +125,16 @@ struct SettingsScreen: View {
|
||||
private var signOutSection: some View {
|
||||
Section {
|
||||
Button { showingLogoutConfirmation = true } label: {
|
||||
Label(ElementL10n.actionSignOut, systemImage: "rectangle.portrait.and.arrow.right")
|
||||
Label(L10n.screenSignoutPreferenceItem, systemImage: "rectangle.portrait.and.arrow.right")
|
||||
}
|
||||
.buttonStyle(.compoundForm())
|
||||
.accessibilityIdentifier("logoutButton")
|
||||
.alert(ElementL10n.actionSignOut, isPresented: $showingLogoutConfirmation) {
|
||||
Button(ElementL10n.actionSignOut,
|
||||
.alert(L10n.screenSignoutConfirmationDialogTitle, isPresented: $showingLogoutConfirmation) {
|
||||
Button(L10n.screenSignoutConfirmationDialogSubmit,
|
||||
role: .destructive,
|
||||
action: logout)
|
||||
} message: {
|
||||
Text(ElementL10n.actionSignOutConfirmationSimple)
|
||||
Text(L10n.screenSignoutConfirmationDialogContent)
|
||||
}
|
||||
} footer: {
|
||||
VStack {
|
||||
@@ -150,7 +150,7 @@ struct SettingsScreen: View {
|
||||
}
|
||||
|
||||
private var doneButton: some View {
|
||||
Button(ElementL10n.done, action: close)
|
||||
Button(L10n.actionDone, action: close)
|
||||
}
|
||||
|
||||
private func close() {
|
||||
@@ -166,9 +166,9 @@ private extension TimelineStyle {
|
||||
var name: String {
|
||||
switch self {
|
||||
case .plain:
|
||||
return ElementL10n.roomTimelineStylePlainLongDescription
|
||||
return L10n.commonModern
|
||||
case .bubbles:
|
||||
return ElementL10n.roomTimelineStyleBubbledLongDescription
|
||||
return L10n.commonBubbles
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ enum StartChatUserSectionType {
|
||||
case .searchResult:
|
||||
return nil
|
||||
case .suggestions:
|
||||
return ElementL10n.directRoomUserListSuggestionsTitle
|
||||
return L10n.commonSuggestions
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,12 +66,12 @@ class StartChatViewModel: StartChatViewModelType, StartChatViewModelProtocol {
|
||||
switch type {
|
||||
case .failedRetrievingDirectRoom:
|
||||
state.bindings.alertInfo = AlertInfo(id: type,
|
||||
title: ElementL10n.dialogTitleError,
|
||||
message: ElementL10n.retrievingDirectRoomError)
|
||||
title: L10n.commonError,
|
||||
message: L10n.screenStartChatErrorStartingChat)
|
||||
case .failedCreatingRoom:
|
||||
state.bindings.alertInfo = AlertInfo(id: type,
|
||||
title: ElementL10n.dialogTitleError,
|
||||
message: ElementL10n.retrievingDirectRoomError)
|
||||
title: L10n.commonError,
|
||||
message: L10n.screenStartChatErrorStartingChat)
|
||||
default:
|
||||
state.bindings.alertInfo = AlertInfo(id: type)
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class StartChatViewModel: StartChatViewModelType, StartChatViewModelProtocol {
|
||||
private func showLoadingIndicator() {
|
||||
userIndicatorController?.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
|
||||
type: .modal,
|
||||
title: ElementL10n.loading,
|
||||
title: L10n.commonLoading,
|
||||
persistent: true))
|
||||
}
|
||||
|
||||
|
||||
@@ -29,21 +29,21 @@ struct StartChatScreen: View {
|
||||
}
|
||||
.scrollContentBackground(.hidden)
|
||||
.background(Color.element.formBackground.ignoresSafeArea())
|
||||
.navigationTitle(ElementL10n.startChat)
|
||||
.navigationTitle(L10n.actionStartChat)
|
||||
.navigationBarTitleDisplayMode(.inline)
|
||||
.toolbar {
|
||||
ToolbarItem(placement: .navigationBarTrailing) {
|
||||
closeButton
|
||||
}
|
||||
}
|
||||
.searchable(text: $context.searchQuery, placement: .navigationBarDrawer(displayMode: .always), prompt: ElementL10n.searchForSomeone)
|
||||
.searchable(text: $context.searchQuery, placement: .navigationBarDrawer(displayMode: .always), prompt: L10n.commonSearchForSomeone)
|
||||
.alert(item: $context.alertInfo) { $0.alert }
|
||||
}
|
||||
|
||||
private var createRoomSection: some View {
|
||||
Section {
|
||||
Button(action: createRoom) {
|
||||
Label(ElementL10n.createARoom, systemImage: "person.3")
|
||||
Label(L10n.actionCreateARoom, systemImage: "person.3")
|
||||
}
|
||||
.buttonStyle(FormButtonStyle(accessory: .navigationLink))
|
||||
}
|
||||
@@ -53,7 +53,7 @@ struct StartChatScreen: View {
|
||||
private var inviteFriendsSection: some View {
|
||||
Section {
|
||||
Button(action: inviteFriends) {
|
||||
Label(ElementL10n.inviteFriendsToElement, systemImage: "square.and.arrow.up")
|
||||
Label(L10n.actionInviteFriendsToApp(InfoPlistReader.main.bundleDisplayName), systemImage: "square.and.arrow.up")
|
||||
}
|
||||
.buttonStyle(FormButtonStyle())
|
||||
.accessibilityIdentifier(A11yIdentifiers.startChatScreen.inviteFriends)
|
||||
@@ -78,7 +78,7 @@ struct StartChatScreen: View {
|
||||
}
|
||||
|
||||
private var closeButton: some View {
|
||||
Button(ElementL10n.actionCancel, action: close)
|
||||
Button(L10n.actionCancel, action: close)
|
||||
.accessibilityIdentifier(A11yIdentifiers.startChatScreen.closeStartChat)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user