diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/Accessibility.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/Accessibility.kt
new file mode 100644
index 00000000..cf5fe6dc
--- /dev/null
+++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/compose/Accessibility.kt
@@ -0,0 +1,16 @@
+package com.ivanovsky.passnotes.presentation.core.compose
+
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.remember
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.semantics.contentDescription
+import androidx.compose.ui.semantics.semantics
+
+@Composable
+fun contentDescription(description: String): Modifier {
+ return remember {
+ Modifier.semantics {
+ contentDescription = description
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/widget/MaterialEditText.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/widget/MaterialEditText.kt
index 83996dcb..dd13f15a 100644
--- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/widget/MaterialEditText.kt
+++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/core/widget/MaterialEditText.kt
@@ -143,6 +143,11 @@ class MaterialEditText(
this.hint = hint
}
+ val description = params.getString(R.styleable.MaterialEditText_description)
+ if (description != null) {
+ binding.textInput.contentDescription = description
+ }
+
val isEyeButtonEnabled = params.getBoolean(
R.styleable.MaterialEditText_isEyeButtonEnabled,
false
@@ -157,10 +162,12 @@ class MaterialEditText(
isEyeButtonEnabled && isClearButtonEnabled -> {
throw IllegalStateException()
}
+
isEyeButtonEnabled -> {
actionButton = ActionButton.EYE
isTextVisible = false
}
+
isClearButtonEnabled -> {
actionButton = ActionButton.CLEAR
}
@@ -272,6 +279,7 @@ class MaterialEditText(
InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_PASSWORD
}
}
+
TextInputType.DIGITS -> {
if (isTextVisible) {
InputType.TYPE_CLASS_NUMBER
@@ -279,12 +287,15 @@ class MaterialEditText(
InputType.TYPE_CLASS_NUMBER + InputType.TYPE_NUMBER_VARIATION_PASSWORD
}
}
+
TextInputType.TEXT_CAP_SENTENCES -> {
InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_FLAG_CAP_SENTENCES
}
+
TextInputType.URL -> {
InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_URI
}
+
TextInputType.EMAIL -> {
InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS
}
@@ -300,11 +311,13 @@ class MaterialEditText(
binding.textInput.maxLines = 1
binding.textInput.isSingleLine = true
}
+
TextInputLines.MULTIPLE_LINES -> {
binding.textInput.isSingleLine = false
binding.textInput.minLines = 1
binding.textInput.maxLines = 25
}
+
else -> {}
}
setTextVisibleInternal(isTextVisible)
@@ -316,9 +329,11 @@ class MaterialEditText(
ImeOptions.ACTION_DONE -> {
binding.textInput.imeOptions = EditorInfo.IME_ACTION_DONE
}
+
ImeOptions.ACTION_NEXT -> {
binding.textInput.imeOptions = EditorInfo.IME_ACTION_NEXT
}
+
else -> {}
}
}
@@ -353,6 +368,7 @@ class MaterialEditText(
}
binding.editTextActionButton.setImageResource(getEyeIcon(isTextVisible))
}
+
ActionButton.CLEAR -> {
binding.editTextActionButton.setImageResource(R.drawable.ic_close_24dp)
}
diff --git a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/serverLogin/ServerLoginScreen.kt b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/serverLogin/ServerLoginScreen.kt
index 9a520575..d740aa24 100644
--- a/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/serverLogin/ServerLoginScreen.kt
+++ b/app/src/main/kotlin/com/ivanovsky/passnotes/presentation/serverLogin/ServerLoginScreen.kt
@@ -14,6 +14,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.tooling.preview.Preview
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.ivanovsky.passnotes.R
@@ -27,6 +28,7 @@ import com.ivanovsky.passnotes.presentation.core.compose.PrimaryTextStyle
import com.ivanovsky.passnotes.presentation.core.compose.ProgressIndicator
import com.ivanovsky.passnotes.presentation.core.compose.ThemedScreenPreview
import com.ivanovsky.passnotes.presentation.core.compose.cells.ui.InfoCell
+import com.ivanovsky.passnotes.presentation.core.compose.contentDescription
import com.ivanovsky.passnotes.presentation.core.compose.model.InputType
import com.ivanovsky.passnotes.presentation.serverLogin.model.LoginType
import com.ivanovsky.passnotes.presentation.serverLogin.model.ServerLoginIntent.OnIgnoreSslValidationStateChanged
@@ -225,6 +227,7 @@ private fun UrlTextField(
end = dimensionResource(R.dimen.element_margin),
top = dimensionResource(R.dimen.element_margin)
)
+ .then(contentDescription(stringResource(R.string.url)))
)
}
@@ -302,6 +305,7 @@ private fun UsernameTextField(
end = dimensionResource(R.dimen.element_margin),
top = dimensionResource(R.dimen.element_margin)
)
+ .then(contentDescription(stringResource(R.string.username)))
)
}
@@ -332,6 +336,7 @@ private fun PasswordTextField(
end = dimensionResource(R.dimen.element_margin),
top = dimensionResource(R.dimen.element_margin)
)
+ .then(contentDescription(stringResource(R.string.password)))
)
}
diff --git a/app/src/main/res/layout/dialog_change_password.xml b/app/src/main/res/layout/dialog_change_password.xml
index 5a5b7b96..19aae001 100644
--- a/app/src/main/res/layout/dialog_change_password.xml
+++ b/app/src/main/res/layout/dialog_change_password.xml
@@ -35,6 +35,7 @@
android:layout_marginStart="@dimen/element_margin"
android:layout_marginTop="@dimen/group_margin"
android:layout_marginEnd="@dimen/element_margin"
+ app:description="@string/password"
app:hint="@string/password"
app:isEyeButtonEnabled="true"
app:layout_constraintBottom_toTopOf="@id/newPassword"
@@ -52,6 +53,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/element_margin"
+ app:description="@string/new_password"
app:hint="@string/new_password"
app:isEyeButtonEnabled="true"
app:layout_constraintBottom_toTopOf="@id/confirmation"
@@ -68,6 +70,7 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/element_margin"
+ app:description="@string/confirm_password"
app:hint="@string/confirm_password"
app:isEyeButtonEnabled="true"
app:layout_constraintBottom_toTopOf="@id/applyButton"
diff --git a/app/src/main/res/layout/group_editor_fragment.xml b/app/src/main/res/layout/group_editor_fragment.xml
index 93c4de9f..2868036f 100644
--- a/app/src/main/res/layout/group_editor_fragment.xml
+++ b/app/src/main/res/layout/group_editor_fragment.xml
@@ -28,7 +28,9 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
app:screenState="@{viewModel.screenState}"
- app:screenStateHandler="@{viewModel.screenStateHandler}" />
+ app:screenStateHandler="@{viewModel.screenStateHandler}"
+ tools:layout_editor_absoluteX="0dp"
+ tools:layout_editor_absoluteY="0dp" />
+ app:tint="?attr/kpIconPrimaryColor" />
diff --git a/app/src/main/res/layout/widget_material_edit_text.xml b/app/src/main/res/layout/widget_material_edit_text.xml
index 37d8a2b4..182d574f 100644
--- a/app/src/main/res/layout/widget_material_edit_text.xml
+++ b/app/src/main/res/layout/widget_material_edit_text.xml
@@ -16,9 +16,9 @@
@@ -30,6 +30,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/small_margin"
+ android:contentDescription="@string/eye_icon"
android:focusable="false"
android:focusableInTouchMode="false"
android:visibility="gone"
diff --git a/app/src/main/res/layout/widget_unlock_view.xml b/app/src/main/res/layout/widget_unlock_view.xml
index 64629b0f..5a37d6b9 100644
--- a/app/src/main/res/layout/widget_unlock_view.xml
+++ b/app/src/main/res/layout/widget_unlock_view.xml
@@ -23,6 +23,7 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/half_margin"
android:layout_marginEnd="@dimen/half_margin"
+ app:description="@string/password"
app:hint="@string/password"
app:isEyeButtonEnabled="true"
app:layout_constraintEnd_toStartOf="@id/unlockButton"
@@ -34,9 +35,9 @@
android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_marginTop="@dimen/small_margin"
+ android:contentDescription="@string/unlock_button"
android:foreground="?attr/selectableItemBackground"
android:minWidth="@dimen/unlock_button_size"
- android:contentDescription="unlockButton"
app:layout_constraintBottom_toBottomOf="@id/password"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@id/password" />
diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml
index 8bb150fa..276b023c 100644
--- a/app/src/main/res/values/attrs.xml
+++ b/app/src/main/res/values/attrs.xml
@@ -8,5 +8,6 @@
+
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 9920b016..2ea773bb 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -44,6 +44,11 @@
Synchronize with source
Details
+
+ URL
+ Unlock button
+ Eye icon
+
Quick Lock
Button to lock opened database