-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Redesigned long press menu #12032
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Stypox
wants to merge
87
commits into
TeamNewPipe:refactor
Choose a base branch
from
Stypox:long-press-menu
base: refactor
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Redesigned long press menu #12032
Changes from all commits
Commits
Show all changes
87 commits
Select commit
Hold shift + click to select a range
e276d70
Add Either type with left, right and match functions
Stypox 64c5aa2
Start implementing LongPressMenu
Stypox 6ad16fc
Calculate button placing in long press menu
Stypox 4fe7b83
Treat decorations better
Stypox a7701c4
Add buttons to long press menu
Stypox 155fa05
Remove button background and make text 2 lines
Stypox d4eb403
Add small Edit button in LongPressMenu
Stypox 8e454dc
Click on long press menu subtitle opens channel details
Stypox 9abbb7b
Initial work on handling many long-press actions
Stypox 719f8a5
Make LongPressable a data class
Stypox 4581f20
Move long press menu drag handle to its own composable
Stypox b727834
Improve how long press menu buttons are laid out
Stypox ee0f98f
Dismiss long press menu after click on a button
Stypox b213a46
Add download long press menu action
Stypox eca3486
Move LongPressable builders to LongPressable class
Stypox 985872f
Replace InfoItemDialog with LongPressMenu
Stypox bfbde93
Remove InfoItemDialog
Stypox 3eb42d6
Slight adjustments to long press menu
Stypox e0b24c7
Add more previews to LongPressMenu
Stypox 1bb298b
Use LongPressMenu in BookmarkFragment
Stypox 612122c
Tune transparencies of decorations in long press menu
Stypox a189337
Use faded marquee text in long press menu header
Stypox 1d16885
Add long press actions to channels and playlists info items
Stypox 4c60498
Add OpenInNew icon next to channel name
Stypox 0347fd9
Fix some lints
Stypox b50db47
Add icons for play/background/popup from here
Stypox 4b90295
Uniform localizing view counts
Stypox 6777871
Implement background/popup/play from here
Stypox 91d5e48
Implement "play from here" for feed fragment
Stypox 89fa03a
Implement "play from here" for channels
Stypox 89dcb6f
Improve icons for background/popup/play from here
Stypox 9f4730e
Implement long pressing on subscriptions
Stypox 701e8c5
Consider duration 0 as duration not known
Stypox 162c9ce
Address Isira review comment
Stypox 23c2de7
Extract FixedHeightCenteredText from LongPressMenu
Stypox 9e1c340
Implement LongPressMenuEditor UI (still not persisted)
Stypox a3af6e2
Add Back content description to toolbar back buttons
Stypox 0cc6334
Access editor from long press menu + fix scrolling
Stypox 6396c97
Rewrite LongPressMenuEditor logic
Stypox e350b10
Make LongPressMenuEditor work with DPAD / Android TV
Stypox f0c3248
Fix an edge case on the DragMarker position logic
Stypox 444aba2
Handle scrolling on Android TV
Stypox 3d6c37a
Autoscroll when dragging close to border
Stypox 032a853
Fix long press menu on DPAD clicks onEditActions right after opened
Stypox f2a1a63
DetectDragModifier now detects long-presses
Stypox 35401e7
Distinguish between isDraggable and isCaption
Stypox 44dc35a
Make channel link less attractive
Stypox b948548
Tune long press menu UI
Stypox cf4bfa5
Make it clearer when items are being dragged under the finger
Stypox 4d8cdc4
Fix strange animations when quickly reording items
Stypox 1a42f30
Improve some strings and add some comments
Stypox 3d62b92
Separate @Composables from state logic for actions editor
Stypox 85cb372
Persist long press actions to settings
Stypox c62004d
Load settings in LongPressMenu too
Stypox 8f19f95
Show loading when action takes some time
Stypox 70c502d
Fix formatting with new ktlint rules
Stypox ec75dda
Only show Enqueue and EnqueueNext if player open
Stypox 5e0b307
Allow playing local playlists directly
Stypox 378fdef
Fix opening channel fragment from anywhere
Stypox 96a5780
Add reset button to long press menu editor
Stypox b3b6cf3
Add bg/popup/play shuffled actions
Stypox f495cc0
Fix player shuffle state not starting out synchronized with queue
Stypox 59841e9
Correctly handle Kodi action in long press menu
Stypox 5094caf
Fix LongPressMenu crashing if dismissed while loading
Stypox 3ee031e
Add accessibility label to show channel details button
Stypox 35e673a
Add tests for LongPressMenuSettings
Stypox 48010d0
Extract some common test methods to InstrumentedTestUtil
Stypox a92c8b2
Setup espresso for testing
Stypox 2a28e7a
Make LongPressMenu scrollable if it does not fit on screen
Stypox dc7ed1c
Add 38 UI tests for LongPressMenu
Stypox 512b536
Resizing display in tests is only supported on API>=24
Stypox 0332568
Add -grpc to emulator options for CI
Stypox 3b19d63
Remove unused field uploaderUrl from LongPressable
Stypox f65094b
Use getPlayQueueStartingAt in BaseListFragment
Stypox d561444
Implement getPlayQueueStartingAt for Compose ItemList too
Stypox 5b10a93
Embed actions impls inside LongPressAction when possible
Stypox 920d630
Add some documentation to tests
Stypox 0830095
Add Subscribe button to LongPressMenu
Stypox 9c558d9
Build LongPressAction lists using builder pattern
Stypox d075539
Add Context.findFragmentManager() extension function
Stypox 3aa5edc
Add more documentation
Stypox 3fc4bc9
Add tooltips for long press menu icons
Stypox 9460813
Add documentation to LongPressMenu and simplify code
Stypox ae214a0
Add 22 tests for LongPressMenuEditor
Stypox 34d4eae
Finish adding documentation to all files
Stypox 90d6c7c
Improve style of item being dragged in LongPressMenuEditor
Stypox a09cf90
Remove previous versions of custom PlayShuffled/FromHere icons
Stypox File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
app/src/androidTest/java/org/schabi/newpipe/InstrumentedTestUtil.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,143 @@ | ||
| package org.schabi.newpipe | ||
|
|
||
| import android.app.Instrumentation | ||
| import android.content.Context | ||
| import android.os.SystemClock | ||
| import android.view.MotionEvent | ||
| import androidx.annotation.StringRes | ||
| import androidx.compose.ui.test.SemanticsNodeInteraction | ||
| import androidx.compose.ui.test.SemanticsNodeInteractionsProvider | ||
| import androidx.compose.ui.test.TouchInjectionScope | ||
| import androidx.compose.ui.test.assert | ||
| import androidx.compose.ui.test.hasScrollAction | ||
| import androidx.compose.ui.test.onNodeWithContentDescription | ||
| import androidx.compose.ui.test.onNodeWithText | ||
| import androidx.compose.ui.test.performTouchInput | ||
| import androidx.compose.ui.test.swipeUp | ||
| import androidx.preference.PreferenceManager | ||
| import androidx.test.platform.app.InstrumentationRegistry | ||
| import org.junit.Assert.assertEquals | ||
| import org.junit.Assert.assertNotEquals | ||
| import org.junit.Assert.fail | ||
|
|
||
| /** | ||
| * Use this instead of calling `InstrumentationRegistry.getInstrumentation()` every time. | ||
| */ | ||
| val inst: Instrumentation | ||
| get() = InstrumentationRegistry.getInstrumentation() | ||
|
|
||
| /** | ||
| * Use this instead of passing contexts around in instrumented tests. | ||
| */ | ||
| val ctx: Context | ||
| get() = InstrumentationRegistry.getInstrumentation().targetContext | ||
|
|
||
| fun putBooleanInPrefs(@StringRes key: Int, value: Boolean) { | ||
| PreferenceManager.getDefaultSharedPreferences(ctx) | ||
| .edit().putBoolean(ctx.getString(key), value).apply() | ||
| } | ||
|
|
||
| fun putStringInPrefs(@StringRes key: Int, value: String) { | ||
| PreferenceManager.getDefaultSharedPreferences(ctx) | ||
| .edit().putString(ctx.getString(key), value).apply() | ||
| } | ||
|
|
||
| fun clearPrefs() { | ||
| PreferenceManager.getDefaultSharedPreferences(ctx) | ||
| .edit().clear().apply() | ||
| } | ||
|
|
||
| /** | ||
| * E.g. useful to tap outside dialogs to see whether they close. | ||
| */ | ||
| fun tapAtAbsoluteXY(x: Float, y: Float) { | ||
| val t = SystemClock.uptimeMillis() | ||
| inst.sendPointerSync(MotionEvent.obtain(t, t, MotionEvent.ACTION_DOWN, x, y, 0)) | ||
| inst.sendPointerSync(MotionEvent.obtain(t, t + 50, MotionEvent.ACTION_UP, x, y, 0)) | ||
| } | ||
|
|
||
| /** | ||
| * Same as the original `onNodeWithText` except that this takes a [StringRes] instead of a [String]. | ||
| */ | ||
| fun SemanticsNodeInteractionsProvider.onNodeWithText( | ||
| @StringRes text: Int, | ||
| substring: Boolean = false, | ||
| ignoreCase: Boolean = false, | ||
| useUnmergedTree: Boolean = false | ||
| ): SemanticsNodeInteraction { | ||
| return this.onNodeWithText(ctx.getString(text), substring, ignoreCase, useUnmergedTree) | ||
| } | ||
|
|
||
| /** | ||
| * Same as the original `onNodeWithContentDescription` except that this takes a [StringRes] instead of a [String]. | ||
| */ | ||
| fun SemanticsNodeInteractionsProvider.onNodeWithContentDescription( | ||
| @StringRes text: Int, | ||
| substring: Boolean = false, | ||
| ignoreCase: Boolean = false, | ||
| useUnmergedTree: Boolean = false | ||
| ): SemanticsNodeInteraction { | ||
| return this.onNodeWithContentDescription(ctx.getString(text), substring, ignoreCase, useUnmergedTree) | ||
| } | ||
|
|
||
| /** | ||
| * Shorthand for `.fetchSemanticsNode().positionOnScreen`. | ||
| */ | ||
| fun SemanticsNodeInteraction.fetchPosOnScreen() = fetchSemanticsNode().positionOnScreen | ||
|
|
||
| /** | ||
| * Asserts that [value] is in the range [[l], [r]] (both extremes included). | ||
| */ | ||
| fun <T : Comparable<T>> assertInRange(l: T, r: T, value: T) { | ||
| if (l > r) { | ||
| fail("Invalid range passed to `assertInRange`: [$l, $r]") | ||
| } | ||
| if (value !in l..r) { | ||
| fail("Expected $value to be in range [$l, $r]") | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Asserts that [value] is NOT in the range [[l], [r]] (both extremes included). | ||
| */ | ||
| fun <T : Comparable<T>> assertNotInRange(l: T, r: T, value: T) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Better variable names please, for all the function parameters as well. |
||
| if (l > r) { | ||
| fail("Invalid range passed to `assertInRange`: [$l, $r]") | ||
| } | ||
| if (value in l..r) { | ||
| fail("Expected $value to NOT be in range [$l, $r]") | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Tries to scroll vertically in the container [this] and uses [itemInsideScrollingContainer] to | ||
| * compute how much the container actually scrolled. Useful in tandem with [assertMoved] or | ||
| * [assertDidNotMove]. | ||
| */ | ||
| fun SemanticsNodeInteraction.scrollVerticallyAndGetOriginalAndFinalY( | ||
| itemInsideScrollingContainer: SemanticsNodeInteraction, | ||
| startY: TouchInjectionScope.() -> Float = { bottom }, | ||
| endY: TouchInjectionScope.() -> Float = { top } | ||
| ): Pair<Float, Float> { | ||
| val originalPosition = itemInsideScrollingContainer.fetchPosOnScreen() | ||
| this.performTouchInput { swipeUp(startY = startY(), endY = endY()) } | ||
| val finalPosition = itemInsideScrollingContainer.fetchPosOnScreen() | ||
| assertEquals(originalPosition.x, finalPosition.x) | ||
| return Pair(originalPosition.y, finalPosition.y) | ||
| } | ||
|
|
||
| /** | ||
| * Simple assert on results from [scrollVerticallyAndGetOriginalAndFinalY]. | ||
| */ | ||
| fun Pair<Float, Float>.assertMoved() { | ||
| val (originalY, finalY) = this | ||
| assertNotEquals(originalY, finalY) | ||
| } | ||
|
|
||
| /** | ||
| * Simple assert on results from [scrollVerticallyAndGetOriginalAndFinalY]. | ||
| */ | ||
| fun Pair<Float, Float>.assertDidNotMove() { | ||
| val (originalY, finalY) = this | ||
| assertEquals(originalY, finalY) | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please prefer
contextandinstrumentationinstead