You've already forked revanced-integrations
mirror of
https://github.com/revanced/revanced-integrations
synced 2025-11-19 03:23:27 +01:00
Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9fa8d6c09 | ||
|
|
f122598e08 | ||
|
|
12ee45bb68 | ||
|
|
eec90ee04c | ||
|
|
0682c4c671 | ||
|
|
59031d95ea | ||
|
|
38e3906240 | ||
|
|
5ed6a57df2 | ||
|
|
33b99f0061 | ||
|
|
f4e8afe7ba | ||
|
|
878ac2a9fa | ||
|
|
b663880741 | ||
|
|
9ab8a646ed | ||
|
|
2002bf8063 | ||
|
|
693ef08c6c |
24
.github/workflows/pull_request.yml
vendored
Normal file
24
.github/workflows/pull_request.yml
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
name: PR to main
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
MESSAGE: merge branch \`${{ github.head_ref || github.ref_name }}\` to \`main\`
|
||||
|
||||
jobs:
|
||||
pull-request:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Open pull request
|
||||
uses: repo-sync/pull-request@v2
|
||||
with:
|
||||
destination_branch: 'main'
|
||||
pr_title: 'chore: ${{ env.MESSAGE }}'
|
||||
pr_body: 'This pull request will ${{ env.MESSAGE }}.'
|
||||
pr_draft: true
|
||||
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build --no-daemon
|
||||
- name: Setup semantic-release
|
||||
run: npm install semantic-release @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
|
||||
run: npm install semantic-release @saithodev/semantic-release-backmerge @semantic-release/git @semantic-release/changelog gradle-semantic-release-plugin -D
|
||||
- name: Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
13
.releaserc
13
.releaserc
@@ -7,11 +7,7 @@
|
||||
}
|
||||
],
|
||||
"plugins": [
|
||||
["@semantic-release/commit-analyzer", {
|
||||
"releaseRules": [
|
||||
{"type": "build", "release": "patch"}
|
||||
]
|
||||
}],
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
"@semantic-release/changelog",
|
||||
"gradle-semantic-release-plugin",
|
||||
@@ -33,6 +29,13 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
[
|
||||
"@saithodev/semantic-release-backmerge",
|
||||
{
|
||||
branches: [{from: "main", to: "dev"}],
|
||||
clearWorkspace: true
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
|
||||
35
CHANGELOG.md
35
CHANGELOG.md
@@ -1,3 +1,38 @@
|
||||
# [0.88.0](https://github.com/revanced/revanced-integrations/compare/v0.87.0...v0.88.0) (2022-12-29)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube:** `hide-breaking-news-shelf` patch ([#258](https://github.com/revanced/revanced-integrations/issues/258)) ([eec90ee](https://github.com/revanced/revanced-integrations/commit/eec90ee04cdfcad08f0448c0f2e860e6eb25294f))
|
||||
|
||||
# [0.88.0-dev.1](https://github.com/revanced/revanced-integrations/compare/v0.87.0...v0.88.0-dev.1) (2022-12-29)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube:** `hide-breaking-news-shelf` patch ([#258](https://github.com/revanced/revanced-integrations/issues/258)) ([eec90ee](https://github.com/revanced/revanced-integrations/commit/eec90ee04cdfcad08f0448c0f2e860e6eb25294f))
|
||||
|
||||
# [0.87.0](https://github.com/revanced/revanced-integrations/compare/v0.86.1...v0.87.0) (2022-12-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/general-ads-patch:** hide guidelines for subscriber ([#249](https://github.com/revanced/revanced-integrations/issues/249)) ([f4e8afe](https://github.com/revanced/revanced-integrations/commit/f4e8afe7ba7c3b516f2a3821918152a55fdd563d))
|
||||
|
||||
## [0.86.1](https://github.com/revanced/revanced-integrations/compare/v0.86.0...v0.86.1) (2022-12-24)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **youtube/theme:** correct background color for the shorts comment box ([#239](https://github.com/revanced/revanced-integrations/issues/239)) ([9ab8a64](https://github.com/revanced/revanced-integrations/commit/9ab8a646ed07d709c46fe7b5dd3238bc23301b8b))
|
||||
|
||||
# [0.86.0](https://github.com/revanced/revanced-integrations/compare/v0.85.1...v0.86.0) (2022-12-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **youtube/return-youtube-dislike:** debug connection statistics, toast on error, high priority background threads ([#236](https://github.com/revanced/revanced-integrations/issues/236)) ([693ef08](https://github.com/revanced/revanced-integrations/commit/693ef08c6c2ebb2a4dde9194583ac77ae3af9fc6))
|
||||
|
||||
## [0.85.1](https://github.com/revanced/revanced-integrations/compare/v0.85.0...v0.85.1) (2022-12-21)
|
||||
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ public final class GeneralAdsPatch extends Filter {
|
||||
public GeneralAdsPatch() {
|
||||
var communityPosts = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_POSTS_REMOVAL, "post_base_wrapper");
|
||||
var communityGuidelines = new BlockRule(SettingsEnum.ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL, "community_guidelines");
|
||||
var subscribersCommunityGuidelines = new BlockRule(SettingsEnum.ADREMOVER_SUBSCRIBERS_COMMUNITY_GUIDELINES_REMOVAL, "sponsorships_comments_upsell");
|
||||
var compactBanner = new BlockRule(SettingsEnum.ADREMOVER_COMPACT_BANNER_REMOVAL, "compact_banner");
|
||||
var inFeedSurvey = new BlockRule(SettingsEnum.ADREMOVER_FEED_SURVEY_REMOVAL, "in_feed_survey");
|
||||
var medicalPanel = new BlockRule(SettingsEnum.ADREMOVER_MEDICAL_PANEL_REMOVAL, "medical_panel");
|
||||
@@ -81,7 +82,8 @@ public final class GeneralAdsPatch extends Filter {
|
||||
infoPanel,
|
||||
channelGuidelines,
|
||||
artistCard,
|
||||
selfSponsor
|
||||
selfSponsor,
|
||||
subscribersCommunityGuidelines
|
||||
);
|
||||
|
||||
var carouselAd = new BlockRule(SettingsEnum.ADREMOVER_GENERAL_ADS_REMOVAL,
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
import app.revanced.integrations.adremover.AdRemoverAPI;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
|
||||
public class HideBreakingNewsPatch {
|
||||
//Used by app.revanced.patches.youtube.layout.homepage.breakingnews.patch.BreakingNewsPatch
|
||||
public static void hideBreakingNews(View view) {
|
||||
if (!SettingsEnum.HIDE_BREAKING_NEWS.getBoolean()) return;
|
||||
AdRemoverAPI.HideViewWithLayout1dp(view);
|
||||
}
|
||||
}
|
||||
@@ -1,34 +1,72 @@
|
||||
package app.revanced.integrations.patches;
|
||||
|
||||
import android.util.Log;
|
||||
import static app.revanced.integrations.utils.ReVancedUtils.getContext;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import app.revanced.integrations.utils.ThemeHelper;
|
||||
|
||||
public class LithoThemePatch {
|
||||
// color constants used in relation with litho components
|
||||
private static final int[] WHITECONSTANTS = {
|
||||
-1, // comments chip background
|
||||
-394759, // music related results panel background
|
||||
-83886081, // video chapters list background
|
||||
private static final int[] WHITE_VALUES = {
|
||||
-1, // comments chip background
|
||||
-394759, // music related results panel background
|
||||
-83886081, // video chapters list background
|
||||
};
|
||||
|
||||
private static final int[] DARKCONSTANTS = {
|
||||
-14145496, // explore drawer background
|
||||
-14606047, // comments chip background
|
||||
-15198184, // music related results panel background
|
||||
-15790321, // comments chip background (new layout)
|
||||
-98492127 // video chapters list background
|
||||
private static final int[] DARK_VALUES = {
|
||||
-14145496, // explore drawer background
|
||||
-14606047, // comments chip background
|
||||
-15198184, // music related results panel background
|
||||
-15790321, // comments chip background (new layout)
|
||||
-98492127 // video chapters list background
|
||||
};
|
||||
|
||||
// background colors
|
||||
private static int whiteColor = 0;
|
||||
private static int blackColor = 0;
|
||||
|
||||
// Used by app.revanced.patches.youtube.layout.theme.patch.LithoThemePatch
|
||||
/**
|
||||
* Change the color of Litho components.
|
||||
* If the color of the component matches one of the values, return the background color .
|
||||
*
|
||||
* @param originalValue The original color value.
|
||||
* @return The new or original color value
|
||||
*/
|
||||
public static int applyLithoTheme(int originalValue) {
|
||||
var isDarkTheme = ThemeHelper.isDarkTheme();
|
||||
|
||||
if ((isDarkTheme && anyEquals(originalValue, DARKCONSTANTS)) || (!isDarkTheme && anyEquals(originalValue, WHITECONSTANTS)))
|
||||
return 0;
|
||||
if (ThemeHelper.isDarkTheme()) {
|
||||
if (anyEquals(originalValue, DARK_VALUES)) return getBlackColor();
|
||||
} else {
|
||||
if (anyEquals(originalValue, WHITE_VALUES)) return getWhiteColor();
|
||||
}
|
||||
return originalValue;
|
||||
}
|
||||
|
||||
private static int getBlackColor() {
|
||||
if (blackColor == 0) blackColor = getColor("yt_black1");
|
||||
return blackColor;
|
||||
}
|
||||
|
||||
private static int getWhiteColor() {
|
||||
if (whiteColor == 0) whiteColor = getColor("yt_white1");
|
||||
return whiteColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the color for a color resource.
|
||||
*
|
||||
* @param name The color resource name.
|
||||
* @return The value of the color.
|
||||
*/
|
||||
private static int getColor(String name) {
|
||||
Context context = getContext();
|
||||
|
||||
return context != null ? context.getColor(context.getResources()
|
||||
.getIdentifier(name, "color", context.getPackageName())
|
||||
) : 0;
|
||||
}
|
||||
|
||||
private static boolean anyEquals(int value, int... of) {
|
||||
for (int v : of) if (value == v) return true;
|
||||
return false;
|
||||
|
||||
@@ -26,28 +26,37 @@ public class Requester {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse, and then disconnect the {@link HttpURLConnection}
|
||||
*
|
||||
* TODO: rename this to #parseJsonAndDisconnect
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*/
|
||||
public static String parseJson(HttpURLConnection connection) throws IOException {
|
||||
String result = parseJson(connection.getInputStream(), false);
|
||||
return parseInputStreamAndClose(connection.getInputStream(), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
|
||||
*
|
||||
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
|
||||
*
|
||||
* @see #parseJson(HttpURLConnection)
|
||||
*/
|
||||
public static String parseJsonAndDisconnect(HttpURLConnection connection) throws IOException {
|
||||
String result = parseJson(connection);
|
||||
connection.disconnect();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse, and then close the {@link InputStream}
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*
|
||||
* TODO: rename this to #parseJsonAndCloseStream
|
||||
* @param stripNewLineCharacters if newline (\n) characters should be stripped from the InputStream
|
||||
*/
|
||||
public static String parseJson(InputStream inputStream, boolean isError) throws IOException {
|
||||
public static String parseInputStreamAndClose(InputStream inputStream, boolean stripNewLineCharacters) throws IOException {
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
|
||||
StringBuilder jsonBuilder = new StringBuilder();
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
jsonBuilder.append(line);
|
||||
if (isError)
|
||||
if (!stripNewLineCharacters)
|
||||
jsonBuilder.append("\n");
|
||||
}
|
||||
return jsonBuilder.toString();
|
||||
@@ -55,34 +64,63 @@ public class Requester {
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse, and then do NOT disconnect the {@link HttpURLConnection}
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*/
|
||||
public static String parseErrorJson(HttpURLConnection connection) throws IOException {
|
||||
// TODO: make this also disconnect, and rename method to #parseErrorJsonAndDisconnect
|
||||
return parseJson(connection.getErrorStream(), true);
|
||||
return parseInputStreamAndClose(connection.getErrorStream(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse, and then disconnect the {@link HttpURLConnection}
|
||||
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
|
||||
*
|
||||
* TODO: rename this to #getJSONObjectAndDisconnect
|
||||
*/
|
||||
public static JSONObject getJSONObject(HttpURLConnection connection) throws JSONException, IOException {
|
||||
return new JSONObject(parseJsonAndDisconnect(connection));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse, and then disconnect the {@link HttpURLConnection}
|
||||
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
|
||||
*
|
||||
* TODO: rename this to #getJSONArrayAndDisconnect
|
||||
* @see #parseErrorJson(HttpURLConnection)
|
||||
*/
|
||||
public static JSONArray getJSONArray(HttpURLConnection connection) throws JSONException, IOException {
|
||||
return new JSONArray(parseJsonAndDisconnect(connection));
|
||||
}
|
||||
|
||||
private static String parseJsonAndDisconnect(HttpURLConnection connection) throws IOException {
|
||||
String json = parseJson(connection);
|
||||
public static String parseErrorJsonAndDisconnect(HttpURLConnection connection) throws IOException {
|
||||
String result = parseErrorJson(connection);
|
||||
connection.disconnect();
|
||||
return json;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*/
|
||||
public static JSONObject parseJSONObject(HttpURLConnection connection) throws JSONException, IOException {
|
||||
return new JSONObject(parseJson(connection));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
|
||||
*
|
||||
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
|
||||
*
|
||||
* @see #parseJSONObject(HttpURLConnection)
|
||||
*/
|
||||
public static JSONObject parseJSONObjectAndDisconnect(HttpURLConnection connection) throws JSONException, IOException {
|
||||
JSONObject object = parseJSONObject(connection);
|
||||
connection.disconnect();
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, and closes the underlying InputStream.
|
||||
*/
|
||||
public static JSONArray parseJSONArray(HttpURLConnection connection) throws JSONException, IOException {
|
||||
return new JSONArray(parseJson(connection));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the {@link HttpURLConnection}, close the underlying InputStream, and disconnect.
|
||||
*
|
||||
* <b>Should only be used if other requests to the server are unlikely in the near future</b>
|
||||
*
|
||||
* @see #parseJSONArray(HttpURLConnection)
|
||||
*/
|
||||
public static JSONArray parseJSONArrayAndDisconnect(HttpURLConnection connection) throws JSONException, IOException {
|
||||
JSONArray array = parseJSONArray(connection);
|
||||
connection.disconnect();
|
||||
return array;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,7 +40,7 @@ public class ReturnYouTubeDislike {
|
||||
*/
|
||||
private static final ExecutorService voteSerialExecutor = Executors.newSingleThreadExecutor();
|
||||
|
||||
// Must be volatile, since non-main threads read this field.
|
||||
// Must be volatile, since this is read/write from different threads
|
||||
private static volatile boolean isEnabled = SettingsEnum.RYD_ENABLED.getBoolean();
|
||||
|
||||
/**
|
||||
@@ -138,11 +138,18 @@ public class ReturnYouTubeDislike {
|
||||
// Have to block the current thread until fetching is done
|
||||
// There's no known way to edit the text after creation yet
|
||||
RYDVoteData votingData;
|
||||
long fetchStartTime = 0;
|
||||
try {
|
||||
votingData = getVoteFetchFuture().get(MILLISECONDS_TO_BLOCK_UI_WHILE_WAITING_FOR_DISLIKE_FETCH_TO_COMPLETE, TimeUnit.MILLISECONDS);
|
||||
Future<RYDVoteData> fetchFuture = getVoteFetchFuture();
|
||||
if (SettingsEnum.DEBUG.getBoolean() && !fetchFuture.isDone()) {
|
||||
fetchStartTime = System.currentTimeMillis();
|
||||
}
|
||||
votingData = fetchFuture.get(MILLISECONDS_TO_BLOCK_UI_WHILE_WAITING_FOR_DISLIKE_FETCH_TO_COMPLETE, TimeUnit.MILLISECONDS);
|
||||
} catch (TimeoutException e) {
|
||||
LogHelper.printDebug(() -> "UI timed out waiting for dislike fetch to complete");
|
||||
return;
|
||||
} finally {
|
||||
recordTimeUISpentWaitingForNetworkCall(fetchStartTime);
|
||||
}
|
||||
if (votingData == null) {
|
||||
LogHelper.printDebug(() -> "Cannot add dislike count to UI (RYD data not available)");
|
||||
@@ -293,4 +300,30 @@ public class ReturnYouTubeDislike {
|
||||
// never will be reached, as the oldest supported YouTube app requires Android N or greater
|
||||
return (int) (100 * dislikePercentage) + "%";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Number of times the UI was forced to wait on a network fetch to complete
|
||||
*/
|
||||
private static volatile int numberOfTimesUIWaitedOnNetworkCalls;
|
||||
|
||||
/**
|
||||
* Total time the UI waited, of all times it was forced to wait.
|
||||
*/
|
||||
private static volatile long totalTimeUIWaitedOnNetworkCalls;
|
||||
|
||||
private static void recordTimeUISpentWaitingForNetworkCall(long timeUIWaitStarted) {
|
||||
if (timeUIWaitStarted == 0 || !SettingsEnum.DEBUG.getBoolean()) {
|
||||
return;
|
||||
}
|
||||
final long timeUIWaitingTotal = System.currentTimeMillis() - timeUIWaitStarted;
|
||||
LogHelper.printDebug(() -> "UI thread waited for: " + timeUIWaitingTotal + "ms for vote fetch to complete");
|
||||
|
||||
totalTimeUIWaitedOnNetworkCalls += timeUIWaitingTotal;
|
||||
numberOfTimesUIWaitedOnNetworkCalls++;
|
||||
final long averageTimeForcedToWait = totalTimeUIWaitedOnNetworkCalls / numberOfTimesUIWaitedOnNetworkCalls;
|
||||
LogHelper.printDebug(() -> "UI thread forced to wait: " + numberOfTimesUIWaitedOnNetworkCalls + " times, "
|
||||
+ "total wait time: " + totalTimeUIWaitedOnNetworkCalls + "ms, "
|
||||
+ "average wait time: " + averageTimeForcedToWait + "ms") ;
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,15 +3,26 @@ package app.revanced.integrations.returnyoutubedislike.requests;
|
||||
import static app.revanced.integrations.requests.Route.Method.GET;
|
||||
import static app.revanced.integrations.requests.Route.Method.POST;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
|
||||
import app.revanced.integrations.requests.Requester;
|
||||
import app.revanced.integrations.requests.Route;
|
||||
|
||||
public class ReturnYouTubeDislikeRoutes {
|
||||
public static final Route SEND_VOTE = new Route(POST, "interact/vote");
|
||||
public static final Route CONFIRM_VOTE = new Route(POST, "interact/confirmVote");
|
||||
public static final Route GET_DISLIKES = new Route(GET, "votes?videoId={video_id}");
|
||||
public static final Route GET_REGISTRATION = new Route(GET, "puzzle/registration?userId={user_id}");
|
||||
public static final Route CONFIRM_REGISTRATION = new Route(POST, "puzzle/registration?userId={user_id}");
|
||||
class ReturnYouTubeDislikeRoutes {
|
||||
static final String RYD_API_URL = "https://returnyoutubedislikeapi.com/";
|
||||
|
||||
static final Route SEND_VOTE = new Route(POST, "interact/vote");
|
||||
static final Route CONFIRM_VOTE = new Route(POST, "interact/confirmVote");
|
||||
static final Route GET_DISLIKES = new Route(GET, "votes?videoId={video_id}");
|
||||
static final Route GET_REGISTRATION = new Route(GET, "puzzle/registration?userId={user_id}");
|
||||
static final Route CONFIRM_REGISTRATION = new Route(POST, "puzzle/registration?userId={user_id}");
|
||||
|
||||
private ReturnYouTubeDislikeRoutes() {
|
||||
}
|
||||
|
||||
static HttpURLConnection getRYDConnectionFromRoute(Route route, String... params) throws IOException {
|
||||
return Requester.getConnectionFromRoute(RYD_API_URL, route, params);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -37,6 +37,7 @@ public enum SettingsEnum {
|
||||
ADREMOVER_FEED_SURVEY_REMOVAL("revanced_adremover_feed_survey", true, ReturnType.BOOLEAN),
|
||||
ADREMOVER_SHORTS_REMOVAL("revanced_adremover_shorts", true, ReturnType.BOOLEAN, true),
|
||||
ADREMOVER_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_community_guidelines", true, ReturnType.BOOLEAN),
|
||||
ADREMOVER_SUBSCRIBERS_COMMUNITY_GUIDELINES_REMOVAL("revanced_adremover_subscribers_community_guidelines_removal", true, ReturnType.BOOLEAN),
|
||||
ADREMOVER_EMERGENCY_BOX_REMOVAL("revanced_adremover_emergency_box_removal", true, ReturnType.BOOLEAN),
|
||||
ADREMOVER_INFO_PANEL_REMOVAL("revanced_adremover_info_panel", true, ReturnType.BOOLEAN),
|
||||
ADREMOVER_MEDICAL_PANEL_REMOVAL("revanced_adremover_medical_panel", true, ReturnType.BOOLEAN),
|
||||
@@ -82,6 +83,7 @@ public enum SettingsEnum {
|
||||
HIDE_SHORTS_COMMENTS_BUTTON("revanced_hide_shorts_comments_button", false, ReturnType.BOOLEAN),
|
||||
HIDE_TIME_AND_SEEKBAR("revanced_hide_time_and_seekbar", false, ReturnType.BOOLEAN),
|
||||
HIDE_WATCH_IN_VR("revanced_hide_watch_in_vr", false, ReturnType.BOOLEAN, true),
|
||||
HIDE_BREAKING_NEWS("revanced_hide_breaking_news", true, ReturnType.BOOLEAN, true),
|
||||
|
||||
// Misc. Settings
|
||||
FIX_PLAYBACK("revanced_fix_playback", false, ReturnType.BOOLEAN, false),
|
||||
|
||||
@@ -13,6 +13,7 @@ import android.preference.PreferenceScreen;
|
||||
import android.preference.SwitchPreference;
|
||||
|
||||
import app.revanced.integrations.returnyoutubedislike.ReturnYouTubeDislike;
|
||||
import app.revanced.integrations.returnyoutubedislike.requests.ReturnYouTubeDislikeApi;
|
||||
import app.revanced.integrations.settings.SettingsEnum;
|
||||
import app.revanced.integrations.utils.SharedPrefHelper;
|
||||
|
||||
@@ -100,6 +101,85 @@ public class ReturnYouTubeDislikeSettingsFragment extends PreferenceFragment {
|
||||
return false;
|
||||
});
|
||||
preferenceScreen.addPreference(aboutWebsitePreference);
|
||||
|
||||
// RYD API connection statistics
|
||||
|
||||
if (SettingsEnum.DEBUG.getBoolean()) {
|
||||
PreferenceCategory emptyCategory = new PreferenceCategory(context); // vertical padding
|
||||
preferenceScreen.addPreference(emptyCategory);
|
||||
|
||||
PreferenceCategory statisticsCategory = new PreferenceCategory(context);
|
||||
statisticsCategory.setTitle(str("revanced_ryd_statistics_category_title"));
|
||||
preferenceScreen.addPreference(statisticsCategory);
|
||||
|
||||
Preference statisticPreference;
|
||||
|
||||
statisticPreference = new Preference(context);
|
||||
statisticPreference.setSelectable(false);
|
||||
statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeAverage_title"));
|
||||
statisticPreference.setSummary(createMillisecondStringFromNumber(ReturnYouTubeDislikeApi.getFetchCallResponseTimeAverage()));
|
||||
preferenceScreen.addPreference(statisticPreference);
|
||||
|
||||
statisticPreference = new Preference(context);
|
||||
statisticPreference.setSelectable(false);
|
||||
statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeMin_title"));
|
||||
statisticPreference.setSummary(createMillisecondStringFromNumber(ReturnYouTubeDislikeApi.getFetchCallResponseTimeMin()));
|
||||
preferenceScreen.addPreference(statisticPreference);
|
||||
|
||||
statisticPreference = new Preference(context);
|
||||
statisticPreference.setSelectable(false);
|
||||
statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeMax_title"));
|
||||
statisticPreference.setSummary(createMillisecondStringFromNumber(ReturnYouTubeDislikeApi.getFetchCallResponseTimeMax()));
|
||||
preferenceScreen.addPreference(statisticPreference);
|
||||
|
||||
String fetchCallTimeWaitingLastSummary;
|
||||
final long fetchCallTimeWaitingLast = ReturnYouTubeDislikeApi.getFetchCallResponseTimeLast();
|
||||
if (fetchCallTimeWaitingLast == ReturnYouTubeDislikeApi.FETCH_CALL_RESPONSE_TIME_VALUE_RATE_LIMIT) {
|
||||
fetchCallTimeWaitingLastSummary = str("revanced_ryd_statistics_getFetchCallResponseTimeLast_rate_limit_summary");
|
||||
} else {
|
||||
fetchCallTimeWaitingLastSummary = createMillisecondStringFromNumber(fetchCallTimeWaitingLast);
|
||||
}
|
||||
statisticPreference = new Preference(context);
|
||||
statisticPreference.setSelectable(false);
|
||||
statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallResponseTimeLast_title"));
|
||||
statisticPreference.setSummary(fetchCallTimeWaitingLastSummary);
|
||||
preferenceScreen.addPreference(statisticPreference);
|
||||
|
||||
statisticPreference = new Preference(context);
|
||||
statisticPreference.setSelectable(false);
|
||||
statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallCount_title"));
|
||||
statisticPreference.setSummary(createSummaryText(ReturnYouTubeDislikeApi.getFetchCallCount(),
|
||||
"revanced_ryd_statistics_getFetchCallCount_zero_summary",
|
||||
"revanced_ryd_statistics_getFetchCallCount_non_zero_summary"));
|
||||
preferenceScreen.addPreference(statisticPreference);
|
||||
|
||||
statisticPreference = new Preference(context);
|
||||
statisticPreference.setSelectable(false);
|
||||
statisticPreference.setTitle(str("revanced_ryd_statistics_getFetchCallNumberOfFailures_title"));
|
||||
statisticPreference.setSummary(createSummaryText(ReturnYouTubeDislikeApi.getFetchCallNumberOfFailures(),
|
||||
"revanced_ryd_statistics_getFetchCallNumberOfFailures_zero_summary",
|
||||
"revanced_ryd_statistics_getFetchCallNumberOfFailures_non_zero_summary"));
|
||||
preferenceScreen.addPreference(statisticPreference);
|
||||
|
||||
statisticPreference = new Preference(context);
|
||||
statisticPreference.setSelectable(false);
|
||||
statisticPreference.setTitle(str("revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_title"));
|
||||
statisticPreference.setSummary(createSummaryText(ReturnYouTubeDislikeApi.getNumberOfRateLimitRequestsEncountered(),
|
||||
"revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_zero_summary",
|
||||
"revanced_ryd_statistics_getNumberOfRateLimitRequestsEncountered_non_zero_summary"));
|
||||
preferenceScreen.addPreference(statisticPreference);
|
||||
}
|
||||
}
|
||||
|
||||
private String createSummaryText(int value, String summaryStringZeroKey, String summaryStringOneOrMoreKey) {
|
||||
if (value == 0) {
|
||||
return str(summaryStringZeroKey);
|
||||
}
|
||||
return String.format(str(summaryStringOneOrMoreKey), value);
|
||||
}
|
||||
|
||||
private static String createMillisecondStringFromNumber(long number) {
|
||||
return String.format(str("revanced_ryd_statistics_millisecond_text"), number);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -46,7 +46,11 @@ public class SBRequester {
|
||||
runVipCheck();
|
||||
|
||||
if (responseCode == 200) {
|
||||
JSONArray responseArray = Requester.getJSONArray(connection);
|
||||
// FIXME? should this use Requester#getJSONArray and not disconnect?
|
||||
// HTTPURLConnection#disconnect says:
|
||||
// disconnect if other requests to the server
|
||||
// are unlikely in the near future.
|
||||
JSONArray responseArray = Requester.parseJSONArrayAndDisconnect(connection);
|
||||
int length = responseArray.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
JSONObject obj = (JSONObject) responseArray.get(i);
|
||||
@@ -96,13 +100,13 @@ public class SBRequester {
|
||||
SponsorBlockUtils.messageToToast = str("submit_failed_duplicate");
|
||||
break;
|
||||
case 403:
|
||||
SponsorBlockUtils.messageToToast = str("submit_failed_forbidden", Requester.parseErrorJson(connection));
|
||||
SponsorBlockUtils.messageToToast = str("submit_failed_forbidden", Requester.parseErrorJsonAndDisconnect(connection));
|
||||
break;
|
||||
case 429:
|
||||
SponsorBlockUtils.messageToToast = str("submit_failed_rate_limit");
|
||||
break;
|
||||
case 400:
|
||||
SponsorBlockUtils.messageToToast = str("submit_failed_invalid", Requester.parseErrorJson(connection));
|
||||
SponsorBlockUtils.messageToToast = str("submit_failed_invalid", Requester.parseErrorJsonAndDisconnect(connection));
|
||||
break;
|
||||
default:
|
||||
SponsorBlockUtils.messageToToast = str("submit_failed_unknown_error", responseCode, connection.getResponseMessage());
|
||||
@@ -143,7 +147,7 @@ public class SBRequester {
|
||||
SponsorBlockUtils.messageToToast = str("vote_succeeded");
|
||||
break;
|
||||
case 403:
|
||||
SponsorBlockUtils.messageToToast = str("vote_failed_forbidden", Requester.parseErrorJson(connection));
|
||||
SponsorBlockUtils.messageToToast = str("vote_failed_forbidden", Requester.parseErrorJsonAndDisconnect(connection));
|
||||
break;
|
||||
default:
|
||||
SponsorBlockUtils.messageToToast = str("vote_failed_unknown_error", responseCode, connection.getResponseMessage());
|
||||
@@ -220,6 +224,6 @@ public class SBRequester {
|
||||
}
|
||||
|
||||
private static JSONObject getJSONObject(Route route, String... params) throws Exception {
|
||||
return Requester.getJSONObject(getConnectionFromRoute(route, params));
|
||||
return Requester.parseJSONObjectAndDisconnect(getConnectionFromRoute(route, params));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,16 +53,18 @@ public class LogHelper {
|
||||
*/
|
||||
public static void printDebug(LogMessage message) {
|
||||
if (SettingsEnum.DEBUG.getBoolean()) {
|
||||
var log = new StringBuilder(message.buildMessageString());
|
||||
var messageString = message.buildMessageString();
|
||||
|
||||
if (SettingsEnum.DEBUG_STACKTRACE.getBoolean()) {
|
||||
var builder = new StringBuilder(messageString);
|
||||
var sw = new StringWriter();
|
||||
new Throwable().printStackTrace(new PrintWriter(sw));
|
||||
|
||||
log.append(String.format("\n%s", sw));
|
||||
builder.append(String.format("\n%s", sw));
|
||||
messageString = builder.toString();
|
||||
}
|
||||
|
||||
Log.d("revanced: " + message.findOuterClassSimpleName(), log.toString());
|
||||
Log.d("revanced: " + message.findOuterClassSimpleName(), messageString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import android.os.Looper;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.Future;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -32,13 +33,22 @@ public class ReVancedUtils {
|
||||
|
||||
/**
|
||||
* General purpose pool for network calls and other background tasks.
|
||||
* All tasks run at max thread priority.
|
||||
*/
|
||||
private static final ThreadPoolExecutor backgroundThreadPool = new ThreadPoolExecutor(
|
||||
2, // minimum 2 threads always ready to be used
|
||||
1, // minimum 1 thread always ready to be used
|
||||
10, // For any threads over the minimum, keep them alive 10 seconds after they go idle
|
||||
SHARED_THREAD_POOL_MAXIMUM_BACKGROUND_THREADS,
|
||||
TimeUnit.SECONDS,
|
||||
new LinkedBlockingQueue<Runnable>());
|
||||
new LinkedBlockingQueue<Runnable>(),
|
||||
new ThreadFactory() {
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t = new Thread(r);
|
||||
t.setPriority(Thread.MAX_PRIORITY); // run at max priority
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
||||
private static void checkIfPoolHasReachedLimit() {
|
||||
if (backgroundThreadPool.getActiveCount() >= SHARED_THREAD_POOL_MAXIMUM_BACKGROUND_THREADS) {
|
||||
@@ -54,13 +64,14 @@ public class ReVancedUtils {
|
||||
}
|
||||
|
||||
public static void runOnBackgroundThread(Runnable task) {
|
||||
checkIfPoolHasReachedLimit();
|
||||
backgroundThreadPool.execute(task);
|
||||
checkIfPoolHasReachedLimit();
|
||||
}
|
||||
|
||||
public static <T> Future<T> submitOnBackgroundThread(Callable<T> call) {
|
||||
Future<T> future = backgroundThreadPool.submit(call);
|
||||
checkIfPoolHasReachedLimit();
|
||||
return backgroundThreadPool.submit(call);
|
||||
return future;
|
||||
}
|
||||
|
||||
public static boolean containsAny(final String value, final String... targets) {
|
||||
@@ -114,8 +125,18 @@ public class ReVancedUtils {
|
||||
return context.getResources().getConfiguration().smallestScreenWidthDp >= 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically logs any exceptions the runnable throws
|
||||
*/
|
||||
public static void runOnMainThread(Runnable runnable) {
|
||||
new Handler(Looper.getMainLooper()).post(runnable);
|
||||
Runnable exceptLoggingRunnable = () -> {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Exception ex) {
|
||||
LogHelper.printException(() -> "Exception on main thread from runnable: " + runnable.toString(), ex);
|
||||
}
|
||||
};
|
||||
new Handler(Looper.getMainLooper()).post(exceptLoggingRunnable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -109,16 +109,19 @@ public class DownloadButton {
|
||||
|
||||
isShowing = z;
|
||||
ImageView imageView = _button.get();
|
||||
if (_constraintLayout != null && imageView != null) {
|
||||
if (z && isDownloadButtonEnabled) {
|
||||
LogHelper.printDebug(() -> "Fading in");
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
imageView.startAnimation(fadeIn);
|
||||
} else if (imageView.getVisibility() == View.VISIBLE) {
|
||||
LogHelper.printDebug(() -> "Fading out");
|
||||
imageView.startAnimation(fadeOut);
|
||||
imageView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (_constraintLayout == null || imageView == null)
|
||||
return;
|
||||
|
||||
if (z && isDownloadButtonEnabled) {
|
||||
LogHelper.printDebug(() -> "Fading in");
|
||||
imageView.setVisibility(View.VISIBLE);
|
||||
imageView.startAnimation(fadeIn);
|
||||
}
|
||||
else if (imageView.getVisibility() == View.VISIBLE) {
|
||||
LogHelper.printDebug(() -> "Fading out");
|
||||
imageView.startAnimation(fadeOut);
|
||||
imageView.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
org.gradle.jvmargs = -Xmx2048m
|
||||
android.useAndroidX = true
|
||||
version = 0.85.1
|
||||
version = 0.88.0
|
||||
|
||||
Reference in New Issue
Block a user