This repository has been archived by the owner on Oct 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 250
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix:
swipe-controls
with active engagement panel (#82)
- Loading branch information
Showing
9 changed files
with
302 additions
and
100 deletions.
There are no files selected for viewing
29 changes: 29 additions & 0 deletions
29
app/src/main/java/app/revanced/integrations/patches/PlayerOverlaysHookPatch.java
This file contains 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,29 @@ | ||
package app.revanced.integrations.patches; | ||
|
||
import android.view.ViewGroup; | ||
|
||
import androidx.annotation.Nullable; | ||
|
||
import app.revanced.integrations.shared.PlayerOverlays; | ||
|
||
/** | ||
* Hook receiver class for 'player-overlays-hook' patch | ||
* | ||
* @usedBy app.revanced.patches.youtube.misc.playeroverlay.patch.PlayerOverlaysHookPatch | ||
* @smali Lapp/revanced/integrations/patches/PlayerOverlaysHookPatch; | ||
*/ | ||
@SuppressWarnings("unused") | ||
public class PlayerOverlaysHookPatch { | ||
/** | ||
* Hook into YouTubePlayerOverlaysLayout.onFinishInflate() method | ||
* | ||
* @param thisRef reference to the view | ||
* @smali YouTubePlayerOverlaysLayout_onFinishInflateHook(Ljava / lang / Object ;)V | ||
*/ | ||
public static void YouTubePlayerOverlaysLayout_onFinishInflateHook(@Nullable Object thisRef) { | ||
if (thisRef == null) return; | ||
if (thisRef instanceof ViewGroup) { | ||
PlayerOverlays.attach((ViewGroup) thisRef); | ||
} | ||
} | ||
} |
This file contains 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
97 changes: 97 additions & 0 deletions
97
app/src/main/java/app/revanced/integrations/shared/PlayerOverlays.kt
This file contains 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,97 @@ | ||
package app.revanced.integrations.shared | ||
|
||
import android.view.View | ||
import android.view.ViewGroup | ||
import app.revanced.integrations.swipecontrols.misc.Rectangle | ||
import app.revanced.integrations.utils.Event | ||
|
||
/** | ||
* hooking class for player overlays | ||
*/ | ||
@Suppress("MemberVisibilityCanBePrivate") | ||
object PlayerOverlays { | ||
|
||
/** | ||
* called when the overlays finished inflating | ||
*/ | ||
val onInflate = Event<ViewGroup>() | ||
|
||
/** | ||
* called when new children are added or removed from the overlay | ||
*/ | ||
val onChildrenChange = Event<ChildrenChangeEventArgs>() | ||
|
||
/** | ||
* called when the overlay layout changes | ||
*/ | ||
val onLayoutChange = Event<LayoutChangeEventArgs>() | ||
|
||
/** | ||
* start listening for events on the provided view group | ||
* | ||
* @param overlaysLayout the overlays view group | ||
*/ | ||
@JvmStatic | ||
fun attach(overlaysLayout: ViewGroup) { | ||
onInflate.invoke(overlaysLayout) | ||
overlaysLayout.setOnHierarchyChangeListener(object : | ||
ViewGroup.OnHierarchyChangeListener { | ||
override fun onChildViewAdded(parent: View?, child: View?) { | ||
if (parent is ViewGroup && child is View) { | ||
onChildrenChange( | ||
ChildrenChangeEventArgs( | ||
parent, | ||
child, | ||
false | ||
) | ||
) | ||
} | ||
} | ||
|
||
override fun onChildViewRemoved(parent: View?, child: View?) { | ||
if (parent is ViewGroup && child is View) { | ||
onChildrenChange( | ||
ChildrenChangeEventArgs( | ||
parent, | ||
child, | ||
true | ||
) | ||
) | ||
} | ||
} | ||
}) | ||
overlaysLayout.addOnLayoutChangeListener { view, newLeft, newTop, newRight, newBottom, oldLeft, oldTop, oldRight, oldBottom -> | ||
if (view is ViewGroup) { | ||
onLayoutChange( | ||
LayoutChangeEventArgs( | ||
view, | ||
Rectangle( | ||
oldLeft, | ||
oldTop, | ||
oldRight - oldLeft, | ||
oldBottom - oldTop | ||
), | ||
Rectangle( | ||
newLeft, | ||
newTop, | ||
newRight - newLeft, | ||
newBottom - newTop | ||
) | ||
) | ||
) | ||
} | ||
} | ||
} | ||
} | ||
|
||
data class ChildrenChangeEventArgs( | ||
val overlaysLayout: ViewGroup, | ||
val childView: View, | ||
val wasChildRemoved: Boolean | ||
) | ||
|
||
data class LayoutChangeEventArgs( | ||
val overlaysLayout: ViewGroup, | ||
val oldRect: Rectangle, | ||
val newRect: Rectangle | ||
) |
4 changes: 3 additions & 1 deletion
4
...revanced/integrations/utils/PlayerType.kt → ...evanced/integrations/shared/PlayerType.kt
This file contains 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 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
140 changes: 140 additions & 0 deletions
140
app/src/main/java/app/revanced/integrations/swipecontrols/controller/SwipeZonesController.kt
This file contains 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,140 @@ | ||
package app.revanced.integrations.swipecontrols.controller | ||
|
||
import android.content.Context | ||
import android.util.TypedValue | ||
import android.view.View | ||
import app.revanced.integrations.shared.LayoutChangeEventArgs | ||
import app.revanced.integrations.shared.PlayerOverlays | ||
import app.revanced.integrations.swipecontrols.misc.Rectangle | ||
import app.revanced.integrations.swipecontrols.misc.applyDimension | ||
import app.revanced.integrations.utils.ReVancedUtils | ||
|
||
/** | ||
* Y- Axis: | ||
* -------- 0 | ||
* ^ | ||
* dead | 40dp | ||
* v | ||
* -------- yDeadTop | ||
* ^ | ||
* swipe | | ||
* v | ||
* -------- yDeadBtm | ||
* ^ | ||
* dead | 80dp | ||
* v | ||
* -------- screenHeight | ||
* | ||
* X- Axis: | ||
* 0 xBrigStart xBrigEnd xVolStart xVolEnd screenWidth | ||
* | | | | | | | ||
* | 20dp | 3/8 | 2/8 | 3/8 | 20dp | | ||
* | <------> | <------> | <------> | <------> | <------> | | ||
* | dead | brightness | dead | volume | dead | | ||
* | <--------------------------------> | | ||
* 1/1 | ||
*/ | ||
@Suppress("PrivatePropertyName") | ||
class SwipeZonesController( | ||
context: Context, | ||
private val fallbackScreenRect: () -> Rectangle | ||
) { | ||
/** | ||
* 20dp, in pixels | ||
*/ | ||
private val _20dp = 20.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) | ||
|
||
/** | ||
* 40dp, in pixels | ||
*/ | ||
private val _40dp = 40.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) | ||
|
||
/** | ||
* 80dp, in pixels | ||
*/ | ||
private val _80dp = 80.applyDimension(context, TypedValue.COMPLEX_UNIT_DIP) | ||
|
||
/** | ||
* id for R.id.engagement_panel | ||
*/ | ||
private val engagementPanelId = | ||
ReVancedUtils.getResourceIdByName(context, "id", "engagement_panel") | ||
|
||
/** | ||
* current bounding rectangle of the player overlays | ||
*/ | ||
private var playerRect: Rectangle? = null | ||
|
||
/** | ||
* current bounding rectangle of the engagement_panel | ||
*/ | ||
private var engagementPanelRect = Rectangle(0, 0, 0, 0) | ||
|
||
/** | ||
* listener for player overlays layout change | ||
*/ | ||
private fun onOverlaysLayoutChanged(args: LayoutChangeEventArgs) { | ||
// update engagement panel bounds | ||
val engagementPanel = args.overlaysLayout.findViewById<View>(engagementPanelId) | ||
engagementPanelRect = | ||
if (engagementPanel == null || engagementPanel.visibility != View.VISIBLE) { | ||
Rectangle(0, 0, 0, 0) | ||
} else { | ||
Rectangle( | ||
engagementPanel.x.toInt(), | ||
engagementPanel.y.toInt(), | ||
engagementPanel.width, | ||
engagementPanel.height | ||
) | ||
} | ||
|
||
// update player bounds | ||
playerRect = args.newRect | ||
} | ||
|
||
init { | ||
PlayerOverlays.onLayoutChange += this::onOverlaysLayoutChanged | ||
} | ||
|
||
/** | ||
* rectangle of the area that is effectively usable for swipe controls | ||
*/ | ||
private val effectiveSwipeRect: Rectangle | ||
get() { | ||
val p = if (playerRect != null) playerRect!! else fallbackScreenRect() | ||
return Rectangle( | ||
p.x + _20dp, | ||
p.y + _40dp, | ||
p.width - engagementPanelRect.width - _20dp, | ||
p.height - _20dp - _80dp | ||
) | ||
} | ||
|
||
/** | ||
* the rectangle of the volume control zone | ||
*/ | ||
val volume: Rectangle | ||
get() { | ||
val zoneWidth = (effectiveSwipeRect.width * 3) / 8 | ||
return Rectangle( | ||
effectiveSwipeRect.right - zoneWidth, | ||
effectiveSwipeRect.top, | ||
zoneWidth, | ||
effectiveSwipeRect.height | ||
) | ||
} | ||
|
||
/** | ||
* the rectangle of the screen brightness control zone | ||
*/ | ||
val brightness: Rectangle | ||
get() { | ||
val zoneWidth = (effectiveSwipeRect.width * 3) / 8 | ||
return Rectangle( | ||
effectiveSwipeRect.left, | ||
effectiveSwipeRect.top, | ||
zoneWidth, | ||
effectiveSwipeRect.height | ||
) | ||
} | ||
} |
This file contains 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.