1
mirror of https://github.com/revanced/revanced-integrations synced 2025-11-21 18:35:37 +01:00

Compare commits

...

40 Commits

Author SHA1 Message Date
semantic-release-bot
c3e302d224 chore(release): 0.46.2 [skip ci]
## [0.46.2](https://github.com/revanced/revanced-integrations/compare/v0.46.1...v0.46.2) (2022-10-01)

### Performance Improvements

* **general-ads:** hook pathBuilder ([c7756e1](c7756e1299))
2022-10-01 02:05:18 +00:00
oSumAtrIX
1010eedbb2 refactor(general-ads): remove unused method 2022-10-01 04:02:02 +02:00
oSumAtrIX
c7756e1299 perf(general-ads): hook pathBuilder
This removes the hook for the bytebuffer
2022-10-01 03:59:11 +02:00
semantic-release-bot
3022afc7c4 chore(release): 0.46.1 [skip ci]
## [0.46.1](https://github.com/revanced/revanced-integrations/compare/v0.46.0...v0.46.1) (2022-09-30)

### Bug Fixes

* **general-ads:** remove duplicate blocklist entry ([#165](https://github.com/revanced/revanced-integrations/issues/165)) ([9bcb04d](9bcb04de8e))
2022-09-30 18:03:18 +00:00
OxrxL
9bcb04de8e fix(general-ads): remove duplicate blocklist entry (#165) 2022-09-30 19:59:15 +02:00
semantic-release-bot
322e145f75 chore(release): 0.46.0 [skip ci]
# [0.46.0](https://github.com/revanced/revanced-integrations/compare/v0.45.0...v0.46.0) (2022-09-30)

### Features

* **general-ads:** block additional home ads ([5a24e84](5a24e84868))
2022-09-30 15:17:03 +00:00
oSumAtrIX
5a24e84868 feat(general-ads): block additional home ads 2022-09-30 17:13:15 +02:00
semantic-release-bot
c049dc3e8d chore(release): 0.45.0 [skip ci]
# [0.45.0](https://github.com/revanced/revanced-integrations/compare/v0.44.1...v0.45.0) (2022-09-29)

### Features

* `disable-startup-shorts-player` patch ([#164](https://github.com/revanced/revanced-integrations/issues/164)) ([149a90a](149a90a2e8))
2022-09-29 21:58:26 +00:00
OxrxL
149a90a2e8 feat: disable-startup-shorts-player patch (#164) 2022-09-29 23:54:09 +02:00
semantic-release-bot
2d001cfb1d chore(release): 0.44.1 [skip ci]
## [0.44.1](https://github.com/revanced/revanced-integrations/compare/v0.44.0...v0.44.1) (2022-09-29)

### Bug Fixes

* **hide-email-address:** invalid initial switch toggle state ([#163](https://github.com/revanced/revanced-integrations/issues/163)) ([8bb93a4](8bb93a439b))
2022-09-29 15:23:47 +00:00
OxrxL
8bb93a439b fix(hide-email-address): invalid initial switch toggle state (#163) 2022-09-29 17:19:46 +02:00
semantic-release-bot
0fe4db9f28 chore(release): 0.44.0 [skip ci]
# [0.44.0](https://github.com/revanced/revanced-integrations/compare/v0.43.1...v0.44.0) (2022-09-28)

### Features

* `hide-email-address` patch ([#149](https://github.com/revanced/revanced-integrations/issues/149)) ([4cc8a22](4cc8a22c26))
2022-09-28 14:34:29 +00:00
OxrxL
4cc8a22c26 feat: hide-email-address patch (#149)
Co-authored-by: oSumAtrIX <johan.melkonyan1@web.de>
2022-09-28 13:28:19 +02:00
semantic-release-bot
11fbf1a5b3 chore(release): 0.43.1 [skip ci]
## [0.43.1](https://github.com/revanced/revanced-integrations/compare/v0.43.0...v0.43.1) (2022-09-27)

### Bug Fixes

* move dummy classes to `dummy` module ([#162](https://github.com/revanced/revanced-integrations/issues/162)) ([fa0ad3a](fa0ad3a57b))
2022-09-27 13:33:59 +00:00
d4rkk3y
fa0ad3a57b fix: move dummy classes to dummy module (#162) 2022-09-27 15:30:25 +02:00
inotia00
73b40595c4 refactor: remove reduntant check for shorts_playing (#150) 2022-09-27 06:54:32 +02:00
semantic-release-bot
04bbe259cb chore(release): 0.43.0 [skip ci]
# [0.43.0](https://github.com/revanced/revanced-integrations/compare/v0.42.2...v0.43.0) (2022-09-26)

### Features

* enable minification  ([#158](https://github.com/revanced/revanced-integrations/issues/158)) ([8dde925](8dde925b47))
2022-09-26 14:32:21 +00:00
Canny
8dde925b47 feat: enable minification (#158)
* chore: proguard

* build: enable minify
2022-09-26 16:28:55 +02:00
semantic-release-bot
4ca1182485 chore(release): 0.42.2 [skip ci]
## [0.42.2](https://github.com/revanced/revanced-integrations/compare/v0.42.1...v0.42.2) (2022-09-25)

### Bug Fixes

* **swipe-controls:** crash on SDK below 24 ([#157](https://github.com/revanced/revanced-integrations/issues/157)) ([4c72ac1](4c72ac1cd5))
2022-09-25 15:55:53 +00:00
Chris
4c72ac1cd5 fix(swipe-controls): crash on SDK below 24 (#157) 2022-09-25 17:52:36 +02:00
semantic-release-bot
cdca96224a chore(release): 0.42.1 [skip ci]
## [0.42.1](https://github.com/revanced/revanced-integrations/compare/v0.42.0...v0.42.1) (2022-09-23)

### Bug Fixes

* **build:** remove distributionSha256Sum property ([#153](https://github.com/revanced/revanced-integrations/issues/153)) [skip ci] ([ae8d39a](ae8d39a831))
* **custom-playback-speed:** fill array to generate required instructions ([#155](https://github.com/revanced/revanced-integrations/issues/155)) ([868e99a](868e99a619))
* **hide-time-and-seekbar:** don't draw the seekbar ([#154](https://github.com/revanced/revanced-integrations/issues/154)) ([f1e9aa3](f1e9aa30ba))
2022-09-23 10:58:02 +00:00
bogadana
868e99a619 fix(custom-playback-speed): fill array to generate required instructions (#155) 2022-09-23 12:53:22 +02:00
OxrxL
f1e9aa30ba fix(hide-time-and-seekbar): don't draw the seekbar (#154) 2022-09-23 12:51:30 +02:00
OxrxL
ae8d39a831 fix(build): remove distributionSha256Sum property (#153) [skip ci] 2022-09-23 11:14:34 +02:00
semantic-release-bot
0304ccb168 chore(release): 0.42.0 [skip ci]
# [0.42.0](https://github.com/revanced/revanced-integrations/compare/v0.41.2...v0.42.0) (2022-09-23)

### Features

* **tiktok:** adapt `tiktok-download` with `tiktok-settings`. ([#152](https://github.com/revanced/revanced-integrations/issues/152)) ([5a710aa](5a710aa033))
2022-09-23 05:43:56 +00:00
d4rkk3y
5a710aa033 feat(tiktok): adapt tiktok-download with tiktok-settings. (#152) 2022-09-23 07:39:44 +02:00
semantic-release-bot
fd924ad934 chore(release): 0.41.2 [skip ci]
## [0.41.2](https://github.com/revanced/revanced-integrations/compare/v0.41.1...v0.41.2) (2022-09-22)
2022-09-22 16:51:03 +00:00
Patryk Miś
f47cc8b375 build: migrate to Kotlin DSL (#151)
Co-authored-by: PatrickMis <24607131+PatrickMis@users.noreply.github.com>
2022-09-22 18:47:46 +02:00
oSumAtrIX
b97c6005f0 refactor(custom-playback-speed): empty initial value for videoSpeeds field 2022-09-22 07:19:12 +02:00
semantic-release-bot
8feeb323ba chore(release): 0.41.1 [skip ci]
## [0.41.1](https://github.com/revanced/revanced-integrations/compare/v0.41.0...v0.41.1) (2022-09-22)
2022-09-22 00:11:29 +00:00
Patryk Miś
c4be039367 build: modernize build code (#148) 2022-09-22 02:08:04 +02:00
semantic-release-bot
0a1f42595e chore(release): 0.41.0 [skip ci]
# [0.41.0](https://github.com/revanced/revanced-integrations/compare/v0.40.0...v0.41.0) (2022-09-21)

### Features

* `tiktok-feed-filter` , `tiktok-settings` and `tiktok-force-login` patch ([#142](https://github.com/revanced/revanced-integrations/issues/142)) ([c3f79eb](c3f79eb27b))
2022-09-21 21:02:57 +00:00
d4rkk3y
c3f79eb27b feat: tiktok-feed-filter , tiktok-settings and tiktok-force-login patch (#142) 2022-09-21 22:59:50 +02:00
semantic-release-bot
cf2d6b955a chore(release): 0.40.0 [skip ci]
# [0.40.0](https://github.com/revanced/revanced-integrations/compare/v0.39.0...v0.40.0) (2022-09-21)

### Bug Fixes

* disable sponsorblock on shorts ([#135](https://github.com/revanced/revanced-integrations/issues/135)) ([3797438](37974389ac))

### Features

* `disable-auto-player-popup-panels` patch ([#145](https://github.com/revanced/revanced-integrations/issues/145)) ([3fd6df8](3fd6df8277))
2022-09-21 01:06:46 +00:00
OxrxL
37974389ac fix: disable sponsorblock on shorts (#135) 2022-09-21 03:03:37 +02:00
OxrxL
3fd6df8277 feat: disable-auto-player-popup-panels patch (#145) 2022-09-21 03:02:47 +02:00
semantic-release-bot
ba22e3bc56 chore(release): 0.39.0 [skip ci]
# [0.39.0](https://github.com/revanced/revanced-integrations/compare/v0.38.0...v0.39.0) (2022-09-21)

### Features

* `hide-time-and-seekbar` patch ([#146](https://github.com/revanced/revanced-integrations/issues/146)) ([7e2f48e](7e2f48eb3e))
2022-09-21 01:01:07 +00:00
OxrxL
7e2f48eb3e feat: hide-time-and-seekbar patch (#146) 2022-09-21 02:58:13 +02:00
semantic-release-bot
6a1669ea71 chore(release): 0.38.0 [skip ci]
# [0.38.0](https://github.com/revanced/revanced-integrations/compare/v0.37.4...v0.38.0) (2022-09-20)

### Features

* disable `swipe-controls` when player controls are visible ([#123](https://github.com/revanced/revanced-integrations/issues/123)) ([6d8c0a0](6d8c0a0c73))
2022-09-20 23:59:25 +00:00
Chris
6d8c0a0c73 feat: disable swipe-controls when player controls are visible (#123) 2022-09-21 01:56:42 +02:00
61 changed files with 2075 additions and 708 deletions

View File

@@ -5,4 +5,4 @@ contact_links:
about: Don't know how or where to start? Check out our documentation!
- name: 🗨 Discussions
url: https://github.com/revanced/revanced-suggestions/discussions
about: Got something you think should change or be added? Search for or start a new discussion!
about: Got something you think should change or be added? Search for or start a new discussion!

View File

@@ -43,4 +43,4 @@ body:
label: Additional context
description: Add additional context here.
validations:
required: false
required: false

View File

@@ -37,4 +37,4 @@ jobs:
- name: Release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release
run: npx semantic-release

View File

@@ -1,3 +1,119 @@
## [0.46.2](https://github.com/revanced/revanced-integrations/compare/v0.46.1...v0.46.2) (2022-10-01)
### Performance Improvements
* **general-ads:** hook pathBuilder ([c7756e1](https://github.com/revanced/revanced-integrations/commit/c7756e1299bdc2e241525ad89561ea67bc372e3a))
## [0.46.1](https://github.com/revanced/revanced-integrations/compare/v0.46.0...v0.46.1) (2022-09-30)
### Bug Fixes
* **general-ads:** remove duplicate blocklist entry ([#165](https://github.com/revanced/revanced-integrations/issues/165)) ([9bcb04d](https://github.com/revanced/revanced-integrations/commit/9bcb04de8e8bd0c8c46ce797db42eb758e632580))
# [0.46.0](https://github.com/revanced/revanced-integrations/compare/v0.45.0...v0.46.0) (2022-09-30)
### Features
* **general-ads:** block additional home ads ([5a24e84](https://github.com/revanced/revanced-integrations/commit/5a24e8486809b73f6c5a95b3f6d28a3da1cddbb8))
# [0.45.0](https://github.com/revanced/revanced-integrations/compare/v0.44.1...v0.45.0) (2022-09-29)
### Features
* `disable-startup-shorts-player` patch ([#164](https://github.com/revanced/revanced-integrations/issues/164)) ([149a90a](https://github.com/revanced/revanced-integrations/commit/149a90a2e8711a95ec4a310c7ba1e8f0ef6a218f))
## [0.44.1](https://github.com/revanced/revanced-integrations/compare/v0.44.0...v0.44.1) (2022-09-29)
### Bug Fixes
* **hide-email-address:** invalid initial switch toggle state ([#163](https://github.com/revanced/revanced-integrations/issues/163)) ([8bb93a4](https://github.com/revanced/revanced-integrations/commit/8bb93a439be21c2f564f3bc2adaedf669977f1fb))
# [0.44.0](https://github.com/revanced/revanced-integrations/compare/v0.43.1...v0.44.0) (2022-09-28)
### Features
* `hide-email-address` patch ([#149](https://github.com/revanced/revanced-integrations/issues/149)) ([4cc8a22](https://github.com/revanced/revanced-integrations/commit/4cc8a22c26c20164d88bff8953d1de53e2041753))
## [0.43.1](https://github.com/revanced/revanced-integrations/compare/v0.43.0...v0.43.1) (2022-09-27)
### Bug Fixes
* move dummy classes to `dummy` module ([#162](https://github.com/revanced/revanced-integrations/issues/162)) ([fa0ad3a](https://github.com/revanced/revanced-integrations/commit/fa0ad3a57b437bfc2d34062ac54e56b6900bafab))
# [0.43.0](https://github.com/revanced/revanced-integrations/compare/v0.42.2...v0.43.0) (2022-09-26)
### Features
* enable minification ([#158](https://github.com/revanced/revanced-integrations/issues/158)) ([8dde925](https://github.com/revanced/revanced-integrations/commit/8dde925b47ff30afc373303b0fdb65c86f9ba82b))
## [0.42.2](https://github.com/revanced/revanced-integrations/compare/v0.42.1...v0.42.2) (2022-09-25)
### Bug Fixes
* **swipe-controls:** crash on SDK below 24 ([#157](https://github.com/revanced/revanced-integrations/issues/157)) ([4c72ac1](https://github.com/revanced/revanced-integrations/commit/4c72ac1cd5ee2aae8478171e56e488563459a0f7))
## [0.42.1](https://github.com/revanced/revanced-integrations/compare/v0.42.0...v0.42.1) (2022-09-23)
### Bug Fixes
* **build:** remove distributionSha256Sum property ([#153](https://github.com/revanced/revanced-integrations/issues/153)) [skip ci] ([ae8d39a](https://github.com/revanced/revanced-integrations/commit/ae8d39a83144bb19f2db1403c32b73232be570b5))
* **custom-playback-speed:** fill array to generate required instructions ([#155](https://github.com/revanced/revanced-integrations/issues/155)) ([868e99a](https://github.com/revanced/revanced-integrations/commit/868e99a6199118151766ecf2dbf7a9df02b59a3e))
* **hide-time-and-seekbar:** don't draw the seekbar ([#154](https://github.com/revanced/revanced-integrations/issues/154)) ([f1e9aa3](https://github.com/revanced/revanced-integrations/commit/f1e9aa30baa582f7eb07f62168ea2d57c5622685))
# [0.42.0](https://github.com/revanced/revanced-integrations/compare/v0.41.2...v0.42.0) (2022-09-23)
### Features
* **tiktok:** adapt `tiktok-download` with `tiktok-settings`. ([#152](https://github.com/revanced/revanced-integrations/issues/152)) ([5a710aa](https://github.com/revanced/revanced-integrations/commit/5a710aa0330741d6ff84dd526e1e59d679e6923c))
## [0.41.2](https://github.com/revanced/revanced-integrations/compare/v0.41.1...v0.41.2) (2022-09-22)
## [0.41.1](https://github.com/revanced/revanced-integrations/compare/v0.41.0...v0.41.1) (2022-09-22)
# [0.41.0](https://github.com/revanced/revanced-integrations/compare/v0.40.0...v0.41.0) (2022-09-21)
### Features
* `tiktok-feed-filter` , `tiktok-settings` and `tiktok-force-login` patch ([#142](https://github.com/revanced/revanced-integrations/issues/142)) ([c3f79eb](https://github.com/revanced/revanced-integrations/commit/c3f79eb27bf71c02299fdd6892179fd081eca07e))
# [0.40.0](https://github.com/revanced/revanced-integrations/compare/v0.39.0...v0.40.0) (2022-09-21)
### Bug Fixes
* disable sponsorblock on shorts ([#135](https://github.com/revanced/revanced-integrations/issues/135)) ([3797438](https://github.com/revanced/revanced-integrations/commit/37974389ac27e98d18cdfc67c61c0945b53bd0c1))
### Features
* `disable-auto-player-popup-panels` patch ([#145](https://github.com/revanced/revanced-integrations/issues/145)) ([3fd6df8](https://github.com/revanced/revanced-integrations/commit/3fd6df82770acacb6fc16b176521abd98080756f))
# [0.39.0](https://github.com/revanced/revanced-integrations/compare/v0.38.0...v0.39.0) (2022-09-21)
### Features
* `hide-time-and-seekbar` patch ([#146](https://github.com/revanced/revanced-integrations/issues/146)) ([7e2f48e](https://github.com/revanced/revanced-integrations/commit/7e2f48eb3e92c49c4ea0516f9a8e7e5fbfb39965))
# [0.38.0](https://github.com/revanced/revanced-integrations/compare/v0.37.4...v0.38.0) (2022-09-20)
### Features
* disable `swipe-controls` when player controls are visible ([#123](https://github.com/revanced/revanced-integrations/issues/123)) ([6d8c0a0](https://github.com/revanced/revanced-integrations/commit/6d8c0a0c738ce976a7a37d2e1e3d38e6ebc29d09))
## [0.37.4](https://github.com/revanced/revanced-integrations/compare/v0.37.3...v0.37.4) (2022-09-18)

2
app/.gitignore vendored
View File

@@ -1 +1 @@
/build
/build

View File

@@ -1,39 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'org.jetbrains.kotlin.android'
android {
compileSdkVersion 32
namespace 'app.revanced.integrations'
defaultConfig {
applicationId "app.revanced.integrations"
minSdkVersion 23
targetSdkVersion 32
versionCode 1
versionName "1.0"
multiDexEnabled false
Properties properties = new Properties()
if (rootProject.file("local.properties").exists()) {
properties.load(rootProject.file("local.properties").newDataInputStream())
}
buildConfigField "String", "YT_API_KEY", "\"${properties.getProperty("youtubeAPIKey", "")}\""
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
}
dependencies {
compileOnly 'androidx.annotation:annotation:1.4.0'
}

48
app/build.gradle.kts Normal file
View File

@@ -0,0 +1,48 @@
import java.io.FileInputStream
import java.util.Properties
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
}
android {
compileSdk = 32
buildToolsVersion = "32.0.0"
namespace = "app.revanced.integrations"
defaultConfig {
applicationId = "app.revanced.integrations"
minSdk = 23
targetSdk = 32
versionCode = 1
versionName = "1.0"
multiDexEnabled = false
val properties = Properties()
if (rootProject.file("local.properties").exists()) {
properties.load(FileInputStream(rootProject.file("local.properties")))
}
buildConfigField("String", "YT_API_KEY", "\"${properties.getProperty("youtubeAPIKey", "")}\"")
}
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
}
}
compileOptions {
sourceCompatibility(JavaVersion.VERSION_11)
targetCompatibility(JavaVersion.VERSION_11)
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
}
dependencies {
compileOnly(project(mapOf("path" to ":dummy")))
compileOnly("androidx.annotation:annotation:1.5.0")
}

View File

@@ -18,4 +18,11 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-renamesourcefileattribute SourceFile
-dontobfuscate
-keep class app.revanced.** {
*;
}
-keep class com.google.** {
*;
}

View File

@@ -2,4 +2,4 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
</manifest>
</manifest>

View File

@@ -3,8 +3,6 @@ package app.revanced.integrations.patches;
import app.revanced.integrations.settings.SettingsEnum;
public class AutoRepeatPatch {
//Used by app.revanced.patches.youtube.layout.autorepeat.patch.AutoRepeatPatch
public static boolean shouldAutoRepeat() {
return SettingsEnum.PREFERRED_AUTO_REPEAT.getBoolean();

View File

@@ -0,0 +1,10 @@
package app.revanced.integrations.patches;
import app.revanced.integrations.settings.SettingsEnum;
public class DisablePlayerPopupPanelsPatch {
//Used by app.revanced.patches.youtube.layout.playerpopuppanels.patch.PlayerPopupPanelsPatch
public static boolean disablePlayerPopupPanels() {
return SettingsEnum.PLAYER_POPUP_PANELS.getBoolean();
}
}

View File

@@ -0,0 +1,10 @@
package app.revanced.integrations.patches;
import app.revanced.integrations.settings.SettingsEnum;
public class DisableStartupShortsPlayerPatch {
//Used by app.revanced.patches.youtube.layout.startupshortsreset.patch.DisableShortsOnStartupPatch
public static boolean disableStartupShortsPlayer() {
return SettingsEnum.DISABLE_STARTUP_SHORTS_PLAYER.getBoolean();
}
}

View File

@@ -1,136 +1,101 @@
package app.revanced.integrations.patches;
import java.util.ArrayList;
import java.util.List;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.utils.LogHelper;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
public class GeneralBytecodeAdsPatch {
//Used by app.revanced.patches.youtube.ad.general.bytecode.patch.GeneralBytecodeAdsPatch
public static boolean containsAd(String value, ByteBuffer buffer) {
return containsLithoAd(value, buffer);
}
public static boolean isAdComponent(StringBuilder pathBuilder) {
var path = pathBuilder.toString();
if (path.isEmpty()) return false;
private static boolean containsLithoAd(String value, ByteBuffer buffer) {
boolean enabled = false;
for (SettingsEnum setting : SettingsEnum.getAdRemovalSettings()) {
if (setting.getBoolean()) {
enabled = true;
break;
}
LogHelper.debug(GeneralBytecodeAdsPatch.class, "Searching for an ad in: " + path);
List<String> blockList = new ArrayList<>();
if (SettingsEnum.ADREMOVER_AD_REMOVAL.getBoolean()) {
blockList.add("video_display_full_buttoned_layout");
blockList.add("ad_");
blockList.add("ads_video_with_context");
blockList.add("cell_divider");
blockList.add("reels_player_overlay");
blockList.add("shelf_header");
blockList.add("watch_metadata_app_promo");
blockList.add("video_display_full_layout");
}
try {
if (value == null || value.isEmpty() || !enabled) return false;
LogHelper.debug(GeneralBytecodeAdsPatch.class, "Searching for AD: " + value);
List<String> blockList = new ArrayList<>();
List<String> bufferBlockList = new ArrayList<>();
if (SettingsEnum.ADREMOVER_AD_REMOVAL.getBoolean()) {
blockList.add("_ad");
blockList.add("ad_badge");
blockList.add("ads_video_with_context");
blockList.add("cell_divider");
blockList.add("reels_player_overlay");
blockList.add("shelf_header");
blockList.add("text_search_ad_with_description_first");
blockList.add("watch_metadata_app_promo");
blockList.add("video_display_full_layout");
bufferBlockList.add("ad_cpn");
}
if (SettingsEnum.ADREMOVER_SUGGESTED_FOR_YOU_REMOVAL.getBoolean()) {
bufferBlockList.add("watch-vrecH");
}
if (SettingsEnum.ADREMOVER_MOVIE_REMOVAL.getBoolean()) {
blockList.add("browsy_bar");
blockList.add("compact_movie");
blockList.add("horizontal_movie_shelf");
blockList.add("movie_and_show_upsell_card");
bufferBlockList.add("YouTube Movies");
}
if (containsAny(value, "home_video_with_context", "related_video_with_context") &&
anyMatch(bufferBlockList, new String(buffer.array(), StandardCharsets.UTF_8)::contains)
) return true;
if (SettingsEnum.ADREMOVER_COMMENTS_REMOVAL.getBoolean()) {
blockList.add("comments_");
}
if (SettingsEnum.ADREMOVER_COMMUNITY_GUIDELINES.getBoolean()) {
blockList.add("community_guidelines");
}
if (SettingsEnum.ADREMOVER_COMPACT_BANNER_REMOVAL.getBoolean()) {
blockList.add("compact_banner");
}
if (SettingsEnum.ADREMOVER_EMERGENCY_BOX_REMOVAL.getBoolean()) {
blockList.add("emergency_onebox");
}
if (SettingsEnum.ADREMOVER_FEED_SURVEY_REMOVAL.getBoolean()) {
blockList.add("in_feed_survey");
}
if (SettingsEnum.ADREMOVER_MEDICAL_PANEL_REMOVAL.getBoolean()) {
blockList.add("medical_panel");
}
if (SettingsEnum.ADREMOVER_PAID_CONTECT_REMOVAL.getBoolean()) {
blockList.add("paid_content_overlay");
}
if (SettingsEnum.ADREMOVER_COMMUNITY_POSTS_REMOVAL.getBoolean()) {
blockList.add("post_base_wrapper");
}
if (SettingsEnum.ADREMOVER_MERCHANDISE_REMOVAL.getBoolean()) {
blockList.add("product_carousel");
}
if (SettingsEnum.ADREMOVER_SHORTS_SHELF.getBoolean()) {
blockList.add("shorts_shelf");
}
if (SettingsEnum.ADREMOVER_INFO_PANEL_REMOVAL.getBoolean()) {
blockList.add("publisher_transparency_panel");
blockList.add("single_item_information_panel");
}
if (SettingsEnum.ADREMOVER_HIDE_SUGGESTIONS.getBoolean()) {
blockList.add("horizontal_video_shelf");
}
if (SettingsEnum.ADREMOVER_HIDE_LATEST_POSTS.getBoolean()) {
blockList.add("post_shelf");
}
if (SettingsEnum.ADREMOVER_HIDE_CHANNEL_GUIDELINES.getBoolean()) {
blockList.add("channel_guidelines_entry_banner");
}
if (containsAny(value,
"home_video_with_context",
"related_video_with_context",
"search_video_with_context",
"menu",
"root",
"-count",
"-space",
"-button"
)) return false;
if (anyMatch(blockList, value::contains)) {
LogHelper.debug(GeneralBytecodeAdsPatch.class, "Blocking ad: " + value);
return true;
}
if (SettingsEnum.DEBUG.getBoolean()) {
if (value.contains("related_video_with_context")) {
LogHelper.debug(GeneralBytecodeAdsPatch.class, value + " | " + bytesToHex(buffer.array()));
return false;
}
LogHelper.debug(GeneralBytecodeAdsPatch.class, value + " returns false.");
}
return false;
} catch (Exception ex) {
LogHelper.printException(GeneralBytecodeAdsPatch.class, ex.getMessage(), ex);
return false;
if (SettingsEnum.ADREMOVER_MOVIE_REMOVAL.getBoolean()) {
blockList.add("browsy_bar");
blockList.add("compact_movie");
blockList.add("horizontal_movie_shelf");
blockList.add("movie_and_show_upsell_card");
}
if (SettingsEnum.ADREMOVER_COMMENTS_REMOVAL.getBoolean()) {
blockList.add("comments_");
}
if (SettingsEnum.ADREMOVER_COMMUNITY_GUIDELINES.getBoolean()) {
blockList.add("community_guidelines");
}
if (SettingsEnum.ADREMOVER_COMPACT_BANNER_REMOVAL.getBoolean()) {
blockList.add("compact_banner");
}
if (SettingsEnum.ADREMOVER_EMERGENCY_BOX_REMOVAL.getBoolean()) {
blockList.add("emergency_onebox");
}
if (SettingsEnum.ADREMOVER_FEED_SURVEY_REMOVAL.getBoolean()) {
blockList.add("in_feed_survey");
}
if (SettingsEnum.ADREMOVER_MEDICAL_PANEL_REMOVAL.getBoolean()) {
blockList.add("medical_panel");
}
if (SettingsEnum.ADREMOVER_PAID_CONTECT_REMOVAL.getBoolean()) {
blockList.add("paid_content_overlay");
}
if (SettingsEnum.ADREMOVER_COMMUNITY_POSTS_REMOVAL.getBoolean()) {
blockList.add("post_base_wrapper");
}
if (SettingsEnum.ADREMOVER_MERCHANDISE_REMOVAL.getBoolean()) {
blockList.add("product_carousel");
}
if (SettingsEnum.ADREMOVER_SHORTS_SHELF.getBoolean()) {
blockList.add("shorts_shelf");
}
if (SettingsEnum.ADREMOVER_INFO_PANEL_REMOVAL.getBoolean()) {
blockList.add("publisher_transparency_panel");
blockList.add("single_item_information_panel");
}
if (SettingsEnum.ADREMOVER_HIDE_SUGGESTIONS.getBoolean()) {
blockList.add("horizontal_video_shelf");
}
if (SettingsEnum.ADREMOVER_HIDE_LATEST_POSTS.getBoolean()) {
blockList.add("post_shelf");
}
if (SettingsEnum.ADREMOVER_HIDE_CHANNEL_GUIDELINES.getBoolean()) {
blockList.add("channel_guidelines_entry_banner");
}
if (containsAny(path,
"home_video_with_context",
"related_video_with_context",
"search_video_with_context",
"menu",
"root",
"-count",
"-space",
"-button"
)) return false;
if (anyMatch(blockList, path::contains)) {
LogHelper.debug(GeneralBytecodeAdsPatch.class, "Blocking ad: " + path);
return true;
}
return false;
}
private static boolean containsAny(String value, String... targets) {
@@ -139,13 +104,6 @@ public class GeneralBytecodeAdsPatch {
return false;
}
private static String bytesToHex(byte[] bytes) {
StringBuilder builder = new StringBuilder(bytes.length * 2);
for (byte b : bytes)
builder.append(String.format("%02x", b));
return builder.toString();
}
private static <T> boolean anyMatch(List<T> value, APredicate<? super T> predicate) {
for (T t : value) {
if (predicate.test(t)) return true;

View File

@@ -0,0 +1,10 @@
package app.revanced.integrations.patches;
import app.revanced.integrations.settings.SettingsEnum;
public class HideEmailAddressPatch {
//Used by app.revanced.patches.youtube.layout.personalinformation.patch.HideEmailAddressPatch
public static boolean hideEmailAddress() {
return SettingsEnum.HIDE_EMAIL_ADDRESS.getBoolean();
}
}

View File

@@ -0,0 +1,10 @@
package app.revanced.integrations.patches;
import app.revanced.integrations.settings.SettingsEnum;
public class HideTimeAndSeekbarPatch {
//Used by app.revanced.patches.youtube.layout.hidetimeandseekbar.patch.HideTimeAndSeekbarPatch
public static boolean hideTimeAndSeekbar() {
return SettingsEnum.HIDE_TIME_AND_SEEKBAR.getBoolean();
}
}

View File

@@ -12,7 +12,7 @@ import app.revanced.integrations.utils.ReVancedUtils;
public class VideoSpeedPatch {
public static final float[] videoSpeeds = {0.25f, 0.5f, 0.75f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 3.0f, 4.0f, 5.0f};
public static final float[] videoSpeeds = { 0, 0 }; // Values are useless as they are being overridden by the respective patch
private static Boolean userChangedSpeed = false;
public static int getDefaultSpeed(Object[] speeds, int speed, Object qInterface) {

View File

@@ -41,7 +41,6 @@ public enum SettingsEnum {
ADREMOVER_INFO_PANEL_REMOVAL("revanced_adremover_info_panel", true, ReturnType.BOOLEAN, true),
ADREMOVER_MEDICAL_PANEL_REMOVAL("revanced_adremover_medical_panel", true, ReturnType.BOOLEAN, true),
ADREMOVER_PAID_CONTECT_REMOVAL("revanced_adremover_paid_content", true, ReturnType.BOOLEAN, true),
ADREMOVER_SUGGESTED_FOR_YOU_REMOVAL("revanced_adremover_suggested", true, ReturnType.BOOLEAN, true),
ADREMOVER_HIDE_SUGGESTIONS("revanced_adremover_hide_suggestions", true, ReturnType.BOOLEAN, true),
ADREMOVER_HIDE_LATEST_POSTS("revanced_adremover_hide_latest_posts", true, ReturnType.BOOLEAN, true),
ADREMOVER_HIDE_CHANNEL_GUIDELINES("revanced_adremover_hide_channel_guidelines", true, ReturnType.BOOLEAN, true),
@@ -52,12 +51,15 @@ public enum SettingsEnum {
BRANDING_SHOWN("revanced_branding_watermark_enabled", false, ReturnType.BOOLEAN),
CAST_BUTTON_SHOWN("revanced_cast_button_enabled", false, ReturnType.BOOLEAN, true),
AUTOPLAY_BUTTON_SHOWN("revanced_autoplay_button_enabled", false, ReturnType.BOOLEAN, true),
//ToDo: Not used atm, Patch missing
USE_TABLET_MINIPLAYER("revanced_tablet_miniplayer", false, ReturnType.BOOLEAN, true),
CREATE_BUTTON_ENABLED("revanced_create_button_enabled", false, ReturnType.BOOLEAN, true),
WIDE_SEARCHBAR("revanced_wide_searchbar", false, ReturnType.BOOLEAN, true),
SHORTS_BUTTON_SHOWN("revanced_shorts_button_enabled", false, ReturnType.BOOLEAN, true),
FULLSCREEN_PANELS_SHOWN("revanced_fullscreen_panels_enabled", false, ReturnType.BOOLEAN), //ToDo: Add to prefs
PLAYER_POPUP_PANELS("revanced_player_popup_panels_enabled", false, ReturnType.BOOLEAN),
HIDE_TIME_AND_SEEKBAR("revanced_hide_time_and_seekbar", false, ReturnType.BOOLEAN),
HIDE_EMAIL_ADDRESS("revanced_hide_email_address", false, ReturnType.BOOLEAN),
DISABLE_STARTUP_SHORTS_PLAYER("revanced_startup_shorts_player_enabled", false, ReturnType.BOOLEAN),
//Misc. Settings
CAPTIONS_ENABLED("revanced_autocaptions_enabled", false, ReturnType.BOOLEAN, false),
@@ -249,5 +251,4 @@ public enum SettingsEnum {
public boolean shouldRebootOnChange() {
return rebootApp;
}
}

View File

@@ -0,0 +1,84 @@
package app.revanced.integrations.shared
import android.app.Activity
import android.view.View
import android.view.ViewGroup
import app.revanced.integrations.utils.ReVancedUtils
import java.lang.ref.WeakReference
/**
* default implementation of [PlayerControlsVisibilityObserver]
*
* @param activity activity that contains the controls_layout view
*/
class PlayerControlsVisibilityObserverImpl(
private val activity: Activity
) : PlayerControlsVisibilityObserver {
/**
* id of the direct parent of controls_layout, R.id.youtube_controls_overlay
*/
private val controlsLayoutParentId =
ReVancedUtils.getResourceIdByName(activity, "id", "youtube_controls_overlay")
/**
* id of R.id.controls_layout
*/
private val controlsLayoutId =
ReVancedUtils.getResourceIdByName(activity, "id", "controls_layout")
/**
* reference to the controls layout view
*/
private var controlsLayoutView = WeakReference<View>(null)
/**
* is the [controlsLayoutView] set to a valid reference of a view?
*/
private val isAttached: Boolean
get() {
val view = controlsLayoutView.get()
return view != null && view.parent != null
}
/**
* find and attach the controls_layout view if needed
*/
private fun maybeAttach() {
if (isAttached) return
// find parent, then controls_layout view
// this is needed because there may be two views where id=R.id.controls_layout
// because why should google confine themselves to their own guidelines...
activity.findViewById<ViewGroup>(controlsLayoutParentId)?.let { parent ->
parent.findViewById<View>(controlsLayoutId)?.let {
controlsLayoutView = WeakReference(it)
}
}
}
override val playerControlsVisibility: Int
get() {
maybeAttach()
return controlsLayoutView.get()?.visibility ?: View.GONE
}
override val arePlayerControlsVisible: Boolean
get() = playerControlsVisibility == View.VISIBLE
}
/**
* provides the visibility status of the fullscreen player controls_layout view.
* this can be used for detecting when the player controls are shown
*/
interface PlayerControlsVisibilityObserver {
/**
* current visibility int of the controls_layout view
*/
val playerControlsVisibility: Int
/**
* is the value of [playerControlsVisibility] equal to [View.VISIBLE]?
*/
val arePlayerControlsVisible: Boolean
}

View File

@@ -49,6 +49,8 @@ public class PlayerController {
private static float sponsorBarThickness = 2f;
private static TimerTask skipSponsorTask = null;
public static boolean shorts_playing = false;
public static String getCurrentVideoId() {
return currentVideoId;
}
@@ -87,7 +89,6 @@ public class PlayerController {
* Called when creating some kind of youtube internal player controlled, every time when new video starts to play
*/
public static void onCreate(final Object o) {
// "Plugin.printStackTrace();
if (o == null) {
LogHelper.printException(PlayerController.class, "onCreate called with null object");
@@ -115,8 +116,9 @@ public class PlayerController {
public static void executeDownloadSegments(String videoId) {
videoHasSegments = false;
timeWithoutSegments = "";
if (Whitelist.isChannelSBWhitelisted())
if (Whitelist.isChannelSBWhitelisted() || shorts_playing) {
return;
}
SponsorSegment[] segments = SBRequester.getSegments(videoId);
Arrays.sort(segments);

View File

@@ -8,6 +8,7 @@ import android.widget.RelativeLayout;
import java.lang.ref.WeakReference;
import app.revanced.integrations.settings.SettingsEnum;
import app.revanced.integrations.sponsorblock.player.PlayerType;
import app.revanced.integrations.utils.LogHelper;
import app.revanced.integrations.utils.ReVancedUtils;

View File

@@ -1,6 +1,7 @@
package app.revanced.integrations.swipecontrols
import android.app.Activity
import android.os.Build
import android.os.Bundle
import android.view.KeyEvent
import android.view.MotionEvent
@@ -10,8 +11,9 @@ import app.revanced.integrations.swipecontrols.controller.AudioVolumeController
import app.revanced.integrations.swipecontrols.controller.ScreenBrightnessController
import app.revanced.integrations.swipecontrols.controller.SwipeZonesController
import app.revanced.integrations.swipecontrols.controller.VolumeKeysController
import app.revanced.integrations.swipecontrols.controller.gesture.NoPtSSwipeGestureController
import app.revanced.integrations.swipecontrols.controller.gesture.SwipeGestureController
import app.revanced.integrations.swipecontrols.controller.gesture.ClassicSwipeController
import app.revanced.integrations.swipecontrols.controller.gesture.PressToSwipeController
import app.revanced.integrations.swipecontrols.controller.gesture.core.GestureController
import app.revanced.integrations.swipecontrols.misc.Rectangle
import app.revanced.integrations.swipecontrols.views.SwipeControlsOverlayLayout
import app.revanced.integrations.utils.LogHelper
@@ -52,7 +54,7 @@ class SwipeControlsHostActivity : Activity() {
/**
* main gesture controller
*/
private lateinit var gesture: SwipeGestureController
private lateinit var gesture: GestureController
/**
* main volume keys controller
@@ -67,17 +69,66 @@ class SwipeControlsHostActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
initialize()
}
override fun onStart() {
super.onStart()
reAttachOverlays()
}
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
ensureInitialized()
return if ((ev != null) && gesture.submitTouchEvent(ev)) true else {
super.dispatchTouchEvent(ev)
}
}
override fun dispatchKeyEvent(ev: KeyEvent?): Boolean {
ensureInitialized()
return if ((ev != null) && keys.onKeyEvent(ev)) true else {
super.dispatchKeyEvent(ev)
}
}
/**
* dispatch a touch event to downstream views
*
* @param event the event to dispatch
* @return was the event consumed?
*/
fun dispatchDownstreamTouchEvent(event: MotionEvent) =
super.dispatchTouchEvent(event)
/**
* ensures that swipe controllers are initialized and attached.
* on some ROMs with SDK <= 23, [onCreate] and [onStart] may not be called correctly.
* see https://github.com/revanced/revanced-patches/issues/446
*/
private fun ensureInitialized() {
if (!this::config.isInitialized) {
LogHelper.printException(
this.javaClass,
"swipe controls were not initialized in onCreate, initializing on-the-fly (SDK is ${Build.VERSION.SDK_INT})"
)
initialize()
reAttachOverlays()
}
}
/**
* initializes controllers, only call once
*/
private fun initialize() {
// create controllers
LogHelper.info(this.javaClass, "initializing swipe controls controllers")
config = SwipeControlsConfigurationProvider(this)
gesture = createGestureController()
keys = VolumeKeysController(this)
audio = createAudioController()
screen = createScreenController()
// create overlay
SwipeControlsOverlayLayout(this).let {
SwipeControlsOverlayLayout(this, config).let {
overlay = it
contentRoot.addView(it)
}
@@ -92,6 +143,9 @@ class SwipeControlsHostActivity : Activity() {
)
}
// create the gesture controller
gesture = createGestureController()
// listen for changes in the player type
PlayerType.onChange += this::onPlayerTypeChanged
@@ -99,36 +153,15 @@ class SwipeControlsHostActivity : Activity() {
currentHost = WeakReference(this)
}
override fun onStart() {
super.onStart()
// (re) attach overlay
/**
* (re) attaches swipe overlays
*/
private fun reAttachOverlays() {
LogHelper.info(this.javaClass, "attaching swipe controls overlay")
contentRoot.removeView(overlay)
contentRoot.addView(overlay)
}
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
return if ((ev != null) && gesture.onTouchEvent(ev)) true else {
super.dispatchTouchEvent(ev)
}
}
override fun dispatchKeyEvent(ev: KeyEvent?): Boolean {
return if((ev != null) && keys.onKeyEvent(ev)) true else {
super.dispatchKeyEvent(ev)
}
}
/**
* dispatch a touch event to downstream views
*
* @param event the event to dispatch
* @return was the event consumed?
*/
fun dispatchDownstreamTouchEvent(event: MotionEvent) =
super.dispatchTouchEvent(event)
/**
* called when the player type changes
*
@@ -163,8 +196,8 @@ class SwipeControlsHostActivity : Activity() {
*/
private fun createGestureController() =
if (config.shouldEnablePressToSwipe)
SwipeGestureController(this)
else NoPtSSwipeGestureController(this)
PressToSwipeController(this)
else ClassicSwipeController(this)
companion object {
/**

View File

@@ -0,0 +1,111 @@
package app.revanced.integrations.swipecontrols.controller.gesture
import android.view.MotionEvent
import app.revanced.integrations.shared.PlayerControlsVisibilityObserver
import app.revanced.integrations.shared.PlayerControlsVisibilityObserverImpl
import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity
import app.revanced.integrations.swipecontrols.controller.gesture.core.BaseGestureController
import app.revanced.integrations.swipecontrols.controller.gesture.core.SwipeDetector
import app.revanced.integrations.swipecontrols.misc.contains
import app.revanced.integrations.swipecontrols.misc.toPoint
/**
* provides the classic swipe controls experience, as it was with 'XFenster'
*
* @param controller reference to the main swipe controller
*/
class ClassicSwipeController(
private val controller: SwipeControlsHostActivity
) : BaseGestureController(controller),
PlayerControlsVisibilityObserver by PlayerControlsVisibilityObserverImpl(controller) {
/**
* the last event captured in [onDown]
*/
private var lastOnDownEvent: MotionEvent? = null
override val shouldForceInterceptEvents: Boolean
get() = currentSwipe == SwipeDetector.SwipeDirection.VERTICAL
override fun isInSwipeZone(motionEvent: MotionEvent): Boolean {
val inVolumeZone = if (controller.config.enableVolumeControls)
(motionEvent.toPoint() in controller.zones.volume) else false
val inBrightnessZone = if (controller.config.enableBrightnessControl)
(motionEvent.toPoint() in controller.zones.brightness) else false
return inVolumeZone || inBrightnessZone
}
override fun shouldDropMotion(motionEvent: MotionEvent): Boolean {
// ignore gestures with more than one pointer
// when such a gesture is detected, dispatch the first event of the gesture to downstream
if (motionEvent.pointerCount > 1) {
lastOnDownEvent?.let {
controller.dispatchDownstreamTouchEvent(it)
it.recycle()
}
lastOnDownEvent = null
return true
}
// ignore gestures when player controls are visible
return arePlayerControlsVisible
}
override fun onDown(motionEvent: MotionEvent): Boolean {
// save the event for later
lastOnDownEvent?.recycle()
lastOnDownEvent = MotionEvent.obtain(motionEvent)
// must be inside swipe zone
return isInSwipeZone(motionEvent)
}
override fun onSingleTapUp(motionEvent: MotionEvent): Boolean {
MotionEvent.obtain(motionEvent).let {
it.action = MotionEvent.ACTION_DOWN
controller.dispatchDownstreamTouchEvent(it)
it.recycle()
}
return false
}
override fun onDoubleTapEvent(motionEvent: MotionEvent?): Boolean {
MotionEvent.obtain(motionEvent).let {
controller.dispatchDownstreamTouchEvent(it)
it.recycle()
}
return super.onDoubleTapEvent(motionEvent)
}
override fun onLongPress(motionEvent: MotionEvent?) {
MotionEvent.obtain(motionEvent).let {
controller.dispatchDownstreamTouchEvent(it)
it.recycle()
}
super.onLongPress(motionEvent)
}
override fun onSwipe(
from: MotionEvent,
to: MotionEvent,
distanceX: Double,
distanceY: Double
): Boolean {
// cancel if not vertical
if (currentSwipe != SwipeDetector.SwipeDirection.VERTICAL) return false
return when (from.toPoint()) {
in controller.zones.volume -> {
scrollVolume(distanceY)
true
}
in controller.zones.brightness -> {
scrollBrightness(distanceY)
true
}
else -> false
}
}
}

View File

@@ -1,28 +0,0 @@
package app.revanced.integrations.swipecontrols.controller.gesture
import android.view.MotionEvent
import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity
/**
* [SwipeGestureController], but with press-to-swipe disabled because a lot of people dislike the feature.
* If you want to change something, try to do it in [SwipeGestureController] so that both configurations can benefit from it
*/
class NoPtSSwipeGestureController(controller: SwipeControlsHostActivity) :
SwipeGestureController(controller) {
/**
* to disable press-to-swipe, we have to become press-to-swipe
*/
override var inSwipeSession
get() = true
set(_) {}
override fun onLongPress(e: MotionEvent?) {
if (e == null) return
// send GestureDetector a ACTION_CANCEL event so it will handle further events
// if this is left out, swipe-to-dismiss is triggered when scrolling down
e.action = MotionEvent.ACTION_CANCEL
detector.onTouchEvent(e)
}
}

View File

@@ -0,0 +1,72 @@
package app.revanced.integrations.swipecontrols.controller.gesture
import android.view.MotionEvent
import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity
import app.revanced.integrations.swipecontrols.controller.gesture.core.BaseGestureController
import app.revanced.integrations.swipecontrols.controller.gesture.core.SwipeDetector
import app.revanced.integrations.swipecontrols.misc.contains
import app.revanced.integrations.swipecontrols.misc.toPoint
/**
* provides the press-to-swipe (PtS) swipe controls experience
*
* @param controller reference to the main swipe controller
*/
class PressToSwipeController(
private val controller: SwipeControlsHostActivity
) : BaseGestureController(controller) {
/**
* monitors if the user is currently in a swipe session.
*/
private var isInSwipeSession = false
override val shouldForceInterceptEvents: Boolean
get() = currentSwipe == SwipeDetector.SwipeDirection.VERTICAL && isInSwipeSession
override fun shouldDropMotion(motionEvent: MotionEvent): Boolean = false
override fun isInSwipeZone(motionEvent: MotionEvent): Boolean {
val inVolumeZone = if (controller.config.enableVolumeControls)
(motionEvent.toPoint() in controller.zones.volume) else false
val inBrightnessZone = if (controller.config.enableBrightnessControl)
(motionEvent.toPoint() in controller.zones.brightness) else false
return inVolumeZone || inBrightnessZone
}
override fun onUp(motionEvent: MotionEvent) {
super.onUp(motionEvent)
isInSwipeSession = false
}
override fun onLongPress(motionEvent: MotionEvent) {
// enter swipe session with feedback
isInSwipeSession = true
controller.overlay.onEnterSwipeSession()
// send GestureDetector a ACTION_CANCEL event so it will handle further events
motionEvent.action = MotionEvent.ACTION_CANCEL
detector.onTouchEvent(motionEvent)
}
override fun onSwipe(
from: MotionEvent,
to: MotionEvent,
distanceX: Double,
distanceY: Double
): Boolean {
// cancel if not in swipe session or vertical
if (!isInSwipeSession || currentSwipe != SwipeDetector.SwipeDirection.VERTICAL) return false
return when (from.toPoint()) {
in controller.zones.volume -> {
scrollVolume(distanceY)
true
}
in controller.zones.brightness -> {
scrollBrightness(distanceY)
true
}
else -> false
}
}
}

View File

@@ -1,232 +0,0 @@
package app.revanced.integrations.swipecontrols.controller.gesture
import android.util.TypedValue
import android.view.GestureDetector
import android.view.MotionEvent
import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity
import app.revanced.integrations.swipecontrols.misc.ScrollDistanceHelper
import app.revanced.integrations.swipecontrols.misc.applyDimension
import app.revanced.integrations.swipecontrols.misc.contains
import app.revanced.integrations.swipecontrols.misc.toPoint
import app.revanced.integrations.utils.LogHelper
import kotlin.math.abs
import kotlin.math.pow
/**
* base gesture controller for volume and brightness swipe controls controls, with press-to-swipe enabled
* for the controller without press-to-swipe, see [NoPtSSwipeGestureController]
*
* @param controller reference to main controller instance
*/
@Suppress("LeakingThis")
open class SwipeGestureController(
private val controller: SwipeControlsHostActivity
) :
GestureDetector.SimpleOnGestureListener() {
/**
* the main gesture detector that powers everything
*/
protected open val detector = GestureDetector(controller, this)
/**
* to enable swipe controls, users must first long- press. this flags monitors that long- press
* NOTE: if you dislike press-to-swipe, and want it disabled, have a look at [NoPtSSwipeGestureController]. it does exactly that
*/
protected open var inSwipeSession = true
/**
* currently in- progress swipe
*/
protected open var currentSwipe: SwipeDirection = SwipeDirection.NONE
/**
* were downstream event cancelled already? used by [onScroll]
*/
protected open var didCancelDownstream = false
/**
* should [onTouchEvent] force- intercept all touch events?
*/
protected open val shouldForceInterceptEvents: Boolean
get() = currentSwipe == SwipeDirection.VERTICAL && inSwipeSession
/**
* scroller for volume adjustment
*/
protected open val volumeScroller = ScrollDistanceHelper(
10.applyDimension(
controller,
TypedValue.COMPLEX_UNIT_DIP
)
) { _, _, direction ->
controller.audio?.apply {
volume += direction
controller.overlay.onVolumeChanged(volume, maxVolume)
}
}
/**
* scroller for screen brightness adjustment
*/
protected open val brightnessScroller = ScrollDistanceHelper(
1.applyDimension(
controller,
TypedValue.COMPLEX_UNIT_DIP
)
) { _, _, direction ->
controller.screen?.apply {
if (screenBrightness > 0 || direction > 0) {
screenBrightness += direction
} else {
restoreDefaultBrightness()
}
controller.overlay.onBrightnessChanged(screenBrightness)
}
}
/**
* touch event callback
*
* @param motionEvent the motion event that was received
* @return intercept the event? if true, child views will not receive the event
*/
fun onTouchEvent(motionEvent: MotionEvent): Boolean {
if (!controller.config.enableSwipeControls) {
return false
}
if (motionEvent.action == MotionEvent.ACTION_UP) {
onUp(motionEvent)
}
return if (shouldForceInterceptEvents || inSwipeZone(motionEvent)) {
detector.onTouchEvent(motionEvent) or shouldForceInterceptEvents
} else false
}
/**
* check if provided motion event is in any active swipe zone?
*
* @param e the event to check
* @return is the event in any active swipe zone?
*/
open fun inSwipeZone(e: MotionEvent): Boolean {
val inVolumeZone = if (controller.config.enableVolumeControls)
(e.toPoint() in controller.zones.volume) else false
val inBrightnessZone = if (controller.config.enableBrightnessControl)
(e.toPoint() in controller.zones.brightness) else false
return inVolumeZone || inBrightnessZone
}
/**
* custom handler for ACTION_UP event, because GestureDetector doesn't offer that :|
* basically just resets all flags to non- swiping values
*
* @param e the motion event
*/
open fun onUp(e: MotionEvent) {
LogHelper.debug(this.javaClass, "onUp(${e.x}, ${e.y}, ${e.action})")
inSwipeSession = false
currentSwipe = SwipeDirection.NONE
didCancelDownstream = false
volumeScroller.reset()
brightnessScroller.reset()
}
override fun onLongPress(e: MotionEvent?) {
if (e == null) return
LogHelper.debug(this.javaClass, "onLongPress(${e.x}, ${e.y}, ${e.action})")
// enter swipe session with feedback
inSwipeSession = true
controller.overlay.onEnterSwipeSession()
// send GestureDetector a ACTION_CANCEL event so it will handle further events
e.action = MotionEvent.ACTION_CANCEL
detector.onTouchEvent(e)
}
override fun onScroll(
eFrom: MotionEvent?,
eTo: MotionEvent?,
disX: Float,
disY: Float
): Boolean {
if (eFrom == null || eTo == null) return false
LogHelper.debug(
this.javaClass,
"onScroll(from: [${eFrom.x}, ${eFrom.y}, ${eFrom.action}], to: [${eTo.x}, ${eTo.y}, ${eTo.action}], d: [$disX, $disY])"
)
return when (currentSwipe) {
// no swipe direction was detected yet, try to detect one
// if the user did not swipe far enough, we cannot detect what direction they swiped
// so we wait until a greater distance was swiped
// NOTE: sqrt() can be high- cost, so using squared magnitudes here
SwipeDirection.NONE -> {
val deltaX = abs(eTo.x - eFrom.x)
val deltaY = abs(eTo.y - eFrom.y)
val swipeMagnitudeSquared = deltaX.pow(2) + deltaY.pow(2)
if (swipeMagnitudeSquared > controller.config.swipeMagnitudeThreshold.pow(2)) {
currentSwipe = if (deltaY > deltaX) {
SwipeDirection.VERTICAL
} else {
SwipeDirection.HORIZONTAL
}
}
return false
}
// horizontal swipe, we should leave this one for downstream to handle
SwipeDirection.HORIZONTAL -> false
// vertical swipe, could be for us
SwipeDirection.VERTICAL -> {
if (!inSwipeSession) {
// not in swipe session, let downstream handle this one
return false
}
// vertical & in swipe session, handle this one:
// first, send ACTION_CANCEL to downstream to let them known they should stop tracking events
if (!didCancelDownstream) {
val eCancel = MotionEvent.obtain(eFrom)
eCancel.action = MotionEvent.ACTION_CANCEL
controller.dispatchDownstreamTouchEvent(eCancel)
eCancel.recycle()
didCancelDownstream = true
}
// then, process the event
when (eFrom.toPoint()) {
in controller.zones.volume -> volumeScroller.add(disY.toDouble())
in controller.zones.brightness -> brightnessScroller.add(disY.toDouble())
}
return true
}
}
}
/**
* direction of a swipe
*/
enum class SwipeDirection {
/**
* swipe has no direction or no swipe
*/
NONE,
/**
* swipe along the X- Axes
*/
HORIZONTAL,
/**
* swipe along the Y- Axes
*/
VERTICAL
}
}

View File

@@ -0,0 +1,154 @@
package app.revanced.integrations.swipecontrols.controller.gesture.core
import android.view.GestureDetector
import android.view.MotionEvent
import app.revanced.integrations.swipecontrols.SwipeControlsHostActivity
/**
* the common base of all [GestureController] classes.
* handles most of the boilerplate code needed for gesture detection
*
* @param controller reference to the main swipe controller
*/
abstract class BaseGestureController(
private val controller: SwipeControlsHostActivity
) : GestureController,
GestureDetector.SimpleOnGestureListener(),
SwipeDetector by SwipeDetectorImpl(
controller.config.swipeMagnitudeThreshold.toDouble()
),
VolumeAndBrightnessScroller by VolumeAndBrightnessScrollerImpl(
controller,
controller.audio,
controller.screen,
controller.overlay,
10,
1
) {
/**
* the main gesture detector that powers everything
*/
@Suppress("LeakingThis")
protected val detector = GestureDetector(controller, this)
/**
* were downstream event cancelled already? used in [onScroll]
*/
private var didCancelDownstream = false
override fun submitTouchEvent(motionEvent: MotionEvent): Boolean {
// ignore if swipe is disabled
if (!controller.config.enableSwipeControls) {
return false
}
// create a copy of the event so we can modify it
// without causing any issues downstream
val me = MotionEvent.obtain(motionEvent)
// check if we should drop this motion
val dropped = shouldDropMotion(me)
if (dropped) {
me.action = MotionEvent.ACTION_CANCEL
}
// send the event to the detector
// if we force intercept events, the event is always consumed
val consumed = detector.onTouchEvent(me) || shouldForceInterceptEvents
// invoke the custom onUp handler
if (me.action == MotionEvent.ACTION_UP || me.action == MotionEvent.ACTION_CANCEL) {
onUp(me)
}
// recycle the copy
me.recycle()
// do not consume dropped events
// or events outside of any swipe zone
return !dropped && consumed && isInSwipeZone(me)
}
/**
* custom handler for [MotionEvent.ACTION_UP] event, because GestureDetector doesn't offer that :|
*
* @param motionEvent the motion event
*/
open fun onUp(motionEvent: MotionEvent) {
didCancelDownstream = false
resetSwipe()
resetScroller()
}
override fun onScroll(
from: MotionEvent,
to: MotionEvent,
distanceX: Float,
distanceY: Float
): Boolean {
// submit to swipe detector
submitForSwipe(from, to, distanceX, distanceY)
// call swipe callback if in a swipe
return if (currentSwipe != SwipeDetector.SwipeDirection.NONE) {
val consumed = onSwipe(
from,
to,
distanceX.toDouble(),
distanceY.toDouble()
)
// if the swipe was consumed, cancel downstream events once
if (consumed && !didCancelDownstream) {
didCancelDownstream = true
MotionEvent.obtain(from).let {
it.action = MotionEvent.ACTION_CANCEL
controller.dispatchDownstreamTouchEvent(it)
it.recycle()
}
}
consumed
} else false
}
/**
* should [submitTouchEvent] force- intercept all touch events?
*/
abstract val shouldForceInterceptEvents: Boolean
/**
* check if provided motion event is in any active swipe zone?
*
* @param motionEvent the event to check
* @return is the event in any active swipe zone?
*/
abstract fun isInSwipeZone(motionEvent: MotionEvent): Boolean
/**
* check if a touch event should be dropped.
* when a event is dropped, the gesture detector received a [MotionEvent.ACTION_CANCEL] event and the event is not consumed
*
* @param motionEvent the event to check
* @return should the event be dropped?
*/
abstract fun shouldDropMotion(motionEvent: MotionEvent): Boolean
/**
* handler for swipe events, once a swipe is detected.
* the direction of the swipe can be accessed in [currentSwipe]
*
* @param from start event of the swipe
* @param to end event of the swipe
* @param distanceX the horizontal distance of the swipe
* @param distanceY the vertical distance of the swipe
* @return was the event consumed?
*/
abstract fun onSwipe(
from: MotionEvent,
to: MotionEvent,
distanceX: Double,
distanceY: Double
): Boolean
}

View File

@@ -0,0 +1,16 @@
package app.revanced.integrations.swipecontrols.controller.gesture.core
import android.view.MotionEvent
/**
* describes a class that accepts motion events and detects gestures
*/
interface GestureController {
/**
* accept a touch event and try to detect the desired gestures using it
*
* @param motionEvent the motion event that was submitted
* @return was a gesture detected?
*/
fun submitTouchEvent(motionEvent: MotionEvent): Boolean
}

View File

@@ -0,0 +1,94 @@
package app.revanced.integrations.swipecontrols.controller.gesture.core
import android.view.MotionEvent
import kotlin.math.abs
import kotlin.math.pow
/**
* describes a class that can detect swipes and their directionality
*/
interface SwipeDetector {
/**
* the currently detected swipe
*/
val currentSwipe: SwipeDirection
/**
* submit a onScroll event for swipe detection
*
* @param from start event
* @param to end event
* @param distanceX horizontal scroll distance
* @param distanceY vertical scroll distance
*/
fun submitForSwipe(
from: MotionEvent,
to: MotionEvent,
distanceX: Float,
distanceY: Float
)
/**
* reset the swipe detection
*/
fun resetSwipe()
/**
* direction of a swipe
*/
enum class SwipeDirection {
/**
* swipe has no direction or no swipe
*/
NONE,
/**
* swipe along the X- Axes
*/
HORIZONTAL,
/**
* swipe along the Y- Axes
*/
VERTICAL
}
}
/**
* detector that can detect swipes and their directionality
*
* @param swipeMagnitudeThreshold minimum magnitude before a swipe is detected as such
*/
class SwipeDetectorImpl(
private val swipeMagnitudeThreshold: Double
) : SwipeDetector {
override var currentSwipe = SwipeDetector.SwipeDirection.NONE
override fun submitForSwipe(
from: MotionEvent,
to: MotionEvent,
distanceX: Float,
distanceY: Float
) {
if (currentSwipe == SwipeDetector.SwipeDirection.NONE) {
// no swipe direction was detected yet, try to detect one
// if the user did not swipe far enough, we cannot detect what direction they swiped
// so we wait until a greater distance was swiped
// NOTE: sqrt() can be high- cost, so using squared magnitudes here
val deltaX = abs(to.x - from.x)
val deltaY = abs(to.y - from.y)
val swipeMagnitudeSquared = deltaX.pow(2) + deltaY.pow(2)
if (swipeMagnitudeSquared > swipeMagnitudeThreshold.pow(2)) {
currentSwipe = if (deltaY > deltaX) {
SwipeDetector.SwipeDirection.VERTICAL
} else {
SwipeDetector.SwipeDirection.HORIZONTAL
}
}
}
}
override fun resetSwipe() {
currentSwipe = SwipeDetector.SwipeDirection.NONE
}
}

View File

@@ -0,0 +1,97 @@
package app.revanced.integrations.swipecontrols.controller.gesture.core
import android.content.Context
import android.util.TypedValue
import app.revanced.integrations.swipecontrols.controller.AudioVolumeController
import app.revanced.integrations.swipecontrols.controller.ScreenBrightnessController
import app.revanced.integrations.swipecontrols.misc.ScrollDistanceHelper
import app.revanced.integrations.swipecontrols.misc.SwipeControlsOverlay
import app.revanced.integrations.swipecontrols.misc.applyDimension
/**
* describes a class that controls volume and brightness based on scrolling events
*/
interface VolumeAndBrightnessScroller {
/**
* submit a scroll for volume adjustment
*
* @param distance the scroll distance
*/
fun scrollVolume(distance: Double)
/**
* submit a scroll for brightness adjustment
*
* @param distance the scroll distance
*/
fun scrollBrightness(distance: Double)
/**
* reset all scroll distances to zero
*/
fun resetScroller()
}
/**
* handles scrolling of volume and brightness, adjusts them using the provided controllers and updates the overlay
*
* @param context context to create the scrollers in
* @param volumeController volume controller instance. if null, volume control is disabled
* @param screenController screen brightness controller instance. if null, brightness control is disabled
* @param overlayController overlay controller instance
* @param volumeDistance unit distance for volume scrolling, in dp
* @param brightnessDistance unit distance for brightness scrolling, in dp
*/
class VolumeAndBrightnessScrollerImpl(
context: Context,
private val volumeController: AudioVolumeController?,
private val screenController: ScreenBrightnessController?,
private val overlayController: SwipeControlsOverlay,
volumeDistance: Int = 10,
brightnessDistance: Int = 1
) : VolumeAndBrightnessScroller {
// region volume
private val volumeScroller =
ScrollDistanceHelper(
volumeDistance.applyDimension(
context,
TypedValue.COMPLEX_UNIT_DIP
)
) { _, _, direction ->
volumeController?.run {
volume += direction
overlayController.onVolumeChanged(volume, maxVolume)
}
}
override fun scrollVolume(distance: Double) = volumeScroller.add(distance)
//endregion
//region brightness
private val brightnessScroller =
ScrollDistanceHelper(
brightnessDistance.applyDimension(
context,
TypedValue.COMPLEX_UNIT_DIP
)
) { _, _, direction ->
screenController?.run {
if (screenBrightness > 0 || direction > 0) {
screenBrightness += direction
} else {
restoreDefaultBrightness()
}
overlayController.onBrightnessChanged(screenBrightness)
}
}
override fun scrollBrightness(distance: Double) = brightnessScroller.add(distance)
//endregion
override fun resetScroller() {
volumeScroller.reset()
brightnessScroller.reset()
}
}

View File

@@ -0,0 +1,13 @@
package app.revanced.tiktok.download;
import app.revanced.tiktok.settings.SettingsEnum;
public class DownloadsPatch {
public static String getDownloadPath() {
return SettingsEnum.TIK_DOWN_PATH.getString();
}
public static boolean shouldRemoveWatermark() {
return SettingsEnum.TIK_DOWN_WATERMARK.getBoolean();
}
}

View File

@@ -0,0 +1,39 @@
package app.revanced.tiktok.feedfilter;
import com.ss.android.ugc.aweme.feed.model.Aweme;
import com.ss.android.ugc.aweme.feed.model.FeedItemList;
import java.util.Iterator;
import java.util.List;
import app.revanced.tiktok.settings.SettingsEnum;
public class FeedItemsFilter {
public static void filter(FeedItemList feedItemList) {
if (SettingsEnum.TIK_REMOVE_ADS.getBoolean()) removeAds(feedItemList);
if (SettingsEnum.TIK_HIDE_LIVE.getBoolean()) removeLive(feedItemList);
}
private static void removeAds(FeedItemList feedItemList) {
List<Aweme> items = feedItemList.items;
Iterator<Aweme> it = items.iterator();
while (it.hasNext()) {
Aweme item = it.next();
if (item != null && (item.isAd() || item.isWithPromotionalMusic())) {
it.remove();
}
}
}
private static void removeLive(FeedItemList feedItemList) {
List<Aweme> items = feedItemList.items;
Iterator<Aweme> it = items.iterator();
while (it.hasNext()) {
Aweme item = it.next();
if (item != null && (item.isLive() || item.isLiveReplay())) {
it.remove();
}
}
}
}

View File

@@ -0,0 +1,5 @@
package app.revanced.tiktok.settings;
public enum ReturnType {
BOOLEAN, INTEGER, STRING, LONG, FLOAT
}

Some files were not shown because too many files have changed in this diff Show More