Use XML resources for copy
This commit is contained in:
@ -0,0 +1,16 @@
|
||||
package app.omnivore.omnivore.ui
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.StringRes
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Singleton
|
||||
class ResourceProvider @Inject constructor(
|
||||
@ApplicationContext private val context: Context
|
||||
) {
|
||||
fun getString(@StringRes stringResId: Int): String {
|
||||
return context.getString(stringResId)
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,7 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.compose.ui.window.Dialog
|
||||
@ -28,8 +29,8 @@ fun AppleAuthButton(viewModel: LoginViewModel) {
|
||||
val showDialog = remember { mutableStateOf(false) }
|
||||
|
||||
LoadingButtonWithIcon(
|
||||
text = "Continue with Apple",
|
||||
loadingText = "Signing in...",
|
||||
text = stringResource(R.string.apple_auth_text),
|
||||
loadingText = stringResource(R.string.apple_auth_loading),
|
||||
isLoading = viewModel.isLoading,
|
||||
icon = painterResource(id = R.drawable.ic_logo_apple),
|
||||
modifier = Modifier.padding(vertical = 6.dp),
|
||||
|
||||
@ -8,7 +8,6 @@ import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.CheckCircle
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
@ -25,7 +24,6 @@ import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.R
|
||||
import org.intellij.lang.annotations.JdkConstants
|
||||
|
||||
@SuppressLint("CoroutineCreationDuringComposition")
|
||||
@Composable
|
||||
@ -42,7 +40,7 @@ fun CreateUserProfileView(viewModel: LoginViewModel) {
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = "Create Your Profile",
|
||||
text = stringResource(R.string.create_user_profile_title),
|
||||
style = MaterialTheme.typography.headlineMedium,
|
||||
modifier = Modifier.padding(bottom = 8.dp)
|
||||
)
|
||||
@ -61,11 +59,11 @@ fun CreateUserProfileView(viewModel: LoginViewModel) {
|
||||
|
||||
// TODO: add a activity indicator (maybe after a delay?)
|
||||
if (viewModel.isLoading) {
|
||||
Text("Loading...")
|
||||
Text(stringResource(R.string.create_user_profile_loading))
|
||||
}
|
||||
|
||||
ClickableText(
|
||||
text = AnnotatedString("Cancel Sign Up"),
|
||||
text = AnnotatedString(stringResource(R.string.create_user_profile_action_cancel)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.cancelNewUserSignUp() }
|
||||
@ -98,8 +96,8 @@ fun UserProfileFields(
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = name,
|
||||
placeholder = { Text(text = "Name") },
|
||||
label = { Text(text = "Name") },
|
||||
placeholder = { Text(stringResource(R.string.create_user_profile_field_placeholder_name)) },
|
||||
label = { Text(stringResource(R.string.create_user_profile_field_label_name)) },
|
||||
onValueChange = onNameChange,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })
|
||||
@ -111,8 +109,8 @@ fun UserProfileFields(
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = username,
|
||||
placeholder = { Text(text = "Username") },
|
||||
label = { Text(text = "Username") },
|
||||
placeholder = { Text(stringResource(R.string.create_user_profile_field_placeholder_username)) },
|
||||
label = { Text(stringResource(R.string.create_user_profile_field_label_username)) },
|
||||
onValueChange = onUsernameChange,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
|
||||
@ -144,7 +142,7 @@ fun UserProfileFields(
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"Please enter a valid name and username.",
|
||||
context.getString(R.string.create_user_profile_error_msg),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
@ -154,7 +152,7 @@ fun UserProfileFields(
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "Submit",
|
||||
text = stringResource(R.string.create_user_profile_action_submit),
|
||||
modifier = Modifier.padding(horizontal = 100.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,10 +1,6 @@
|
||||
package app.omnivore.omnivore.ui.auth
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.view.ViewGroup
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.text.ClickableText
|
||||
@ -16,10 +12,10 @@ import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
@ -27,8 +23,8 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import app.omnivore.omnivore.BuildConfig
|
||||
import app.omnivore.omnivore.R
|
||||
|
||||
@SuppressLint("CoroutineCreationDuringComposition")
|
||||
@Composable
|
||||
@ -55,28 +51,28 @@ fun EmailLoginView(viewModel: LoginViewModel) {
|
||||
|
||||
// TODO: add a activity indicator (maybe after a delay?)
|
||||
if (viewModel.isLoading) {
|
||||
Text("Loading...")
|
||||
Text(stringResource(R.string.email_login_loading))
|
||||
}
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
ClickableText(
|
||||
text = AnnotatedString("Return to Social Login"),
|
||||
text = AnnotatedString(stringResource(R.string.email_login_action_back)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.showSocialLogin() }
|
||||
)
|
||||
|
||||
ClickableText(
|
||||
text = AnnotatedString("Don't have an account?"),
|
||||
text = AnnotatedString(stringResource(R.string.email_login_action_no_account)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.showEmailSignUp() }
|
||||
)
|
||||
|
||||
ClickableText(
|
||||
text = AnnotatedString("Forgot your password?"),
|
||||
text = AnnotatedString(stringResource(R.string.email_login_action_forgot_password)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = {
|
||||
@ -111,8 +107,8 @@ fun LoginFields(
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = email,
|
||||
placeholder = { Text(text = "user@email.com") },
|
||||
label = { Text(text = "Email") },
|
||||
placeholder = { Text(stringResource(R.string.email_login_field_placeholder_email)) },
|
||||
label = { Text(stringResource(R.string.email_login_field_label_email)) },
|
||||
onValueChange = onEmailChange,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Done,
|
||||
@ -123,8 +119,8 @@ fun LoginFields(
|
||||
|
||||
OutlinedTextField(
|
||||
value = password,
|
||||
placeholder = { Text(text = "Password") },
|
||||
label = { Text(text = "Password") },
|
||||
placeholder = { Text(stringResource(R.string.email_login_field_placeholder_password)) },
|
||||
label = { Text(stringResource(R.string.email_login_field_label_password)) },
|
||||
onValueChange = onPasswordChange,
|
||||
visualTransformation = PasswordVisualTransformation(),
|
||||
keyboardOptions = KeyboardOptions(
|
||||
@ -141,7 +137,7 @@ fun LoginFields(
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"Please enter an email address and password.",
|
||||
context.getString(R.string.email_login_error_msg),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
@ -151,7 +147,7 @@ fun LoginFields(
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "Login",
|
||||
text = stringResource(R.string.email_login_action_login),
|
||||
modifier = Modifier.padding(horizontal = 100.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@ -18,6 +18,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
@ -25,6 +26,7 @@ import androidx.compose.ui.text.input.PasswordVisualTransformation
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.R
|
||||
|
||||
@Composable
|
||||
fun EmailSignUpView(viewModel: LoginViewModel) {
|
||||
@ -32,8 +34,6 @@ fun EmailSignUpView(viewModel: LoginViewModel) {
|
||||
val email = viewModel.pendingEmailUserCreds?.email ?: ""
|
||||
val password = viewModel.pendingEmailUserCreds?.password ?: ""
|
||||
|
||||
val verificationMessage = "We've sent a verification email to ${email}. Please verify your email and then tap the button below."
|
||||
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
@ -43,7 +43,7 @@ fun EmailSignUpView(viewModel: LoginViewModel) {
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Text(
|
||||
text = verificationMessage,
|
||||
text = stringResource(R.string.email_signup_verification_message, email),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
|
||||
@ -55,13 +55,13 @@ fun EmailSignUpView(viewModel: LoginViewModel) {
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "Check Status",
|
||||
text = stringResource(R.string.email_signup_check_status),
|
||||
modifier = Modifier.padding(horizontal = 100.dp)
|
||||
)
|
||||
}
|
||||
|
||||
ClickableText(
|
||||
text = AnnotatedString("Use a different email?"),
|
||||
text = AnnotatedString(stringResource(R.string.email_signup_action_use_different_email)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.showEmailSignUp() }
|
||||
@ -115,21 +115,21 @@ fun EmailSignUpForm(viewModel: LoginViewModel) {
|
||||
|
||||
// TODO: add a activity indicator (maybe after a delay?)
|
||||
if (viewModel.isLoading) {
|
||||
Text("Loading...")
|
||||
Text(stringResource(R.string.email_signup_loading))
|
||||
}
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
ClickableText(
|
||||
text = AnnotatedString("Return to Social Login"),
|
||||
text = AnnotatedString(stringResource(R.string.email_signup_action_back)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.showSocialLogin() }
|
||||
)
|
||||
|
||||
ClickableText(
|
||||
text = AnnotatedString("Already have an account?"),
|
||||
text = AnnotatedString(stringResource(R.string.email_signup_action_already_have_account)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.showEmailSignIn() }
|
||||
@ -167,8 +167,8 @@ fun EmailSignUpFields(
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = email,
|
||||
placeholder = { Text(text = "user@email.com") },
|
||||
label = { Text(text = "Email") },
|
||||
placeholder = { Text(stringResource(R.string.email_signup_field_placeholder_email)) },
|
||||
label = { Text(stringResource(R.string.email_signup_field_label_email)) },
|
||||
onValueChange = onEmailChange,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })
|
||||
@ -176,8 +176,8 @@ fun EmailSignUpFields(
|
||||
|
||||
OutlinedTextField(
|
||||
value = password,
|
||||
placeholder = { Text(text = "Password") },
|
||||
label = { Text(text = "Password") },
|
||||
placeholder = { Text(stringResource(R.string.email_signup_field_placeholder_password)) },
|
||||
label = { Text(stringResource(R.string.email_signup_field_label_password)) },
|
||||
onValueChange = onPasswordChange,
|
||||
visualTransformation = PasswordVisualTransformation(),
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
@ -186,8 +186,8 @@ fun EmailSignUpFields(
|
||||
|
||||
OutlinedTextField(
|
||||
value = name,
|
||||
placeholder = { Text(text = "Name") },
|
||||
label = { Text(text = "Name") },
|
||||
placeholder = { Text(stringResource(R.string.email_signup_field_placeholder_name)) },
|
||||
label = { Text(stringResource(R.string.email_signup_field_label_name)) },
|
||||
onValueChange = onNameChange,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })
|
||||
@ -199,8 +199,8 @@ fun EmailSignUpFields(
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = username,
|
||||
placeholder = { Text(text = "Username") },
|
||||
label = { Text(text = "Username") },
|
||||
placeholder = { Text(stringResource(R.string.email_signup_field_placeholder_username)) },
|
||||
label = { Text(stringResource(R.string.email_signup_field_label_username)) },
|
||||
onValueChange = onUsernameChange,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() }),
|
||||
@ -231,7 +231,7 @@ fun EmailSignUpFields(
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"Please complete all fields.",
|
||||
context.getString(R.string.email_signup_error_msg),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
@ -241,7 +241,7 @@ fun EmailSignUpFields(
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "Sign Up",
|
||||
text = stringResource(R.string.email_signup_action_sign_up),
|
||||
modifier = Modifier.padding(horizontal = 100.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.omnivore.omnivore.BuildConfig
|
||||
import app.omnivore.omnivore.R
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||
@ -38,8 +39,8 @@ fun GoogleAuthButton(viewModel: LoginViewModel) {
|
||||
}
|
||||
|
||||
LoadingButtonWithIcon(
|
||||
text = "Continue with Google",
|
||||
loadingText = "Signing in...",
|
||||
text = stringResource(R.string.google_auth_text),
|
||||
loadingText = stringResource(R.string.google_auth_loading),
|
||||
isLoading = viewModel.isLoading,
|
||||
icon = painterResource(id = R.drawable.ic_logo_google),
|
||||
onClick = {
|
||||
|
||||
@ -11,6 +11,7 @@ import app.omnivore.omnivore.dataService.DataService
|
||||
import app.omnivore.omnivore.graphql.generated.ValidateUsernameQuery
|
||||
import app.omnivore.omnivore.networking.Networker
|
||||
import app.omnivore.omnivore.networking.viewer
|
||||
import app.omnivore.omnivore.ui.ResourceProvider
|
||||
import com.apollographql.apollo3.ApolloClient
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInAccount
|
||||
import com.google.android.gms.common.api.ApiException
|
||||
@ -22,6 +23,7 @@ import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import java.util.regex.Pattern
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
enum class RegistrationState {
|
||||
SocialLogin,
|
||||
EmailSignIn,
|
||||
@ -40,7 +42,8 @@ class LoginViewModel @Inject constructor(
|
||||
private val datastoreRepo: DatastoreRepository,
|
||||
private val eventTracker: EventTracker,
|
||||
private val networker: Networker,
|
||||
private val dataService: DataService
|
||||
private val dataService: DataService,
|
||||
private val resourceProvider: ResourceProvider
|
||||
): ViewModel() {
|
||||
private var validateUsernameJob: Job? = null
|
||||
|
||||
@ -76,7 +79,7 @@ class LoginViewModel @Inject constructor(
|
||||
datastoreRepo.putString(DatastoreKeys.omnivoreSelfHostedWebServer, webServer)
|
||||
Toast.makeText(
|
||||
context,
|
||||
"Self-hosting settings updated.",
|
||||
context.getString(R.string.login_view_model_self_hosting_settings_updated),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
@ -88,7 +91,7 @@ class LoginViewModel @Inject constructor(
|
||||
datastoreRepo.clearValue(DatastoreKeys.omnivoreSelfHostedWebServer)
|
||||
Toast.makeText(
|
||||
context,
|
||||
"Self-hosting settings reset.",
|
||||
context.getString(R.string.login_view_model_self_hosting_settings_reset),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
@ -156,7 +159,8 @@ class LoginViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
if (potentialUsername.length < 4 || potentialUsername.length > 15) {
|
||||
usernameValidationErrorMessage = "Username must be between 4 and 15 characters long."
|
||||
usernameValidationErrorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_username_validation_length_error_msg)
|
||||
hasValidUsername = false
|
||||
return@launch
|
||||
}
|
||||
@ -166,7 +170,8 @@ class LoginViewModel @Inject constructor(
|
||||
.matches()
|
||||
|
||||
if (!isValidPattern) {
|
||||
usernameValidationErrorMessage = "Username can contain only letters and numbers"
|
||||
usernameValidationErrorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_username_validation_alphanumeric_error_msg)
|
||||
hasValidUsername = false
|
||||
return@launch
|
||||
}
|
||||
@ -185,11 +190,13 @@ class LoginViewModel @Inject constructor(
|
||||
hasValidUsername = true
|
||||
} else {
|
||||
hasValidUsername = false
|
||||
usernameValidationErrorMessage = "This username is not available."
|
||||
usernameValidationErrorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_username_not_available_error_msg)
|
||||
}
|
||||
} catch (e: java.lang.Exception) {
|
||||
hasValidUsername = false
|
||||
usernameValidationErrorMessage = "Sorry we're having trouble connecting to the server."
|
||||
usernameValidationErrorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_connection_error_msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -216,7 +223,8 @@ class LoginViewModel @Inject constructor(
|
||||
if (result.body()?.authToken != null) {
|
||||
datastoreRepo.putString(DatastoreKeys.omnivoreAuthToken, result.body()?.authToken!!)
|
||||
} else {
|
||||
errorMessage = "Something went wrong. Please check your email/password and try again"
|
||||
errorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_something_went_wrong_error_msg)
|
||||
}
|
||||
|
||||
if (result.body()?.authCookieString != null) {
|
||||
@ -251,7 +259,8 @@ class LoginViewModel @Inject constructor(
|
||||
isLoading = false
|
||||
|
||||
if (result.errorBody() != null) {
|
||||
errorMessage = "Something went wrong. Please check your entries and try again"
|
||||
errorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_something_went_wrong_two_error_msg)
|
||||
} else {
|
||||
pendingEmailUserCreds = PendingEmailUserCreds(email, password)
|
||||
}
|
||||
@ -284,7 +293,8 @@ class LoginViewModel @Inject constructor(
|
||||
if (result.body()?.authToken != null) {
|
||||
datastoreRepo.putString(DatastoreKeys.omnivoreAuthToken, result.body()?.authToken!!)
|
||||
} else {
|
||||
errorMessage = "Something went wrong. Please check your email/password and try again"
|
||||
errorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_something_went_wrong_error_msg)
|
||||
}
|
||||
|
||||
if (result.body()?.authCookieString != null) {
|
||||
@ -315,7 +325,7 @@ class LoginViewModel @Inject constructor(
|
||||
}
|
||||
|
||||
fun showGoogleErrorMessage() {
|
||||
errorMessage = "Failed to authenticate with Google."
|
||||
errorMessage = resourceProvider.getString(R.string.login_view_model_google_auth_error_msg)
|
||||
}
|
||||
|
||||
fun handleGoogleAuthTask(task: Task<GoogleSignInAccount>) {
|
||||
@ -324,7 +334,8 @@ class LoginViewModel @Inject constructor(
|
||||
|
||||
// If token is missing then set the error message
|
||||
if (googleIdToken == null) {
|
||||
errorMessage = "No authentication token found."
|
||||
errorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_missing_auth_token_error_msg)
|
||||
return
|
||||
}
|
||||
|
||||
@ -361,10 +372,12 @@ class LoginViewModel @Inject constructor(
|
||||
}
|
||||
418 -> {
|
||||
// Show pending email state
|
||||
errorMessage = "Something went wrong. Please check your credentials and try again"
|
||||
errorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_something_went_wrong_two_error_msg)
|
||||
}
|
||||
else -> {
|
||||
errorMessage = "Something went wrong. Please check your credentials and try again"
|
||||
errorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_something_went_wrong_two_error_msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -386,7 +399,8 @@ class LoginViewModel @Inject constructor(
|
||||
)
|
||||
registrationStateLiveData.value = RegistrationState.PendingUser
|
||||
} else {
|
||||
errorMessage = "Something went wrong. Please check your credentials and try again"
|
||||
errorMessage = resourceProvider.getString(
|
||||
R.string.login_view_model_something_went_wrong_two_error_msg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,6 +23,7 @@ import androidx.compose.ui.graphics.RectangleShape
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.platform.LocalUriHandler
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
@ -34,6 +35,7 @@ import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.core.content.ContextCompat
|
||||
import app.omnivore.omnivore.BuildConfig
|
||||
import app.omnivore.omnivore.DatastoreKeys
|
||||
import app.omnivore.omnivore.R
|
||||
|
||||
@SuppressLint("CoroutineCreationDuringComposition")
|
||||
@Composable
|
||||
@ -62,7 +64,7 @@ fun SelfHostedView(viewModel: LoginViewModel) {
|
||||
|
||||
// TODO: add a activity indicator (maybe after a delay?)
|
||||
if (viewModel.isLoading) {
|
||||
Text("Loading...")
|
||||
Text(stringResource(R.string.self_hosted_view_loading))
|
||||
}
|
||||
|
||||
Row(
|
||||
@ -72,14 +74,14 @@ fun SelfHostedView(viewModel: LoginViewModel) {
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||
) {
|
||||
ClickableText(
|
||||
text = AnnotatedString("Reset"),
|
||||
text = AnnotatedString(stringResource(R.string.self_hosted_view_action_reset)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.resetSelfHostingDetails(context) },
|
||||
modifier = Modifier.align(Alignment.CenterHorizontally)
|
||||
)
|
||||
ClickableText(
|
||||
text = AnnotatedString("Back"),
|
||||
text = AnnotatedString(stringResource(R.string.self_hosted_view_action_back)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.showSocialLogin() },
|
||||
@ -91,7 +93,7 @@ fun SelfHostedView(viewModel: LoginViewModel) {
|
||||
// "your private self-hosted instance.\n\n"
|
||||
// )
|
||||
ClickableText(
|
||||
text = AnnotatedString("Learn more about self-hosting Omnivore"),
|
||||
text = AnnotatedString(stringResource(R.string.self_hosted_view_action_learn_more)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = {
|
||||
@ -130,7 +132,7 @@ fun SelfHostedFields(
|
||||
OutlinedTextField(
|
||||
value = apiServer,
|
||||
placeholder = { Text(text = "https://api-prod.omnivore.app/") },
|
||||
label = { Text(text = "API Server") },
|
||||
label = { Text(stringResource(R.string.self_hosted_view_field_api_url_label)) },
|
||||
onValueChange = onAPIServerChange,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Done,
|
||||
@ -142,7 +144,7 @@ fun SelfHostedFields(
|
||||
OutlinedTextField(
|
||||
value = webServer,
|
||||
placeholder = { Text(text = "https://omnivore.app/") },
|
||||
label = { Text(text = "Web Server") },
|
||||
label = { Text(stringResource(R.string.self_hosted_view_field_web_url_label)) },
|
||||
onValueChange = onWebServerChange,
|
||||
keyboardOptions = KeyboardOptions(
|
||||
imeAction = ImeAction.Done,
|
||||
@ -158,7 +160,7 @@ fun SelfHostedFields(
|
||||
} else {
|
||||
Toast.makeText(
|
||||
context,
|
||||
"Please enter API Server and Web server addresses.",
|
||||
context.getString(R.string.self_hosted_view_error_msg),
|
||||
Toast.LENGTH_SHORT
|
||||
).show()
|
||||
}
|
||||
@ -168,7 +170,7 @@ fun SelfHostedFields(
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "Save",
|
||||
text = stringResource(R.string.self_hosted_view_action_save),
|
||||
modifier = Modifier.padding(horizontal = 100.dp)
|
||||
)
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ fun AuthProviderView(viewModel: LoginViewModel) {
|
||||
AppleAuthButton(viewModel)
|
||||
|
||||
ClickableText(
|
||||
text = AnnotatedString("Continue with Email"),
|
||||
text = AnnotatedString(stringResource(R.string.welcome_screen_action_continue_with_email)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.showEmailSignIn() }
|
||||
@ -144,7 +144,7 @@ fun AuthProviderView(viewModel: LoginViewModel) {
|
||||
Spacer(modifier = Modifier.weight(1.0F))
|
||||
|
||||
ClickableText(
|
||||
text = AnnotatedString("Self-hosting options"),
|
||||
text = AnnotatedString(stringResource(R.string.welcome_screen_action_self_hosting_options)),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
.plus(TextStyle(textDecoration = TextDecoration.Underline)),
|
||||
onClick = { viewModel.showSelfHostedSettings() },
|
||||
|
||||
@ -20,10 +20,12 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import app.omnivore.omnivore.R
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@ -59,13 +61,13 @@ fun LabelCreationDialog(onDismiss: () -> Unit, onSave: (String, String) -> Unit)
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(text = "Cancel")
|
||||
Text(text = stringResource(R.string.label_creation_action_cancel))
|
||||
}
|
||||
|
||||
Text("Create New Label", fontWeight = FontWeight.ExtraBold)
|
||||
Text(stringResource(R.string.label_creation_title), fontWeight = FontWeight.ExtraBold)
|
||||
|
||||
TextButton(onClick = { onSave(labelName, selectedHex) }) {
|
||||
Text(text = "Create")
|
||||
Text(text = stringResource(R.string.label_creation_action_create))
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,7 +78,7 @@ fun LabelCreationDialog(onDismiss: () -> Unit, onSave: (String, String) -> Unit)
|
||||
.fillMaxWidth()
|
||||
.padding(vertical = 10.dp)
|
||||
) {
|
||||
Text("Assign a name and color.")
|
||||
Text(stringResource(R.string.label_creation_content))
|
||||
}
|
||||
|
||||
Row(
|
||||
@ -88,7 +90,7 @@ fun LabelCreationDialog(onDismiss: () -> Unit, onSave: (String, String) -> Unit)
|
||||
) {
|
||||
OutlinedTextField(
|
||||
value = labelName,
|
||||
placeholder = { Text(text = "Label Name") },
|
||||
placeholder = { Text(stringResource(R.string.label_creation_label_placeholder)) },
|
||||
onValueChange = { labelName = it },
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
|
||||
keyboardActions = KeyboardActions(onDone = { focusManager.clearFocus() })
|
||||
|
||||
@ -36,6 +36,7 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.layout.boundsInWindow
|
||||
import androidx.compose.ui.layout.onGloballyPositioned
|
||||
import androidx.compose.ui.platform.*
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextRange
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
@ -44,6 +45,7 @@ import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.DpSize
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.models.ServerSyncStatus
|
||||
import app.omnivore.omnivore.persistence.entities.SavedItemLabel
|
||||
import app.omnivore.omnivore.ui.library.LibraryViewModel
|
||||
@ -260,7 +262,9 @@ fun LabelsSelectionSheetContent(
|
||||
it.name.toLowerCase(Locale.current) == text
|
||||
}
|
||||
|
||||
val titleText = if (isLibraryMode) "Filter by Label" else "Set Labels"
|
||||
val titleText = if (isLibraryMode)
|
||||
stringResource(R.string.label_selection_sheet_title) else
|
||||
stringResource(R.string.label_selection_sheet_title_alt)
|
||||
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
@ -282,13 +286,15 @@ fun LabelsSelectionSheetContent(
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
TextButton(onClick = onCancel) {
|
||||
Text(text = "Cancel")
|
||||
Text(text = stringResource(R.string.label_selection_sheet_action_cancel))
|
||||
}
|
||||
|
||||
Text(titleText, fontWeight = FontWeight.ExtraBold)
|
||||
|
||||
TextButton(onClick = { onSave(state.chips.map { it.label }) }) {
|
||||
Text(text = if (isLibraryMode) "Search" else "Save")
|
||||
Text(text = if (isLibraryMode)
|
||||
stringResource(R.string.label_selection_sheet_action_search) else
|
||||
stringResource(R.string.label_selection_sheet_action_save))
|
||||
}
|
||||
}
|
||||
|
||||
@ -341,7 +347,11 @@ fun LabelsSelectionSheetContent(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
val label = findOrCreateLabel(labelsViewModel = labelsViewModel, labels = labels, name = filterTextValue)
|
||||
val label = findOrCreateLabel(
|
||||
labelsViewModel = labelsViewModel,
|
||||
labels = labels,
|
||||
name = filterTextValue
|
||||
)
|
||||
state.addChip(LabelChipView(label))
|
||||
filterTextValue = TextFieldValue()
|
||||
}
|
||||
@ -354,7 +364,7 @@ fun LabelsSelectionSheetContent(
|
||||
contentDescription = null,
|
||||
modifier = Modifier.padding(end = 8.dp)
|
||||
)
|
||||
Text(text = "Create a new label named \"${filterTextValue.text}\"")
|
||||
Text(text = stringResource(R.string.label_selection_sheet_text_create, filterTextValue.text))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.intl.Locale
|
||||
import androidx.compose.ui.text.toLowerCase
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -69,7 +70,7 @@ fun LibraryFilterBar(viewModel: LibraryViewModel) {
|
||||
)
|
||||
AssistChip(
|
||||
onClick = { viewModel.showLabelsSelectionSheetLiveData.value = true },
|
||||
label = { Text("Labels") },
|
||||
label = { Text(stringResource(R.string.library_filter_bar_label_labels)) },
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
Icons.Default.ArrowDropDown,
|
||||
|
||||
@ -18,6 +18,7 @@ import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.navigation.NavHostController
|
||||
import app.omnivore.omnivore.R
|
||||
@ -34,7 +35,9 @@ fun LibraryNavigationBar(
|
||||
|
||||
TopAppBar(
|
||||
title = {
|
||||
Text(if (actionsMenuItem == null) "Library" else "")
|
||||
Text(if (actionsMenuItem == null)
|
||||
stringResource(R.string.library_nav_bar_title) else
|
||||
stringResource(R.string.library_nav_bar_title_alt))
|
||||
},
|
||||
modifier = Modifier.statusBarsPadding(),
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
@ -218,7 +221,7 @@ fun SearchField(
|
||||
value = searchText,
|
||||
onValueChange = onSearchTextChanged,
|
||||
placeholder = {
|
||||
Text(text = "Search")
|
||||
Text(text = stringResource(R.string.library_nav_bar_field_placeholder_search))
|
||||
},
|
||||
leadingIcon = {
|
||||
IconButton(
|
||||
|
||||
@ -19,6 +19,7 @@ import app.omnivore.omnivore.graphql.generated.type.SetLabelsInput
|
||||
import app.omnivore.omnivore.models.ServerSyncStatus
|
||||
import app.omnivore.omnivore.networking.*
|
||||
import app.omnivore.omnivore.persistence.entities.*
|
||||
import app.omnivore.omnivore.ui.ResourceProvider
|
||||
import com.apollographql.apollo3.api.Optional
|
||||
import com.apollographql.apollo3.api.Optional.Companion.presentIfNotNull
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@ -31,7 +32,8 @@ import javax.inject.Inject
|
||||
class LibraryViewModel @Inject constructor(
|
||||
private val networker: Networker,
|
||||
private val dataService: DataService,
|
||||
private val datastoreRepo: DatastoreRepository
|
||||
private val datastoreRepo: DatastoreRepository,
|
||||
private val resourceProvider: ResourceProvider
|
||||
): ViewModel(), SavedItemViewModel {
|
||||
private val contentRequestChannel = Channel<String>(capacity = Channel.UNLIMITED)
|
||||
|
||||
@ -348,9 +350,9 @@ class LibraryViewModel @Inject constructor(
|
||||
dataService.db.savedItemAndSavedItemLabelCrossRefDao().insertAll(crossRefs)
|
||||
|
||||
if (!networkResult || labelCreationError) {
|
||||
snackbarMessage = "Unable to set labels"
|
||||
snackbarMessage = resourceProvider.getString(R.string.library_view_model_snackbar_error)
|
||||
} else {
|
||||
snackbarMessage = "Labels updated"
|
||||
snackbarMessage = resourceProvider.getString(R.string.library_view_model_snackbar_success)
|
||||
}
|
||||
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
|
||||
@ -43,6 +43,7 @@ import kotlinx.coroutines.launch
|
||||
import app.omnivore.omnivore.persistence.entities.Highlight
|
||||
import app.omnivore.omnivore.ui.theme.OmnivoreTheme
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
|
||||
|
||||
fun notebookMD(notes: List<Highlight>, highlights: List<Highlight>): String {
|
||||
@ -80,6 +81,9 @@ fun NotebookView(savedItemId: String, viewModel: NotebookViewModel, onEditNote:
|
||||
val scrollState = rememberScrollState()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val snackBarHostState = remember { SnackbarHostState() }
|
||||
val context = LocalContext.current
|
||||
val snackBarHostStateMsg = context.getString(R.string.notebook_view_snackbar_msg)
|
||||
|
||||
val clipboard: ClipboardManager? =
|
||||
LocalContext.current.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?
|
||||
|
||||
@ -89,7 +93,7 @@ fun NotebookView(savedItemId: String, viewModel: NotebookViewModel, onEditNote:
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Notebook") },
|
||||
title = { Text(stringResource(R.string.notebook_view_title)) },
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.background
|
||||
),
|
||||
@ -109,7 +113,7 @@ fun NotebookView(savedItemId: String, viewModel: NotebookViewModel, onEditNote:
|
||||
onDismissRequest = { isMenuOpen = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text("Copy") },
|
||||
text = { Text(stringResource(R.string.notebook_view_action_copy)) },
|
||||
onClick = {
|
||||
val clip = ClipData.newPlainText("notebook", notebookMD(notes, highlights))
|
||||
clipboard?.let {
|
||||
@ -117,7 +121,7 @@ fun NotebookView(savedItemId: String, viewModel: NotebookViewModel, onEditNote:
|
||||
} ?: run {
|
||||
coroutineScope.launch {
|
||||
snackBarHostState
|
||||
.showSnackbar("Notebook copied")
|
||||
.showSnackbar(snackBarHostStateMsg)
|
||||
}
|
||||
}
|
||||
isMenuOpen = false
|
||||
@ -154,7 +158,7 @@ fun EditNoteModal(initialValue: String?, onDismiss: (save: Boolean, text: String
|
||||
Scaffold(
|
||||
topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = { Text("Note") },
|
||||
title = { Text(stringResource(R.string.edit_note_modal_title)) },
|
||||
modifier = Modifier.statusBarsPadding(),
|
||||
colors = TopAppBarDefaults.topAppBarColors(
|
||||
containerColor = MaterialTheme.colorScheme.background
|
||||
@ -163,14 +167,14 @@ fun EditNoteModal(initialValue: String?, onDismiss: (save: Boolean, text: String
|
||||
TextButton(onClick = {
|
||||
onDismiss(false, initialValue)
|
||||
}) {
|
||||
Text(text = "Cancel")
|
||||
Text(text = stringResource(R.string.edit_note_modal_action_cancel))
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
TextButton(onClick = {
|
||||
onDismiss(true, annotation.value)
|
||||
}) {
|
||||
Text(text = "Save")
|
||||
Text(text = stringResource(R.string.edit_note_modal_action_save))
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -205,7 +209,7 @@ fun ArticleNotes(viewModel: NotebookViewModel, item: SavedItemWithLabelsAndHighl
|
||||
.padding(start = 15.dp)
|
||||
.padding(top = 20.dp, bottom = 50.dp)
|
||||
) {
|
||||
Text("Article Notes")
|
||||
Text(stringResource(R.string.article_notes_title))
|
||||
Divider(modifier = Modifier.padding(bottom= 15.dp))
|
||||
notes.forEach { note ->
|
||||
MarkdownText(
|
||||
@ -231,7 +235,7 @@ fun ArticleNotes(viewModel: NotebookViewModel, item: SavedItemWithLabelsAndHighl
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "Add Notes...",
|
||||
text = stringResource(R.string.article_notes_action_add_notes),
|
||||
style = androidx.compose.material.MaterialTheme.typography.subtitle2,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 2.dp, horizontal = 0.dp),
|
||||
@ -250,6 +254,8 @@ fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Hi
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val snackBarHostState = remember { SnackbarHostState() }
|
||||
val context = LocalContext.current
|
||||
val snackBarHostStateMsg = context.getString(R.string.highlights_list_snackbar_msg)
|
||||
val clipboard: ClipboardManager? =
|
||||
LocalContext.current.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager?
|
||||
|
||||
@ -258,7 +264,7 @@ fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Hi
|
||||
.padding(start = 15.dp)
|
||||
.padding(top = 40.dp, bottom = 100.dp)
|
||||
) {
|
||||
Text("Highlights")
|
||||
Text(stringResource(R.string.highlights_list_title))
|
||||
Divider(modifier = Modifier.padding(bottom= 10.dp))
|
||||
highlights.forEach { highlight ->
|
||||
var isMenuOpen by remember { mutableStateOf(false) }
|
||||
@ -282,7 +288,7 @@ fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Hi
|
||||
onDismissRequest = { isMenuOpen = false }
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text("Copy") },
|
||||
text = { Text(stringResource(R.string.highlights_list_action_copy)) },
|
||||
onClick = {
|
||||
val clip = ClipData.newPlainText("highlight", highlight.quote)
|
||||
clipboard?.let {
|
||||
@ -290,7 +296,7 @@ fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Hi
|
||||
} ?: run {
|
||||
coroutineScope.launch {
|
||||
snackBarHostState
|
||||
.showSnackbar("Highlight copied")
|
||||
.showSnackbar(snackBarHostStateMsg)
|
||||
}
|
||||
}
|
||||
isMenuOpen = false
|
||||
@ -354,7 +360,7 @@ fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Hi
|
||||
)
|
||||
) {
|
||||
Text(
|
||||
text = "Add Note...",
|
||||
text = stringResource(R.string.highlights_list_action_add_note),
|
||||
style = androidx.compose.material.MaterialTheme.typography.subtitle2,
|
||||
modifier = Modifier
|
||||
.padding(vertical = 2.dp, horizontal = 0.dp),
|
||||
@ -365,7 +371,7 @@ fun HighlightsList(item: SavedItemWithLabelsAndHighlights, onEditNote: (note: Hi
|
||||
}
|
||||
if (highlights.isEmpty()) {
|
||||
Text(
|
||||
text = "You have not added any highlights to this page.",
|
||||
text = stringResource(R.string.highlights_list_error_msg_no_highlights),
|
||||
style = androidx.compose.material.MaterialTheme.typography.subtitle2,
|
||||
modifier = Modifier.padding(vertical = 10.dp, horizontal = 10.dp)
|
||||
)
|
||||
|
||||
@ -20,6 +20,7 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.colorResource
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
@ -103,7 +104,7 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) {
|
||||
}
|
||||
}
|
||||
|
||||
Text("Font Size:", style = TextStyle(
|
||||
Text(stringResource(R.string.reader_preferences_view_font_size), style = TextStyle(
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color(red = 137, green = 137, blue = 137)
|
||||
@ -118,7 +119,7 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) {
|
||||
valueRange = 10f..48f,
|
||||
)
|
||||
|
||||
Text("Margin", style = TextStyle(
|
||||
Text(stringResource(R.string.reader_preferences_view_margin), style = TextStyle(
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color(red = 137, green = 137, blue = 137)
|
||||
@ -133,7 +134,7 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) {
|
||||
valueRange = 60f..100f,
|
||||
)
|
||||
|
||||
Text("Line Spacing", style = TextStyle(
|
||||
Text(stringResource(R.string.reader_preferences_view_line_spacing), style = TextStyle(
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color(red = 137, green = 137, blue = 137)
|
||||
@ -153,13 +154,13 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) {
|
||||
modifier = Modifier
|
||||
.padding(vertical = 4.dp)
|
||||
) {
|
||||
Text("Theme:", style = TextStyle(
|
||||
Text(stringResource(R.string.reader_preferences_view_theme), style = TextStyle(
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color(red = 137, green = 137, blue = 137)
|
||||
))
|
||||
Spacer(modifier = Modifier.weight(1.0F))
|
||||
Text("Auto", style = TextStyle(
|
||||
Text(stringResource(R.string.reader_preferences_view_auto), style = TextStyle(
|
||||
fontSize = 10.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = Color(red = 137, green = 137, blue = 137)
|
||||
@ -208,7 +209,8 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) {
|
||||
}
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text("High Contrast Text",
|
||||
Text(
|
||||
stringResource(R.string.reader_preferences_view_high_constrast_text),
|
||||
style = TextStyle(
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
@ -225,7 +227,8 @@ fun ReaderPreferencesView(webReaderViewModel: WebReaderViewModel) {
|
||||
}
|
||||
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Text("Justify Text",
|
||||
Text(
|
||||
stringResource(R.string.reader_preferences_view_justify_text),
|
||||
style = TextStyle(
|
||||
fontSize = 15.sp,
|
||||
fontWeight = FontWeight.Normal,
|
||||
|
||||
@ -44,6 +44,7 @@ import kotlinx.coroutines.launch
|
||||
import kotlin.math.roundToInt
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.omnivore.omnivore.ui.components.LabelsViewModel
|
||||
import app.omnivore.omnivore.ui.notebook.EditNoteModal
|
||||
|
||||
@ -80,7 +81,7 @@ class WebReaderLoadingContainerActivity: ComponentActivity() {
|
||||
.background(color = Color.Black)
|
||||
) {
|
||||
if (viewModel.hasFetchError.value == true) {
|
||||
Text("We were unable to fetch your content.")
|
||||
Text(stringResource(R.string.web_reader_loading_container_error_msg))
|
||||
} else {
|
||||
WebReaderLoadingContainer(
|
||||
requestID = requestID,
|
||||
@ -200,13 +201,13 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
||||
sheetContent = {
|
||||
when (bottomSheetState) {
|
||||
BottomSheetState.PREFERENCES -> {
|
||||
BottomSheetUI("Reader Preferences") {
|
||||
BottomSheetUI(stringResource(R.string.web_reader_loading_container_bottom_sheet_reader_preferences)) {
|
||||
ReaderPreferencesView(webReaderViewModel)
|
||||
}
|
||||
}
|
||||
BottomSheetState.NOTEBOOK -> {
|
||||
webReaderParams?.let { params ->
|
||||
BottomSheetUI(title = "Notebook") {
|
||||
BottomSheetUI(title = stringResource(R.string.web_reader_loading_container_bottom_sheet_notebook)) {
|
||||
NotebookView(savedItemId = params.item.savedItemId, viewModel = notebookViewModel, onEditNote = {
|
||||
notebookViewModel.highlightUnderEdit = it
|
||||
webReaderViewModel.setBottomSheet(BottomSheetState.EDITNOTE)
|
||||
@ -255,7 +256,7 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
||||
)
|
||||
}
|
||||
BottomSheetState.LABELS -> {
|
||||
BottomSheetUI(title = "Notebook") {
|
||||
BottomSheetUI(title = stringResource(R.string.web_reader_loading_container_bottom_sheet_notebook)) {
|
||||
LabelsSelectionSheetContent(
|
||||
labels = labels,
|
||||
labelsViewModel = labelsViewModel,
|
||||
@ -283,7 +284,7 @@ fun WebReaderLoadingContainer(slug: String? = null, requestID: String? = null,
|
||||
}
|
||||
}
|
||||
BottomSheetState.LINK -> {
|
||||
BottomSheetUI(title = "Open Link") {
|
||||
BottomSheetUI(title = stringResource(R.string.web_reader_loading_container_bottom_sheet_open_link)) {
|
||||
OpenLinkView(webReaderViewModel)
|
||||
}
|
||||
}
|
||||
@ -460,25 +461,25 @@ fun OpenLinkView(webReaderViewModel: WebReaderViewModel) {
|
||||
.padding(horizontal = 50.dp), verticalArrangement = Arrangement.spacedBy(20.dp)) {
|
||||
Row {
|
||||
Button(onClick = { webReaderViewModel.openCurrentLink(context) }, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = "Open in Browser")
|
||||
Text(text = stringResource(R.string.open_link_view_action_open_in_browser))
|
||||
|
||||
}
|
||||
}
|
||||
Row() {
|
||||
Button(onClick = { webReaderViewModel.saveCurrentLink(context) }, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = "Save to Omnivore")
|
||||
Text(text = stringResource(R.string.open_link_view_action_save_to_omnivore))
|
||||
|
||||
}
|
||||
}
|
||||
Row() {
|
||||
Button(onClick = {webReaderViewModel.copyCurrentLink(context) }, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = "Copy Link")
|
||||
Text(text = stringResource(R.string.open_link_view_action_copy_link))
|
||||
|
||||
}
|
||||
}
|
||||
Row {
|
||||
Button(onClick = {webReaderViewModel.resetBottomSheet() }, modifier = Modifier.fillMaxWidth()) {
|
||||
Text(text = "Cancel")
|
||||
Text(text = stringResource(R.string.open_link_view_action_cancel))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,6 +12,7 @@ import androidx.lifecycle.*
|
||||
import app.omnivore.omnivore.DatastoreKeys
|
||||
import app.omnivore.omnivore.DatastoreRepository
|
||||
import app.omnivore.omnivore.EventTracker
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.dataService.*
|
||||
import app.omnivore.omnivore.graphql.generated.type.CreateLabelInput
|
||||
import app.omnivore.omnivore.graphql.generated.type.SetLabelsInput
|
||||
@ -139,7 +140,11 @@ class WebReaderViewModel @Inject constructor(
|
||||
currentLink?.let {
|
||||
viewModelScope.launch {
|
||||
val success = networker.saveUrl(it)
|
||||
Toast.makeText(context, if (success) "Link saved" else "Error saving link" , Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(context,
|
||||
if (success)
|
||||
context.getString(R.string.web_reader_view_model_save_link_success) else
|
||||
context.getString(R.string.web_reader_view_model_save_link_error),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
bottomSheetStateLiveData.postValue(BottomSheetState.NONE)
|
||||
@ -153,7 +158,9 @@ class WebReaderViewModel @Inject constructor(
|
||||
clipboard.setPrimaryClip(clip)
|
||||
clipboard?.let {
|
||||
clipboard?.setPrimaryClip(clip)
|
||||
Toast.makeText(context, "Link Copied", Toast.LENGTH_SHORT).show()
|
||||
Toast.makeText(context,
|
||||
context.getString(R.string.web_reader_view_model_copy_link_success),
|
||||
Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
bottomSheetStateLiveData.postValue(BottomSheetState.NONE)
|
||||
|
||||
@ -14,8 +14,10 @@ import androidx.compose.material.ButtonDefaults
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import app.omnivore.omnivore.MainActivity
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.ui.reader.PDFReaderActivity
|
||||
import app.omnivore.omnivore.ui.reader.WebReaderLoadingContainerActivity
|
||||
import kotlinx.coroutines.launch
|
||||
@ -36,7 +38,7 @@ fun SaveContent(viewModel: SaveViewModel, modalBottomSheetState: ModalBottomShee
|
||||
.fillMaxSize()
|
||||
.padding(top = 48.dp, bottom = 32.dp)
|
||||
) {
|
||||
Text(text = viewModel.message ?: "Saving")
|
||||
Text(text = viewModel.message ?: stringResource(R.string.save_content_msg))
|
||||
Row {
|
||||
if (enableReadNow) {
|
||||
Button(
|
||||
@ -55,7 +57,7 @@ fun SaveContent(viewModel: SaveViewModel, modalBottomSheetState: ModalBottomShee
|
||||
backgroundColor = Color.White
|
||||
)
|
||||
) {
|
||||
Text(text = "Read Now")
|
||||
Text(text = stringResource(R.string.save_content_action_read_now))
|
||||
}
|
||||
|
||||
Spacer(modifier = Modifier.width(8.dp))
|
||||
@ -72,7 +74,9 @@ fun SaveContent(viewModel: SaveViewModel, modalBottomSheetState: ModalBottomShee
|
||||
backgroundColor = Color(0xffffd234)
|
||||
)
|
||||
) {
|
||||
Text(text = if (enableReadNow) "Read Later" else "Dismiss")
|
||||
Text(text = if (enableReadNow)
|
||||
stringResource(R.string.save_content_action_read_later) else
|
||||
stringResource(R.string.save_content_action_dismiss))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,8 +12,10 @@ import androidx.lifecycle.viewModelScope
|
||||
import app.omnivore.omnivore.Constants
|
||||
import app.omnivore.omnivore.DatastoreKeys
|
||||
import app.omnivore.omnivore.DatastoreRepository
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.graphql.generated.SaveUrlMutation
|
||||
import app.omnivore.omnivore.graphql.generated.type.SaveUrlInput
|
||||
import app.omnivore.omnivore.ui.ResourceProvider
|
||||
import com.apollographql.apollo3.ApolloClient
|
||||
import com.apollographql.apollo3.api.Optional
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
@ -32,7 +34,8 @@ enum class SaveState {
|
||||
|
||||
@HiltViewModel
|
||||
class SaveViewModel @Inject constructor(
|
||||
private val datastoreRepo: DatastoreRepository
|
||||
private val datastoreRepo: DatastoreRepository,
|
||||
private val resourceProvider: ResourceProvider
|
||||
) : ViewModel() {
|
||||
val saveState = MutableLiveData(SaveState.NONE)
|
||||
|
||||
@ -62,13 +65,13 @@ class SaveViewModel @Inject constructor(
|
||||
fun saveURL(url: String) {
|
||||
viewModelScope.launch {
|
||||
isLoading = true
|
||||
message = "Saving to Omnivore..."
|
||||
message = resourceProvider.getString(R.string.save_view_model_msg)
|
||||
saveState.postValue(SaveState.SAVING)
|
||||
|
||||
val authToken = getAuthToken()
|
||||
|
||||
if (authToken == null) {
|
||||
message = "You are not logged in. Please login before saving."
|
||||
message = resourceProvider.getString(R.string.save_view_model_error_not_logged_in)
|
||||
isLoading = false
|
||||
return@launch
|
||||
}
|
||||
@ -103,15 +106,15 @@ class SaveViewModel @Inject constructor(
|
||||
|
||||
val success = (response.data?.saveUrl?.onSaveSuccess?.url != null)
|
||||
message = if (success) {
|
||||
"Page Saved"
|
||||
resourceProvider.getString(R.string.save_view_model_page_saved_success)
|
||||
} else {
|
||||
"There was an error saving your page"
|
||||
resourceProvider.getString(R.string.save_view_model_page_saved_error)
|
||||
}
|
||||
|
||||
saveState.postValue(SaveState.SAVED)
|
||||
Log.d(ContentValues.TAG, "Saved URL?: $success")
|
||||
} catch (e: java.lang.Exception) {
|
||||
message = "There was an error saving your page"
|
||||
message = resourceProvider.getString(R.string.save_view_model_page_saved_error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.omnivore.omnivore.R
|
||||
import app.omnivore.omnivore.ui.library.SavedItemAction
|
||||
import app.omnivore.omnivore.ui.reader.WebReaderViewModel
|
||||
@ -31,7 +32,7 @@ fun SavedItemContextMenu(
|
||||
onDismissRequest = onDismiss
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text("Edit Labels") },
|
||||
text = { Text(stringResource(R.string.saved_item_context_menu_action_edit_labels)) },
|
||||
onClick = {
|
||||
actionHandler(SavedItemAction.EditLabels)
|
||||
onDismiss()
|
||||
@ -44,7 +45,9 @@ fun SavedItemContextMenu(
|
||||
}
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text(if (isArchived) "Unarchive" else "Archive") },
|
||||
text = { Text(if (isArchived)
|
||||
stringResource(R.string.saved_item_context_menu_action_unarchive) else
|
||||
stringResource(R.string.saved_item_context_menu_action_archive)) },
|
||||
onClick = {
|
||||
val action = if (isArchived) SavedItemAction.Unarchive else SavedItemAction.Archive
|
||||
actionHandler(action)
|
||||
@ -58,7 +61,7 @@ fun SavedItemContextMenu(
|
||||
}
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text("Share Original") },
|
||||
text = { Text(stringResource(R.string.saved_item_context_menu_action_share_original)) },
|
||||
onClick = {
|
||||
webReaderViewModel.showShareLinkSheet(context)
|
||||
onDismiss()
|
||||
@ -71,7 +74,7 @@ fun SavedItemContextMenu(
|
||||
}
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text("Remove Item") },
|
||||
text = { Text(stringResource(R.string.saved_item_context_menu_action_remove_item)) },
|
||||
onClick = {
|
||||
actionHandler(SavedItemAction.Delete)
|
||||
onDismiss()
|
||||
|
||||
@ -5,6 +5,8 @@ import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.omnivore.omnivore.R
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignIn
|
||||
import com.google.android.gms.auth.api.signin.GoogleSignInOptions
|
||||
|
||||
@ -14,9 +16,9 @@ fun LogoutDialog(onClose: (Boolean) -> Unit) {
|
||||
|
||||
AlertDialog(
|
||||
onDismissRequest = { onClose(false) },
|
||||
title = { Text(text = "Logout") },
|
||||
title = { Text(text = stringResource(R.string.logout_dialog_title)) },
|
||||
text = {
|
||||
Text("Are you sure you want to logout?")
|
||||
Text(stringResource(R.string.logout_dialog_confirm_msg))
|
||||
},
|
||||
confirmButton = {
|
||||
Button(onClick = {
|
||||
@ -28,12 +30,12 @@ fun LogoutDialog(onClose: (Boolean) -> Unit) {
|
||||
googleSignIn.signOut()
|
||||
onClose(true)
|
||||
}) {
|
||||
Text("Confirm")
|
||||
Text(stringResource(R.string.logout_dialog_action_confirm))
|
||||
}
|
||||
},
|
||||
dismissButton = {
|
||||
Button(onClick = { onClose(false) }) {
|
||||
Text("Cancel")
|
||||
Text(stringResource(R.string.logout_dialog_action_cancel))
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@ -14,8 +14,10 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import app.omnivore.omnivore.R
|
||||
|
||||
@Composable
|
||||
fun ManageAccountDialog(onDismiss: () -> Unit, settingsViewModel: SettingsViewModel) {
|
||||
@ -43,7 +45,7 @@ fun ManageAccountView(settingsViewModel: SettingsViewModel) {
|
||||
.padding(top = 12.dp, bottom = 12.dp),
|
||||
horizontalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text("Manage Account")
|
||||
Text(stringResource(R.string.manage_account_title))
|
||||
}
|
||||
|
||||
Column(
|
||||
@ -55,7 +57,7 @@ fun ManageAccountView(settingsViewModel: SettingsViewModel) {
|
||||
modifier = Modifier
|
||||
.clickable(onClick = { settingsViewModel.resetDataCache() })
|
||||
) {
|
||||
Text("Reset Data Cache")
|
||||
Text(stringResource(R.string.manage_account_action_reset_data_cache))
|
||||
Spacer(modifier = Modifier.weight(1.0F))
|
||||
Icon(imageVector = Icons.Filled.Refresh, contentDescription = null)
|
||||
}
|
||||
|
||||
@ -11,9 +11,11 @@ import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.viewinterop.AndroidView
|
||||
import androidx.navigation.NavHostController
|
||||
import app.omnivore.omnivore.Routes
|
||||
import app.omnivore.omnivore.R
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter", "SetJavaScriptEnabled")
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@ -22,7 +24,7 @@ fun PolicyWebView(navController: NavHostController, url: String) {
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { androidx.compose.material3.Text("Settings") },
|
||||
title = { androidx.compose.material3.Text(stringResource(R.string.policy_webview_title)) },
|
||||
actions = {
|
||||
IconButton(onClick = { navController.navigate(Routes.Settings.route) }) {
|
||||
Icon(
|
||||
|
||||
@ -14,6 +14,7 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavHostController
|
||||
import app.omnivore.omnivore.R
|
||||
@ -37,7 +38,7 @@ fun SettingsView(
|
||||
Scaffold(
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
title = { Text("Settings") },
|
||||
title = { Text(stringResource(R.string.settings_view_title)) },
|
||||
actions = {
|
||||
IconButton(onClick = { navController.navigate(Routes.Library.route) }) {
|
||||
Icon(
|
||||
@ -100,19 +101,31 @@ fun SettingsViewContent(loginViewModel: LoginViewModel, settingsViewModel: Setti
|
||||
//
|
||||
// SectionSpacer()
|
||||
|
||||
SettingRow(text = "Documentation") { navController.navigate(Routes.Documentation.route) }
|
||||
SettingRow(text = stringResource(R.string.settings_view_setting_row_documentation)) {
|
||||
navController.navigate(Routes.Documentation.route)
|
||||
}
|
||||
RowDivider()
|
||||
SettingRow(text = "Feedback") { Intercom.client().present(space = IntercomSpace.Messages) }
|
||||
SettingRow(text = stringResource(R.string.settings_view_setting_row_feedback)) {
|
||||
Intercom.client().present(space = IntercomSpace.Messages)
|
||||
}
|
||||
RowDivider()
|
||||
SettingRow(text = "Privacy Policy") { navController.navigate(Routes.PrivacyPolicy.route) }
|
||||
SettingRow(text = stringResource(R.string.settings_view_setting_row_privacy_policy)) {
|
||||
navController.navigate(Routes.PrivacyPolicy.route)
|
||||
}
|
||||
RowDivider()
|
||||
SettingRow(text = "Terms and Conditions") { navController.navigate(Routes.TermsAndConditions.route) }
|
||||
SettingRow(text = stringResource(R.string.settings_view_setting_row_terms_and_conditions)) {
|
||||
navController.navigate(Routes.TermsAndConditions.route)
|
||||
}
|
||||
|
||||
SectionSpacer()
|
||||
|
||||
SettingRow(text = "Manage Account") { showManageAccountDialog.value = true }
|
||||
SettingRow(text = stringResource(R.string.settings_view_setting_row_manage_account)) {
|
||||
showManageAccountDialog.value = true
|
||||
}
|
||||
RowDivider()
|
||||
SettingRow(text = "Logout", includeIcon = false) { showLogoutDialog.value = true }
|
||||
SettingRow(text = stringResource(R.string.settings_view_setting_row_logout), includeIcon = false) {
|
||||
showLogoutDialog.value = true
|
||||
}
|
||||
RowDivider()
|
||||
}
|
||||
|
||||
|
||||
@ -12,4 +12,195 @@
|
||||
<string name="highlight_note">Note</string>
|
||||
<string name="copyTextSelection">Copy</string>
|
||||
<string name="pdf_highlight_menu_note">Note</string>
|
||||
|
||||
<!-- Apple Auth -->
|
||||
<string name="apple_auth_text">Continue with Apple</string>
|
||||
<string name="apple_auth_loading">Signing in...</string>
|
||||
|
||||
<!-- Create User Profile -->
|
||||
<string name="create_user_profile_title">Create Your Profile</string>
|
||||
<string name="create_user_profile_loading">Loading...</string>
|
||||
<string name="create_user_profile_action_cancel">Cancel Sign Up</string>
|
||||
<string name="create_user_profile_action_submit">Submit</string>
|
||||
<string name="create_user_profile_field_placeholder_name">Name</string>
|
||||
<string name="create_user_profile_field_label_name">Name</string>
|
||||
<string name="create_user_profile_field_placeholder_username">Username</string>
|
||||
<string name="create_user_profile_field_label_username">Username</string>
|
||||
<string name="create_user_profile_error_msg">Please enter a valid name and username.</string>
|
||||
|
||||
<!-- Email Login -->
|
||||
<string name="email_login_loading">Loading...</string>
|
||||
<string name="email_login_action_back">Return to Social Login</string>
|
||||
<string name="email_login_action_no_account">Don\'t have an account?</string>
|
||||
<string name="email_login_action_forgot_password">Forgot your password?</string>
|
||||
<string name="email_login_action_login">Login</string>
|
||||
<string name="email_login_field_placeholder_email">user@email.com</string>
|
||||
<string name="email_login_field_label_email">Email</string>
|
||||
<string name="email_login_field_placeholder_password">Password</string>
|
||||
<string name="email_login_field_label_password">Password</string>
|
||||
<string name="email_login_error_msg">Please enter an email address and password.</string>
|
||||
|
||||
<!-- Email Sign Up -->
|
||||
<string name="email_signup_verification_message">We\'ve sent a verification email to %1$s. Please verify your email and then tap the button below.</string>
|
||||
<string name="email_signup_check_status">Check Status</string>
|
||||
<string name="email_signup_action_use_different_email">Use a different email?</string>
|
||||
<string name="email_signup_loading">Loading...</string>
|
||||
<string name="email_signup_action_back">Return to Social Login</string>
|
||||
<string name="email_signup_action_already_have_account">Already have an account?</string>
|
||||
<string name="email_signup_action_sign_up">Sign Up</string>
|
||||
<string name="email_signup_field_placeholder_email">user@email.com</string>
|
||||
<string name="email_signup_field_label_email">Email</string>
|
||||
<string name="email_signup_field_placeholder_password">Password</string>
|
||||
<string name="email_signup_field_label_password">Password</string>
|
||||
<string name="email_signup_field_placeholder_name">Name</string>
|
||||
<string name="email_signup_field_label_name">Name</string>
|
||||
<string name="email_signup_field_placeholder_username">Name</string>
|
||||
<string name="email_signup_field_label_username">Name</string>
|
||||
<string name="email_signup_error_msg">Please complete all fields.</string>
|
||||
|
||||
<!-- Google Auth -->
|
||||
<string name="google_auth_text">Continue with Google</string>
|
||||
<string name="google_auth_loading">Signing in...</string>
|
||||
|
||||
<!-- LoginViewModel -->
|
||||
<string name="login_view_model_self_hosting_settings_updated">Self-hosting settings updated.</string>
|
||||
<string name="login_view_model_self_hosting_settings_reset">Self-hosting settings reset.</string>
|
||||
<string name="login_view_model_username_validation_length_error_msg">Username must be between 4 and 15 characters long.</string>
|
||||
<string name="login_view_model_username_validation_alphanumeric_error_msg">Username can contain only letters and numbers.</string>
|
||||
<string name="login_view_model_username_not_available_error_msg">This username is not available.</string>
|
||||
<string name="login_view_model_connection_error_msg">Sorry we\'re having trouble connecting to the server.</string>
|
||||
<string name="login_view_model_something_went_wrong_error_msg">Something went wrong. Please check your email/password and try again.</string>
|
||||
<string name="login_view_model_something_went_wrong_two_error_msg">Something went wrong. Please check your credentials and try again.</string>
|
||||
<string name="login_view_model_google_auth_error_msg">Failed to authenticate with Google.</string>
|
||||
<string name="login_view_model_missing_auth_token_error_msg">No authentication token found.</string>
|
||||
|
||||
<!-- SelfHostedView -->
|
||||
<string name="self_hosted_view_loading">Loading...</string>
|
||||
<string name="self_hosted_view_action_reset">Reset</string>
|
||||
<string name="self_hosted_view_action_back">Back</string>
|
||||
<string name="self_hosted_view_action_save">Save</string>
|
||||
<string name="self_hosted_view_action_learn_more">Learn more about self-hosting Omnivore</string>
|
||||
<string name="self_hosted_view_field_api_url_label">API Server</string>
|
||||
<string name="self_hosted_view_field_web_url_label">Web Server</string>
|
||||
<string name="self_hosted_view_error_msg">Please enter API Server and Web server addresses.</string>
|
||||
|
||||
<!-- WelcomeScreen -->
|
||||
<string name="welcome_screen_action_dismiss">Dismiss</string>
|
||||
<string name="welcome_screen_action_continue_with_email">Continue with Email</string>
|
||||
<string name="welcome_screen_action_self_hosting_options">Self-hosting options</string>
|
||||
|
||||
<!-- LabelCreationDialog -->
|
||||
<string name="label_creation_title">Create New Label</string>
|
||||
<string name="label_creation_content">Assign a name and color.</string>
|
||||
<string name="label_creation_action_create">Create</string>
|
||||
<string name="label_creation_action_cancel">Cancel</string>
|
||||
<string name="label_creation_label_placeholder">Label Name</string>
|
||||
|
||||
<!-- LabelSelectionSheet -->
|
||||
<string name="label_selection_sheet_title">Filter by Label</string>
|
||||
<string name="label_selection_sheet_title_alt">Set Labels</string>
|
||||
<string name="label_selection_sheet_action_cancel">Cancel</string>
|
||||
<string name="label_selection_sheet_action_search">Search</string>
|
||||
<string name="label_selection_sheet_action_save">Save</string>
|
||||
<string name="label_selection_sheet_text_create">Create a new label named \"%1$s\"</string>
|
||||
|
||||
<!-- LibraryFilterBar -->
|
||||
<string name="library_filter_bar_label_labels">Labels</string>
|
||||
|
||||
<!-- LibraryNavigationBar -->
|
||||
<string name="library_nav_bar_title">Library</string>
|
||||
<string name="library_nav_bar_title_alt"></string>
|
||||
<string name="library_nav_bar_field_placeholder_search">Search</string>
|
||||
|
||||
<!-- LibraryViewModel -->
|
||||
<string name="library_view_model_snackbar_success">Labels updated</string>
|
||||
<string name="library_view_model_snackbar_error">Unable to set labels</string>
|
||||
|
||||
<!-- NotebookView -->
|
||||
<string name="notebook_view_title">Notebook</string>
|
||||
<string name="notebook_view_action_copy">Copy</string>
|
||||
<string name="notebook_view_snackbar_msg">Notebook copied</string>
|
||||
|
||||
<!-- EditNoteModal -->
|
||||
<string name="edit_note_modal_title">Note</string>
|
||||
<string name="edit_note_modal_action_save">Save</string>
|
||||
<string name="edit_note_modal_action_cancel">Cancel</string>
|
||||
|
||||
<!-- ArticleNotes -->
|
||||
<string name="article_notes_title">Article Notes</string>
|
||||
<string name="article_notes_action_add_notes">Add Notes...</string>
|
||||
|
||||
<!-- HighlightsList -->
|
||||
<string name="highlights_list_title">Highlights</string>
|
||||
<string name="highlights_list_action_copy">Copy</string>
|
||||
<string name="highlights_list_snackbar_msg">Highlight copied</string>
|
||||
<string name="highlights_list_action_add_note">Add Note...</string>
|
||||
<string name="highlights_list_error_msg_no_highlights">You have not added any highlights to this page.</string>
|
||||
|
||||
<!-- ReaderPreferencesView -->
|
||||
<string name="reader_preferences_view_font_size">Font Size:</string>
|
||||
<string name="reader_preferences_view_margin">Margin</string>
|
||||
<string name="reader_preferences_view_line_spacing">Line Spacing</string>
|
||||
<string name="reader_preferences_view_theme">Theme:</string>
|
||||
<string name="reader_preferences_view_auto">Auto</string>
|
||||
<string name="reader_preferences_view_high_constrast_text">High Contrast Text</string>
|
||||
<string name="reader_preferences_view_justify_text">Justify Text</string>
|
||||
|
||||
<!-- WebReaderLoadingContainer -->
|
||||
<string name="web_reader_loading_container_error_msg">We were unable to fetch your content.</string>
|
||||
<string name="web_reader_loading_container_bottom_sheet_reader_preferences">Reader Preferences</string>
|
||||
<string name="web_reader_loading_container_bottom_sheet_notebook">Notebook</string>
|
||||
<string name="web_reader_loading_container_bottom_sheet_open_link">Open Link</string>
|
||||
|
||||
<!-- OpenLinkView -->
|
||||
<string name="open_link_view_action_open_in_browser">Open in Browser</string>
|
||||
<string name="open_link_view_action_save_to_omnivore">Save to Omnivore</string>
|
||||
<string name="open_link_view_action_copy_link">Copy Link</string>
|
||||
<string name="open_link_view_action_cancel">Cancel</string>
|
||||
|
||||
<!-- WebReaderViewModel -->
|
||||
<string name="web_reader_view_model_save_link_success">Link saved</string>
|
||||
<string name="web_reader_view_model_save_link_error">Error saving link</string>
|
||||
<string name="web_reader_view_model_copy_link_success">Link copied</string>
|
||||
|
||||
<!-- SaveContent -->
|
||||
<string name="save_content_msg">Saving</string>
|
||||
<string name="save_content_action_read_now">Read Now</string>
|
||||
<string name="save_content_action_read_later">Read Later</string>
|
||||
<string name="save_content_action_dismiss">Dismiss</string>
|
||||
|
||||
<!-- SaveViewModel -->
|
||||
<string name="save_view_model_msg">Saving to Omnivore...</string>
|
||||
<string name="save_view_model_error_not_logged_in">You are not logged in. Please login before saving.</string>
|
||||
<string name="save_view_model_page_saved_success">Page Saved</string>
|
||||
<string name="save_view_model_page_saved_error">There was an error saving your page</string>
|
||||
|
||||
<!-- SavedItemContextMenu -->
|
||||
<string name="saved_item_context_menu_action_edit_labels">Edit Labels</string>
|
||||
<string name="saved_item_context_menu_action_archive">Archive</string>
|
||||
<string name="saved_item_context_menu_action_unarchive">Unarchive</string>
|
||||
<string name="saved_item_context_menu_action_share_original">Share Original</string>
|
||||
<string name="saved_item_context_menu_action_remove_item">Remove Item</string>
|
||||
|
||||
<!-- LogoutDialog -->
|
||||
<string name="logout_dialog_title">Logout</string>
|
||||
<string name="logout_dialog_confirm_msg">Are you sure you want to logout?</string>
|
||||
<string name="logout_dialog_action_confirm">Confirm</string>
|
||||
<string name="logout_dialog_action_cancel">Cancel</string>
|
||||
|
||||
<!-- ManageAccount -->
|
||||
<string name="manage_account_title">Manage Account</string>
|
||||
<string name="manage_account_action_reset_data_cache">Reset Data Cache</string>
|
||||
|
||||
<!-- PolicyWebView -->
|
||||
<string name="policy_webview_title">Settings</string>
|
||||
|
||||
<!-- SettingsView -->
|
||||
<string name="settings_view_title">Settings</string>
|
||||
<string name="settings_view_setting_row_documentation">Documentation</string>
|
||||
<string name="settings_view_setting_row_feedback">Feedback</string>
|
||||
<string name="settings_view_setting_row_privacy_policy">Privacy Policy</string>
|
||||
<string name="settings_view_setting_row_terms_and_conditions">Terms and Conditions</string>
|
||||
<string name="settings_view_setting_row_manage_account">Manage Account</string>
|
||||
<string name="settings_view_setting_row_logout">Logout</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user