diff --git a/TRANSLATIONS.md b/TRANSLATIONS.md
index 42b127df..c8dce02f 100644
--- a/TRANSLATIONS.md
+++ b/TRANSLATIONS.md
@@ -19,34 +19,34 @@ See [Android Translations Converter](https://github.com/Crustack/android-transla
| Language | Coverage |
|----------|----------|
-| ๐บ๐ธ English | 100% (331/331) |
-| ๐ช๐ธ Catalan | 19% (65/331) |
-| ๐จ๐ฟ Czech | 94% (313/331) |
-| ๐ฉ๐ฐ Danish | 20% (69/331) |
-| ๐ฉ๐ช German | 98% (327/331) |
-| ๐ฌ๐ท Greek | 21% (72/331) |
-| ๐ช๐ธ Spanish | 94% (314/331) |
-| ๐ซ๐ท French | 98% (327/331) |
-| ๐ญ๐บ Hungarian | 19% (65/331) |
-| ๐ฎ๐ฉ Indonesian | 22% (75/331) |
-| ๐ฎ๐น Italian | 87% (291/331) |
-| ๐ฏ๐ต Japanese | 22% (73/331) |
-| ๐ฒ๐ฒ Burmese | 27% (90/331) |
-| ๐ณ๐ด Norwegian Bokmรฅl | 32% (106/331) |
-| ๐ณ๐ฑ Dutch | 64% (212/331) |
-| ๐ณ๐ด Norwegian Nynorsk | 32% (106/331) |
-| ๐ต๐ฑ Polish | 90% (300/331) |
-| ๐ง๐ท Portuguese (Brazil) | 94% (312/331) |
-| ๐ต๐น Portuguese (Portugal) | 21% (71/331) |
-| ๐ท๐ด Romanian | 90% (301/331) |
-| ๐ท๐บ Russian | 92% (305/331) |
-| ๐ธ๐ฐ Slovak | 19% (65/331) |
-| ๐ธ๐ฎ Slovenian | 32% (109/331) |
-| ๐ธ๐ช Swedish | 19% (63/331) |
-| ๐ต๐ญ Tagalog | 19% (65/331) |
-| ๐น๐ท Turkish | 22% (73/331) |
-| ๐บ๐ฆ Ukrainian | 98% (326/331) |
-| ๐ป๐ณ Vietnamese | 32% (107/331) |
-| ๐จ๐ณ Chinese (Simplified) | 97% (323/331) |
-| ๐น๐ผ Chinese (Traditional) | 88% (294/331) |
+| ๐บ๐ธ English | 100% (333/333) |
+| ๐ช๐ธ Catalan | 19% (65/333) |
+| ๐จ๐ฟ Czech | 93% (313/333) |
+| ๐ฉ๐ฐ Danish | 20% (69/333) |
+| ๐ฉ๐ช German | 98% (327/333) |
+| ๐ฌ๐ท Greek | 21% (72/333) |
+| ๐ช๐ธ Spanish | 94% (314/333) |
+| ๐ซ๐ท French | 98% (327/333) |
+| ๐ญ๐บ Hungarian | 19% (65/333) |
+| ๐ฎ๐ฉ Indonesian | 22% (75/333) |
+| ๐ฎ๐น Italian | 87% (291/333) |
+| ๐ฏ๐ต Japanese | 21% (73/333) |
+| ๐ฒ๐ฒ Burmese | 27% (90/333) |
+| ๐ณ๐ด Norwegian Bokmรฅl | 31% (106/333) |
+| ๐ณ๐ฑ Dutch | 63% (212/333) |
+| ๐ณ๐ด Norwegian Nynorsk | 31% (106/333) |
+| ๐ต๐ฑ Polish | 90% (300/333) |
+| ๐ง๐ท Portuguese (Brazil) | 93% (312/333) |
+| ๐ต๐น Portuguese (Portugal) | 21% (71/333) |
+| ๐ท๐ด Romanian | 90% (301/333) |
+| ๐ท๐บ Russian | 91% (305/333) |
+| ๐ธ๐ฐ Slovak | 19% (65/333) |
+| ๐ธ๐ฎ Slovenian | 32% (109/333) |
+| ๐ธ๐ช Swedish | 18% (63/333) |
+| ๐ต๐ญ Tagalog | 19% (65/333) |
+| ๐น๐ท Turkish | 21% (73/333) |
+| ๐บ๐ฆ Ukrainian | 97% (326/333) |
+| ๐ป๐ณ Vietnamese | 32% (107/333) |
+| ๐จ๐ณ Chinese (Simplified) | 96% (323/333) |
+| ๐น๐ผ Chinese (Traditional) | 88% (294/333) |
\ No newline at end of file
diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt
index b02a233c..bc670fd0 100644
--- a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt
+++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt
@@ -98,6 +98,7 @@ import com.philkes.notallyx.utils.findWebUrls
import com.philkes.notallyx.utils.getFileName
import com.philkes.notallyx.utils.getMimeType
import com.philkes.notallyx.utils.getUriForFile
+import com.philkes.notallyx.utils.isInLandscapeMode
import com.philkes.notallyx.utils.log
import com.philkes.notallyx.utils.mergeSkipFirst
import com.philkes.notallyx.utils.observeSkipFirst
@@ -132,6 +133,8 @@ abstract class EditActivity(private val type: Type) :
internal lateinit var changeHistory: ChangeHistory
protected var undo: View? = null
protected var redo: View? = null
+ protected var jumpToTop: View? = null
+ protected var jumpToBottom: View? = null
protected var colorInt: Int = -1
protected var inputMethodManager: InputMethodManager? = null
@@ -546,6 +549,22 @@ abstract class EditActivity(private val type: Type) :
protected fun isInSearchMode(): Boolean = binding.EnterSearchKeyword.visibility == VISIBLE
+ protected fun updateJumpButtonsVisibility(manualSize: Int? = null) {
+ jumpToTop?.post {
+ val show =
+ when (notallyModel.type) {
+ Type.NOTE ->
+ (manualSize ?: binding.EnterBody.lineCount) >
+ (if (isInLandscapeMode) 30 else 75)
+ Type.LIST ->
+ (manualSize ?: notallyModel.items.size) >
+ (if (isInLandscapeMode) 15 else 25)
+ }
+ jumpToTop?.isVisible = show
+ jumpToBottom?.isVisible = show
+ }
+ }
+
protected fun endSearch() {
binding.EnterSearchKeyword.apply {
visibility = GONE
@@ -570,6 +589,14 @@ abstract class EditActivity(private val type: Type) :
}
binding.BottomAppBarCenter.apply {
removeAllViews()
+ jumpToTop =
+ addIconButton(
+ R.string.jump_to_top,
+ R.drawable.vertical_align_top,
+ marginStart = 0,
+ ) {
+ binding.ScrollView.apply { post { fullScroll(View.FOCUS_UP) } }
+ }
undo =
addIconButton(
R.string.undo,
@@ -613,6 +640,26 @@ abstract class EditActivity(private val type: Type) :
}
}
.apply { isEnabled = changeHistory.canRedo.value }
+ jumpToBottom =
+ addIconButton(
+ R.string.jump_to_bottom,
+ R.drawable.vertical_align_bottom,
+ marginStart = 2,
+ ) {
+ binding.ScrollView.apply {
+ post {
+ val lastChild: View? = binding.ScrollView.getChildAt(0)
+ if (lastChild != null) {
+ val bottom: Int =
+ lastChild.bottom + binding.ScrollView.paddingBottom
+ binding.ScrollView.smoothScrollTo(0, bottom)
+ } else {
+ fullScroll(View.FOCUS_DOWN)
+ }
+ }
+ }
+ }
+ updateJumpButtonsVisibility()
}
binding.BottomAppBarRight.apply {
removeAllViews()
diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt
index 00f9836b..585d0576 100644
--- a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt
+++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt
@@ -241,11 +241,13 @@ class EditListActivity : EditActivity(Type.LIST), MoreListActions {
endSearch()
}
},
- ) { _ ->
- if (isInSearchMode() && search.results.value > 0) {
- updateSearchResults(search.query)
- }
- }
+ { _ ->
+ if (isInSearchMode() && search.results.value > 0) {
+ updateSearchResults(search.query)
+ }
+ },
+ { items -> updateJumpButtonsVisibility(items) },
+ )
adapter =
ListItemAdapter(
colorInt,
diff --git a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt
index c0eba2b0..a6487357 100644
--- a/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt
+++ b/app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt
@@ -162,6 +162,7 @@ class EditNoteActivity : EditActivity(Type.NOTE), AddNoteActions {
notallyModel.body = text
if (textChanged) {
updateSearchResults(search.query)
+ updateJumpButtonsVisibility()
}
}
}
diff --git a/app/src/main/java/com/philkes/notallyx/presentation/view/note/listitem/ListManager.kt b/app/src/main/java/com/philkes/notallyx/presentation/view/note/listitem/ListManager.kt
index cbcbcad4..4b217ec8 100644
--- a/app/src/main/java/com/philkes/notallyx/presentation/view/note/listitem/ListManager.kt
+++ b/app/src/main/java/com/philkes/notallyx/presentation/view/note/listitem/ListManager.kt
@@ -3,7 +3,6 @@ package com.philkes.notallyx.presentation.view.note.listitem
import android.util.Log
import android.view.View
import android.view.inputmethod.InputMethodManager
-import android.widget.EditText
import androidx.recyclerview.widget.RecyclerView
import com.philkes.notallyx.data.model.ListItem
import com.philkes.notallyx.data.model.check
@@ -48,6 +47,7 @@ class ListManager(
private val inputMethodManager: InputMethodManager?,
private val endSearch: (() -> Unit)?,
val refreshSearch: ((refocusView: View?) -> Unit)?,
+ val onItemSizeChanged: ((items: Int) -> Unit)?,
) {
lateinit var adapter: ListItemAdapter
var checkedAdapter: CheckedListItemAdapter? = null
@@ -151,6 +151,7 @@ class ListManager(
inputMethodManager?.let { viewHolder.focusEditText(inputMethodManager = it) }
}
}
+ onItemSizeChanged?.invoke(items.size + (itemsChecked?.size() ?: 0))
}
/**
@@ -201,6 +202,7 @@ class ListManager(
if (pushChange && result) {
changeHistory.push(ListDeleteChange(stateBefore, getState(), this))
}
+ onItemSizeChanged?.invoke(items.size + (itemsChecked?.size() ?: 0))
return result
}
@@ -372,6 +374,7 @@ class ListManager(
if (pushChange) {
changeHistory.push(DeleteCheckedChange(stateBefore, getState(), this))
}
+ onItemSizeChanged?.invoke(items.size + (itemsChecked?.size() ?: 0))
}
fun findParent(item: ListItem) = items.findParent(item) ?: itemsChecked?.findParent(item)
diff --git a/app/src/main/java/com/philkes/notallyx/utils/AndroidExtensions.kt b/app/src/main/java/com/philkes/notallyx/utils/AndroidExtensions.kt
index 39e16f80..5f5be32e 100644
--- a/app/src/main/java/com/philkes/notallyx/utils/AndroidExtensions.kt
+++ b/app/src/main/java/com/philkes/notallyx/utils/AndroidExtensions.kt
@@ -246,6 +246,9 @@ fun Activity.showErrorDialog(
.show()
}
+val Activity.isInLandscapeMode
+ get() = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
+
private const val MAX_LOGS_FILE_SIZE_KB: Long = 2048
private fun Context.logToFile(
diff --git a/app/src/main/res/drawable/vertical_align_bottom.xml b/app/src/main/res/drawable/vertical_align_bottom.xml
new file mode 100644
index 00000000..2b404619
--- /dev/null
+++ b/app/src/main/res/drawable/vertical_align_bottom.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/drawable/vertical_align_top.xml b/app/src/main/res/drawable/vertical_align_top.xml
new file mode 100644
index 00000000..5cd27f8a
--- /dev/null
+++ b/app/src/main/res/drawable/vertical_align_top.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 61781f33..ad627fc4 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -216,6 +216,8 @@
Item
JSON Files
In order to import your Notes from JSON files (single file or folder), click Import. Every valid JSON file is imported as a separate note, the fileโs name becomes the noteโs title.
+ Jump to bottom
+ Jump to top
Label exists
Hide/Show the label in the navigation panel
Labels
diff --git a/app/src/test/kotlin/com/philkes/notallyx/recyclerview/listmanager/ListManagerTestBase.kt b/app/src/test/kotlin/com/philkes/notallyx/recyclerview/listmanager/ListManagerTestBase.kt
index 9e56209e..4f5edda2 100644
--- a/app/src/test/kotlin/com/philkes/notallyx/recyclerview/listmanager/ListManagerTestBase.kt
+++ b/app/src/test/kotlin/com/philkes/notallyx/recyclerview/listmanager/ListManagerTestBase.kt
@@ -59,7 +59,7 @@ open class ListManagerTestBase {
listItemVH = mock(ListItemVH::class.java)
preferences = mock(NotallyXPreferences::class.java)
listManager =
- ListManager(recyclerView, changeHistory, preferences, inputMethodManager, {}) {}
+ ListManager(recyclerView, changeHistory, preferences, inputMethodManager, {}, {}, null)
// Prepare view holder
`when`(recyclerView.findViewHolderForAdapterPosition(anyInt())).thenReturn(listItemVH)
}
diff --git a/app/translations.xlsx b/app/translations.xlsx
index 294205ab..88cdb42b 100644
Binary files a/app/translations.xlsx and b/app/translations.xlsx differ