Skip to content

Commit cfc9eb2

Browse files
committed
Add scroll to top/bottom in note view for long notes
1 parent 8a4b959 commit cfc9eb2

File tree

10 files changed

+86
-7
lines changed

10 files changed

+86
-7
lines changed

app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditActivity.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ import com.philkes.notallyx.utils.findWebUrls
9898
import com.philkes.notallyx.utils.getFileName
9999
import com.philkes.notallyx.utils.getMimeType
100100
import com.philkes.notallyx.utils.getUriForFile
101+
import com.philkes.notallyx.utils.isInLandscapeMode
101102
import com.philkes.notallyx.utils.log
102103
import com.philkes.notallyx.utils.mergeSkipFirst
103104
import com.philkes.notallyx.utils.observeSkipFirst
@@ -132,6 +133,8 @@ abstract class EditActivity(private val type: Type) :
132133
internal lateinit var changeHistory: ChangeHistory
133134
protected var undo: View? = null
134135
protected var redo: View? = null
136+
protected var jumpToTop: View? = null
137+
protected var jumpToBottom: View? = null
135138

136139
protected var colorInt: Int = -1
137140
protected var inputMethodManager: InputMethodManager? = null
@@ -546,6 +549,23 @@ abstract class EditActivity(private val type: Type) :
546549

547550
protected fun isInSearchMode(): Boolean = binding.EnterSearchKeyword.visibility == VISIBLE
548551

552+
protected fun updateJumpButtonsVisibility(manualSize: Int? = null) {
553+
jumpToTop?.post {
554+
Log.d("JUMP", "Lines: ${binding.EnterBody.lineCount}")
555+
val show =
556+
when (notallyModel.type) {
557+
Type.NOTE ->
558+
(manualSize ?: binding.EnterBody.lineCount) >
559+
(if (isInLandscapeMode) 30 else 75)
560+
Type.LIST ->
561+
(manualSize ?: notallyModel.items.size) >
562+
(if (isInLandscapeMode) 15 else 25)
563+
}
564+
jumpToTop?.isVisible = show
565+
jumpToBottom?.isVisible = show
566+
}
567+
}
568+
549569
protected fun endSearch() {
550570
binding.EnterSearchKeyword.apply {
551571
visibility = GONE
@@ -570,6 +590,14 @@ abstract class EditActivity(private val type: Type) :
570590
}
571591
binding.BottomAppBarCenter.apply {
572592
removeAllViews()
593+
jumpToTop =
594+
addIconButton(
595+
R.string.jump_to_top,
596+
R.drawable.vertical_align_top,
597+
marginStart = 0,
598+
) {
599+
binding.ScrollView.apply { post { fullScroll(View.FOCUS_UP) } }
600+
}
573601
undo =
574602
addIconButton(
575603
R.string.undo,
@@ -613,6 +641,26 @@ abstract class EditActivity(private val type: Type) :
613641
}
614642
}
615643
.apply { isEnabled = changeHistory.canRedo.value }
644+
jumpToBottom =
645+
addIconButton(
646+
R.string.jump_to_bottom,
647+
R.drawable.vertical_align_bottom,
648+
marginStart = 2,
649+
) {
650+
binding.ScrollView.apply {
651+
post {
652+
val lastChild: View? = binding.ScrollView.getChildAt(0)
653+
if (lastChild != null) {
654+
val bottom: Int =
655+
lastChild.bottom + binding.ScrollView.paddingBottom
656+
binding.ScrollView.smoothScrollTo(0, bottom)
657+
} else {
658+
fullScroll(View.FOCUS_DOWN)
659+
}
660+
}
661+
}
662+
}
663+
updateJumpButtonsVisibility()
616664
}
617665
binding.BottomAppBarRight.apply {
618666
removeAllViews()

app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditListActivity.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,13 @@ class EditListActivity : EditActivity(Type.LIST), MoreListActions {
241241
endSearch()
242242
}
243243
},
244-
) { _ ->
245-
if (isInSearchMode() && search.results.value > 0) {
246-
updateSearchResults(search.query)
247-
}
248-
}
244+
{ _ ->
245+
if (isInSearchMode() && search.results.value > 0) {
246+
updateSearchResults(search.query)
247+
}
248+
},
249+
{ items -> updateJumpButtonsVisibility(items) },
250+
)
249251
adapter =
250252
ListItemAdapter(
251253
colorInt,

app/src/main/java/com/philkes/notallyx/presentation/activity/note/EditNoteActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ class EditNoteActivity : EditActivity(Type.NOTE), AddNoteActions {
162162
notallyModel.body = text
163163
if (textChanged) {
164164
updateSearchResults(search.query)
165+
updateJumpButtonsVisibility()
165166
}
166167
}
167168
}

app/src/main/java/com/philkes/notallyx/presentation/view/note/listitem/ListManager.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package com.philkes.notallyx.presentation.view.note.listitem
33
import android.util.Log
44
import android.view.View
55
import android.view.inputmethod.InputMethodManager
6-
import android.widget.EditText
76
import androidx.recyclerview.widget.RecyclerView
87
import com.philkes.notallyx.data.model.ListItem
98
import com.philkes.notallyx.data.model.check
@@ -48,6 +47,7 @@ class ListManager(
4847
private val inputMethodManager: InputMethodManager?,
4948
private val endSearch: (() -> Unit)?,
5049
val refreshSearch: ((refocusView: View?) -> Unit)?,
50+
val onItemSizeChanged: ((items: Int) -> Unit)?,
5151
) {
5252
lateinit var adapter: ListItemAdapter
5353
var checkedAdapter: CheckedListItemAdapter? = null
@@ -151,6 +151,7 @@ class ListManager(
151151
inputMethodManager?.let { viewHolder.focusEditText(inputMethodManager = it) }
152152
}
153153
}
154+
onItemSizeChanged?.invoke(items.size)
154155
}
155156

156157
/**
@@ -201,6 +202,7 @@ class ListManager(
201202
if (pushChange && result) {
202203
changeHistory.push(ListDeleteChange(stateBefore, getState(), this))
203204
}
205+
onItemSizeChanged?.invoke(items.size)
204206
return result
205207
}
206208

@@ -372,6 +374,7 @@ class ListManager(
372374
if (pushChange) {
373375
changeHistory.push(DeleteCheckedChange(stateBefore, getState(), this))
374376
}
377+
onItemSizeChanged?.invoke(items.size)
375378
}
376379

377380
fun findParent(item: ListItem) = items.findParent(item) ?: itemsChecked?.findParent(item)

app/src/main/java/com/philkes/notallyx/utils/AndroidExtensions.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,9 @@ fun Activity.showErrorDialog(
246246
.show()
247247
}
248248

249+
val Activity.isInLandscapeMode
250+
get() = resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE
251+
249252
private const val MAX_LOGS_FILE_SIZE_KB: Long = 2048
250253

251254
private fun Context.logToFile(
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="960"
5+
android:viewportHeight="960"
6+
android:tint="?attr/colorControlNormal">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M160,840L160,760L800,760L800,840L160,840ZM480,680L280,480L336,424L440,528L440,120L520,120L520,528L624,424L680,480L480,680Z"/>
10+
</vector>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android"
2+
android:width="24dp"
3+
android:height="24dp"
4+
android:viewportWidth="960"
5+
android:viewportHeight="960"
6+
android:tint="?attr/colorControlNormal">
7+
<path
8+
android:fillColor="@android:color/white"
9+
android:pathData="M160,200L160,120L800,120L800,200L160,200ZM440,840L440,432L336,536L280,480L480,280L680,480L624,536L520,432L520,840L440,840Z"/>
10+
</vector>

app/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@
216216
<string name="item">Item</string>
217217
<string name="json_files">JSON Files</string>
218218
<string name="json_files_help">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.</string>
219+
<string name="jump_to_bottom">Jump to bottom</string>
220+
<string name="jump_to_top">Jump to top</string>
219221
<string name="label_exists">Label exists</string>
220222
<string name="label_visibility">Hide/Show the label in the navigation panel</string>
221223
<string name="labels">Labels</string>

app/src/test/kotlin/com/philkes/notallyx/recyclerview/listmanager/ListManagerTestBase.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ open class ListManagerTestBase {
5959
listItemVH = mock(ListItemVH::class.java)
6060
preferences = mock(NotallyXPreferences::class.java)
6161
listManager =
62-
ListManager(recyclerView, changeHistory, preferences, inputMethodManager, {}) {}
62+
ListManager(recyclerView, changeHistory, preferences, inputMethodManager, {}, {}, null)
6363
// Prepare view holder
6464
`when`(recyclerView.findViewHolderForAdapterPosition(anyInt())).thenReturn(listItemVH)
6565
}

app/translations.xlsx

188 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)