From c13100c27cbcec73499b58a9ecbc3e446f9ac77b Mon Sep 17 00:00:00 2001 From: bomiva <76726737+bomiva@users.noreply.github.com> Date: Tue, 29 Dec 2020 03:09:01 -0500 Subject: [PATCH 01/56] Add that it is available on other platforms --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c5e342c8..9d7fa4bd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -177,7 +177,7 @@ Don\'t do anything About This app uses the API from Sponsor Block - Tap to learn more at: sponsor.ajay.app + Tap to learn more, and see downloads for other platforms at: sponsor.ajay.app Integration made by JakubWeg Tap to skip From 88a90d6617f7dad5ee35f3bdff47f5fd51833b16 Mon Sep 17 00:00:00 2001 From: KevinX8 Date: Sun, 4 Apr 2021 20:18:39 +0100 Subject: [PATCH 02/56] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 92c0190b..25002675 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # SponsorBlock YouTube Vanced Implementation -In order to use this in YouTube/Vanced you must first apply the smali mods outlined in smali.md (if you mod vanced directly it is not required) +In order to use this in YouTube/Vanced you must first apply the smali mods applied to vanced (the patching process used for this is currently automated using our closed source tools with no plans to open source it for the time being) (if you mod vanced directly it is not required) * First make your edits in android studio and then compile the code to a debug apk * Decompile this apk using apktool https://github.com/iBotPeaches/Apktool * Take this decompiled folder and look for a folder labeled pl in one of your dex class folders (usually the second one) From 9cdc1ed857ad06b2c5143e3094d298035ed8f263 Mon Sep 17 00:00:00 2001 From: caneleex Date: Wed, 7 Apr 2021 09:35:59 +0200 Subject: [PATCH 03/56] fix a bug where the Skip count tracking option wouldn't change --- app/src/main/java/pl/jakubweg/SponsorBlockSettings.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 27b1939f..1aaf2b25 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -122,6 +122,7 @@ public class SponsorBlockSettings { if (tmp1 != null) adjustNewSegmentMillis = Integer.parseInt(tmp1); + countSkips = preferences.getBoolean(PREFERENCES_KEY_COUNT_SKIPS, countSkips); uuid = preferences.getString(PREFERENCES_KEY_UUID, null); if (uuid == null) { From 3276433d7a0ea43e4bce8a460e34230aff58bf1f Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 16 Apr 2021 19:46:10 +0200 Subject: [PATCH 04/56] fix field access in setSponsorBarReact --- app/src/main/java/pl/jakubweg/PlayerController.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 4019d456..995a7d8c 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -13,6 +13,7 @@ import android.view.ViewGroup; import android.widget.Toast; import java.lang.ref.WeakReference; +import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Timer; @@ -305,7 +306,9 @@ public class PlayerController { public static void setSponsorBarRect(final Object self) { try { - Rect rect = ((Rect) self.getClass().getField("e").get(self)); + Field field = self.getClass().getDeclaredField("e"); + field.setAccessible(true); + Rect rect = (Rect) field.get(self); if (rect != null) { setSponsorBarAbsoluteLeft(rect.left); setSponsorBarAbsoluteRight(rect.right); From d0caaaeacc3641eeffca10443743b0bfff925c0d Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Apr 2021 23:26:16 +0200 Subject: [PATCH 05/56] rename YouTubeApplication --- ...ication.java => YouTubeTikTokRoot_Application.java} | 2 +- .../youtube/sponsors/player/ui/SponsorBlockView.java | 8 ++++---- app/src/main/java/pl/jakubweg/ShieldButton.java | 10 +++++----- app/src/main/java/pl/jakubweg/SkipSegmentView.java | 7 ++----- 4 files changed, 12 insertions(+), 15 deletions(-) rename app/src/main/java/com/google/android/apps/youtube/app/{YouTubeApplication.java => YouTubeTikTokRoot_Application.java} (81%) diff --git a/app/src/main/java/com/google/android/apps/youtube/app/YouTubeApplication.java b/app/src/main/java/com/google/android/apps/youtube/app/YouTubeTikTokRoot_Application.java similarity index 81% rename from app/src/main/java/com/google/android/apps/youtube/app/YouTubeApplication.java rename to app/src/main/java/com/google/android/apps/youtube/app/YouTubeTikTokRoot_Application.java index ef8400e4..2c321f2a 100644 --- a/app/src/main/java/com/google/android/apps/youtube/app/YouTubeApplication.java +++ b/app/src/main/java/com/google/android/apps/youtube/app/YouTubeTikTokRoot_Application.java @@ -4,7 +4,7 @@ import android.app.Application; import android.content.Context; import android.os.Bundle; -public class YouTubeApplication extends Application { +public class YouTubeTikTokRoot_Application extends Application { protected void onCreate(final Bundle bundle) { super.onCreate(); } diff --git a/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SponsorBlockView.java b/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SponsorBlockView.java index af1d011f..86e2c932 100644 --- a/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SponsorBlockView.java +++ b/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SponsorBlockView.java @@ -7,7 +7,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.RelativeLayout; -import com.google.android.apps.youtube.app.YouTubeApplication; +import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; import java.lang.ref.WeakReference; @@ -69,9 +69,9 @@ public class SponsorBlockView { } private static void addView() { - inlineSponsorOverlay = new RelativeLayout(YouTubeApplication.getAppContext()); + inlineSponsorOverlay = new RelativeLayout(YouTubeTikTokRoot_Application.getAppContext()); setLayoutParams(inlineSponsorOverlay); - LayoutInflater.from(YouTubeApplication.getAppContext()).inflate(getIdentifier("inline_sponsor_overlay", "layout"), inlineSponsorOverlay); + LayoutInflater.from(YouTubeTikTokRoot_Application.getAppContext()).inflate(getIdentifier("inline_sponsor_overlay", "layout"), inlineSponsorOverlay); _youtubeOverlaysLayout.addView(inlineSponsorOverlay, _youtubeOverlaysLayout.getChildCount() - 2); @@ -151,7 +151,7 @@ public class SponsorBlockView { } private static int getIdentifier(String name, String defType) { - Context context = YouTubeApplication.getAppContext(); + Context context = YouTubeTikTokRoot_Application.getAppContext(); return context.getResources().getIdentifier(name, defType, context.getPackageName()); } } diff --git a/app/src/main/java/pl/jakubweg/ShieldButton.java b/app/src/main/java/pl/jakubweg/ShieldButton.java index fb9e7c3f..eeadc584 100644 --- a/app/src/main/java/pl/jakubweg/ShieldButton.java +++ b/app/src/main/java/pl/jakubweg/ShieldButton.java @@ -9,7 +9,7 @@ import android.view.animation.AnimationUtils; import android.widget.ImageView; import android.widget.RelativeLayout; -import com.google.android.apps.youtube.app.YouTubeApplication; +import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; import java.lang.ref.WeakReference; @@ -103,7 +103,7 @@ public class ShieldButton { } private static void initButtonVisibilitySettings() { - Context context = YouTubeApplication.getAppContext(); + Context context = YouTubeTikTokRoot_Application.getAppContext(); if(context == null){ Log.e(TAG, "context is null"); SponsorBlockSettings.isSponsorBlockEnabled = false; @@ -118,16 +118,16 @@ public class ShieldButton { //region Helpers private static int getIdentifier(String name, String defType) { - Context context = YouTubeApplication.getAppContext(); + Context context = YouTubeTikTokRoot_Application.getAppContext(); return context.getResources().getIdentifier(name, defType, context.getPackageName()); } private static int getInteger(String name) { - return YouTubeApplication.getAppContext().getResources().getInteger(getIdentifier(name, "integer")); + return YouTubeTikTokRoot_Application.getAppContext().getResources().getInteger(getIdentifier(name, "integer")); } private static Animation getAnimation(String name) { - return AnimationUtils.loadAnimation(YouTubeApplication.getAppContext(), getIdentifier(name, "anim")); + return AnimationUtils.loadAnimation(YouTubeTikTokRoot_Application.getAppContext(), getIdentifier(name, "anim")); } //endregion } diff --git a/app/src/main/java/pl/jakubweg/SkipSegmentView.java b/app/src/main/java/pl/jakubweg/SkipSegmentView.java index cd1a891b..5e2a485e 100644 --- a/app/src/main/java/pl/jakubweg/SkipSegmentView.java +++ b/app/src/main/java/pl/jakubweg/SkipSegmentView.java @@ -6,14 +6,11 @@ import android.util.DisplayMetrics; import android.util.Log; import android.widget.Toast; -import com.google.android.apps.youtube.app.YouTubeApplication; - -import java.lang.ref.WeakReference; +import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; import static fi.vanced.libraries.youtube.sponsors.player.ui.SponsorBlockView.hideSkipButton; import static fi.vanced.libraries.youtube.sponsors.player.ui.SponsorBlockView.showSkipButton; import static pl.jakubweg.PlayerController.VERBOSE; -import static pl.jakubweg.StringRef.str; @SuppressLint({"RtlHardcoded", "SetTextI18n", "LongLogTag", "AppCompatCustomView"}) public class SkipSegmentView { @@ -36,7 +33,7 @@ public class SkipSegmentView { } lastNotifiedSegment = segment; String skipMessage = segment.category.skipMessage.toString(); - Context context = YouTubeApplication.getAppContext(); + Context context = YouTubeTikTokRoot_Application.getAppContext(); if (VERBOSE) Log.d(TAG, String.format("notifySkipped; message=%s", skipMessage)); From 40cf6058260a0180546c29afb8a768b9f22501b1 Mon Sep 17 00:00:00 2001 From: caneleex Date: Wed, 21 Apr 2021 19:56:30 +0200 Subject: [PATCH 06/56] remove thread check from PlayerController.setCurrentVideoId --- app/src/main/java/pl/jakubweg/PlayerController.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 4019d456..eb5ad8f3 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -65,9 +65,6 @@ public class PlayerController { return; } - if (Looper.myLooper() != Looper.getMainLooper()) // check if thread is not main - return; - if (videoId.equals(currentVideoId)) return; From e22146a8e38dc9a69a266efbcd6c2a55987310eb Mon Sep 17 00:00:00 2001 From: caneleex Date: Wed, 21 Apr 2021 22:55:40 +0200 Subject: [PATCH 07/56] remove unused imports --- app/src/main/java/pl/jakubweg/PlayerController.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index eb5ad8f3..157053f3 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -2,7 +2,6 @@ package pl.jakubweg; import android.annotation.SuppressLint; import android.app.Activity; -import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; import android.os.Handler; @@ -10,7 +9,6 @@ import android.os.Looper; import android.util.Log; import android.view.View; import android.view.ViewGroup; -import android.widget.Toast; import java.lang.ref.WeakReference; import java.lang.reflect.Method; From 03f6e496b9de13def155a5fd8e153bad8bdde381 Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 22 Apr 2021 18:43:14 +0200 Subject: [PATCH 08/56] add support for voting --- .../SponsorBlockPreferenceFragment.java | 14 +- .../pl/jakubweg/SponsorBlockSettings.java | 26 ++- .../java/pl/jakubweg/SponsorBlockUtils.java | 156 +++++++++++++++++- .../main/java/pl/jakubweg/VotingButton.java | 133 +++++++++++++++ app/src/main/res/drawable/ic_sb_voting.xml | 5 + app/src/main/res/values/strings.xml | 12 ++ 6 files changed, 331 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/pl/jakubweg/VotingButton.java create mode 100644 app/src/main/res/drawable/ic_sb_voting.xml diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index 595e001d..8e44e38b 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -18,7 +18,6 @@ import android.preference.SwitchPreference; import android.text.InputType; import android.widget.Toast; -import java.io.File; import java.util.ArrayList; import static pl.jakubweg.SponsorBlockSettings.DefaultBehaviour; @@ -28,10 +27,10 @@ import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_NEW_SEGMENT_ENABL import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_SHOW_TOAST_WHEN_SKIP; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_SPONSOR_BLOCK_ENABLED; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_UUID; +import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_VOTING_ENABLED; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_NAME; import static pl.jakubweg.SponsorBlockSettings.adjustNewSegmentMillis; import static pl.jakubweg.SponsorBlockSettings.countSkips; -import static pl.jakubweg.SponsorBlockSettings.getPreferences; import static pl.jakubweg.SponsorBlockSettings.setSeenGuidelines; import static pl.jakubweg.SponsorBlockSettings.showToastWhenSkippedAutomatically; import static pl.jakubweg.SponsorBlockSettings.uuid; @@ -104,6 +103,17 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement }); } + { + SwitchPreference preference = new SwitchPreference(context); + preferenceScreen.addPreference(preference); + preference.setTitle(str("enable_voting")); + preference.setSummary(str("enable_voting_sum")); + preference.setKey(PREFERENCES_KEY_VOTING_ENABLED); + preference.setDefaultValue(SponsorBlockSettings.isVotingEnabled); + preference.setChecked(SponsorBlockSettings.isVotingEnabled); + preferencesToDisableWhenSBDisabled.add(preference); + } + addGeneralCategory(context, preferenceScreen); addSegmentsCategory(context, preferenceScreen); addAboutCategory(context, preferenceScreen); diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 1aaf2b25..91c47e1d 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -7,7 +7,6 @@ import android.text.Html; import android.text.TextUtils; import android.util.Log; -import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -25,8 +24,10 @@ public class SponsorBlockSettings { public static final String PREFERENCES_KEY_SPONSOR_BLOCK_ENABLED = "sb-enabled"; public static final String PREFERENCES_KEY_SEEN_GUIDELINES = "sb-seen-gl"; public static final String PREFERENCES_KEY_NEW_SEGMENT_ENABLED = "sb-new-segment-enabled"; + public static final String PREFERENCES_KEY_VOTING_ENABLED = "sb-voting-enabled"; public static final String sponsorBlockSkipSegmentsUrl = "https://sponsor.ajay.app/api/skipSegments"; public static final String sponsorBlockViewedUrl = "https://sponsor.ajay.app/api/viewedVideoSponsorTime"; + public static final String sponsorBlockVoteUrl = "https://sponsor.ajay.app/api/voteOnSponsorTime"; public static final SegmentBehaviour DefaultBehaviour = SegmentBehaviour.SkipAutomatically; @@ -34,6 +35,7 @@ public class SponsorBlockSettings { public static boolean isSponsorBlockEnabled = false; public static boolean seenGuidelinesPopup = false; public static boolean isAddNewSegmentEnabled = false; + public static boolean isVotingEnabled = true; public static boolean showToastWhenSkippedAutomatically = true; public static boolean countSkips = true; public static int adjustNewSegmentMillis = 150; @@ -54,6 +56,14 @@ public class SponsorBlockSettings { return sponsorBlockViewedUrl + "?UUID=" + UUID; } + public static String getSponsorBlockVoteUrl(String uuid, String userId, int type) { + return sponsorBlockVoteUrl + "?UUID=" + uuid + "&userID=" + userId + "&type=" + type; + } + + public static String getSponsorBlockVoteUrl(String uuid, String userId, String category) { + return sponsorBlockVoteUrl + "?UUID=" + uuid + "&userID=" + userId + "&category=" + category; + } + public static SharedPreferences getPreferences(Context context) { return context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE); } @@ -73,20 +83,26 @@ public class SponsorBlockSettings { if (!isSponsorBlockEnabled) { SkipSegmentView.hide(); NewSegmentHelperLayout.hide(); - SponsorBlockUtils.hideButton(); + SponsorBlockUtils.hideShieldButton(); PlayerController.sponsorSegmentsOfCurrentVideo = null; } else if (/*isAddNewSegmentEnabled*/false) { - SponsorBlockUtils.showButton(); + SponsorBlockUtils.showShieldButton(); } isAddNewSegmentEnabled = preferences.getBoolean(PREFERENCES_KEY_NEW_SEGMENT_ENABLED, isAddNewSegmentEnabled); if (!/*isAddNewSegmentEnabled*/false) { NewSegmentHelperLayout.hide(); - SponsorBlockUtils.hideButton(); + SponsorBlockUtils.hideShieldButton(); } else { - SponsorBlockUtils.showButton(); + SponsorBlockUtils.showShieldButton(); } + isVotingEnabled = preferences.getBoolean(PREFERENCES_KEY_VOTING_ENABLED, isVotingEnabled); + if (!isVotingEnabled) + SponsorBlockUtils.hideVoteButton(); + else + SponsorBlockUtils.showVoteButton(); + SegmentBehaviour[] possibleBehaviours = SegmentBehaviour.values(); final ArrayList enabledCategories = new ArrayList<>(possibleBehaviours.length); for (SegmentInfo segment : SegmentInfo.valuesWithoutPreview()) { diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index fea969bf..84d89bb4 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -6,6 +6,8 @@ import android.content.Context; import android.content.DialogInterface; import android.os.Handler; import android.os.Looper; +import android.text.Html; +import android.text.Spanned; import android.util.Log; import android.view.View; import android.widget.EditText; @@ -37,7 +39,9 @@ import static pl.jakubweg.PlayerController.VERBOSE; import static pl.jakubweg.PlayerController.getCurrentVideoId; import static pl.jakubweg.PlayerController.getLastKnownVideoTime; import static pl.jakubweg.PlayerController.sponsorSegmentsOfCurrentVideo; +import static pl.jakubweg.SponsorBlockSettings.getSponsorBlockVoteUrl; import static pl.jakubweg.SponsorBlockSettings.sponsorBlockSkipSegmentsUrl; +import static pl.jakubweg.SponsorBlockSettings.uuid; import static pl.jakubweg.StringRef.str; @SuppressWarnings({"LongLogTag"}) @@ -56,6 +60,15 @@ public abstract class SponsorBlockUtils { NewSegmentHelperLayout.toggle(); } }; + public static final View.OnClickListener voteButtonListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + if (debug) { + Log.d(TAG, "Vote button clicked"); + } + SponsorBlockUtils.onVotingClicked(v.getContext()); + } + }; private static int shareBtnId = -1; private static long newSponsorSegmentDialogShownMillis; private static long newSponsorSegmentStartMillis = -1; @@ -145,8 +158,10 @@ public abstract class SponsorBlockUtils { new Thread(submitRunnable).start(); } }; - private static boolean isShown = false; + private static boolean isShieldShown = false; + private static boolean isVoteShown = false; private static WeakReference sponsorBlockBtn = new WeakReference<>(null); + private static WeakReference votingBtn = new WeakReference<>(null); private static String messageToToast = ""; private static EditByHandSaveDialogListener editByHandSaveDialogListener = new EditByHandSaveDialogListener(); private static final DialogInterface.OnClickListener editByHandDialogListener = new DialogInterface.OnClickListener() { @@ -180,6 +195,36 @@ public abstract class SponsorBlockUtils { dialog.dismiss(); } }; + private static final DialogInterface.OnClickListener segmentVoteClickListener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + final Context context = ((AlertDialog) dialog).getContext(); + final SponsorSegment segment = sponsorSegmentsOfCurrentVideo[which]; + + new AlertDialog.Builder(context) // negative and positive are switched for more intuitive order + .setNegativeButton(str("vote_upvote"), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Toast.makeText(context, str("vote_started"), Toast.LENGTH_SHORT).show(); + voteForSegment(segment, true, null); + } + }) + .setPositiveButton(str("vote_downvote"), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + Toast.makeText(context, str("vote_started"), Toast.LENGTH_SHORT).show(); + voteForSegment(segment, false, null); + } + }) + .setNeutralButton(str("vote_category"), new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + onNewCategorySelect(segment, context); + } + }) + .show(); + } + }; private static Runnable toastRunnable = new Runnable() { @Override public void run() { @@ -250,9 +295,9 @@ public abstract class SponsorBlockUtils { private SponsorBlockUtils() { } - public static void showButton() { - if (isShown) return; - isShown = true; + public static void showShieldButton() { + if (isShieldShown) return; + isShieldShown = true; View i = sponsorBlockBtn.get(); if (i == null) return; i.setVisibility(VISIBLE); @@ -261,14 +306,33 @@ public abstract class SponsorBlockUtils { i.invalidate(); } - public static void hideButton() { - if (!isShown) return; - isShown = false; + public static void hideShieldButton() { + if (!isShieldShown) return; + isShieldShown = false; View i = sponsorBlockBtn.get(); if (i != null) i.setVisibility(GONE); } + public static void showVoteButton() { + if (isVoteShown) return; + isVoteShown = true; + View i = votingBtn.get(); + if (i == null) return; + i.setVisibility(VISIBLE); + i.bringToFront(); + i.requestLayout(); + i.invalidate(); + } + + public static void hideVoteButton() { + if (!isVoteShown) return; + isVoteShown = false; + View i = votingBtn.get(); + if (i != null) + i.setVisibility(GONE); + } + @SuppressLint("DefaultLocale") public static void onMarkLocationClicked(Context context) { newSponsorSegmentDialogShownMillis = PlayerController.getLastKnownVideoTime(); @@ -305,6 +369,43 @@ public abstract class SponsorBlockUtils { } } + public static void onVotingClicked(final Context context) { + if (sponsorSegmentsOfCurrentVideo == null || sponsorSegmentsOfCurrentVideo.length == 0) // prevent crashing or empty dialog + return; + CharSequence[] titles = new CharSequence[sponsorSegmentsOfCurrentVideo.length]; + for (int i = 0; i < sponsorSegmentsOfCurrentVideo.length; i++) { + SponsorSegment segment = sponsorSegmentsOfCurrentVideo[i]; + + String start = dateFormatter.format(new Date(segment.start)); + String end = dateFormatter.format(new Date(segment.end)); + Spanned html = Html.fromHtml(String.format(" %s
%s to %s", + segment.category.color, segment.category.title, start, end)); + titles[i] = html; + } + + new AlertDialog.Builder(context) + .setItems(titles, segmentVoteClickListener) + .show(); + } + + private static void onNewCategorySelect(final SponsorSegment segment, Context context) { + final SponsorBlockSettings.SegmentInfo[] values = SponsorBlockSettings.SegmentInfo.valuesWithoutPreview(); + CharSequence[] titles = new CharSequence[values.length]; + for (int i = 0; i < values.length; i++) { + titles[i] = values[i].getTitleWithDot(); + } + + new AlertDialog.Builder(context) + .setTitle(str("new_segment_choose_category")) + .setItems(titles, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + voteForSegment(segment, false, values[which].key); + } + }) + .show(); + } + @SuppressLint("DefaultLocale") public static void onPreviewClicked(Context context) { if (newSponsorSegmentStartMillis >= 0 && newSponsorSegmentStartMillis < newSponsorSegmentEndMillis) { @@ -416,7 +517,46 @@ public abstract class SponsorBlockUtils { HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); - connection.getInputStream().close(); + connection.disconnect(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void voteForSegment(SponsorSegment segment, boolean upvote, String category) { + messageToToast = null; + try { + String voteUrl = category == null + ? getSponsorBlockVoteUrl(segment.UUID, uuid, upvote ? 1 : 0) + : getSponsorBlockVoteUrl(segment.UUID, uuid, category); + URL url = new URL(voteUrl); + + Log.d("sponsorblock", "requesting: " + url.getPath()); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + + switch (connection.getResponseCode()) { + default: + messageToToast = String.format(str("vote_failed_unknown_error"), connection.getResponseCode(), connection.getResponseMessage()); + break; + case 429: + messageToToast = str("vote_failed_rate_limit"); + break; + case 403: + messageToToast = str("vote_failed_forbidden"); + break; + case 409: + messageToToast = str("vote_failed_duplicate"); + break; + case 200: + messageToToast = str("vote_succeeded"); + break; + } + + Log.i(TAG, "Voted for segment with status: " + connection.getResponseCode() + ", " + messageToToast); + new Handler(Looper.getMainLooper()).post(toastRunnable); + connection.disconnect(); } catch (IOException e) { e.printStackTrace(); diff --git a/app/src/main/java/pl/jakubweg/VotingButton.java b/app/src/main/java/pl/jakubweg/VotingButton.java new file mode 100644 index 00000000..1b87eeb1 --- /dev/null +++ b/app/src/main/java/pl/jakubweg/VotingButton.java @@ -0,0 +1,133 @@ +package pl.jakubweg; + +import android.content.Context; +import android.content.SharedPreferences; +import android.util.Log; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.ImageView; +import android.widget.RelativeLayout; + +import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; + +import java.lang.ref.WeakReference; + +import static fi.razerman.youtube.XGlobals.debug; + +public class VotingButton { + static String TAG = "VOTING"; + static RelativeLayout _youtubeControlsLayout; + static WeakReference _votingButton = new WeakReference<>(null); + static int fadeDurationFast; + static int fadeDurationScheduled; + static Animation fadeIn; + static Animation fadeOut; + static boolean isShowing; + + public static void initialize(Object viewStub) { + try { + if(debug){ + Log.d(TAG, "initializing voting button"); + } + + _youtubeControlsLayout = (RelativeLayout) viewStub; + initButtonVisibilitySettings(); + + ImageView imageView = (ImageView)_youtubeControlsLayout + .findViewById(getIdentifier("voting_button", "id")); + + if (debug && imageView == null){ + Log.d(TAG, "Couldn't find imageView with tag \"voting_button\""); + } + if (imageView == null) return; + imageView.setOnClickListener(SponsorBlockUtils.voteButtonListener); + _votingButton = new WeakReference<>(imageView); + + // Animations + fadeDurationFast = getInteger("fade_duration_fast"); + fadeDurationScheduled = getInteger("fade_duration_scheduled"); + fadeIn = getAnimation("fade_in"); + fadeIn.setDuration(fadeDurationFast); + fadeOut = getAnimation("fade_out"); + fadeOut.setDuration(fadeDurationScheduled); + isShowing = true; + changeVisibilityImmediate(false); + } + catch (Exception ex) { + Log.e(TAG, "Unable to set RelativeLayout", ex); + } + } + + public static void changeVisibilityImmediate(boolean visible) { + changeVisibility(visible, true); + } + + public static void changeVisibilityNegatedImmediate(boolean visible) { + changeVisibility(!visible, true); + } + + public static void changeVisibility(boolean visible) { + changeVisibility(visible, false); + } + + public static void changeVisibility(boolean visible, boolean immediate) { + if (isShowing == visible) return; + isShowing = visible; + + ImageView iView = _votingButton.get(); + if (_youtubeControlsLayout == null || iView == null) return; + + if (visible && shouldBeShown()) { + if (debug) { + Log.d(TAG, "Fading in"); + } + iView.setVisibility(View.VISIBLE); + if (!immediate) + iView.startAnimation(fadeIn); + return; + } + + if (iView.getVisibility() == View.VISIBLE) { + if (debug) { + Log.d(TAG, "Fading out"); + } + if (!immediate) + iView.startAnimation(fadeOut); + iView.setVisibility(shouldBeShown() ? View.INVISIBLE : View.GONE); + } + } + + private static boolean shouldBeShown() { + return SponsorBlockSettings.isVotingEnabled && SponsorBlockSettings.isSponsorBlockEnabled; + } + + private static void initButtonVisibilitySettings() { + Context context = YouTubeTikTokRoot_Application.getAppContext(); + if(context == null){ + Log.e(TAG, "context is null"); + SponsorBlockSettings.isSponsorBlockEnabled = false; + SponsorBlockSettings.isVotingEnabled = false; + return; + } + + SharedPreferences sharedPreferences = context.getSharedPreferences(SponsorBlockSettings.PREFERENCES_NAME, Context.MODE_PRIVATE); + SponsorBlockSettings.isSponsorBlockEnabled = sharedPreferences.getBoolean(SponsorBlockSettings.PREFERENCES_KEY_SPONSOR_BLOCK_ENABLED, false); + SponsorBlockSettings.isVotingEnabled = sharedPreferences.getBoolean(SponsorBlockSettings.PREFERENCES_KEY_VOTING_ENABLED, false); + } + + //region Helpers + private static int getIdentifier(String name, String defType) { + Context context = YouTubeTikTokRoot_Application.getAppContext(); + return context.getResources().getIdentifier(name, defType, context.getPackageName()); + } + + private static int getInteger(String name) { + return YouTubeTikTokRoot_Application.getAppContext().getResources().getInteger(getIdentifier(name, "integer")); + } + + private static Animation getAnimation(String name) { + return AnimationUtils.loadAnimation(YouTubeTikTokRoot_Application.getAppContext(), getIdentifier(name, "anim")); + } + //endregion +} diff --git a/app/src/main/res/drawable/ic_sb_voting.xml b/app/src/main/res/drawable/ic_sb_voting.xml new file mode 100644 index 00000000..61638035 --- /dev/null +++ b/app/src/main/res/drawable/ic_sb_voting.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9d7fa4bd..e7ca3cf8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -143,6 +143,8 @@ Switch this on for very cool sponsor segments skipping Enable new segment adding Switch this on to enable experimental segment adding (has button visibility issues). + Enable voting + Switch this on to enable voting. What to do with different segments General Show a toast when skipping segment automatically @@ -188,6 +190,16 @@ Segment submitted successfully Submitting segment… + Unable to vote for segment: Status: %d %s + Can\'t vote for segment.\nRate Limited (Too many from the same user or IP) + Can\'t vote for segment.\nA moderator has decided that this segment is correct + Can\'t vote for segment.\nDuplicate + Voted successfully + Voting for segment… + Upvote + Downvote + Change category + Choose the segment category You\'ve disabled this category in the settings, enable it to be able to submit New Sponsor Block segment From f4808a977865e9510e74fc97a763b35c198356a8 Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 22 Apr 2021 20:19:00 +0200 Subject: [PATCH 09/56] change vote buttons to items --- .../java/pl/jakubweg/SponsorBlockUtils.java | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 84d89bb4..5756f424 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -201,25 +201,30 @@ public abstract class SponsorBlockUtils { final Context context = ((AlertDialog) dialog).getContext(); final SponsorSegment segment = sponsorSegmentsOfCurrentVideo[which]; - new AlertDialog.Builder(context) // negative and positive are switched for more intuitive order - .setNegativeButton(str("vote_upvote"), new DialogInterface.OnClickListener() { + final VoteOption[] voteOptions = VoteOption.values(); + String[] items = new String[voteOptions.length]; + + for (int i = 0; i < voteOptions.length; i++) { + items[i] = voteOptions[i].title; + } + + new AlertDialog.Builder(context) + .setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - Toast.makeText(context, str("vote_started"), Toast.LENGTH_SHORT).show(); - voteForSegment(segment, true, null); - } - }) - .setPositiveButton(str("vote_downvote"), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - Toast.makeText(context, str("vote_started"), Toast.LENGTH_SHORT).show(); - voteForSegment(segment, false, null); - } - }) - .setNeutralButton(str("vote_category"), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - onNewCategorySelect(segment, context); + switch (voteOptions[which]) { + case UPVOTE: + Toast.makeText(context, str("vote_started"), Toast.LENGTH_SHORT).show(); + voteForSegment(segment, true, null); + break; + case DOWNVOTE: + Toast.makeText(context, str("vote_started"), Toast.LENGTH_SHORT).show(); + voteForSegment(segment, false, null); + break; + case CATEGORY_CHANGE: + onNewCategorySelect(segment, context); + break; + } } }) .show(); @@ -563,6 +568,18 @@ public abstract class SponsorBlockUtils { } } + private enum VoteOption { + UPVOTE(str("vote_upvote")), + DOWNVOTE(str("vote_downvote")), + CATEGORY_CHANGE(str("vote_category")); + + public final String title; + + VoteOption(String title) { + this.title = title; + } + } + private static class EditByHandSaveDialogListener implements DialogInterface.OnClickListener { public boolean settingStart; public WeakReference editText; From c87b38330a3786d85472b66d27a2b7dfa3f5bbc4 Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 22 Apr 2021 21:13:39 +0200 Subject: [PATCH 10/56] fix black boxes in toasts --- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 5756f424..a3da7d87 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -212,19 +212,21 @@ public abstract class SponsorBlockUtils { .setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + Context con = context.getApplicationContext(); switch (voteOptions[which]) { case UPVOTE: - Toast.makeText(context, str("vote_started"), Toast.LENGTH_SHORT).show(); + Toast.makeText(con, str("vote_started"), Toast.LENGTH_SHORT).show(); voteForSegment(segment, true, null); break; case DOWNVOTE: - Toast.makeText(context, str("vote_started"), Toast.LENGTH_SHORT).show(); + Toast.makeText(con, str("vote_started"), Toast.LENGTH_SHORT).show(); voteForSegment(segment, false, null); break; case CATEGORY_CHANGE: - onNewCategorySelect(segment, context); + onNewCategorySelect(segment, con); break; } + appContext = new WeakReference<>(con); } }) .show(); @@ -370,7 +372,7 @@ public abstract class SponsorBlockUtils { .setPositiveButton(android.R.string.yes, segmentReadyDialogButtonListener) .show(); } else { - Toast.makeText(context, "Mark two locations on the time bar first", Toast.LENGTH_SHORT).show(); + Toast.makeText(context, str("new_segment_mark_locations_first"), Toast.LENGTH_SHORT).show(); } } From 2edb665b8b126e64f16df8aba5b4813861ef7543 Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 22 Apr 2021 21:17:15 +0200 Subject: [PATCH 11/56] fix change category crash --- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index a3da7d87..737830a8 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -223,7 +223,7 @@ public abstract class SponsorBlockUtils { voteForSegment(segment, false, null); break; case CATEGORY_CHANGE: - onNewCategorySelect(segment, con); + onNewCategorySelect(segment, context); break; } appContext = new WeakReference<>(con); From 0ec120a0237b9c173ae67f998388594e802fa02d Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 23 Apr 2021 18:14:23 +0200 Subject: [PATCH 12/56] duplicate code is never returned --- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 3 --- app/src/main/res/values/strings.xml | 1 - 2 files changed, 4 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 737830a8..04ebf0ce 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -553,9 +553,6 @@ public abstract class SponsorBlockUtils { case 403: messageToToast = str("vote_failed_forbidden"); break; - case 409: - messageToToast = str("vote_failed_duplicate"); - break; case 200: messageToToast = str("vote_succeeded"); break; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e7ca3cf8..a3484f16 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -193,7 +193,6 @@ Unable to vote for segment: Status: %d %s Can\'t vote for segment.\nRate Limited (Too many from the same user or IP) Can\'t vote for segment.\nA moderator has decided that this segment is correct - Can\'t vote for segment.\nDuplicate Voted successfully Voting for segment… Upvote From 25bc38af8759812f0145700d9beb8ae0f71debe2 Mon Sep 17 00:00:00 2001 From: caneleex Date: Sat, 24 Apr 2021 14:20:57 +0200 Subject: [PATCH 13/56] use options rather than boolean --- .../java/pl/jakubweg/SponsorBlockUtils.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 04ebf0ce..6be97cca 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -212,21 +212,18 @@ public abstract class SponsorBlockUtils { .setItems(items, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - Context con = context.getApplicationContext(); + appContext = new WeakReference<>(context.getApplicationContext()); switch (voteOptions[which]) { case UPVOTE: - Toast.makeText(con, str("vote_started"), Toast.LENGTH_SHORT).show(); - voteForSegment(segment, true, null); + voteForSegment(segment, VoteOption.UPVOTE); break; case DOWNVOTE: - Toast.makeText(con, str("vote_started"), Toast.LENGTH_SHORT).show(); - voteForSegment(segment, false, null); + voteForSegment(segment, VoteOption.DOWNVOTE); break; case CATEGORY_CHANGE: onNewCategorySelect(segment, context); break; } - appContext = new WeakReference<>(con); } }) .show(); @@ -407,7 +404,7 @@ public abstract class SponsorBlockUtils { .setItems(titles, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - voteForSegment(segment, false, values[which].key); + voteForSegment(segment, VoteOption.CATEGORY_CHANGE, values[which].key); } }) .show(); @@ -530,14 +527,15 @@ public abstract class SponsorBlockUtils { } } - public static void voteForSegment(SponsorSegment segment, boolean upvote, String category) { + public static void voteForSegment(SponsorSegment segment, VoteOption voteOption, String... args) { messageToToast = null; try { - String voteUrl = category == null - ? getSponsorBlockVoteUrl(segment.UUID, uuid, upvote ? 1 : 0) - : getSponsorBlockVoteUrl(segment.UUID, uuid, category); + String voteUrl = voteOption == VoteOption.CATEGORY_CHANGE + ? getSponsorBlockVoteUrl(segment.UUID, uuid, args[0]) + : getSponsorBlockVoteUrl(segment.UUID, uuid, voteOption == VoteOption.UPVOTE ? 1 : 0); URL url = new URL(voteUrl); + Toast.makeText(appContext.get(), str("vote_started"), Toast.LENGTH_SHORT).show(); Log.d("sponsorblock", "requesting: " + url.getPath()); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); From 80697320caea746db9dafb0716cbe809d02f9891 Mon Sep 17 00:00:00 2001 From: caneleex Date: Sun, 25 Apr 2021 15:20:31 +0200 Subject: [PATCH 14/56] add toast when voting while no segments are present --- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 4 +++- app/src/main/res/values/strings.xml | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 6be97cca..cfc4cfba 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -374,8 +374,10 @@ public abstract class SponsorBlockUtils { } public static void onVotingClicked(final Context context) { - if (sponsorSegmentsOfCurrentVideo == null || sponsorSegmentsOfCurrentVideo.length == 0) // prevent crashing or empty dialog + if (sponsorSegmentsOfCurrentVideo == null || sponsorSegmentsOfCurrentVideo.length == 0) { + Toast.makeText(context.getApplicationContext(), str("vote_no_segments"), Toast.LENGTH_SHORT).show(); return; + } CharSequence[] titles = new CharSequence[sponsorSegmentsOfCurrentVideo.length]; for (int i = 0; i < sponsorSegmentsOfCurrentVideo.length; i++) { SponsorSegment segment = sponsorSegmentsOfCurrentVideo[i]; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a3484f16..05b7a056 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -198,6 +198,7 @@ Upvote Downvote Change category + There are no segments to vote for Choose the segment category You\'ve disabled this category in the settings, enable it to be able to submit From d92c73f9f34bc14d9fa90f9e013afcd645ad7956 Mon Sep 17 00:00:00 2001 From: caneleex Date: Sun, 25 Apr 2021 16:32:35 +0200 Subject: [PATCH 15/56] add spacing to the voting ui --- .../main/java/pl/jakubweg/SponsorBlockUtils.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index cfc4cfba..6029f367 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -7,7 +7,6 @@ import android.content.DialogInterface; import android.os.Handler; import android.os.Looper; import android.text.Html; -import android.text.Spanned; import android.util.Log; import android.view.View; import android.widget.EditText; @@ -378,15 +377,19 @@ public abstract class SponsorBlockUtils { Toast.makeText(context.getApplicationContext(), str("vote_no_segments"), Toast.LENGTH_SHORT).show(); return; } - CharSequence[] titles = new CharSequence[sponsorSegmentsOfCurrentVideo.length]; - for (int i = 0; i < sponsorSegmentsOfCurrentVideo.length; i++) { + int segmentAmount = sponsorSegmentsOfCurrentVideo.length; + CharSequence[] titles = new CharSequence[segmentAmount]; + for (int i = 0; i < segmentAmount; i++) { SponsorSegment segment = sponsorSegmentsOfCurrentVideo[i]; String start = dateFormatter.format(new Date(segment.start)); String end = dateFormatter.format(new Date(segment.end)); - Spanned html = Html.fromHtml(String.format(" %s
%s to %s", + StringBuilder htmlBuilder = new StringBuilder(); + htmlBuilder.append(String.format(" %s
%s to %s", segment.category.color, segment.category.title, start, end)); - titles[i] = html; + if (i + 1 != segmentAmount) // prevents trailing new line after last segment + htmlBuilder.append("
"); + titles[i] = Html.fromHtml(htmlBuilder.toString()); } new AlertDialog.Builder(context) From ad7bdf0fb8f61f322f0fedb233d123f748682289 Mon Sep 17 00:00:00 2001 From: caneleex Date: Wed, 28 Apr 2021 22:39:23 +0200 Subject: [PATCH 16/56] fix SB and voting buttons overlapping YouTube icons --- .../java/pl/jakubweg/PlayerController.java | 12 +++++++++- .../main/java/pl/jakubweg/ShieldButton.java | 5 +++++ .../java/pl/jakubweg/SponsorBlockUtils.java | 22 +++++-------------- .../main/java/pl/jakubweg/VotingButton.java | 5 +++++ 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 74ca9cc6..ac613de9 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -95,7 +95,7 @@ public class PlayerController { Log.i(TAG, String.format("onCreate called with object %s on thread %s", o.toString(), Thread.currentThread().toString())); try { - setMillisecondMethod = o.getClass().getMethod("replaceMeWithsetMillisecondMethod", Long.TYPE); + setMillisecondMethod = o.getClass().getMethod("t", Long.TYPE); setMillisecondMethod.setAccessible(true); lastKnownVideoTime = 0; @@ -198,6 +198,12 @@ public class PlayerController { if (millis <= 0) return; //findAndSkipSegment(false); + if (millis == currentVideoLength) { + SponsorBlockUtils.hideShieldButton(); + SponsorBlockUtils.hideVoteButton(); + return; + } + SponsorSegment[] segments = sponsorSegmentsOfCurrentVideo; if (segments == null || segments.length == 0) return; @@ -274,6 +280,10 @@ public class PlayerController { setCurrentVideoTime(millis); } + public static long getCurrentVideoLength() { + return currentVideoLength; + } + public static long getLastKnownVideoTime() { return lastKnownVideoTime; } diff --git a/app/src/main/java/pl/jakubweg/ShieldButton.java b/app/src/main/java/pl/jakubweg/ShieldButton.java index eeadc584..34a703d2 100644 --- a/app/src/main/java/pl/jakubweg/ShieldButton.java +++ b/app/src/main/java/pl/jakubweg/ShieldButton.java @@ -14,6 +14,8 @@ import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; import java.lang.ref.WeakReference; import static fi.razerman.youtube.XGlobals.debug; +import static pl.jakubweg.PlayerController.getCurrentVideoLength; +import static pl.jakubweg.PlayerController.getLastKnownVideoTime; public class ShieldButton { static String TAG = "SHIELD"; @@ -79,6 +81,9 @@ public class ShieldButton { if (_youtubeControlsLayout == null || iView == null) return; if (visible && shouldBeShown()) { + if (getLastKnownVideoTime() == getCurrentVideoLength()) { + return; + } if (debug) { Log.d(TAG, "Fading in"); } diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 6be97cca..990387c8 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -158,10 +158,6 @@ public abstract class SponsorBlockUtils { new Thread(submitRunnable).start(); } }; - private static boolean isShieldShown = false; - private static boolean isVoteShown = false; - private static WeakReference sponsorBlockBtn = new WeakReference<>(null); - private static WeakReference votingBtn = new WeakReference<>(null); private static String messageToToast = ""; private static EditByHandSaveDialogListener editByHandSaveDialogListener = new EditByHandSaveDialogListener(); private static final DialogInterface.OnClickListener editByHandDialogListener = new DialogInterface.OnClickListener() { @@ -300,9 +296,7 @@ public abstract class SponsorBlockUtils { } public static void showShieldButton() { - if (isShieldShown) return; - isShieldShown = true; - View i = sponsorBlockBtn.get(); + View i = ShieldButton._shieldBtn.get(); if (i == null) return; i.setVisibility(VISIBLE); i.bringToFront(); @@ -311,17 +305,13 @@ public abstract class SponsorBlockUtils { } public static void hideShieldButton() { - if (!isShieldShown) return; - isShieldShown = false; - View i = sponsorBlockBtn.get(); + View i = ShieldButton._shieldBtn.get(); if (i != null) i.setVisibility(GONE); } public static void showVoteButton() { - if (isVoteShown) return; - isVoteShown = true; - View i = votingBtn.get(); + View i = VotingButton._votingButton.get(); if (i == null) return; i.setVisibility(VISIBLE); i.bringToFront(); @@ -330,9 +320,7 @@ public abstract class SponsorBlockUtils { } public static void hideVoteButton() { - if (!isVoteShown) return; - isVoteShown = false; - View i = votingBtn.get(); + View i = VotingButton._votingButton.get(); if (i != null) i.setVisibility(GONE); } @@ -445,7 +433,7 @@ public abstract class SponsorBlockUtils { if (v.getId() != shareBtnId || !/*SponsorBlockSettings.isAddNewSegmentEnabled*/false) return; // if (VERBOSE) // Log.d(TAG, "VISIBILITY CHANGED of view " + v); - ImageView sponsorBtn = sponsorBlockBtn.get(); + ImageView sponsorBtn = ShieldButton._shieldBtn.get(); if (sponsorBtn != null) { sponsorBtn.setVisibility(v.getVisibility()); } diff --git a/app/src/main/java/pl/jakubweg/VotingButton.java b/app/src/main/java/pl/jakubweg/VotingButton.java index 1b87eeb1..9795d158 100644 --- a/app/src/main/java/pl/jakubweg/VotingButton.java +++ b/app/src/main/java/pl/jakubweg/VotingButton.java @@ -14,6 +14,8 @@ import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; import java.lang.ref.WeakReference; import static fi.razerman.youtube.XGlobals.debug; +import static pl.jakubweg.PlayerController.getCurrentVideoLength; +import static pl.jakubweg.PlayerController.getLastKnownVideoTime; public class VotingButton { static String TAG = "VOTING"; @@ -79,6 +81,9 @@ public class VotingButton { if (_youtubeControlsLayout == null || iView == null) return; if (visible && shouldBeShown()) { + if (getLastKnownVideoTime() == getCurrentVideoLength()) { + return; + } if (debug) { Log.d(TAG, "Fading in"); } From 23182e928edea54d8d100d9ccd8ac63752409255 Mon Sep 17 00:00:00 2001 From: caneleex Date: Wed, 28 Apr 2021 22:40:39 +0200 Subject: [PATCH 17/56] remove testing change --- app/src/main/java/pl/jakubweg/PlayerController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index ac613de9..0cb79823 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -95,7 +95,7 @@ public class PlayerController { Log.i(TAG, String.format("onCreate called with object %s on thread %s", o.toString(), Thread.currentThread().toString())); try { - setMillisecondMethod = o.getClass().getMethod("t", Long.TYPE); + setMillisecondMethod = o.getClass().getMethod("replaceMeWithsetMillisecondMethod", Long.TYPE); setMillisecondMethod.setAccessible(true); lastKnownVideoTime = 0; From 087b80cf8eb2ee21c3c398ee35900068882ba311 Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 29 Apr 2021 12:35:01 +0200 Subject: [PATCH 18/56] fix another issue with buttons --- app/src/main/java/pl/jakubweg/ShieldButton.java | 2 +- app/src/main/java/pl/jakubweg/VotingButton.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/ShieldButton.java b/app/src/main/java/pl/jakubweg/ShieldButton.java index 34a703d2..b2774c3b 100644 --- a/app/src/main/java/pl/jakubweg/ShieldButton.java +++ b/app/src/main/java/pl/jakubweg/ShieldButton.java @@ -81,7 +81,7 @@ public class ShieldButton { if (_youtubeControlsLayout == null || iView == null) return; if (visible && shouldBeShown()) { - if (getLastKnownVideoTime() == getCurrentVideoLength()) { + if (getLastKnownVideoTime() >= getCurrentVideoLength()) { return; } if (debug) { diff --git a/app/src/main/java/pl/jakubweg/VotingButton.java b/app/src/main/java/pl/jakubweg/VotingButton.java index 9795d158..215b49c7 100644 --- a/app/src/main/java/pl/jakubweg/VotingButton.java +++ b/app/src/main/java/pl/jakubweg/VotingButton.java @@ -81,7 +81,7 @@ public class VotingButton { if (_youtubeControlsLayout == null || iView == null) return; if (visible && shouldBeShown()) { - if (getLastKnownVideoTime() == getCurrentVideoLength()) { + if (getLastKnownVideoTime() >= getCurrentVideoLength()) { return; } if (debug) { From 234edac030f69a356dd95ab8e37cd9c95f00e923 Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 29 Apr 2021 15:03:23 +0200 Subject: [PATCH 19/56] fix a lot of unintended button behaviors --- .../main/java/pl/jakubweg/PlayerController.java | 3 +++ app/src/main/java/pl/jakubweg/ShieldButton.java | 2 +- .../java/pl/jakubweg/SponsorBlockSettings.java | 14 ++++++-------- .../main/java/pl/jakubweg/SponsorBlockUtils.java | 4 ++-- app/src/main/java/pl/jakubweg/VotingButton.java | 2 +- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 0cb79823..93de59d6 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -204,6 +204,9 @@ public class PlayerController { return; } + SponsorBlockUtils.showShieldButton(); // skipping from end to the video will show the buttons again + SponsorBlockUtils.showVoteButton(); + SponsorSegment[] segments = sponsorSegmentsOfCurrentVideo; if (segments == null || segments.length == 0) return; diff --git a/app/src/main/java/pl/jakubweg/ShieldButton.java b/app/src/main/java/pl/jakubweg/ShieldButton.java index b2774c3b..670174c7 100644 --- a/app/src/main/java/pl/jakubweg/ShieldButton.java +++ b/app/src/main/java/pl/jakubweg/ShieldButton.java @@ -103,7 +103,7 @@ public class ShieldButton { } } - private static boolean shouldBeShown() { + static boolean shouldBeShown() { return SponsorBlockSettings.isSponsorBlockEnabled && SponsorBlockSettings.isAddNewSegmentEnabled; } diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 91c47e1d..d9630afe 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -83,25 +83,23 @@ public class SponsorBlockSettings { if (!isSponsorBlockEnabled) { SkipSegmentView.hide(); NewSegmentHelperLayout.hide(); - SponsorBlockUtils.hideShieldButton(); + ShieldButton.changeVisibilityImmediate(false); + VotingButton.changeVisibilityImmediate(false); PlayerController.sponsorSegmentsOfCurrentVideo = null; } else if (/*isAddNewSegmentEnabled*/false) { SponsorBlockUtils.showShieldButton(); } isAddNewSegmentEnabled = preferences.getBoolean(PREFERENCES_KEY_NEW_SEGMENT_ENABLED, isAddNewSegmentEnabled); - if (!/*isAddNewSegmentEnabled*/false) { + if (!isAddNewSegmentEnabled) { NewSegmentHelperLayout.hide(); - SponsorBlockUtils.hideShieldButton(); + ShieldButton.changeVisibilityImmediate(false); } else { - SponsorBlockUtils.showShieldButton(); + ShieldButton.changeVisibilityImmediate(true); } isVotingEnabled = preferences.getBoolean(PREFERENCES_KEY_VOTING_ENABLED, isVotingEnabled); - if (!isVotingEnabled) - SponsorBlockUtils.hideVoteButton(); - else - SponsorBlockUtils.showVoteButton(); + VotingButton.changeVisibilityImmediate(isVotingEnabled); SegmentBehaviour[] possibleBehaviours = SegmentBehaviour.values(); final ArrayList enabledCategories = new ArrayList<>(possibleBehaviours.length); diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 6e1c8d56..d79fa6c9 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -296,7 +296,7 @@ public abstract class SponsorBlockUtils { public static void showShieldButton() { View i = ShieldButton._shieldBtn.get(); - if (i == null) return; + if (i == null || i.isShown() || !ShieldButton.shouldBeShown()) return; i.setVisibility(VISIBLE); i.bringToFront(); i.requestLayout(); @@ -311,7 +311,7 @@ public abstract class SponsorBlockUtils { public static void showVoteButton() { View i = VotingButton._votingButton.get(); - if (i == null) return; + if (i == null || i.isShown() || !VotingButton.shouldBeShown()) return; i.setVisibility(VISIBLE); i.bringToFront(); i.requestLayout(); diff --git a/app/src/main/java/pl/jakubweg/VotingButton.java b/app/src/main/java/pl/jakubweg/VotingButton.java index 215b49c7..b0bd09e6 100644 --- a/app/src/main/java/pl/jakubweg/VotingButton.java +++ b/app/src/main/java/pl/jakubweg/VotingButton.java @@ -103,7 +103,7 @@ public class VotingButton { } } - private static boolean shouldBeShown() { + static boolean shouldBeShown() { return SponsorBlockSettings.isVotingEnabled && SponsorBlockSettings.isSponsorBlockEnabled; } From bf6c9e7b2899eea1a9d3c1048d1462013a2af964 Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 29 Apr 2021 22:47:40 +0200 Subject: [PATCH 20/56] fix more issues with buttons i don't even know anymore --- app/src/main/java/pl/jakubweg/PlayerController.java | 7 ++++--- .../main/java/pl/jakubweg/SponsorBlockSettings.java | 13 ++++++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 93de59d6..d20efc5d 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -204,9 +204,6 @@ public class PlayerController { return; } - SponsorBlockUtils.showShieldButton(); // skipping from end to the video will show the buttons again - SponsorBlockUtils.showVoteButton(); - SponsorSegment[] segments = sponsorSegmentsOfCurrentVideo; if (segments == null || segments.length == 0) return; @@ -275,6 +272,10 @@ public class PlayerController { * Called very high frequency (once every about 100ms), also in background. It sometimes triggers when a video is paused (couple times in the row with the same value) */ public static void setCurrentVideoTimeHighPrecision(final long millis) { + if ((millis < lastKnownVideoTime && lastKnownVideoTime >= currentVideoLength) || millis == 0) { + SponsorBlockUtils.showShieldButton(); // skipping from end to the video will show the buttons again + SponsorBlockUtils.showVoteButton(); + } if (lastKnownVideoTime > 0) { lastKnownVideoTime = millis; VideoInformation.lastKnownVideoTime = lastKnownVideoTime; diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index d9630afe..12821f00 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -83,8 +83,8 @@ public class SponsorBlockSettings { if (!isSponsorBlockEnabled) { SkipSegmentView.hide(); NewSegmentHelperLayout.hide(); - ShieldButton.changeVisibilityImmediate(false); - VotingButton.changeVisibilityImmediate(false); + SponsorBlockUtils.hideShieldButton(); + SponsorBlockUtils.hideVoteButton(); PlayerController.sponsorSegmentsOfCurrentVideo = null; } else if (/*isAddNewSegmentEnabled*/false) { SponsorBlockUtils.showShieldButton(); @@ -93,13 +93,16 @@ public class SponsorBlockSettings { isAddNewSegmentEnabled = preferences.getBoolean(PREFERENCES_KEY_NEW_SEGMENT_ENABLED, isAddNewSegmentEnabled); if (!isAddNewSegmentEnabled) { NewSegmentHelperLayout.hide(); - ShieldButton.changeVisibilityImmediate(false); + SponsorBlockUtils.hideShieldButton(); } else { - ShieldButton.changeVisibilityImmediate(true); + SponsorBlockUtils.showShieldButton(); } isVotingEnabled = preferences.getBoolean(PREFERENCES_KEY_VOTING_ENABLED, isVotingEnabled); - VotingButton.changeVisibilityImmediate(isVotingEnabled); + if (!isVotingEnabled) + SponsorBlockUtils.hideVoteButton(); + else + SponsorBlockUtils.showVoteButton(); SegmentBehaviour[] possibleBehaviours = SegmentBehaviour.values(); final ArrayList enabledCategories = new ArrayList<>(possibleBehaviours.length); From 1ffb7872c043467d309401613c1461dca4d2f2de Mon Sep 17 00:00:00 2001 From: caneleex Date: Thu, 29 Apr 2021 23:05:23 +0200 Subject: [PATCH 21/56] remove unnecessary check --- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index d79fa6c9..41e73be8 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -296,7 +296,7 @@ public abstract class SponsorBlockUtils { public static void showShieldButton() { View i = ShieldButton._shieldBtn.get(); - if (i == null || i.isShown() || !ShieldButton.shouldBeShown()) return; + if (i == null || !ShieldButton.shouldBeShown()) return; i.setVisibility(VISIBLE); i.bringToFront(); i.requestLayout(); @@ -311,7 +311,7 @@ public abstract class SponsorBlockUtils { public static void showVoteButton() { View i = VotingButton._votingButton.get(); - if (i == null || i.isShown() || !VotingButton.shouldBeShown()) return; + if (i == null || !VotingButton.shouldBeShown()) return; i.setVisibility(VISIBLE); i.bringToFront(); i.requestLayout(); From 3460237c0f5449d989985d4099ee06a58a383a6f Mon Sep 17 00:00:00 2001 From: Oizaro <75915943+Oizaro@users.noreply.github.com> Date: Tue, 8 Jun 2021 18:25:01 +0200 Subject: [PATCH 22/56] Fixes (#34) * General improvements - Fixed preferences not obtained properly. - Cleaned up libraries and code. - Update deps. * Update README.md --- README.md | 10 ++++++---- app/build.gradle | 17 ++++++++--------- app/src/main/AndroidManifest.xml | 8 -------- .../main/java/pl/jakubweg/InjectedPlugin.java | 1 - .../main/java/pl/jakubweg/PlayerController.java | 10 ++++++++++ app/src/main/java/pl/jakubweg/ShieldButton.java | 15 --------------- .../SponsorBlockPreferenceFragment.java | 3 ++- .../java/pl/jakubweg/SponsorBlockSettings.java | 2 +- .../java/pl/jakubweg/SponsorBlockUtils.java | 1 - .../main/java/pl/jakubweg/SponsorSegment.java | 1 - app/src/main/java/pl/jakubweg/VotingButton.java | 15 --------------- build.gradle | 2 +- gradle/wrapper/gradle-wrapper.properties | 6 +++--- 13 files changed, 31 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 25002675..46097319 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,10 @@ # SponsorBlock YouTube Vanced Implementation In order to use this in YouTube/Vanced you must first apply the smali mods applied to vanced (the patching process used for this is currently automated using our closed source tools with no plans to open source it for the time being) (if you mod vanced directly it is not required) -* First make your edits in android studio and then compile the code to a debug apk +* First make your edits in android studio +* Change the string "replaceMeWithsetMillisecondMethod" on PlayerController.java to the method name of YouTube package +* Compile debug apk * Decompile this apk using apktool https://github.com/iBotPeaches/Apktool -* Take this decompiled folder and look for a folder labeled pl in one of your dex class folders (usually the second one) -* Decompile YouTube/Vanced using apktool (you only need to decompile the base apk files(for vanced you can get these using vanced manager and looking in android/data/com.vanced.manager for black or dark.apk), if you are decompiling stock youtube you must also merge a dpi split into it (todo)) -* Copy the pl folder from earlier into the 4th dex class folder (remove any existing one completely first) +* Take this decompiled folder and look for a folder labeled pl in one of your dex class folders +* Decompile YouTube/Vanced using apktool (you only need to decompile the base apk files (for vanced you can get these using vanced manager and looking in android/data/com.vanced.manager for black or dark.apk), if you are decompiling stock youtube you must also merge a dpi split into it (todo)) +* Copy the pl folder from earlier into the dex class folder (remove any existing one completely first) * Recompile your modded YouTube/Vanced using apktool and sign it + all splits required for your device using the same key diff --git a/app/build.gradle b/app/build.gradle index f6eb4abc..a08ece6e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 30 - buildToolsVersion "30.0.1" + buildToolsVersion "30.0.2" defaultConfig { applicationId "pl.jakubweg" @@ -10,8 +10,7 @@ android { targetSdkVersion 30 versionCode 1 versionName "1.0" - - testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + multiDexEnabled false } buildTypes { @@ -20,13 +19,13 @@ android { proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } } dependencies { - implementation fileTree(dir: "libs", include: ["*.jar"]) - implementation 'androidx.appcompat:appcompat:1.2.0' - testImplementation 'junit:junit:4.12' - androidTestImplementation 'androidx.test.ext:junit:1.1.1' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + implementation 'androidx.annotation:annotation:1.2.0' +} -} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 80c110cd..430ba65c 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,12 +1,4 @@ - - - \ No newline at end of file diff --git a/app/src/main/java/pl/jakubweg/InjectedPlugin.java b/app/src/main/java/pl/jakubweg/InjectedPlugin.java index 021038f6..bc6519a7 100644 --- a/app/src/main/java/pl/jakubweg/InjectedPlugin.java +++ b/app/src/main/java/pl/jakubweg/InjectedPlugin.java @@ -92,7 +92,6 @@ public class InjectedPlugin { Log.i(TAG, spacesStr + "Normal view: " + view); } } - } diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index d20efc5d..c06d0e58 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -2,6 +2,7 @@ package pl.jakubweg; import android.annotation.SuppressLint; import android.app.Activity; +import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; import android.os.Handler; @@ -10,6 +11,8 @@ import android.util.Log; import android.view.View; import android.view.ViewGroup; +import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; + import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -59,6 +62,13 @@ public class PlayerController { VideoInformation.currentVideoId = videoId; + Context context = YouTubeTikTokRoot_Application.getAppContext(); + if(context == null){ + Log.e(TAG, "context is null"); + return; + } + SponsorBlockSettings.update(context); + if (!SponsorBlockSettings.isSponsorBlockEnabled) { currentVideoId = null; return; diff --git a/app/src/main/java/pl/jakubweg/ShieldButton.java b/app/src/main/java/pl/jakubweg/ShieldButton.java index 670174c7..0acaf4f3 100644 --- a/app/src/main/java/pl/jakubweg/ShieldButton.java +++ b/app/src/main/java/pl/jakubweg/ShieldButton.java @@ -34,7 +34,6 @@ public class ShieldButton { } _youtubeControlsLayout = (RelativeLayout) viewStub; - initButtonVisibilitySettings(); ImageView imageView = (ImageView)_youtubeControlsLayout .findViewById(getIdentifier("sponsorblock_button", "id")); @@ -107,20 +106,6 @@ public class ShieldButton { return SponsorBlockSettings.isSponsorBlockEnabled && SponsorBlockSettings.isAddNewSegmentEnabled; } - private static void initButtonVisibilitySettings() { - Context context = YouTubeTikTokRoot_Application.getAppContext(); - if(context == null){ - Log.e(TAG, "context is null"); - SponsorBlockSettings.isSponsorBlockEnabled = false; - SponsorBlockSettings.isAddNewSegmentEnabled = false; - return; - } - - SharedPreferences sharedPreferences = context.getSharedPreferences(SponsorBlockSettings.PREFERENCES_NAME, Context.MODE_PRIVATE); - SponsorBlockSettings.isSponsorBlockEnabled = sharedPreferences.getBoolean(SponsorBlockSettings.PREFERENCES_KEY_SPONSOR_BLOCK_ENABLED, false); - SponsorBlockSettings.isAddNewSegmentEnabled = sharedPreferences.getBoolean(SponsorBlockSettings.PREFERENCES_KEY_NEW_SEGMENT_ENABLED, false); - } - //region Helpers private static int getIdentifier(String name, String defType) { Context context = YouTubeTikTokRoot_Application.getAppContext(); diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index 8e44e38b..e29c651b 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -36,7 +36,6 @@ import static pl.jakubweg.SponsorBlockSettings.showToastWhenSkippedAutomatically import static pl.jakubweg.SponsorBlockSettings.uuid; import static pl.jakubweg.StringRef.str; - @SuppressWarnings({"unused", "deprecation"}) // injected public class SponsorBlockPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { @@ -54,6 +53,8 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context); setPreferenceScreen(preferenceScreen); + SponsorBlockSettings.update(context); + { SwitchPreference preference = new SwitchPreference(context); preferenceScreen.addPreference(preference); diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 12821f00..d2a0f12e 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -86,7 +86,7 @@ public class SponsorBlockSettings { SponsorBlockUtils.hideShieldButton(); SponsorBlockUtils.hideVoteButton(); PlayerController.sponsorSegmentsOfCurrentVideo = null; - } else if (/*isAddNewSegmentEnabled*/false) { + } else { /*isAddNewSegmentEnabled*/ SponsorBlockUtils.showShieldButton(); } diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 41e73be8..11757297 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -602,5 +602,4 @@ public abstract class SponsorBlockUtils { } } } - } diff --git a/app/src/main/java/pl/jakubweg/SponsorSegment.java b/app/src/main/java/pl/jakubweg/SponsorSegment.java index f96117d0..b6ea2d48 100644 --- a/app/src/main/java/pl/jakubweg/SponsorSegment.java +++ b/app/src/main/java/pl/jakubweg/SponsorSegment.java @@ -26,5 +26,4 @@ public class SponsorSegment implements Comparable { public int compareTo(SponsorSegment o) { return (int) (this.start - o.start); } - } diff --git a/app/src/main/java/pl/jakubweg/VotingButton.java b/app/src/main/java/pl/jakubweg/VotingButton.java index b0bd09e6..9b9f558b 100644 --- a/app/src/main/java/pl/jakubweg/VotingButton.java +++ b/app/src/main/java/pl/jakubweg/VotingButton.java @@ -34,7 +34,6 @@ public class VotingButton { } _youtubeControlsLayout = (RelativeLayout) viewStub; - initButtonVisibilitySettings(); ImageView imageView = (ImageView)_youtubeControlsLayout .findViewById(getIdentifier("voting_button", "id")); @@ -107,20 +106,6 @@ public class VotingButton { return SponsorBlockSettings.isVotingEnabled && SponsorBlockSettings.isSponsorBlockEnabled; } - private static void initButtonVisibilitySettings() { - Context context = YouTubeTikTokRoot_Application.getAppContext(); - if(context == null){ - Log.e(TAG, "context is null"); - SponsorBlockSettings.isSponsorBlockEnabled = false; - SponsorBlockSettings.isVotingEnabled = false; - return; - } - - SharedPreferences sharedPreferences = context.getSharedPreferences(SponsorBlockSettings.PREFERENCES_NAME, Context.MODE_PRIVATE); - SponsorBlockSettings.isSponsorBlockEnabled = sharedPreferences.getBoolean(SponsorBlockSettings.PREFERENCES_KEY_SPONSOR_BLOCK_ENABLED, false); - SponsorBlockSettings.isVotingEnabled = sharedPreferences.getBoolean(SponsorBlockSettings.PREFERENCES_KEY_VOTING_ENABLED, false); - } - //region Helpers private static int getIdentifier(String name, String defType) { Context context = YouTubeTikTokRoot_Application.getAppContext(); diff --git a/build.gradle b/build.gradle index 6754c23d..996b567e 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath "com.android.tools.build:gradle:4.0.1" + classpath 'com.android.tools.build:gradle:4.2.1' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 66f8458b..e7c8788f 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Aug 18 22:56:28 EEST 2020 +#Mon Jun 07 19:51:48 CEST 2021 distributionBase=GRADLE_USER_HOME +distributionUrl=https\://services.gradle.org/distributions/gradle-7.0.2-bin.zip distributionPath=wrapper/dists -zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip +zipStoreBase=GRADLE_USER_HOME From e08567892d1be46a404062c2a4504d4edaae9558 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 14 Jun 2021 19:12:51 +0200 Subject: [PATCH 23/56] fix buttons after watching Shorts Fixes #36 --- .../youtube/Helpers/XSwipeHelper.java | 8 ++++++++ .../sponsors/player/ui/SponsorBlockView.java | 20 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 app/src/main/java/fi/razerman/youtube/Helpers/XSwipeHelper.java diff --git a/app/src/main/java/fi/razerman/youtube/Helpers/XSwipeHelper.java b/app/src/main/java/fi/razerman/youtube/Helpers/XSwipeHelper.java new file mode 100644 index 00000000..7817e2b5 --- /dev/null +++ b/app/src/main/java/fi/razerman/youtube/Helpers/XSwipeHelper.java @@ -0,0 +1,8 @@ +package fi.razerman.youtube.Helpers; + +import android.view.ViewGroup; + +public class XSwipeHelper { + // Implementation in another repo + public static ViewGroup nextGenWatchLayout; +} \ No newline at end of file diff --git a/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SponsorBlockView.java b/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SponsorBlockView.java index 86e2c932..f2cedf98 100644 --- a/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SponsorBlockView.java +++ b/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SponsorBlockView.java @@ -11,6 +11,8 @@ import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; import java.lang.ref.WeakReference; +import fi.razerman.youtube.Helpers.XSwipeHelper; + import static fi.razerman.youtube.XGlobals.debug; public class SponsorBlockView { @@ -145,11 +147,29 @@ public class SponsorBlockView { } private static void bringLayoutToFront() { + checkLayout(); inlineSponsorOverlay.bringToFront(); inlineSponsorOverlay.requestLayout(); inlineSponsorOverlay.invalidate(); } + private static void checkLayout() { + if (inlineSponsorOverlay.getHeight() == 0) { + View layout = XSwipeHelper.nextGenWatchLayout.findViewById(getIdentifier("player_overlays", "id")); + if (layout != null) { + + initialize(layout); + + if (debug){ + Log.d("XGlobals", "player_overlays refreshed for SB"); + } + } + else if (debug){ + Log.d("XGlobals", "player_overlays was not found for SB"); + } + } + } + private static int getIdentifier(String name, String defType) { Context context = YouTubeTikTokRoot_Application.getAppContext(); return context.getResources().getIdentifier(name, defType, context.getPackageName()); From b9e454e329594487c388ce03249abba4be2ee4da Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 18 Jun 2021 14:46:55 +0200 Subject: [PATCH 24/56] add preview category (#17) --- .../java/pl/jakubweg/PlayerController.java | 4 ++-- .../SponsorBlockPreferenceFragment.java | 2 +- .../pl/jakubweg/SponsorBlockSettings.java | 20 ++++++++++--------- .../java/pl/jakubweg/SponsorBlockUtils.java | 18 ++++++++++------- app/src/main/res/values/strings.xml | 3 +++ 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index c06d0e58..9dc1a2f3 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -269,7 +269,7 @@ public class PlayerController { @Override public void run() { if (SponsorBlockSettings.countSkips && - segment.category != SponsorBlockSettings.SegmentInfo.Preview && + segment.category != SponsorBlockSettings.SegmentInfo.Unsubmitted && millis - segment.start < 2000) { // Only skips from the start should count as a view SponsorBlockUtils.sendViewCountRequest(segment); @@ -508,7 +508,7 @@ public class PlayerController { skipToMillisecond(segment.end + 2); SkipSegmentView.hide(); - if (segment.category == SponsorBlockSettings.SegmentInfo.Preview) { + if (segment.category == SponsorBlockSettings.SegmentInfo.Unsubmitted) { SponsorSegment[] newSegments = new SponsorSegment[sponsorSegmentsOfCurrentVideo.length - 1]; int i = 0; for (SponsorSegment sponsorSegment : sponsorSegmentsOfCurrentVideo) { diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index e29c651b..fb3f667e 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -158,7 +158,7 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement entryValues[i] = behaviour.key; } - for (SponsorBlockSettings.SegmentInfo segmentInfo : SponsorBlockSettings.SegmentInfo.valuesWithoutPreview()) { + for (SponsorBlockSettings.SegmentInfo segmentInfo : SponsorBlockSettings.SegmentInfo.valuesWithoutUnsubmitted()) { ListPreference preference = new ListPreference(context); preference.setTitle(segmentInfo.getTitleWithDot()); preference.setSummary(segmentInfo.description.toString()); diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index d2a0f12e..770b1797 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -106,7 +106,7 @@ public class SponsorBlockSettings { SegmentBehaviour[] possibleBehaviours = SegmentBehaviour.values(); final ArrayList enabledCategories = new ArrayList<>(possibleBehaviours.length); - for (SegmentInfo segment : SegmentInfo.valuesWithoutPreview()) { + for (SegmentInfo segment : SegmentInfo.valuesWithoutUnsubmitted()) { SegmentBehaviour behaviour = null; String value = preferences.getString(segment.key, null); if (value == null) @@ -127,7 +127,7 @@ public class SponsorBlockSettings { enabledCategories.add(segment.key); } - //"[%22sponsor%22,%22outro%22,%22music_offtopic%22,%22intro%22,%22selfpromo%22,%22interaction%22]"; + //"[%22sponsor%22,%22outro%22,%22music_offtopic%22,%22intro%22,%22selfpromo%22,%22interaction%22,%22preview%22]"; if (enabledCategories.size() == 0) sponsorBlockUrlCategories = "[]"; else @@ -179,21 +179,23 @@ public class SponsorBlockSettings { Interaction("interaction", sf("segments_subscribe"), sf("skipped_subscribe"), sf("segments_subscribe_sum"), null, 0xFFcc00ff), SelfPromo("selfpromo", sf("segments_selfpromo"), sf("skipped_selfpromo"), sf("segments_selfpromo_sum"), null, 0xFFffff00), MusicOfftopic("music_offtopic", sf("segments_nomusic"), sf("skipped_nomusic"), sf("segments_nomusic_sum"), null, 0xFFff9900), - Preview("preview", StringRef.empty, sf("skipped_preview"), StringRef.empty, SegmentBehaviour.SkipAutomatically, 0xFF000000), + Preview("preview", sf("segments_preview"), sf("skipped_preview"), sf("segments_preview_sum"), null, 0xFF0b9d65), + Unsubmitted("unsubmitted", StringRef.empty, sf("skipped_unsubmitted"), StringRef.empty, SegmentBehaviour.SkipAutomatically, 0xFFFFFFFF), ; - private static SegmentInfo[] mValuesWithoutPreview = new SegmentInfo[]{ + private static SegmentInfo[] mValuesWithoutUnsubmitted = new SegmentInfo[]{ Sponsor, Intro, Outro, Interaction, SelfPromo, - MusicOfftopic + MusicOfftopic, + Preview }; - private static Map mValuesMap = new HashMap<>(7); + private static Map mValuesMap = new HashMap<>(8); static { - for (SegmentInfo value : valuesWithoutPreview()) + for (SegmentInfo value : valuesWithoutUnsubmitted()) mValuesMap.put(value.key, value); } @@ -223,8 +225,8 @@ public class SponsorBlockSettings { paint.setColor(color); } - public static SegmentInfo[] valuesWithoutPreview() { - return mValuesWithoutPreview; + public static SegmentInfo[] valuesWithoutUnsubmitted() { + return mValuesWithoutUnsubmitted; } public static SegmentInfo byCategoryKey(String key) { diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 11757297..299992f1 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -27,6 +27,7 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.List; import java.util.Locale; import java.util.Objects; import java.util.TimeZone; @@ -96,7 +97,7 @@ public abstract class SponsorBlockUtils { private static final DialogInterface.OnClickListener segmentTypeListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { - SponsorBlockSettings.SegmentInfo segmentType = SponsorBlockSettings.SegmentInfo.valuesWithoutPreview()[which]; + SponsorBlockSettings.SegmentInfo segmentType = SponsorBlockSettings.SegmentInfo.valuesWithoutUnsubmitted()[which]; boolean enableButton; if (!segmentType.behaviour.showOnTimeBar) { Toast.makeText( @@ -126,7 +127,7 @@ public abstract class SponsorBlockUtils { Context context = ((AlertDialog) dialog).getContext(); dialog.dismiss(); - SponsorBlockSettings.SegmentInfo[] values = SponsorBlockSettings.SegmentInfo.valuesWithoutPreview(); + SponsorBlockSettings.SegmentInfo[] values = SponsorBlockSettings.SegmentInfo.valuesWithoutUnsubmitted(); CharSequence[] titles = new CharSequence[values.length]; for (int i = 0; i < values.length; i++) { // titles[i] = values[i].title; @@ -366,9 +367,12 @@ public abstract class SponsorBlockUtils { return; } int segmentAmount = sponsorSegmentsOfCurrentVideo.length; - CharSequence[] titles = new CharSequence[segmentAmount]; + List titles = new ArrayList<>(segmentAmount); // I've replaced an array with a list to prevent null elements in the array as unsubmitted segments get filtered out for (int i = 0; i < segmentAmount; i++) { SponsorSegment segment = sponsorSegmentsOfCurrentVideo[i]; + if (segment.category == SponsorBlockSettings.SegmentInfo.Unsubmitted) { + continue; + } String start = dateFormatter.format(new Date(segment.start)); String end = dateFormatter.format(new Date(segment.end)); @@ -377,16 +381,16 @@ public abstract class SponsorBlockUtils { segment.category.color, segment.category.title, start, end)); if (i + 1 != segmentAmount) // prevents trailing new line after last segment htmlBuilder.append("
"); - titles[i] = Html.fromHtml(htmlBuilder.toString()); + titles.add(Html.fromHtml(htmlBuilder.toString())); } new AlertDialog.Builder(context) - .setItems(titles, segmentVoteClickListener) + .setItems(titles.toArray(new CharSequence[0]), segmentVoteClickListener) .show(); } private static void onNewCategorySelect(final SponsorSegment segment, Context context) { - final SponsorBlockSettings.SegmentInfo[] values = SponsorBlockSettings.SegmentInfo.valuesWithoutPreview(); + final SponsorBlockSettings.SegmentInfo[] values = SponsorBlockSettings.SegmentInfo.valuesWithoutUnsubmitted(); CharSequence[] titles = new CharSequence[values.length]; for (int i = 0; i < values.length; i++) { titles[i] = values[i].getTitleWithDot(); @@ -414,7 +418,7 @@ public abstract class SponsorBlockUtils { final SponsorSegment[] segments = original == null ? new SponsorSegment[1] : Arrays.copyOf(original, original.length + 1); segments[segments.length - 1] = new SponsorSegment(newSponsorSegmentStartMillis, newSponsorSegmentEndMillis, - SponsorBlockSettings.SegmentInfo.Preview, null); + SponsorBlockSettings.SegmentInfo.Unsubmitted, null); Arrays.sort(segments); sponsorSegmentsOfCurrentVideo = segments; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 05b7a056..7b1d5fed 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -167,6 +167,8 @@ Similar to "sponsor" except for unpaid or self promotion. This includes sections about merchandise, donations, or information about who they collaborated with Music: Non-Music Section Only for use in music videos. This includes introductions or outros in music videos + Preview/Recap + Quick recap of previous episodes, or a preview of what\'s coming up later in the current video. Meant for edited together clips, not for spoken summaries. Skipped sponsor Skipped intro Skipped outro @@ -174,6 +176,7 @@ Skipped self promotion Skipped silence Skipped preview + Skipped unsubmitted segment Skip automatically Show a skip button Don\'t do anything From dce63e76e2afb8d1e6b0ccabff0e01da93b5f98a Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 18 Jun 2021 14:51:14 +0200 Subject: [PATCH 25/56] add length of the video without segments to the time bar --- .../java/pl/jakubweg/SponsorBlockUtils.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 299992f1..6ad0272c 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -9,10 +9,14 @@ import android.os.Looper; import android.text.Html; import android.util.Log; import android.view.View; +import android.view.ViewGroup; import android.widget.EditText; import android.widget.ImageView; +import android.widget.TextView; import android.widget.Toast; +import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; + import org.json.JSONArray; import org.json.JSONObject; @@ -32,6 +36,8 @@ import java.util.Locale; import java.util.Objects; import java.util.TimeZone; +import fi.razerman.youtube.Helpers.XSwipeHelper; + import static android.view.View.GONE; import static android.view.View.VISIBLE; import static fi.razerman.youtube.XGlobals.debug; @@ -48,8 +54,12 @@ import static pl.jakubweg.StringRef.str; public abstract class SponsorBlockUtils { public static final String TAG = "jakubweg.SponsorBlockUtils"; public static final String DATE_FORMAT = "HH:mm:ss.SSS"; + public static final String WITHOUT_SEGMENTS_FORMAT = " (m:ss)"; + public static final String WITHOUT_SEGMENTS_FORMAT_H = " (H:m:ss)"; @SuppressLint("SimpleDateFormat") public static final SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT); + public static final SimpleDateFormat withoutSegmentsFormatter = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT); + public static final SimpleDateFormat withoutSegmentsFormatterH = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT_H); private static final int sponsorBtnId = 1234; public static final View.OnClickListener sponsorBlockBtnListener = new View.OnClickListener() { @Override @@ -507,9 +517,19 @@ public abstract class SponsorBlockUtils { Log.e(TAG, "download segments failed", e); } + View layout = XSwipeHelper.nextGenWatchLayout.findViewById(getIdentifier("player_overlays", "id")); + View bar = layout.findViewById(getIdentifier("time_bar_total_time", "id")); + + ((TextView) bar).append(getTimeWithoutSegments()); + return sponsorSegments.toArray(new SponsorSegment[0]); } + private static int getIdentifier(String name, String defType) { + Context context = YouTubeTikTokRoot_Application.getAppContext(); + return context.getResources().getIdentifier(name, defType, context.getPackageName()); + } + public static void sendViewCountRequest(SponsorSegment segment) { try { URL url = new URL(SponsorBlockSettings.getSponsorBlockViewedUrl(segment.UUID)); @@ -562,6 +582,18 @@ public abstract class SponsorBlockUtils { } } + public static String getTimeWithoutSegments() { + if (!SponsorBlockSettings.isSponsorBlockEnabled || sponsorSegmentsOfCurrentVideo == null) { + return ""; + } + long timeWithoutSegments = PlayerController.getCurrentVideoLength(); + for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) { + timeWithoutSegments -= segment.end - segment.start; + } + Date date = new Date(timeWithoutSegments); + return timeWithoutSegments >= 3600000 ? withoutSegmentsFormatterH.format(date) : withoutSegmentsFormatter.format(date); + } + private enum VoteOption { UPVOTE(str("vote_upvote")), DOWNVOTE(str("vote_downvote")), From 7b6f1d6774d2ebb1c02655860711d92a55ec58cb Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 18 Jun 2021 14:53:50 +0200 Subject: [PATCH 26/56] remove useless debug import --- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 6ad0272c..a72427d6 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -9,7 +9,6 @@ import android.os.Looper; import android.text.Html; import android.util.Log; import android.view.View; -import android.view.ViewGroup; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; From 9b17e70e0ec67b925f9be958293c224ac59dc8e8 Mon Sep 17 00:00:00 2001 From: caneleex Date: Sun, 20 Jun 2021 21:08:20 +0200 Subject: [PATCH 27/56] change preview color --- app/src/main/java/pl/jakubweg/SponsorBlockSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 770b1797..02109661 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -179,7 +179,7 @@ public class SponsorBlockSettings { Interaction("interaction", sf("segments_subscribe"), sf("skipped_subscribe"), sf("segments_subscribe_sum"), null, 0xFFcc00ff), SelfPromo("selfpromo", sf("segments_selfpromo"), sf("skipped_selfpromo"), sf("segments_selfpromo_sum"), null, 0xFFffff00), MusicOfftopic("music_offtopic", sf("segments_nomusic"), sf("skipped_nomusic"), sf("segments_nomusic_sum"), null, 0xFFff9900), - Preview("preview", sf("segments_preview"), sf("skipped_preview"), sf("segments_preview_sum"), null, 0xFF0b9d65), + Preview("preview", sf("segments_preview"), sf("skipped_preview"), sf("segments_preview_sum"), null, 0xFF008fd6), Unsubmitted("unsubmitted", StringRef.empty, sf("skipped_unsubmitted"), StringRef.empty, SegmentBehaviour.SkipAutomatically, 0xFFFFFFFF), ; From e88cf5143dbd9188bc06b271a5005863195551f3 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 16:19:47 +0200 Subject: [PATCH 28/56] initial cleanup --- .../java/pl/jakubweg/PlayerController.java | 69 ++-- .../java/pl/jakubweg/SkipSegmentView.java | 2 + .../pl/jakubweg/SponsorBlockSettings.java | 20 - .../java/pl/jakubweg/SponsorBlockUtils.java | 353 +++++------------- .../{ => objects}/SponsorSegment.java | 4 +- .../java/pl/jakubweg/objects/UserStats.java | 31 ++ .../java/pl/jakubweg/requests/Requester.java | 176 +++++++++ .../main/java/pl/jakubweg/requests/Route.java | 73 ++++ 8 files changed, 410 insertions(+), 318 deletions(-) rename app/src/main/java/pl/jakubweg/{ => objects}/SponsorSegment.java (91%) create mode 100644 app/src/main/java/pl/jakubweg/objects/UserStats.java create mode 100644 app/src/main/java/pl/jakubweg/requests/Requester.java create mode 100644 app/src/main/java/pl/jakubweg/requests/Route.java diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 9dc1a2f3..808a9643 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -21,6 +21,8 @@ import java.util.Timer; import java.util.TimerTask; import fi.vanced.libraries.youtube.player.VideoInformation; +import pl.jakubweg.objects.SponsorSegment; +import pl.jakubweg.requests.Requester; @SuppressLint({"LongLogTag"}) public class PlayerController { @@ -38,12 +40,9 @@ public class PlayerController { private static String currentVideoId; private static long currentVideoLength = 1L; private static long lastKnownVideoTime = -1L; - private static final Runnable findAndSkipSegmentRunnable = new Runnable() { - @Override - public void run() { + private static final Runnable findAndSkipSegmentRunnable = () -> { // Log.d(TAG, "findAndSkipSegmentRunnable"); - findAndSkipSegment(false); - } + findAndSkipSegment(false); }; private static float sponsorBarLeft = 1f; private static float sponsorBarRight = 1f; @@ -121,7 +120,7 @@ public class PlayerController { } public static void executeDownloadSegments(String videoId) { - SponsorSegment[] segments = SponsorBlockUtils.getSegmentsForVideo(videoId); + SponsorSegment[] segments = Requester.getSegments(videoId); Arrays.sort(segments); if (VERBOSE) @@ -265,15 +264,12 @@ public class PlayerController { } private static void sendViewRequestAsync(final long millis, final SponsorSegment segment) { - new Thread(new Runnable() { - @Override - public void run() { - if (SponsorBlockSettings.countSkips && - segment.category != SponsorBlockSettings.SegmentInfo.Unsubmitted && - millis - segment.start < 2000) { - // Only skips from the start should count as a view - SponsorBlockUtils.sendViewCountRequest(segment); - } + new Thread(() -> { + if (SponsorBlockSettings.countSkips && + segment.category != SponsorBlockSettings.SegmentInfo.Unsubmitted && + millis - segment.start < 2000) { + // Only skips from the start should count as a view + Requester.sendViewCountRequest(segment); } }).start(); } @@ -371,13 +367,10 @@ public class PlayerController { if (VERBOSE) Log.d(TAG, "addSkipSponsorView15: view=" + view.toString()); - new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { - @Override - public void run() { - final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) view).getChildAt(2); - Activity context = ((Activity) viewGroup.getContext()); - NewSegmentHelperLayout.context = context; - } + new Handler(Looper.getMainLooper()).postDelayed(() -> { + final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) view).getChildAt(2); + Activity context = ((Activity) viewGroup.getContext()); + NewSegmentHelperLayout.context = context; }, 500); } @@ -385,13 +378,10 @@ public class PlayerController { playerActivity = new WeakReference<>((Activity) view.getContext()); if (VERBOSE) Log.d(TAG, "addSkipSponsorView14: view=" + view.toString()); - new Handler(Looper.getMainLooper()).postDelayed(new Runnable() { - @Override - public void run() { - final ViewGroup viewGroup = (ViewGroup) view.getParent(); - Activity activity = (Activity) viewGroup.getContext(); - NewSegmentHelperLayout.context = activity; - } + new Handler(Looper.getMainLooper()).postDelayed(() -> { + final ViewGroup viewGroup = (ViewGroup) view.getParent(); + Activity activity = (Activity) viewGroup.getContext(); + NewSegmentHelperLayout.context = activity; }, 500); } @@ -455,18 +445,15 @@ public class PlayerController { Log.d(TAG, String.format("Requesting skip to millis=%d on thread %s", millisecond, Thread.currentThread().toString())); final long finalMillisecond = millisecond; - new Handler(Looper.getMainLooper()).post(new Runnable() { - @Override - public void run() { - try { - if (VERBOSE) - Log.i(TAG, "Skipping to millis=" + finalMillisecond); - lastKnownVideoTime = finalMillisecond; - VideoInformation.lastKnownVideoTime = lastKnownVideoTime; - setMillisecondMethod.invoke(currentObj, finalMillisecond); - } catch (Exception e) { - Log.e(TAG, "Cannot skip to millisecond", e); - } + new Handler(Looper.getMainLooper()).post(() -> { + try { + if (VERBOSE) + Log.i(TAG, "Skipping to millis=" + finalMillisecond); + lastKnownVideoTime = finalMillisecond; + VideoInformation.lastKnownVideoTime = lastKnownVideoTime; + setMillisecondMethod.invoke(currentObj, finalMillisecond); + } catch (Exception e) { + Log.e(TAG, "Cannot skip to millisecond", e); } }); } diff --git a/app/src/main/java/pl/jakubweg/SkipSegmentView.java b/app/src/main/java/pl/jakubweg/SkipSegmentView.java index 5e2a485e..0d9fe81f 100644 --- a/app/src/main/java/pl/jakubweg/SkipSegmentView.java +++ b/app/src/main/java/pl/jakubweg/SkipSegmentView.java @@ -8,6 +8,8 @@ import android.widget.Toast; import com.google.android.apps.youtube.app.YouTubeTikTokRoot_Application; +import pl.jakubweg.objects.SponsorSegment; + import static fi.vanced.libraries.youtube.sponsors.player.ui.SponsorBlockView.hideSkipButton; import static fi.vanced.libraries.youtube.sponsors.player.ui.SponsorBlockView.showSkipButton; import static pl.jakubweg.PlayerController.VERBOSE; diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 02109661..165d5ff0 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -25,10 +25,6 @@ public class SponsorBlockSettings { public static final String PREFERENCES_KEY_SEEN_GUIDELINES = "sb-seen-gl"; public static final String PREFERENCES_KEY_NEW_SEGMENT_ENABLED = "sb-new-segment-enabled"; public static final String PREFERENCES_KEY_VOTING_ENABLED = "sb-voting-enabled"; - public static final String sponsorBlockSkipSegmentsUrl = "https://sponsor.ajay.app/api/skipSegments"; - public static final String sponsorBlockViewedUrl = "https://sponsor.ajay.app/api/viewedVideoSponsorTime"; - public static final String sponsorBlockVoteUrl = "https://sponsor.ajay.app/api/voteOnSponsorTime"; - public static final SegmentBehaviour DefaultBehaviour = SegmentBehaviour.SkipAutomatically; @@ -48,22 +44,6 @@ public class SponsorBlockSettings { Log.e("jakubweg.Settings", "Do not call SponsorBlockSettings constructor!"); } - public static String getSponsorBlockUrlWithCategories(String videoId) { - return sponsorBlockSkipSegmentsUrl + "?videoID=" + videoId + "&categories=" + sponsorBlockUrlCategories; - } - - public static String getSponsorBlockViewedUrl(String UUID) { - return sponsorBlockViewedUrl + "?UUID=" + UUID; - } - - public static String getSponsorBlockVoteUrl(String uuid, String userId, int type) { - return sponsorBlockVoteUrl + "?UUID=" + uuid + "&userID=" + userId + "&type=" + type; - } - - public static String getSponsorBlockVoteUrl(String uuid, String userId, String category) { - return sponsorBlockVoteUrl + "?UUID=" + uuid + "&userID=" + userId + "&category=" + category; - } - public static SharedPreferences getPreferences(Context context) { return context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_PRIVATE); } diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 299992f1..aa9399ba 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -32,6 +32,9 @@ import java.util.Locale; import java.util.Objects; import java.util.TimeZone; +import pl.jakubweg.objects.SponsorSegment; +import pl.jakubweg.requests.Requester; + import static android.view.View.GONE; import static android.view.View.VISIBLE; import static fi.razerman.youtube.XGlobals.debug; @@ -39,10 +42,9 @@ import static pl.jakubweg.PlayerController.VERBOSE; import static pl.jakubweg.PlayerController.getCurrentVideoId; import static pl.jakubweg.PlayerController.getLastKnownVideoTime; import static pl.jakubweg.PlayerController.sponsorSegmentsOfCurrentVideo; -import static pl.jakubweg.SponsorBlockSettings.getSponsorBlockVoteUrl; -import static pl.jakubweg.SponsorBlockSettings.sponsorBlockSkipSegmentsUrl; import static pl.jakubweg.SponsorBlockSettings.uuid; import static pl.jakubweg.StringRef.str; +import static pl.jakubweg.requests.Requester.voteForSegment; @SuppressWarnings({"LongLogTag"}) public abstract class SponsorBlockUtils { @@ -51,23 +53,17 @@ public abstract class SponsorBlockUtils { @SuppressLint("SimpleDateFormat") public static final SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT); private static final int sponsorBtnId = 1234; - public static final View.OnClickListener sponsorBlockBtnListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - if (debug) { - Log.d(TAG, "Shield button clicked"); - } - NewSegmentHelperLayout.toggle(); + public static final View.OnClickListener sponsorBlockBtnListener = v -> { + if (debug) { + Log.d(TAG, "Shield button clicked"); } + NewSegmentHelperLayout.toggle(); }; - public static final View.OnClickListener voteButtonListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - if (debug) { - Log.d(TAG, "Vote button clicked"); - } - SponsorBlockUtils.onVotingClicked(v.getContext()); + public static final View.OnClickListener voteButtonListener = v -> { + if (debug) { + Log.d(TAG, "Vote button clicked"); } + SponsorBlockUtils.onVotingClicked(v.getContext()); }; private static int shareBtnId = -1; private static long newSponsorSegmentDialogShownMillis; @@ -158,134 +154,88 @@ public abstract class SponsorBlockUtils { new Thread(submitRunnable).start(); } }; - private static String messageToToast = ""; - private static EditByHandSaveDialogListener editByHandSaveDialogListener = new EditByHandSaveDialogListener(); - private static final DialogInterface.OnClickListener editByHandDialogListener = new DialogInterface.OnClickListener() { - @SuppressLint("DefaultLocale") - @Override - public void onClick(DialogInterface dialog, int which) { - Context context = ((AlertDialog) dialog).getContext(); + public static String messageToToast = ""; + private static final EditByHandSaveDialogListener editByHandSaveDialogListener = new EditByHandSaveDialogListener(); + private static final DialogInterface.OnClickListener editByHandDialogListener = (dialog, which) -> { + Context context = ((AlertDialog) dialog).getContext(); - final boolean isStart = DialogInterface.BUTTON_NEGATIVE == which; + final boolean isStart = DialogInterface.BUTTON_NEGATIVE == which; - final EditText textView = new EditText(context); - textView.setHint(DATE_FORMAT); - if (isStart) { - if (newSponsorSegmentStartMillis >= 0) - textView.setText(dateFormatter.format(new Date(newSponsorSegmentStartMillis))); - } else { - if (newSponsorSegmentEndMillis >= 0) - textView.setText(dateFormatter.format(new Date(newSponsorSegmentEndMillis))); - } - - editByHandSaveDialogListener.settingStart = isStart; - editByHandSaveDialogListener.editText = new WeakReference<>(textView); - new AlertDialog.Builder(context) - .setTitle(str(isStart ? "new_segment_time_start" : "new_segment_time_end")) - .setView(textView) - .setNegativeButton(android.R.string.cancel, null) - .setNeutralButton(str("new_segment_now"), editByHandSaveDialogListener) - .setPositiveButton(android.R.string.ok, editByHandSaveDialogListener) - .show(); - - dialog.dismiss(); + final EditText textView = new EditText(context); + textView.setHint(DATE_FORMAT); + if (isStart) { + if (newSponsorSegmentStartMillis >= 0) + textView.setText(dateFormatter.format(new Date(newSponsorSegmentStartMillis))); + } else { + if (newSponsorSegmentEndMillis >= 0) + textView.setText(dateFormatter.format(new Date(newSponsorSegmentEndMillis))); } + + editByHandSaveDialogListener.settingStart = isStart; + editByHandSaveDialogListener.editText = new WeakReference<>(textView); + new AlertDialog.Builder(context) + .setTitle(str(isStart ? "new_segment_time_start" : "new_segment_time_end")) + .setView(textView) + .setNegativeButton(android.R.string.cancel, null) + .setNeutralButton(str("new_segment_now"), editByHandSaveDialogListener) + .setPositiveButton(android.R.string.ok, editByHandSaveDialogListener) + .show(); + + dialog.dismiss(); }; - private static final DialogInterface.OnClickListener segmentVoteClickListener = new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - final Context context = ((AlertDialog) dialog).getContext(); - final SponsorSegment segment = sponsorSegmentsOfCurrentVideo[which]; - - final VoteOption[] voteOptions = VoteOption.values(); - String[] items = new String[voteOptions.length]; - - for (int i = 0; i < voteOptions.length; i++) { - items[i] = voteOptions[i].title; - } - - new AlertDialog.Builder(context) - .setItems(items, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - appContext = new WeakReference<>(context.getApplicationContext()); - switch (voteOptions[which]) { - case UPVOTE: - voteForSegment(segment, VoteOption.UPVOTE); - break; - case DOWNVOTE: - voteForSegment(segment, VoteOption.DOWNVOTE); - break; - case CATEGORY_CHANGE: - onNewCategorySelect(segment, context); - break; - } - } - }) - .show(); - } + private static final Runnable toastRunnable = () -> { + Context context = appContext.get(); + if (context != null && messageToToast != null) + Toast.makeText(context, messageToToast, Toast.LENGTH_LONG).show(); }; - private static Runnable toastRunnable = new Runnable() { - @Override - public void run() { - Context context = appContext.get(); - if (context != null && messageToToast != null) - Toast.makeText(context, messageToToast, Toast.LENGTH_LONG).show(); + private static final DialogInterface.OnClickListener segmentVoteClickListener = (dialog, which) -> { + final Context context = ((AlertDialog) dialog).getContext(); + final SponsorSegment segment = sponsorSegmentsOfCurrentVideo[which]; + + final VoteOption[] voteOptions = VoteOption.values(); + String[] items = new String[voteOptions.length]; + + for (int i = 0; i < voteOptions.length; i++) { + items[i] = voteOptions[i].title; } + + new AlertDialog.Builder(context) + .setItems(items, (dialog1, which1) -> { + appContext = new WeakReference<>(context.getApplicationContext()); + switch (voteOptions[which1]) { + case UPVOTE: + voteForSegment(segment, VoteOption.UPVOTE, appContext.get(), toastRunnable); + break; + case DOWNVOTE: + voteForSegment(segment, VoteOption.DOWNVOTE, appContext.get(), toastRunnable); + break; + case CATEGORY_CHANGE: + onNewCategorySelect(segment, context); + break; + } + }) + .show(); }; - private static final Runnable submitRunnable = new Runnable() { - @Override - public void run() { - messageToToast = null; - final String uuid = SponsorBlockSettings.uuid; - final long start = newSponsorSegmentStartMillis; - final long end = newSponsorSegmentEndMillis; - final String videoId = getCurrentVideoId(); - final SponsorBlockSettings.SegmentInfo segmentType = SponsorBlockUtils.newSponsorBlockSegmentType; - try { - - if (start < 0 || end < 0 || start >= end || segmentType == null || videoId == null || uuid == null) { - Log.e(TAG, "Unable to submit times, invalid parameters"); - return; - } - - URL url = new URL(String.format(Locale.US, - sponsorBlockSkipSegmentsUrl + "?videoID=%s&userID=%s&startTime=%.3f&endTime=%.3f&category=%s", - videoId, uuid, ((float) start) / 1000f, ((float) end) / 1000f, segmentType.key)); - - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - switch (connection.getResponseCode()) { - default: - messageToToast = String.format(str("submit_failed_unknown_error"), connection.getResponseCode(), connection.getResponseMessage()); - break; - case 429: - messageToToast = str("submit_failed_rate_limit"); - break; - case 403: - messageToToast = str("submit_failed_forbidden"); - break; - case 409: - messageToToast = str("submit_failed_duplicate"); - break; - case 200: - messageToToast = str("submit_succeeded"); - break; - } - - Log.i(TAG, "Segment submitted with status: " + connection.getResponseCode() + ", " + messageToToast); - new Handler(Looper.getMainLooper()).post(toastRunnable); - - connection.disconnect(); - - newSponsorSegmentEndMillis = newSponsorSegmentStartMillis = -1; - } catch (Exception e) { - Log.e(TAG, "Unable to submit segment", e); + private static final Runnable submitRunnable = () -> { + messageToToast = null; + final String uuid = SponsorBlockSettings.uuid; + final long start = newSponsorSegmentStartMillis; + final long end = newSponsorSegmentEndMillis; + final String videoId = getCurrentVideoId(); + final SponsorBlockSettings.SegmentInfo segmentType = SponsorBlockUtils.newSponsorBlockSegmentType; + try { + if (start < 0 || end < 0 || start >= end || segmentType == null || videoId == null || uuid == null) { + Log.e(TAG, "Unable to submit times, invalid parameters"); + return; } - - if (videoId != null) - PlayerController.executeDownloadSegments(videoId); + Requester.submitSegments(videoId, uuid, ((float) start) / 1000f, ((float) end) / 1000f, segmentType.key, toastRunnable); + newSponsorSegmentEndMillis = newSponsorSegmentStartMillis = -1; + } catch (Exception e) { + Log.e(TAG, "Unable to submit segment", e); } + + if (videoId != null) + PlayerController.executeDownloadSegments(videoId); }; static { @@ -398,12 +348,7 @@ public abstract class SponsorBlockUtils { new AlertDialog.Builder(context) .setTitle(str("new_segment_choose_category")) - .setItems(titles, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - voteForSegment(segment, VoteOption.CATEGORY_CHANGE, values[which].key); - } - }) + .setItems(titles, (dialog, which) -> voteForSegment(segment, VoteOption.CATEGORY_CHANGE, appContext.get(), toastRunnable, values[which].key)) .show(); } @@ -448,121 +393,7 @@ public abstract class SponsorBlockUtils { } } - public synchronized static SponsorSegment[] getSegmentsForVideo(String videoId) { - newSponsorSegmentEndMillis = newSponsorSegmentStartMillis = -1; - - ArrayList sponsorSegments = new ArrayList<>(); - try { - if (VERBOSE) - Log.i(TAG, "Trying to download segments for videoId=" + videoId); - - URL url = new URL(SponsorBlockSettings.getSponsorBlockUrlWithCategories(videoId)); - - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - switch (connection.getResponseCode()) { - default: - Log.e(TAG, "Unable to download segments: Status: " + connection.getResponseCode() + " " + connection.getResponseMessage()); - break; - case 404: - Log.w(TAG, "No segments for this video (ERR404)"); - break; - case 200: - if (VERBOSE) - Log.i(TAG, "Received status 200 OK, parsing response..."); - - StringBuilder stringBuilder = new StringBuilder(); - BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - stringBuilder.append(line); - } - connection.getInputStream().close(); - - - JSONArray responseArray = new JSONArray(stringBuilder.toString()); - int length = responseArray.length(); - for (int i = 0; i < length; i++) { - JSONObject obj = ((JSONObject) responseArray.get(i)); - JSONArray segments = obj.getJSONArray("segment"); - long start = (long) (segments.getDouble(0) * 1000); - long end = (long) (segments.getDouble(1) * 1000); - String category = obj.getString("category"); - String UUID = obj.getString("UUID"); - - SponsorBlockSettings.SegmentInfo segmentCategory = SponsorBlockSettings.SegmentInfo.byCategoryKey(category); - if (segmentCategory != null && segmentCategory.behaviour.showOnTimeBar) { - SponsorSegment segment = new SponsorSegment(start, end, segmentCategory, UUID); - sponsorSegments.add(segment); - } - } - - if (VERBOSE) - Log.v(TAG, "Parsing done"); - break; - } - - connection.disconnect(); - - } catch (Exception e) { - Log.e(TAG, "download segments failed", e); - } - - return sponsorSegments.toArray(new SponsorSegment[0]); - } - - public static void sendViewCountRequest(SponsorSegment segment) { - try { - URL url = new URL(SponsorBlockSettings.getSponsorBlockViewedUrl(segment.UUID)); - - Log.d("sponsorblock", "requesting: " + url.getPath()); - - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.disconnect(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - public static void voteForSegment(SponsorSegment segment, VoteOption voteOption, String... args) { - messageToToast = null; - try { - String voteUrl = voteOption == VoteOption.CATEGORY_CHANGE - ? getSponsorBlockVoteUrl(segment.UUID, uuid, args[0]) - : getSponsorBlockVoteUrl(segment.UUID, uuid, voteOption == VoteOption.UPVOTE ? 1 : 0); - URL url = new URL(voteUrl); - - Toast.makeText(appContext.get(), str("vote_started"), Toast.LENGTH_SHORT).show(); - Log.d("sponsorblock", "requesting: " + url.getPath()); - - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - - switch (connection.getResponseCode()) { - default: - messageToToast = String.format(str("vote_failed_unknown_error"), connection.getResponseCode(), connection.getResponseMessage()); - break; - case 429: - messageToToast = str("vote_failed_rate_limit"); - break; - case 403: - messageToToast = str("vote_failed_forbidden"); - break; - case 200: - messageToToast = str("vote_succeeded"); - break; - } - - Log.i(TAG, "Voted for segment with status: " + connection.getResponseCode() + ", " + messageToToast); - new Handler(Looper.getMainLooper()).post(toastRunnable); - - connection.disconnect(); - } catch (IOException e) { - e.printStackTrace(); - } - } - - private enum VoteOption { + public enum VoteOption { UPVOTE(str("vote_upvote")), DOWNVOTE(str("vote_downvote")), CATEGORY_CHANGE(str("vote_category")); @@ -606,4 +437,14 @@ public abstract class SponsorBlockUtils { } } } + + public static int countMatches(CharSequence seq, char c) + { + int count = 0; + for (int i = 0; i < seq.length(); i++) { + if (seq.charAt(i) == c) + count++; + } + return count; + } } diff --git a/app/src/main/java/pl/jakubweg/SponsorSegment.java b/app/src/main/java/pl/jakubweg/objects/SponsorSegment.java similarity index 91% rename from app/src/main/java/pl/jakubweg/SponsorSegment.java rename to app/src/main/java/pl/jakubweg/objects/SponsorSegment.java index b6ea2d48..1819bba7 100644 --- a/app/src/main/java/pl/jakubweg/SponsorSegment.java +++ b/app/src/main/java/pl/jakubweg/objects/SponsorSegment.java @@ -1,4 +1,6 @@ -package pl.jakubweg; +package pl.jakubweg.objects; + +import pl.jakubweg.SponsorBlockSettings; public class SponsorSegment implements Comparable { public final long start; diff --git a/app/src/main/java/pl/jakubweg/objects/UserStats.java b/app/src/main/java/pl/jakubweg/objects/UserStats.java new file mode 100644 index 00000000..f638f610 --- /dev/null +++ b/app/src/main/java/pl/jakubweg/objects/UserStats.java @@ -0,0 +1,31 @@ +package pl.jakubweg.objects; + +public class UserStats { + private final String userName; + private final double minutesSaved; + private final int segmentCount; + private final int viewCount; + + public UserStats(String userName, double minutesSaved, int segmentCount, int viewCount) { + this.userName = userName; + this.minutesSaved = minutesSaved; + this.segmentCount = segmentCount; + this.viewCount = viewCount; + } + + public String getUserName() { + return userName; + } + + public double getMinutesSaved() { + return minutesSaved; + } + + public int getSegmentCount() { + return segmentCount; + } + + public int getViewCount() { + return viewCount; + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java new file mode 100644 index 00000000..af9a3fcb --- /dev/null +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -0,0 +1,176 @@ +package pl.jakubweg.requests; + +import android.content.Context; +import android.os.Handler; +import android.os.Looper; +import android.widget.Toast; + +import org.json.JSONArray; +import org.json.JSONObject; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.ArrayList; +import java.util.List; + +import pl.jakubweg.SponsorBlockSettings; +import pl.jakubweg.SponsorBlockUtils; +import pl.jakubweg.SponsorBlockUtils.VoteOption; +import pl.jakubweg.objects.SponsorSegment; +import pl.jakubweg.objects.UserStats; + +import static pl.jakubweg.StringRef.str; + +public class Requester { + private static final String SPONSORBLOCK_API_URL = "https://sponsor.ajay.app/api/"; + private static final String TIME_TEMPLATE = "%.3f"; + + private Requester() {} + + public static synchronized SponsorSegment[] getSegments(String videoId) { + List segments = new ArrayList<>(); + try { + HttpURLConnection connection = getConnectionFromRoute(Route.GET_SEGMENTS, videoId); + int responseCode = connection.getResponseCode(); + + switch (responseCode) { + case 200: + JSONArray responseArray = new JSONArray(parseJson(connection)); + int length = responseArray.length(); + for (int i = 0; i < length; i++) { + JSONObject obj = ((JSONObject) responseArray.get(i)); + JSONArray segment = obj.getJSONArray("segment"); + long start = (long) (segment.getDouble(0) * 1000); + long end = (long) (segment.getDouble(1) * 1000); + String category = obj.getString("category"); + String uuid = obj.getString("UUID"); + + SponsorBlockSettings.SegmentInfo segmentCategory = SponsorBlockSettings.SegmentInfo.byCategoryKey(category); + if (segmentCategory != null && segmentCategory.behaviour.showOnTimeBar) { + SponsorSegment sponsorSegment = new SponsorSegment(start, end, segmentCategory, uuid); + segments.add(sponsorSegment); + } + } + break; + case 404: + break; + } + connection.disconnect(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + return segments.toArray(new SponsorSegment[0]); + } + + public static void submitSegments(String videoId, String uuid, float startTime, float endTime, String category, Runnable toastRunnable) { + try { + String start = String.format(TIME_TEMPLATE, startTime); + String end = String.format(TIME_TEMPLATE, endTime); + HttpURLConnection connection = getConnectionFromRoute(Route.SUBMIT_SEGMENTS, videoId, uuid, start, end, category); + int responseCode = connection.getResponseCode(); + + switch (responseCode) { + case 200: + SponsorBlockUtils.messageToToast = str("submit_succeeded"); + break; + case 409: + SponsorBlockUtils.messageToToast = str("submit_failed_duplicate"); + break; + case 403: + SponsorBlockUtils.messageToToast = str("submit_failed_forbidden"); + break; + case 429: + SponsorBlockUtils.messageToToast = str("submit_failed_rate_limit"); + break; + } + new Handler(Looper.getMainLooper()).post(toastRunnable); + connection.disconnect(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void sendViewCountRequest(SponsorSegment segment) { + try { + HttpURLConnection connection = getConnectionFromRoute(Route.VIEWED_SEGMENT, segment.UUID); + connection.disconnect(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static void voteForSegment(SponsorSegment segment, VoteOption voteOption, Context context, Runnable toastRunnable, String... args) { + try { + String segmentUuid = segment.UUID; + String uuid = SponsorBlockSettings.uuid; + String vote = Integer.toString(voteOption == VoteOption.UPVOTE ? 1 : 0); + + Toast.makeText(context, str("vote_started"), Toast.LENGTH_SHORT).show(); + + HttpURLConnection connection = voteOption == VoteOption.CATEGORY_CHANGE + ? getConnectionFromRoute(Route.VOTE_ON_SEGMENT_CATEGORY, segmentUuid, uuid, args[0]) + : getConnectionFromRoute(Route.VOTE_ON_SEGMENT_QUALITY, segmentUuid, uuid, vote); + int responseCode = connection.getResponseCode(); + + switch (responseCode) { + case 200: + SponsorBlockUtils.messageToToast = str("vote_succeeded"); + break; + case 403: + SponsorBlockUtils.messageToToast = str("vote_failed_forbidden"); + break; + case 429: + SponsorBlockUtils.messageToToast = str("vote_failed_rate_limit"); + break; + default: + SponsorBlockUtils.messageToToast = String.format(str("vote_failed_unknown_error"), responseCode, connection.getResponseMessage()); + break; + } + new Handler(Looper.getMainLooper()).post(toastRunnable); + connection.disconnect(); + } + catch (Exception ex) { + ex.printStackTrace(); + } + } + + public static UserStats getUserStats() { + try { + HttpURLConnection connection = getConnectionFromRoute(Route.GET_USER_STATS, SponsorBlockSettings.uuid); + JSONObject json = new JSONObject(parseJson(connection)); + connection.disconnect(); + return new UserStats(json.getString("userName"), json.getDouble("minutesSaved"), json.getInt("segmentCount"), + json.getInt("viewCount")); + } + catch (Exception ex) { + ex.printStackTrace(); + } + return new UserStats("", 0, 0, 0); + } + + private static HttpURLConnection getConnectionFromRoute(Route route, String... params) throws IOException { + String url = SPONSORBLOCK_API_URL + route.compile(params).getCompiledRoute(); + HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); + connection.setRequestMethod(route.getMethod().name()); + return connection; + } + + private static String parseJson(HttpURLConnection connection) throws IOException { + StringBuilder jsonBuilder = new StringBuilder(); + InputStream inputStream = connection.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + String line; + while ((line = reader.readLine()) != null) { + jsonBuilder.append(line); + } + inputStream.close(); + return jsonBuilder.toString(); + } +} \ No newline at end of file diff --git a/app/src/main/java/pl/jakubweg/requests/Route.java b/app/src/main/java/pl/jakubweg/requests/Route.java new file mode 100644 index 00000000..5cbf44e1 --- /dev/null +++ b/app/src/main/java/pl/jakubweg/requests/Route.java @@ -0,0 +1,73 @@ +package pl.jakubweg.requests; + +import pl.jakubweg.SponsorBlockUtils; + +import static pl.jakubweg.requests.Route.Method.*; + +public class Route { + public static final Route GET_SEGMENTS = new Route(GET, "skipSegments?videoID={video_id}&categories={categories}"); + public static final Route VIEWED_SEGMENT = new Route(POST, "viewedVideoSponsorTime?UUID={segment_id}"); + public static final Route GET_USER_STATS = new Route(GET, "userInfo"); + public static final Route SUBMIT_SEGMENTS = new Route(POST, "skipSegments?videoID={video_id}&userID={user_id}&startTime={start_time}&endTime={end_time}&category={category}"); + public static final Route VOTE_ON_SEGMENT_QUALITY = new Route(POST, "voteOnSponsorTime?UUID={segment_id}&userID={user_id}&type={type}"); + public static final Route VOTE_ON_SEGMENT_CATEGORY = new Route(POST, "voteOnSponsorTime?UUID={segment_id}&userID={user_id}&category={category}"); + + private final String route; + private final Method method; + private final int paramCount; + + private Route(Method method, String route) { + this.method = method; + this.route = route; + this.paramCount = SponsorBlockUtils.countMatches(route, '{'); + + if (paramCount != SponsorBlockUtils.countMatches(route, '}')) + throw new IllegalArgumentException("Not enough parameters"); + } + + public Method getMethod() { + return method; + } + + public CompiledRoute compile(String... params) + { + if (params.length != paramCount) + throw new IllegalArgumentException("Error Compiling Route: [" + route + "], incorrect amount of parameters provided." + + "Expected: " + paramCount + ", Provided: " + params.length); + + StringBuilder compiledRoute = new StringBuilder(route); + for (int i = 0; i < paramCount; i++) { + int paramStart = compiledRoute.indexOf("{"); + int paramEnd = compiledRoute.indexOf("}"); + compiledRoute.replace(paramStart, paramEnd + 1, params[i]); + } + return new CompiledRoute(this, compiledRoute.toString()); + } + + public static class CompiledRoute { + private final Route baseRoute; + private final String compiledRoute; + + private CompiledRoute(Route baseRoute, String compiledRoute) { + this.baseRoute = baseRoute; + this.compiledRoute = compiledRoute; + } + + public Route getBaseRoute() { + return baseRoute; + } + + public String getCompiledRoute() { + return compiledRoute; + } + + public Method getMethod() { + return baseRoute.method; + } + } + + public enum Method { + GET, + POST + } +} \ No newline at end of file From 6038d8d318448e33b94bed17bd135ec94af77354 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 16:44:33 +0200 Subject: [PATCH 29/56] cleanup imports --- .../sponsors/player/ui/SkipSponsorButton.java | 4 ---- app/src/main/java/pl/jakubweg/ShieldButton.java | 1 - .../main/java/pl/jakubweg/SponsorBlockUtils.java | 13 ------------- app/src/main/java/pl/jakubweg/VotingButton.java | 1 - build.gradle | 6 +++--- 5 files changed, 3 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SkipSponsorButton.java b/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SkipSponsorButton.java index 17446b90..925e28f8 100644 --- a/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SkipSponsorButton.java +++ b/app/src/main/java/fi/vanced/libraries/youtube/sponsors/player/ui/SkipSponsorButton.java @@ -1,20 +1,16 @@ package fi.vanced.libraries.youtube.sponsors.player.ui; import android.content.Context; -import android.content.res.ColorStateList; import android.content.res.Resources; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.ColorDrawable; -import android.graphics.drawable.RippleDrawable; import android.os.Build; import android.util.AttributeSet; import android.util.Log; -import android.util.TypedValue; import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; -import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; diff --git a/app/src/main/java/pl/jakubweg/ShieldButton.java b/app/src/main/java/pl/jakubweg/ShieldButton.java index 0acaf4f3..6e15540c 100644 --- a/app/src/main/java/pl/jakubweg/ShieldButton.java +++ b/app/src/main/java/pl/jakubweg/ShieldButton.java @@ -1,7 +1,6 @@ package pl.jakubweg; import android.content.Context; -import android.content.SharedPreferences; import android.util.Log; import android.view.View; import android.view.animation.Animation; diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index aa9399ba..24943665 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -4,8 +4,6 @@ import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; -import android.os.Handler; -import android.os.Looper; import android.text.Html; import android.util.Log; import android.view.View; @@ -13,22 +11,13 @@ import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; -import org.json.JSONArray; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; import java.lang.ref.WeakReference; -import java.net.HttpURLConnection; -import java.net.URL; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.List; -import java.util.Locale; import java.util.Objects; import java.util.TimeZone; @@ -38,11 +27,9 @@ import pl.jakubweg.requests.Requester; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static fi.razerman.youtube.XGlobals.debug; -import static pl.jakubweg.PlayerController.VERBOSE; import static pl.jakubweg.PlayerController.getCurrentVideoId; import static pl.jakubweg.PlayerController.getLastKnownVideoTime; import static pl.jakubweg.PlayerController.sponsorSegmentsOfCurrentVideo; -import static pl.jakubweg.SponsorBlockSettings.uuid; import static pl.jakubweg.StringRef.str; import static pl.jakubweg.requests.Requester.voteForSegment; diff --git a/app/src/main/java/pl/jakubweg/VotingButton.java b/app/src/main/java/pl/jakubweg/VotingButton.java index 9b9f558b..7d5d61aa 100644 --- a/app/src/main/java/pl/jakubweg/VotingButton.java +++ b/app/src/main/java/pl/jakubweg/VotingButton.java @@ -1,7 +1,6 @@ package pl.jakubweg; import android.content.Context; -import android.content.SharedPreferences; import android.util.Log; import android.view.View; import android.view.animation.Animation; diff --git a/build.gradle b/build.gradle index 996b567e..ff0783ab 100644 --- a/build.gradle +++ b/build.gradle @@ -2,10 +2,10 @@ buildscript { repositories { google() - jcenter() + mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:4.2.1' + classpath 'com.android.tools.build:gradle:4.2.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files @@ -15,7 +15,7 @@ buildscript { allprojects { repositories { google() - jcenter() + mavenCentral() } } From dfe62274fda061f191b583b14d3cda9fc7a6e300 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 17:14:16 +0200 Subject: [PATCH 30/56] fix requesting segments --- app/src/main/java/pl/jakubweg/SponsorBlockSettings.java | 2 +- app/src/main/java/pl/jakubweg/requests/Requester.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 165d5ff0..4a290724 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -36,7 +36,7 @@ public class SponsorBlockSettings { public static boolean countSkips = true; public static int adjustNewSegmentMillis = 150; public static String uuid = ""; - private static String sponsorBlockUrlCategories = "[]"; + public static String sponsorBlockUrlCategories = "[]"; @SuppressWarnings("unused") @Deprecated diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index af9a3fcb..fcfc0d30 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -34,7 +34,7 @@ public class Requester { public static synchronized SponsorSegment[] getSegments(String videoId) { List segments = new ArrayList<>(); try { - HttpURLConnection connection = getConnectionFromRoute(Route.GET_SEGMENTS, videoId); + HttpURLConnection connection = getConnectionFromRoute(Route.GET_SEGMENTS, videoId, SponsorBlockSettings.sponsorBlockUrlCategories); int responseCode = connection.getResponseCode(); switch (responseCode) { From 8cbd0b7104e18070b2c732b48070196eb6c74390 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 17:32:06 +0200 Subject: [PATCH 31/56] cleanup more stuff --- .../java/pl/jakubweg/PlayerController.java | 4 +- .../SponsorBlockPreferenceFragment.java | 73 +++++++------------ .../pl/jakubweg/SponsorBlockSettings.java | 45 ++++++------ .../java/pl/jakubweg/SponsorBlockUtils.java | 4 +- .../main/java/pl/jakubweg/requests/Route.java | 3 +- 5 files changed, 53 insertions(+), 76 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 808a9643..e725f27a 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -266,7 +266,7 @@ public class PlayerController { private static void sendViewRequestAsync(final long millis, final SponsorSegment segment) { new Thread(() -> { if (SponsorBlockSettings.countSkips && - segment.category != SponsorBlockSettings.SegmentInfo.Unsubmitted && + segment.category != SponsorBlockSettings.SegmentInfo.UNSUBMITTED && millis - segment.start < 2000) { // Only skips from the start should count as a view Requester.sendViewCountRequest(segment); @@ -495,7 +495,7 @@ public class PlayerController { skipToMillisecond(segment.end + 2); SkipSegmentView.hide(); - if (segment.category == SponsorBlockSettings.SegmentInfo.Unsubmitted) { + if (segment.category == SponsorBlockSettings.SegmentInfo.UNSUBMITTED) { SponsorSegment[] newSegments = new SponsorSegment[sponsorSegmentsOfCurrentVideo.length - 1]; int i = 0; for (SponsorSegment sponsorSegment : sponsorSegmentsOfCurrentVideo) { diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index fb3f667e..e04caf7d 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -3,7 +3,6 @@ package pl.jakubweg; import android.app.Activity; import android.app.AlertDialog; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; @@ -39,7 +38,7 @@ import static pl.jakubweg.StringRef.str; @SuppressWarnings({"unused", "deprecation"}) // injected public class SponsorBlockPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { - private ArrayList preferencesToDisableWhenSBDisabled = new ArrayList<>(); + private final ArrayList preferencesToDisableWhenSBDisabled = new ArrayList<>(); @Override public void onCreate(Bundle savedInstanceState) { @@ -63,13 +62,10 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement preference.setChecked(SponsorBlockSettings.isSponsorBlockEnabled); preference.setTitle(str("enable_sb")); preference.setSummary(str("enable_sb_sum")); - preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object newValue) { - final boolean value = (Boolean) newValue; - enableCategoriesIfNeeded(value); - return true; - } + preference.setOnPreferenceChangeListener((preference1, newValue) -> { + final boolean value = (Boolean) newValue; + enableCategoriesIfNeeded(value); + return true; }); } @@ -82,25 +78,17 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement preference.setTitle(str("enable_segmadding")); preference.setSummary(str("enable_segmadding_sum")); preferencesToDisableWhenSBDisabled.add(preference); - preference.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object o) { - final boolean value = (Boolean) o; - if (value && !SponsorBlockSettings.seenGuidelinesPopup) { - new AlertDialog.Builder(preference.getContext()) - .setTitle(str("sb_guidelines_popup_title")) - .setMessage(str("sb_guidelines_popup_content")) - .setNegativeButton(str("sb_guidelines_popup_already_read"), null) - .setPositiveButton(str("sb_guidelines_popup_open"), new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - openGuidelines(); - } - }) - .show(); - } - return true; + preference.setOnPreferenceChangeListener((preference12, o) -> { + final boolean value = (Boolean) o; + if (value && !SponsorBlockSettings.seenGuidelinesPopup) { + new AlertDialog.Builder(preference12.getContext()) + .setTitle(str("sb_guidelines_popup_title")) + .setMessage(str("sb_guidelines_popup_content")) + .setNegativeButton(str("sb_guidelines_popup_already_read"), null) + .setPositiveButton(str("sb_guidelines_popup_open"), (dialogInterface, i) -> openGuidelines()) + .show(); } + return true; }); } @@ -181,14 +169,11 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement screen.addPreference(preference); preference.setTitle(str("about_api")); preference.setSummary(str("about_api_sum")); - preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse("http://sponsor.ajay.app")); - preference.getContext().startActivity(i); - return false; - } + preference.setOnPreferenceClickListener(preference1 -> { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse("http://sponsor.ajay.app")); + preference1.getContext().startActivity(i); + return false; }); } @@ -210,12 +195,9 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement Preference preference = new Preference(context); preference.setTitle(str("sb_guidelines_preference_title")); preference.setSummary(str("sb_guidelines_preference_sum")); - preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - openGuidelines(); - return false; - } + preference.setOnPreferenceClickListener(preference1 -> { + openGuidelines(); + return false; }); screen.addPreference(preference); } @@ -226,12 +208,9 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement preference.setSummary(str("general_skiptoast_sum")); preference.setKey(PREFERENCES_KEY_SHOW_TOAST_WHEN_SKIP); preference.setDefaultValue(showToastWhenSkippedAutomatically); - preference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - Toast.makeText(preference.getContext(), str("skipped_sponsor"), Toast.LENGTH_SHORT).show(); - return false; - } + preference.setOnPreferenceClickListener(preference12 -> { + Toast.makeText(preference12.getContext(), str("skipped_sponsor"), Toast.LENGTH_SHORT).show(); + return false; }); preferencesToDisableWhenSBDisabled.add(preference); screen.addPreference(preference); diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 4a290724..80e74250 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -26,7 +26,7 @@ public class SponsorBlockSettings { public static final String PREFERENCES_KEY_NEW_SEGMENT_ENABLED = "sb-new-segment-enabled"; public static final String PREFERENCES_KEY_VOTING_ENABLED = "sb-voting-enabled"; - public static final SegmentBehaviour DefaultBehaviour = SegmentBehaviour.SkipAutomatically; + public static final SegmentBehaviour DefaultBehaviour = SegmentBehaviour.SKIP_AUTOMATICALLY; public static boolean isSponsorBlockEnabled = false; public static boolean seenGuidelinesPopup = false; @@ -108,7 +108,7 @@ public class SponsorBlockSettings { } //"[%22sponsor%22,%22outro%22,%22music_offtopic%22,%22intro%22,%22selfpromo%22,%22interaction%22,%22preview%22]"; - if (enabledCategories.size() == 0) + if (enabledCategories.isEmpty()) sponsorBlockUrlCategories = "[]"; else sponsorBlockUrlCategories = "[%22" + TextUtils.join("%22,%22", enabledCategories) + "%22]"; @@ -132,9 +132,9 @@ public class SponsorBlockSettings { } public enum SegmentBehaviour { - SkipAutomatically("skip", sf("skip_automatically"), true, true), - ManualSkip("manual-skip", sf("skip_showbutton"), false, true), - Ignore("ignore", sf("skip_ignore"), false, false); + SKIP_AUTOMATICALLY("skip", sf("skip_automatically"), true, true), + MANUAL_SKIP("manual-skip", sf("skip_showbutton"), false, true), + IGNORE("ignore", sf("skip_ignore"), false, false); public final String key; public final StringRef name; @@ -153,26 +153,25 @@ public class SponsorBlockSettings { } public enum SegmentInfo { - Sponsor("sponsor", sf("segments_sponsor"), sf("skipped_sponsor"), sf("segments_sponsor_sum"), null, 0xFF00d400), - Intro("intro", sf("segments_intermission"), sf("skipped_intermission"), sf("segments_intermission_sum"), null, 0xFF00ffff), - Outro("outro", sf("segments_endcards"), sf("skipped_endcard"), sf("segments_endcards_sum"), null, 0xFF0202ed), - Interaction("interaction", sf("segments_subscribe"), sf("skipped_subscribe"), sf("segments_subscribe_sum"), null, 0xFFcc00ff), - SelfPromo("selfpromo", sf("segments_selfpromo"), sf("skipped_selfpromo"), sf("segments_selfpromo_sum"), null, 0xFFffff00), - MusicOfftopic("music_offtopic", sf("segments_nomusic"), sf("skipped_nomusic"), sf("segments_nomusic_sum"), null, 0xFFff9900), - Preview("preview", sf("segments_preview"), sf("skipped_preview"), sf("segments_preview_sum"), null, 0xFF008fd6), - Unsubmitted("unsubmitted", StringRef.empty, sf("skipped_unsubmitted"), StringRef.empty, SegmentBehaviour.SkipAutomatically, 0xFFFFFFFF), - ; + SPONSOR("sponsor", sf("segments_sponsor"), sf("skipped_sponsor"), sf("segments_sponsor_sum"), null, 0xFF00d400), + INTRO("intro", sf("segments_intermission"), sf("skipped_intermission"), sf("segments_intermission_sum"), null, 0xFF00ffff), + OUTRO("outro", sf("segments_endcards"), sf("skipped_endcard"), sf("segments_endcards_sum"), null, 0xFF0202ed), + INTERACTION("interaction", sf("segments_subscribe"), sf("skipped_subscribe"), sf("segments_subscribe_sum"), null, 0xFFcc00ff), + SELF_PROMO("selfpromo", sf("segments_selfpromo"), sf("skipped_selfpromo"), sf("segments_selfpromo_sum"), null, 0xFFffff00), + MUSIC_OFFTOPIC("music_offtopic", sf("segments_nomusic"), sf("skipped_nomusic"), sf("segments_nomusic_sum"), null, 0xFFff9900), + PREVIEW("preview", sf("segments_preview"), sf("skipped_preview"), sf("segments_preview_sum"), null, 0xFF008fd6), + UNSUBMITTED("unsubmitted", StringRef.empty, sf("skipped_unsubmitted"), StringRef.empty, SegmentBehaviour.SKIP_AUTOMATICALLY, 0xFFFFFFFF),; - private static SegmentInfo[] mValuesWithoutUnsubmitted = new SegmentInfo[]{ - Sponsor, - Intro, - Outro, - Interaction, - SelfPromo, - MusicOfftopic, - Preview + private static final SegmentInfo[] mValuesWithoutUnsubmitted = new SegmentInfo[]{ + SPONSOR, + INTRO, + OUTRO, + INTERACTION, + SELF_PROMO, + MUSIC_OFFTOPIC, + PREVIEW }; - private static Map mValuesMap = new HashMap<>(8); + private static final Map mValuesMap = new HashMap<>(8); static { for (SegmentInfo value : valuesWithoutUnsubmitted()) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 24943665..517e27ef 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -307,7 +307,7 @@ public abstract class SponsorBlockUtils { List titles = new ArrayList<>(segmentAmount); // I've replaced an array with a list to prevent null elements in the array as unsubmitted segments get filtered out for (int i = 0; i < segmentAmount; i++) { SponsorSegment segment = sponsorSegmentsOfCurrentVideo[i]; - if (segment.category == SponsorBlockSettings.SegmentInfo.Unsubmitted) { + if (segment.category == SponsorBlockSettings.SegmentInfo.UNSUBMITTED) { continue; } @@ -350,7 +350,7 @@ public abstract class SponsorBlockUtils { final SponsorSegment[] segments = original == null ? new SponsorSegment[1] : Arrays.copyOf(original, original.length + 1); segments[segments.length - 1] = new SponsorSegment(newSponsorSegmentStartMillis, newSponsorSegmentEndMillis, - SponsorBlockSettings.SegmentInfo.Unsubmitted, null); + SponsorBlockSettings.SegmentInfo.UNSUBMITTED, null); Arrays.sort(segments); sponsorSegmentsOfCurrentVideo = segments; diff --git a/app/src/main/java/pl/jakubweg/requests/Route.java b/app/src/main/java/pl/jakubweg/requests/Route.java index 5cbf44e1..2fccac49 100644 --- a/app/src/main/java/pl/jakubweg/requests/Route.java +++ b/app/src/main/java/pl/jakubweg/requests/Route.java @@ -29,8 +29,7 @@ public class Route { return method; } - public CompiledRoute compile(String... params) - { + public CompiledRoute compile(String... params) { if (params.length != paramCount) throw new IllegalArgumentException("Error Compiling Route: [" + route + "], incorrect amount of parameters provided." + "Expected: " + paramCount + ", Provided: " + params.length); From 52aeeded2002fded5287b7ff73da67a3c3e9839a Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 18:54:26 +0200 Subject: [PATCH 32/56] we show stats now --- .../SponsorBlockPreferenceFragment.java | 50 ++++++++++++++++++- .../java/pl/jakubweg/requests/Requester.java | 13 ++++- .../main/java/pl/jakubweg/requests/Route.java | 7 +-- 3 files changed, 65 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index e04caf7d..ee56fb07 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -17,8 +17,13 @@ import android.preference.SwitchPreference; import android.text.InputType; import android.widget.Toast; +import java.text.DecimalFormat; import java.util.ArrayList; +import pl.jakubweg.objects.UserStats; +import pl.jakubweg.requests.Requester; + +import static android.text.Html.fromHtml; import static pl.jakubweg.SponsorBlockSettings.DefaultBehaviour; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_ADJUST_NEW_SEGMENT_STEP; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_COUNT_SKIPS; @@ -37,7 +42,7 @@ import static pl.jakubweg.StringRef.str; @SuppressWarnings({"unused", "deprecation"}) // injected public class SponsorBlockPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { - + private static final DecimalFormat FORMATTER = new DecimalFormat("#,###,###"); private final ArrayList preferencesToDisableWhenSBDisabled = new ArrayList<>(); @Override @@ -105,6 +110,7 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement addGeneralCategory(context, preferenceScreen); addSegmentsCategory(context, preferenceScreen); + addStatsCategory(context, preferenceScreen); addAboutCategory(context, preferenceScreen); enableCategoriesIfNeeded(SponsorBlockSettings.isSponsorBlockEnabled); @@ -159,6 +165,48 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement } + private void addStatsCategory(Context context, PreferenceScreen screen) { + PreferenceCategory category = new PreferenceCategory(context); + screen.addPreference(category); + category.setTitle("stats"); + + UserStats stats = Requester.getUserStats(); + + { + EditTextPreference preference = new EditTextPreference(context); + screen.addPreference(preference); + String userName = stats.getUserName(); + preference.setTitle(fromHtml("Your username: " + userName + "")); + preference.setSummary("Click to change your username"); + preference.setText(userName); + preference.setOnPreferenceChangeListener((preference1, newUsername) -> { + Requester.setUsername((String) newUsername); + return false; + }); + } + + { + Preference preference = new Preference(context); + screen.addPreference(preference); + String formatted = FORMATTER.format(stats.getSegmentCount()); + preference.setTitle(fromHtml("Submissions: " + formatted + "")); + } + + { + Preference preference = new Preference(context); + screen.addPreference(preference); + String formatted = FORMATTER.format(stats.getViewCount()); + + double saved = stats.getMinutesSaved(); + int hoursSaved = (int) (saved / 60); + double minutesSaved = saved % 60; + String formattedSaved = String.format("%dh %.1f minutes", hoursSaved, minutesSaved); + + preference.setTitle(fromHtml("You've saved people from " + formatted + " segments.")); + preference.setSummary(fromHtml("That's " + formattedSaved + " of their lives.")); + } + } + private void addAboutCategory(Context context, PreferenceScreen screen) { PreferenceCategory category = new PreferenceCategory(context); screen.addPreference(category); diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index fcfc0d30..97bdf66c 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -3,6 +3,7 @@ package pl.jakubweg.requests; import android.content.Context; import android.os.Handler; import android.os.Looper; +import android.util.Log; import android.widget.Toast; import org.json.JSONArray; @@ -152,7 +153,17 @@ public class Requester { catch (Exception ex) { ex.printStackTrace(); } - return new UserStats("", 0, 0, 0); + return new UserStats("N/A", -1, -1, -1); + } + + public static void setUsername(String username) { + try { + HttpURLConnection connection = getConnectionFromRoute(Route.CHANGE_USERNAME, SponsorBlockSettings.uuid, username); + connection.disconnect(); + } + catch (Exception ex) { + ex.printStackTrace(); + } } private static HttpURLConnection getConnectionFromRoute(Route route, String... params) throws IOException { diff --git a/app/src/main/java/pl/jakubweg/requests/Route.java b/app/src/main/java/pl/jakubweg/requests/Route.java index 2fccac49..86b1c634 100644 --- a/app/src/main/java/pl/jakubweg/requests/Route.java +++ b/app/src/main/java/pl/jakubweg/requests/Route.java @@ -7,7 +7,8 @@ import static pl.jakubweg.requests.Route.Method.*; public class Route { public static final Route GET_SEGMENTS = new Route(GET, "skipSegments?videoID={video_id}&categories={categories}"); public static final Route VIEWED_SEGMENT = new Route(POST, "viewedVideoSponsorTime?UUID={segment_id}"); - public static final Route GET_USER_STATS = new Route(GET, "userInfo"); + public static final Route GET_USER_STATS = new Route(GET, "userInfo?userID={user_id}"); + public static final Route CHANGE_USERNAME = new Route(POST, "setUsername?userID={user_id}&username={username}"); public static final Route SUBMIT_SEGMENTS = new Route(POST, "skipSegments?videoID={video_id}&userID={user_id}&startTime={start_time}&endTime={end_time}&category={category}"); public static final Route VOTE_ON_SEGMENT_QUALITY = new Route(POST, "voteOnSponsorTime?UUID={segment_id}&userID={user_id}&type={type}"); public static final Route VOTE_ON_SEGMENT_CATEGORY = new Route(POST, "voteOnSponsorTime?UUID={segment_id}&userID={user_id}&category={category}"); @@ -31,8 +32,8 @@ public class Route { public CompiledRoute compile(String... params) { if (params.length != paramCount) - throw new IllegalArgumentException("Error Compiling Route: [" + route + "], incorrect amount of parameters provided." + - "Expected: " + paramCount + ", Provided: " + params.length); + throw new IllegalArgumentException("Error compiling route [" + route + "], incorrect amount of parameters provided. " + + "Expected: " + paramCount + ", provided: " + params.length); StringBuilder compiledRoute = new StringBuilder(route); for (int i = 0; i < paramCount; i++) { From eb8b6117b927b7c061d692bade3ef232990df53d Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 21:51:26 +0200 Subject: [PATCH 33/56] add local skips tracking --- .../java/pl/jakubweg/PlayerController.java | 13 +++++ .../SponsorBlockPreferenceFragment.java | 47 ++++++++++++++----- .../pl/jakubweg/SponsorBlockSettings.java | 6 +++ .../java/pl/jakubweg/SponsorBlockUtils.java | 4 +- app/src/main/java/pl/jakubweg/StringRef.java | 14 +++++- .../java/pl/jakubweg/requests/Requester.java | 8 +++- .../main/java/pl/jakubweg/requests/Route.java | 2 +- app/src/main/res/values/strings.xml | 8 ++++ 8 files changed, 85 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index e725f27a..5a2c48b3 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -3,6 +3,7 @@ package pl.jakubweg; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; +import android.content.SharedPreferences; import android.graphics.Canvas; import android.graphics.Rect; import android.os.Handler; @@ -24,6 +25,9 @@ import fi.vanced.libraries.youtube.player.VideoInformation; import pl.jakubweg.objects.SponsorSegment; import pl.jakubweg.requests.Requester; +import static pl.jakubweg.SponsorBlockSettings.skippedSegments; +import static pl.jakubweg.SponsorBlockSettings.skippedTime; + @SuppressLint({"LongLogTag"}) public class PlayerController { public static final String TAG = "jakubweg.PlayerController"; @@ -264,6 +268,15 @@ public class PlayerController { } private static void sendViewRequestAsync(final long millis, final SponsorSegment segment) { + if (segment.category != SponsorBlockSettings.SegmentInfo.UNSUBMITTED) { + Context context = YouTubeTikTokRoot_Application.getAppContext(); + if (context != null) { + SharedPreferences preferences = SponsorBlockSettings.getPreferences(context); + long newSkippedTime = skippedTime + segment.end - segment.start; + preferences.edit().putInt(SponsorBlockSettings.PREFERENCES_KEY_SKIPPED_SEGMENTS, skippedSegments + 1).apply(); + preferences.edit().putLong(SponsorBlockSettings.PREFERENCES_KEY_SKIPPED_SEGMENTS_TIME, newSkippedTime).apply(); + } + } new Thread(() -> { if (SponsorBlockSettings.countSkips && segment.category != SponsorBlockSettings.SegmentInfo.UNSUBMITTED && diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index ee56fb07..ec39f50b 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -15,10 +15,12 @@ import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.preference.SwitchPreference; import android.text.InputType; +import android.util.Log; import android.widget.Toast; import java.text.DecimalFormat; import java.util.ArrayList; +import java.util.concurrent.TimeUnit; import pl.jakubweg.objects.UserStats; import pl.jakubweg.requests.Requester; @@ -37,12 +39,15 @@ import static pl.jakubweg.SponsorBlockSettings.adjustNewSegmentMillis; import static pl.jakubweg.SponsorBlockSettings.countSkips; import static pl.jakubweg.SponsorBlockSettings.setSeenGuidelines; import static pl.jakubweg.SponsorBlockSettings.showToastWhenSkippedAutomatically; +import static pl.jakubweg.SponsorBlockSettings.skippedSegments; +import static pl.jakubweg.SponsorBlockSettings.skippedTime; import static pl.jakubweg.SponsorBlockSettings.uuid; import static pl.jakubweg.StringRef.str; @SuppressWarnings({"unused", "deprecation"}) // injected public class SponsorBlockPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { private static final DecimalFormat FORMATTER = new DecimalFormat("#,###,###"); + private static final String SAVED_TEMPLATE = "%dh %.1f minutes"; private final ArrayList preferencesToDisableWhenSBDisabled = new ArrayList<>(); @Override @@ -168,16 +173,17 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement private void addStatsCategory(Context context, PreferenceScreen screen) { PreferenceCategory category = new PreferenceCategory(context); screen.addPreference(category); - category.setTitle("stats"); + category.setTitle(str("stats")); + preferencesToDisableWhenSBDisabled.add(category); UserStats stats = Requester.getUserStats(); { EditTextPreference preference = new EditTextPreference(context); - screen.addPreference(preference); + category.addPreference(preference); String userName = stats.getUserName(); - preference.setTitle(fromHtml("Your username: " + userName + "")); - preference.setSummary("Click to change your username"); + preference.setTitle(fromHtml(str("stats_username", userName))); + preference.setSummary(str("stats_username_change")); preference.setText(userName); preference.setOnPreferenceChangeListener((preference1, newUsername) -> { Requester.setUsername((String) newUsername); @@ -187,23 +193,42 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement { Preference preference = new Preference(context); - screen.addPreference(preference); + category.addPreference(preference); String formatted = FORMATTER.format(stats.getSegmentCount()); - preference.setTitle(fromHtml("Submissions: " + formatted + "")); + preference.setTitle(fromHtml(str("stats_submissions", formatted))); } { Preference preference = new Preference(context); - screen.addPreference(preference); + category.addPreference(preference); String formatted = FORMATTER.format(stats.getViewCount()); double saved = stats.getMinutesSaved(); int hoursSaved = (int) (saved / 60); double minutesSaved = saved % 60; - String formattedSaved = String.format("%dh %.1f minutes", hoursSaved, minutesSaved); + String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); - preference.setTitle(fromHtml("You've saved people from " + formatted + " segments.")); - preference.setSummary(fromHtml("That's " + formattedSaved + " of their lives.")); + preference.setTitle(fromHtml(str("stats_saved", formatted))); + preference.setSummary(fromHtml(str("stats_saved_sum", formattedSaved))); + preference.setOnPreferenceClickListener(preference1 -> { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse("https://sponsor.ajay.app/stats/")); + preference1.getContext().startActivity(i); + return false; + }); + } + + { + Preference preference = new Preference(context); + category.addPreference(preference); + String formatted = FORMATTER.format(skippedSegments); + + long hoursSaved = skippedTime / 3600000; + double minutesSaved = (skippedTime / 60000d) % 60; + String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); + + preference.setTitle(fromHtml(str("stats_self_saved", formatted))); + preference.setSummary(fromHtml(str("stats_self_saved_sum", formattedSaved))); } } @@ -219,7 +244,7 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement preference.setSummary(str("about_api_sum")); preference.setOnPreferenceClickListener(preference1 -> { Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse("http://sponsor.ajay.app")); + i.setData(Uri.parse("https://sponsor.ajay.app")); preference1.getContext().startActivity(i); return false; }); diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 80e74250..8ab81f27 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -25,6 +25,8 @@ public class SponsorBlockSettings { public static final String PREFERENCES_KEY_SEEN_GUIDELINES = "sb-seen-gl"; public static final String PREFERENCES_KEY_NEW_SEGMENT_ENABLED = "sb-new-segment-enabled"; public static final String PREFERENCES_KEY_VOTING_ENABLED = "sb-voting-enabled"; + public static final String PREFERENCES_KEY_SKIPPED_SEGMENTS = "sb-skipped-segments"; + public static final String PREFERENCES_KEY_SKIPPED_SEGMENTS_TIME = "sb-skipped-segments-time"; public static final SegmentBehaviour DefaultBehaviour = SegmentBehaviour.SKIP_AUTOMATICALLY; @@ -37,6 +39,8 @@ public class SponsorBlockSettings { public static int adjustNewSegmentMillis = 150; public static String uuid = ""; public static String sponsorBlockUrlCategories = "[]"; + public static int skippedSegments; + public static long skippedTime; @SuppressWarnings("unused") @Deprecated @@ -113,6 +117,8 @@ public class SponsorBlockSettings { else sponsorBlockUrlCategories = "[%22" + TextUtils.join("%22,%22", enabledCategories) + "%22]"; + skippedSegments = preferences.getInt(PREFERENCES_KEY_SKIPPED_SEGMENTS, skippedSegments); + skippedTime = preferences.getLong(PREFERENCES_KEY_SKIPPED_SEGMENTS_TIME, skippedTime); showToastWhenSkippedAutomatically = preferences.getBoolean(PREFERENCES_KEY_SHOW_TOAST_WHEN_SKIP, showToastWhenSkippedAutomatically); String tmp1 = preferences.getString(PREFERENCES_KEY_ADJUST_NEW_SEGMENT_STEP, null); diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 517e27ef..2047e1ec 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -268,7 +268,7 @@ public abstract class SponsorBlockUtils { new AlertDialog.Builder(context) .setTitle(str("new_segment_title")) - .setMessage(String.format(str("new_segment_mark_time_as_question"), + .setMessage(str("new_segment_mark_time_as_question", newSponsorSegmentDialogShownMillis / 60000, newSponsorSegmentDialogShownMillis / 1000 % 60, newSponsorSegmentDialogShownMillis % 1000)) @@ -286,7 +286,7 @@ public abstract class SponsorBlockUtils { long end = (newSponsorSegmentEndMillis) / 1000; new AlertDialog.Builder(context) .setTitle(str("new_segment_confirm_title")) - .setMessage(String.format(str("new_segment_confirm_content"), + .setMessage(str("new_segment_confirm_content", start / 60, start % 60, end / 60, end % 60, length / 60, length % 60)) diff --git a/app/src/main/java/pl/jakubweg/StringRef.java b/app/src/main/java/pl/jakubweg/StringRef.java index efd55c63..903b3a71 100644 --- a/app/src/main/java/pl/jakubweg/StringRef.java +++ b/app/src/main/java/pl/jakubweg/StringRef.java @@ -24,7 +24,7 @@ public class StringRef { packageName = context.getPackageName(); } - private static HashMap strings = new HashMap<>(); + private static final HashMap strings = new HashMap<>(); /** * Gets strings reference from shared collection or creates if not exists yet, @@ -52,6 +52,18 @@ public class StringRef { return sf(id).toString(); } + /** + * Gets string value by string id, shorthand for sf(id).toString() and formats the string + * with given args. + * @param id string resource name/id + * @param args the args to format the string with + * @return String value from string.xml formatted with given args + */ + @NonNull + public static String str(@NonNull String id, Object... args) { + return String.format(str(id), args); + } + /** * Creates a StringRef object that'll not change it's value diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index 97bdf66c..c5d19039 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -131,7 +131,7 @@ public class Requester { SponsorBlockUtils.messageToToast = str("vote_failed_rate_limit"); break; default: - SponsorBlockUtils.messageToToast = String.format(str("vote_failed_unknown_error"), responseCode, connection.getResponseMessage()); + SponsorBlockUtils.messageToToast = str("vote_failed_unknown_error", responseCode, connection.getResponseMessage()); break; } new Handler(Looper.getMainLooper()).post(toastRunnable); @@ -143,6 +143,10 @@ public class Requester { } public static UserStats getUserStats() { + UserStats defaultStats = new UserStats("N/A", -1, -1, -1); + if (!SponsorBlockSettings.isSponsorBlockEnabled) + return defaultStats; + try { HttpURLConnection connection = getConnectionFromRoute(Route.GET_USER_STATS, SponsorBlockSettings.uuid); JSONObject json = new JSONObject(parseJson(connection)); @@ -153,7 +157,7 @@ public class Requester { catch (Exception ex) { ex.printStackTrace(); } - return new UserStats("N/A", -1, -1, -1); + return defaultStats; } public static void setUsername(String username) { diff --git a/app/src/main/java/pl/jakubweg/requests/Route.java b/app/src/main/java/pl/jakubweg/requests/Route.java index 86b1c634..bf326c39 100644 --- a/app/src/main/java/pl/jakubweg/requests/Route.java +++ b/app/src/main/java/pl/jakubweg/requests/Route.java @@ -7,7 +7,7 @@ import static pl.jakubweg.requests.Route.Method.*; public class Route { public static final Route GET_SEGMENTS = new Route(GET, "skipSegments?videoID={video_id}&categories={categories}"); public static final Route VIEWED_SEGMENT = new Route(POST, "viewedVideoSponsorTime?UUID={segment_id}"); - public static final Route GET_USER_STATS = new Route(GET, "userInfo?userID={user_id}"); + public static final Route GET_USER_STATS = new Route(GET, "userInfo?userID={user_id}&values=[\"userName\", \"minutesSaved\", \"segmentCount\", \"viewCount\"]"); public static final Route CHANGE_USERNAME = new Route(POST, "setUsername?userID={user_id}&username={username}"); public static final Route SUBMIT_SEGMENTS = new Route(POST, "skipSegments?videoID={video_id}&userID={user_id}&startTime={start_time}&endTime={end_time}&category={category}"); public static final Route VOTE_ON_SEGMENT_QUALITY = new Route(POST, "voteOnSponsorTime?UUID={segment_id}&userID={user_id}&type={type}"); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7b1d5fed..2ac3e7bc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -180,6 +180,14 @@ Skip automatically Show a skip button Don\'t do anything + Stats + Your username: <b>%s</b> + Click to change your username + Submissions: <b>%s</b> + You\'ve saved people from <b>%s</b> segments. + That\'s <b>%s</b> of their lives. Click to see the leaderboard + You\'ve skipped <b>%s</b> segments. + That\'s <b>%s</b>. About This app uses the API from Sponsor Block Tap to learn more, and see downloads for other platforms at: sponsor.ajay.app From 1cbf1603de9aba6a9fb42069ab97e6f17b8dcb0a Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 21:53:28 +0200 Subject: [PATCH 34/56] make sure nothing weird happens here --- app/src/main/java/pl/jakubweg/PlayerController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 5a2c48b3..388819a9 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -272,7 +272,7 @@ public class PlayerController { Context context = YouTubeTikTokRoot_Application.getAppContext(); if (context != null) { SharedPreferences preferences = SponsorBlockSettings.getPreferences(context); - long newSkippedTime = skippedTime + segment.end - segment.start; + long newSkippedTime = skippedTime + (segment.end - segment.start); preferences.edit().putInt(SponsorBlockSettings.PREFERENCES_KEY_SKIPPED_SEGMENTS, skippedSegments + 1).apply(); preferences.edit().putLong(SponsorBlockSettings.PREFERENCES_KEY_SKIPPED_SEGMENTS_TIME, newSkippedTime).apply(); } From 76591f180e3b4b2c08e15f6bd8f271a8fa673586 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 21:55:15 +0200 Subject: [PATCH 35/56] optimize imports --- .../main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java | 2 -- app/src/main/java/pl/jakubweg/requests/Requester.java | 1 - 2 files changed, 3 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index ec39f50b..0bb01c52 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -15,12 +15,10 @@ import android.preference.PreferenceFragment; import android.preference.PreferenceScreen; import android.preference.SwitchPreference; import android.text.InputType; -import android.util.Log; import android.widget.Toast; import java.text.DecimalFormat; import java.util.ArrayList; -import java.util.concurrent.TimeUnit; import pl.jakubweg.objects.UserStats; import pl.jakubweg.requests.Requester; diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index c5d19039..903922ff 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -3,7 +3,6 @@ package pl.jakubweg.requests; import android.content.Context; import android.os.Handler; import android.os.Looper; -import android.util.Log; import android.widget.Toast; import org.json.JSONArray; From 1cd5732fe9a20169a964de98f85fd9df23d97023 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 21:58:28 +0200 Subject: [PATCH 36/56] remove comma weirdness --- app/src/main/java/pl/jakubweg/SponsorBlockSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 8ab81f27..6d0af356 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -166,7 +166,7 @@ public class SponsorBlockSettings { SELF_PROMO("selfpromo", sf("segments_selfpromo"), sf("skipped_selfpromo"), sf("segments_selfpromo_sum"), null, 0xFFffff00), MUSIC_OFFTOPIC("music_offtopic", sf("segments_nomusic"), sf("skipped_nomusic"), sf("segments_nomusic_sum"), null, 0xFFff9900), PREVIEW("preview", sf("segments_preview"), sf("skipped_preview"), sf("segments_preview_sum"), null, 0xFF008fd6), - UNSUBMITTED("unsubmitted", StringRef.empty, sf("skipped_unsubmitted"), StringRef.empty, SegmentBehaviour.SKIP_AUTOMATICALLY, 0xFFFFFFFF),; + UNSUBMITTED("unsubmitted", StringRef.empty, sf("skipped_unsubmitted"), StringRef.empty, SegmentBehaviour.SKIP_AUTOMATICALLY, 0xFFFFFFFF); private static final SegmentInfo[] mValuesWithoutUnsubmitted = new SegmentInfo[]{ SPONSOR, From 6748bce0e80f84b801fa895a80f5b421d95371f5 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 21:59:44 +0200 Subject: [PATCH 37/56] replace hardcoded value with dynamic getter --- app/src/main/java/pl/jakubweg/SponsorBlockSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 6d0af356..e98af06f 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -177,7 +177,7 @@ public class SponsorBlockSettings { MUSIC_OFFTOPIC, PREVIEW }; - private static final Map mValuesMap = new HashMap<>(8); + private static final Map mValuesMap = new HashMap<>(values().length + 1); static { for (SegmentInfo value : valuesWithoutUnsubmitted()) From c589b41990b3ed7c890ec116c1ee357396a2693b Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 22:01:51 +0200 Subject: [PATCH 38/56] remove wrong calc --- app/src/main/java/pl/jakubweg/SponsorBlockSettings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index e98af06f..b645e6d0 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -177,7 +177,7 @@ public class SponsorBlockSettings { MUSIC_OFFTOPIC, PREVIEW }; - private static final Map mValuesMap = new HashMap<>(values().length + 1); + private static final Map mValuesMap = new HashMap<>(values().length); static { for (SegmentInfo value : valuesWithoutUnsubmitted()) From 6f63df0ce66f912d2e99da192199754b6a053fb0 Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 23 Jul 2021 14:45:10 +0200 Subject: [PATCH 39/56] make loading stats async --- .../SponsorBlockPreferenceFragment.java | 59 +---------- .../java/pl/jakubweg/requests/Requester.java | 100 +++++++++++++++--- app/src/main/res/values/strings.xml | 2 + 3 files changed, 91 insertions(+), 70 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index 0bb01c52..188b7bce 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -20,10 +20,8 @@ import android.widget.Toast; import java.text.DecimalFormat; import java.util.ArrayList; -import pl.jakubweg.objects.UserStats; import pl.jakubweg.requests.Requester; -import static android.text.Html.fromHtml; import static pl.jakubweg.SponsorBlockSettings.DefaultBehaviour; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_ADJUST_NEW_SEGMENT_STEP; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_COUNT_SKIPS; @@ -37,15 +35,13 @@ import static pl.jakubweg.SponsorBlockSettings.adjustNewSegmentMillis; import static pl.jakubweg.SponsorBlockSettings.countSkips; import static pl.jakubweg.SponsorBlockSettings.setSeenGuidelines; import static pl.jakubweg.SponsorBlockSettings.showToastWhenSkippedAutomatically; -import static pl.jakubweg.SponsorBlockSettings.skippedSegments; -import static pl.jakubweg.SponsorBlockSettings.skippedTime; import static pl.jakubweg.SponsorBlockSettings.uuid; import static pl.jakubweg.StringRef.str; @SuppressWarnings({"unused", "deprecation"}) // injected public class SponsorBlockPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { - private static final DecimalFormat FORMATTER = new DecimalFormat("#,###,###"); - private static final String SAVED_TEMPLATE = "%dh %.1f minutes"; + public static final DecimalFormat FORMATTER = new DecimalFormat("#,###,###"); + public static final String SAVED_TEMPLATE = "%dh %.1f minutes"; private final ArrayList preferencesToDisableWhenSBDisabled = new ArrayList<>(); @Override @@ -174,59 +170,12 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement category.setTitle(str("stats")); preferencesToDisableWhenSBDisabled.add(category); - UserStats stats = Requester.getUserStats(); - - { - EditTextPreference preference = new EditTextPreference(context); - category.addPreference(preference); - String userName = stats.getUserName(); - preference.setTitle(fromHtml(str("stats_username", userName))); - preference.setSummary(str("stats_username_change")); - preference.setText(userName); - preference.setOnPreferenceChangeListener((preference1, newUsername) -> { - Requester.setUsername((String) newUsername); - return false; - }); - } - { Preference preference = new Preference(context); category.addPreference(preference); - String formatted = FORMATTER.format(stats.getSegmentCount()); - preference.setTitle(fromHtml(str("stats_submissions", formatted))); - } + preference.setTitle(str("stats_loading")); - { - Preference preference = new Preference(context); - category.addPreference(preference); - String formatted = FORMATTER.format(stats.getViewCount()); - - double saved = stats.getMinutesSaved(); - int hoursSaved = (int) (saved / 60); - double minutesSaved = saved % 60; - String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); - - preference.setTitle(fromHtml(str("stats_saved", formatted))); - preference.setSummary(fromHtml(str("stats_saved_sum", formattedSaved))); - preference.setOnPreferenceClickListener(preference1 -> { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse("https://sponsor.ajay.app/stats/")); - preference1.getContext().startActivity(i); - return false; - }); - } - - { - Preference preference = new Preference(context); - category.addPreference(preference); - String formatted = FORMATTER.format(skippedSegments); - - long hoursSaved = skippedTime / 3600000; - double minutesSaved = (skippedTime / 60000d) % 60; - String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); - - preference.setTitle(fromHtml(str("stats_self_saved", formatted))); - preference.setSummary(fromHtml(str("stats_self_saved_sum", formattedSaved))); + Requester.retrieveUserStats(category, preference); } } diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index 903922ff..73062b75 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -1,8 +1,13 @@ package pl.jakubweg.requests; import android.content.Context; +import android.content.Intent; +import android.net.Uri; import android.os.Handler; import android.os.Looper; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.PreferenceCategory; import android.widget.Toast; import org.json.JSONArray; @@ -23,6 +28,11 @@ import pl.jakubweg.SponsorBlockUtils.VoteOption; import pl.jakubweg.objects.SponsorSegment; import pl.jakubweg.objects.UserStats; +import static android.text.Html.fromHtml; +import static pl.jakubweg.SponsorBlockPreferenceFragment.FORMATTER; +import static pl.jakubweg.SponsorBlockPreferenceFragment.SAVED_TEMPLATE; +import static pl.jakubweg.SponsorBlockSettings.skippedSegments; +import static pl.jakubweg.SponsorBlockSettings.skippedTime; import static pl.jakubweg.StringRef.str; public class Requester { @@ -141,22 +151,82 @@ public class Requester { } } - public static UserStats getUserStats() { - UserStats defaultStats = new UserStats("N/A", -1, -1, -1); - if (!SponsorBlockSettings.isSponsorBlockEnabled) - return defaultStats; + @SuppressWarnings("deprecation") + public static void retrieveUserStats(PreferenceCategory category, Preference loadingPreference) { + if (!SponsorBlockSettings.isSponsorBlockEnabled) { + loadingPreference.setTitle(str("stats_sb_disabled")); + return; + } - try { - HttpURLConnection connection = getConnectionFromRoute(Route.GET_USER_STATS, SponsorBlockSettings.uuid); - JSONObject json = new JSONObject(parseJson(connection)); - connection.disconnect(); - return new UserStats(json.getString("userName"), json.getDouble("minutesSaved"), json.getInt("segmentCount"), - json.getInt("viewCount")); - } - catch (Exception ex) { - ex.printStackTrace(); - } - return defaultStats; + Context context = category.getContext(); + + new Thread(() -> { + try { + HttpURLConnection connection = getConnectionFromRoute(Route.GET_USER_STATS, SponsorBlockSettings.uuid); + JSONObject json = new JSONObject(parseJson(connection)); + connection.disconnect(); + UserStats stats = new UserStats(json.getString("userName"), json.getDouble("minutesSaved"), json.getInt("segmentCount"), + json.getInt("viewCount")); + + category.removePreference(loadingPreference); + + { + EditTextPreference preference = new EditTextPreference(context); + category.addPreference(preference); + String userName = stats.getUserName(); + preference.setTitle(fromHtml(str("stats_username", userName))); + preference.setSummary(str("stats_username_change")); + preference.setText(userName); + preference.setOnPreferenceChangeListener((preference1, newUsername) -> { + Requester.setUsername((String) newUsername); + return false; + }); + } + + { + Preference preference = new Preference(context); + category.addPreference(preference); + String formatted = FORMATTER.format(stats.getSegmentCount()); + preference.setTitle(fromHtml(str("stats_submissions", formatted))); + } + + { + Preference preference = new Preference(context); + category.addPreference(preference); + String formatted = FORMATTER.format(stats.getViewCount()); + + double saved = stats.getMinutesSaved(); + int hoursSaved = (int) (saved / 60); + double minutesSaved = saved % 60; + String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); + + preference.setTitle(fromHtml(str("stats_saved", formatted))); + preference.setSummary(fromHtml(str("stats_saved_sum", formattedSaved))); + preference.setOnPreferenceClickListener(preference1 -> { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse("https://sponsor.ajay.app/stats/")); + preference1.getContext().startActivity(i); + return false; + }); + } + + { + Preference preference = new Preference(context); + category.addPreference(preference); + String formatted = FORMATTER.format(skippedSegments); + + long hoursSaved = skippedTime / 3600000; + double minutesSaved = (skippedTime / 60000d) % 60; + String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); + + preference.setTitle(fromHtml(str("stats_self_saved", formatted))); + preference.setSummary(fromHtml(str("stats_self_saved_sum", formattedSaved))); + } + } + catch (Exception ex) { + ex.printStackTrace(); + } + }).start(); } public static void setUsername(String username) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2ac3e7bc..5c063ac9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -181,6 +181,8 @@ Show a skip button Don\'t do anything Stats + Loading.. + SponsorBlock is disabled Your username: <b>%s</b> Click to change your username Submissions: <b>%s</b> From 8b4ff63f31419284201ed912602d810feed732c5 Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 23 Jul 2021 14:56:54 +0200 Subject: [PATCH 40/56] moved appending the settings --- .../java/pl/jakubweg/SponsorBlockUtils.java | 90 ++++++++++++++++--- .../java/pl/jakubweg/requests/Requester.java | 67 +------------- 2 files changed, 81 insertions(+), 76 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 2047e1ec..c76b5968 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -4,6 +4,11 @@ import android.annotation.SuppressLint; import android.app.AlertDialog; import android.content.Context; import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.preference.EditTextPreference; +import android.preference.Preference; +import android.preference.PreferenceCategory; import android.text.Html; import android.util.Log; import android.view.View; @@ -22,14 +27,20 @@ import java.util.Objects; import java.util.TimeZone; import pl.jakubweg.objects.SponsorSegment; +import pl.jakubweg.objects.UserStats; import pl.jakubweg.requests.Requester; +import static android.text.Html.fromHtml; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static fi.razerman.youtube.XGlobals.debug; import static pl.jakubweg.PlayerController.getCurrentVideoId; import static pl.jakubweg.PlayerController.getLastKnownVideoTime; import static pl.jakubweg.PlayerController.sponsorSegmentsOfCurrentVideo; +import static pl.jakubweg.SponsorBlockPreferenceFragment.FORMATTER; +import static pl.jakubweg.SponsorBlockPreferenceFragment.SAVED_TEMPLATE; +import static pl.jakubweg.SponsorBlockSettings.skippedSegments; +import static pl.jakubweg.SponsorBlockSettings.skippedTime; import static pl.jakubweg.StringRef.str; import static pl.jakubweg.requests.Requester.voteForSegment; @@ -380,6 +391,75 @@ public abstract class SponsorBlockUtils { } } + public static int countMatches(CharSequence seq, char c) { + int count = 0; + for (int i = 0; i < seq.length(); i++) { + if (seq.charAt(i) == c) + count++; + } + return count; + } + + @SuppressWarnings("deprecation") + public static void addUserStats(PreferenceCategory category, Preference loadingPreference, UserStats stats) { + category.removePreference(loadingPreference); + + Context context = category.getContext(); + + { + EditTextPreference preference = new EditTextPreference(context); + category.addPreference(preference); + String userName = stats.getUserName(); + preference.setTitle(fromHtml(str("stats_username", userName))); + preference.setSummary(str("stats_username_change")); + preference.setText(userName); + preference.setOnPreferenceChangeListener((preference1, newUsername) -> { + Requester.setUsername((String) newUsername); + return false; + }); + } + + { + Preference preference = new Preference(context); + category.addPreference(preference); + String formatted = FORMATTER.format(stats.getSegmentCount()); + preference.setTitle(fromHtml(str("stats_submissions", formatted))); + } + + { + Preference preference = new Preference(context); + category.addPreference(preference); + String formatted = FORMATTER.format(stats.getViewCount()); + + double saved = stats.getMinutesSaved(); + int hoursSaved = (int) (saved / 60); + double minutesSaved = saved % 60; + String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); + + preference.setTitle(fromHtml(str("stats_saved", formatted))); + preference.setSummary(fromHtml(str("stats_saved_sum", formattedSaved))); + preference.setOnPreferenceClickListener(preference1 -> { + Intent i = new Intent(Intent.ACTION_VIEW); + i.setData(Uri.parse("https://sponsor.ajay.app/stats/")); + preference1.getContext().startActivity(i); + return false; + }); + } + + { + Preference preference = new Preference(context); + category.addPreference(preference); + String formatted = FORMATTER.format(skippedSegments); + + long hoursSaved = skippedTime / 3600000; + double minutesSaved = (skippedTime / 60000d) % 60; + String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); + + preference.setTitle(fromHtml(str("stats_self_saved", formatted))); + preference.setSummary(fromHtml(str("stats_self_saved_sum", formattedSaved))); + } + } + public enum VoteOption { UPVOTE(str("vote_upvote")), DOWNVOTE(str("vote_downvote")), @@ -424,14 +504,4 @@ public abstract class SponsorBlockUtils { } } } - - public static int countMatches(CharSequence seq, char c) - { - int count = 0; - for (int i = 0; i < seq.length(); i++) { - if (seq.charAt(i) == c) - count++; - } - return count; - } } diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index 73062b75..6c681758 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -1,11 +1,8 @@ package pl.jakubweg.requests; import android.content.Context; -import android.content.Intent; -import android.net.Uri; import android.os.Handler; import android.os.Looper; -import android.preference.EditTextPreference; import android.preference.Preference; import android.preference.PreferenceCategory; import android.widget.Toast; @@ -28,11 +25,6 @@ import pl.jakubweg.SponsorBlockUtils.VoteOption; import pl.jakubweg.objects.SponsorSegment; import pl.jakubweg.objects.UserStats; -import static android.text.Html.fromHtml; -import static pl.jakubweg.SponsorBlockPreferenceFragment.FORMATTER; -import static pl.jakubweg.SponsorBlockPreferenceFragment.SAVED_TEMPLATE; -import static pl.jakubweg.SponsorBlockSettings.skippedSegments; -import static pl.jakubweg.SponsorBlockSettings.skippedTime; import static pl.jakubweg.StringRef.str; public class Requester { @@ -151,15 +143,12 @@ public class Requester { } } - @SuppressWarnings("deprecation") public static void retrieveUserStats(PreferenceCategory category, Preference loadingPreference) { if (!SponsorBlockSettings.isSponsorBlockEnabled) { loadingPreference.setTitle(str("stats_sb_disabled")); return; } - Context context = category.getContext(); - new Thread(() -> { try { HttpURLConnection connection = getConnectionFromRoute(Route.GET_USER_STATS, SponsorBlockSettings.uuid); @@ -167,61 +156,7 @@ public class Requester { connection.disconnect(); UserStats stats = new UserStats(json.getString("userName"), json.getDouble("minutesSaved"), json.getInt("segmentCount"), json.getInt("viewCount")); - - category.removePreference(loadingPreference); - - { - EditTextPreference preference = new EditTextPreference(context); - category.addPreference(preference); - String userName = stats.getUserName(); - preference.setTitle(fromHtml(str("stats_username", userName))); - preference.setSummary(str("stats_username_change")); - preference.setText(userName); - preference.setOnPreferenceChangeListener((preference1, newUsername) -> { - Requester.setUsername((String) newUsername); - return false; - }); - } - - { - Preference preference = new Preference(context); - category.addPreference(preference); - String formatted = FORMATTER.format(stats.getSegmentCount()); - preference.setTitle(fromHtml(str("stats_submissions", formatted))); - } - - { - Preference preference = new Preference(context); - category.addPreference(preference); - String formatted = FORMATTER.format(stats.getViewCount()); - - double saved = stats.getMinutesSaved(); - int hoursSaved = (int) (saved / 60); - double minutesSaved = saved % 60; - String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); - - preference.setTitle(fromHtml(str("stats_saved", formatted))); - preference.setSummary(fromHtml(str("stats_saved_sum", formattedSaved))); - preference.setOnPreferenceClickListener(preference1 -> { - Intent i = new Intent(Intent.ACTION_VIEW); - i.setData(Uri.parse("https://sponsor.ajay.app/stats/")); - preference1.getContext().startActivity(i); - return false; - }); - } - - { - Preference preference = new Preference(context); - category.addPreference(preference); - String formatted = FORMATTER.format(skippedSegments); - - long hoursSaved = skippedTime / 3600000; - double minutesSaved = (skippedTime / 60000d) % 60; - String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); - - preference.setTitle(fromHtml(str("stats_self_saved", formatted))); - preference.setSummary(fromHtml(str("stats_self_saved_sum", formattedSaved))); - } + SponsorBlockUtils.addUserStats(category, loadingPreference, stats); } catch (Exception ex) { ex.printStackTrace(); From 8d189aba5799d4a27fcd128beccc3d0d1e9e370f Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 23 Jul 2021 17:10:56 +0200 Subject: [PATCH 41/56] add setting --- .../pl/jakubweg/SponsorBlockPreferenceFragment.java | 12 ++++++++++++ .../main/java/pl/jakubweg/SponsorBlockSettings.java | 4 +++- app/src/main/res/values/strings.xml | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index fb3f667e..879800e8 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -24,6 +24,7 @@ import static pl.jakubweg.SponsorBlockSettings.DefaultBehaviour; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_ADJUST_NEW_SEGMENT_STEP; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_COUNT_SKIPS; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_NEW_SEGMENT_ENABLED; +import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_SHOW_TIME_WITHOUT_SEGMENTS; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_SHOW_TOAST_WHEN_SKIP; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_SPONSOR_BLOCK_ENABLED; import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_KEY_UUID; @@ -32,6 +33,7 @@ import static pl.jakubweg.SponsorBlockSettings.PREFERENCES_NAME; import static pl.jakubweg.SponsorBlockSettings.adjustNewSegmentMillis; import static pl.jakubweg.SponsorBlockSettings.countSkips; import static pl.jakubweg.SponsorBlockSettings.setSeenGuidelines; +import static pl.jakubweg.SponsorBlockSettings.showTimeWithoutSegments; import static pl.jakubweg.SponsorBlockSettings.showToastWhenSkippedAutomatically; import static pl.jakubweg.SponsorBlockSettings.uuid; import static pl.jakubweg.StringRef.str; @@ -247,6 +249,16 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement screen.addPreference(preference); } + { + Preference preference = new SwitchPreference(context); + preference.setTitle(str("general_ime_without_sb")); + preference.setSummary(str("general_time_without_sb_sum")); + preference.setKey(PREFERENCES_KEY_SHOW_TIME_WITHOUT_SEGMENTS); + preference.setDefaultValue(showTimeWithoutSegments); + preferencesToDisableWhenSBDisabled.add(preference); + screen.addPreference(preference); + } + { EditTextPreference preference = new EditTextPreference(context); preference.getEditText().setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_SIGNED); diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java index 770b1797..f5e9a9de 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockSettings.java @@ -28,7 +28,7 @@ public class SponsorBlockSettings { public static final String sponsorBlockSkipSegmentsUrl = "https://sponsor.ajay.app/api/skipSegments"; public static final String sponsorBlockViewedUrl = "https://sponsor.ajay.app/api/viewedVideoSponsorTime"; public static final String sponsorBlockVoteUrl = "https://sponsor.ajay.app/api/voteOnSponsorTime"; - + public static final String PREFERENCES_KEY_SHOW_TIME_WITHOUT_SEGMENTS = "sb-length-without-segments"; public static final SegmentBehaviour DefaultBehaviour = SegmentBehaviour.SkipAutomatically; @@ -38,6 +38,7 @@ public class SponsorBlockSettings { public static boolean isVotingEnabled = true; public static boolean showToastWhenSkippedAutomatically = true; public static boolean countSkips = true; + public static boolean showTimeWithoutSegments = true; public static int adjustNewSegmentMillis = 150; public static String uuid = ""; private static String sponsorBlockUrlCategories = "[]"; @@ -140,6 +141,7 @@ public class SponsorBlockSettings { adjustNewSegmentMillis = Integer.parseInt(tmp1); countSkips = preferences.getBoolean(PREFERENCES_KEY_COUNT_SKIPS, countSkips); + showTimeWithoutSegments = preferences.getBoolean(PREFERENCES_KEY_SHOW_TIME_WITHOUT_SEGMENTS, showTimeWithoutSegments); uuid = preferences.getString(PREFERENCES_KEY_UUID, null); if (uuid == null) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7b1d5fed..d9d3991b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -151,6 +151,8 @@ Click to see an example toast Skip count tracking This lets SponsorBlock leaderboard system know how much time people have saved. The extension sends a message to the server each time you skip a segment. + Show time without segments + This time appears in brackets next to the current time. This shows the total video duration minus any segments. Adjusting new segment step This is the number of milliseconds you can move when you use the time adjustment buttons while adding new segment Your unique user id From 5334bc4caee472f06d04aebf033005841ee641b4 Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 23 Jul 2021 17:13:17 +0200 Subject: [PATCH 42/56] fix string key --- .../main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java index 879800e8..d4eabff8 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockPreferenceFragment.java @@ -251,7 +251,7 @@ public class SponsorBlockPreferenceFragment extends PreferenceFragment implement { Preference preference = new SwitchPreference(context); - preference.setTitle(str("general_ime_without_sb")); + preference.setTitle(str("general_time_without_sb")); preference.setSummary(str("general_time_without_sb_sum")); preference.setKey(PREFERENCES_KEY_SHOW_TIME_WITHOUT_SEGMENTS); preference.setDefaultValue(showTimeWithoutSegments); From e3725669985a8320c00726889a66a0d631d6ad11 Mon Sep 17 00:00:00 2001 From: xfileFIN Date: Fri, 23 Jul 2021 18:28:54 +0300 Subject: [PATCH 43/56] Experiments for fixing the appending --- .../libraries/youtube/player/PlayerType.java | 2 + .../java/pl/jakubweg/SponsorBlockUtils.java | 56 +++++++++++++++++-- 2 files changed, 53 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/fi/vanced/libraries/youtube/player/PlayerType.java b/app/src/main/java/fi/vanced/libraries/youtube/player/PlayerType.java index 448ebe0c..84eabe45 100644 --- a/app/src/main/java/fi/vanced/libraries/youtube/player/PlayerType.java +++ b/app/src/main/java/fi/vanced/libraries/youtube/player/PlayerType.java @@ -1,9 +1,11 @@ package fi.vanced.libraries.youtube.player; import fi.vanced.libraries.youtube.sponsors.player.ui.SponsorBlockView; +import pl.jakubweg.SponsorBlockUtils; public class PlayerType { public static void playerTypeChanged(String playerType) { SponsorBlockView.playerTypeChanged(playerType); + SponsorBlockUtils.playerTypeChanged(playerType); } } diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index a72427d6..1e6f084e 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -36,6 +36,7 @@ import java.util.Objects; import java.util.TimeZone; import fi.razerman.youtube.Helpers.XSwipeHelper; +import fi.razerman.youtube.XGlobals; import static android.view.View.GONE; import static android.view.View.VISIBLE; @@ -59,6 +60,8 @@ public abstract class SponsorBlockUtils { public static final SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT); public static final SimpleDateFormat withoutSegmentsFormatter = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT); public static final SimpleDateFormat withoutSegmentsFormatterH = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT_H); + private static boolean videoHasSegments = false; + private static boolean needToAppendTime = false; private static final int sponsorBtnId = 1234; public static final View.OnClickListener sponsorBlockBtnListener = new View.OnClickListener() { @Override @@ -471,9 +474,13 @@ public abstract class SponsorBlockUtils { switch (connection.getResponseCode()) { default: Log.e(TAG, "Unable to download segments: Status: " + connection.getResponseCode() + " " + connection.getResponseMessage()); + videoHasSegments = false; + needToAppendTime = false; break; case 404: Log.w(TAG, "No segments for this video (ERR404)"); + videoHasSegments = false; + needToAppendTime = false; break; case 200: if (VERBOSE) @@ -507,6 +514,9 @@ public abstract class SponsorBlockUtils { if (VERBOSE) Log.v(TAG, "Parsing done"); + + videoHasSegments = true; + needToAppendTime = true; break; } @@ -516,11 +526,6 @@ public abstract class SponsorBlockUtils { Log.e(TAG, "download segments failed", e); } - View layout = XSwipeHelper.nextGenWatchLayout.findViewById(getIdentifier("player_overlays", "id")); - View bar = layout.findViewById(getIdentifier("time_bar_total_time", "id")); - - ((TextView) bar).append(getTimeWithoutSegments()); - return sponsorSegments.toArray(new SponsorSegment[0]); } @@ -581,6 +586,35 @@ public abstract class SponsorBlockUtils { } } + public static void forceAppendTimeWithoutSegments() { + appendTimeWithoutSegments(true); + } + + public static void appendTimeWithoutSegments() { + appendTimeWithoutSegments(false); + } + + public static void appendTimeWithoutSegments(boolean forceAppend) { + try { + if (!videoHasSegments || (!needToAppendTime && !forceAppend)) { + return; + } + + View layout = XSwipeHelper.nextGenWatchLayout.findViewById(getIdentifier("player_overlays", "id")); + if (layout != null) { + View bar = layout.findViewById(getIdentifier("time_bar_total_time", "id")); + ((TextView) bar).append(getTimeWithoutSegments()); + } + else if (XGlobals.debug){ + Log.d(TAG, "player_overlays was not found"); + } + + needToAppendTime = false; + } catch (Exception e) { + Log.e(TAG, "setting the time without segments failed", e); + } + } + public static String getTimeWithoutSegments() { if (!SponsorBlockSettings.isSponsorBlockEnabled || sponsorSegmentsOfCurrentVideo == null) { return ""; @@ -593,6 +627,18 @@ public abstract class SponsorBlockUtils { return timeWithoutSegments >= 3600000 ? withoutSegmentsFormatterH.format(date) : withoutSegmentsFormatter.format(date); } + public static void playerTypeChanged(String playerType) { + try { + if (videoHasSegments && (playerType.equalsIgnoreCase("NONE"))) { + needToAppendTime = true; + return; + } + } + catch (Exception ex) { + Log.e(TAG, "Player type changed caused a crash.", ex); + } + } + private enum VoteOption { UPVOTE(str("vote_upvote")), DOWNVOTE(str("vote_downvote")), From fc3fb979ba79cfc5b44607c4e7bee521aa5fdc24 Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 23 Jul 2021 17:44:42 +0200 Subject: [PATCH 44/56] reset segments when closing videos --- app/src/main/java/pl/jakubweg/PlayerController.java | 3 ++- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 9dc1a2f3..b9964150 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -56,7 +56,8 @@ public class PlayerController { public static void setCurrentVideoId(final String videoId) { if (videoId == null) { - Log.d(TAG, "setCurrentVideoId: videoId is null"); + currentVideoId = null; + sponsorSegmentsOfCurrentVideo = null; return; } diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 1e6f084e..fceb5b76 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -616,7 +616,7 @@ public abstract class SponsorBlockUtils { } public static String getTimeWithoutSegments() { - if (!SponsorBlockSettings.isSponsorBlockEnabled || sponsorSegmentsOfCurrentVideo == null) { + if (!SponsorBlockSettings.isSponsorBlockEnabled || !SponsorBlockSettings.showTimeWithoutSegments || sponsorSegmentsOfCurrentVideo == null) { return ""; } long timeWithoutSegments = PlayerController.getCurrentVideoLength(); @@ -631,6 +631,7 @@ public abstract class SponsorBlockUtils { try { if (videoHasSegments && (playerType.equalsIgnoreCase("NONE"))) { needToAppendTime = true; + PlayerController.setCurrentVideoId(null); return; } } From 04efa79b531ab9efc3fbc3dd4de50e570dd6ede7 Mon Sep 17 00:00:00 2001 From: xfileFIN Date: Sat, 24 Jul 2021 00:24:51 +0300 Subject: [PATCH 45/56] Test ready I guess --- .../java/pl/jakubweg/SponsorBlockUtils.java | 46 +++++-------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index fceb5b76..e5ef0d51 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -7,6 +7,7 @@ import android.content.DialogInterface; import android.os.Handler; import android.os.Looper; import android.text.Html; +import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.EditText; @@ -61,7 +62,7 @@ public abstract class SponsorBlockUtils { public static final SimpleDateFormat withoutSegmentsFormatter = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT); public static final SimpleDateFormat withoutSegmentsFormatterH = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT_H); private static boolean videoHasSegments = false; - private static boolean needToAppendTime = false; + private static String timeWithoutSegments = ""; private static final int sponsorBtnId = 1234; public static final View.OnClickListener sponsorBlockBtnListener = new View.OnClickListener() { @Override @@ -471,16 +472,14 @@ public abstract class SponsorBlockUtils { URL url = new URL(SponsorBlockSettings.getSponsorBlockUrlWithCategories(videoId)); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + videoHasSegments = false; + timeWithoutSegments = ""; switch (connection.getResponseCode()) { default: Log.e(TAG, "Unable to download segments: Status: " + connection.getResponseCode() + " " + connection.getResponseMessage()); - videoHasSegments = false; - needToAppendTime = false; break; case 404: Log.w(TAG, "No segments for this video (ERR404)"); - videoHasSegments = false; - needToAppendTime = false; break; case 200: if (VERBOSE) @@ -516,7 +515,6 @@ public abstract class SponsorBlockUtils { Log.v(TAG, "Parsing done"); videoHasSegments = true; - needToAppendTime = true; break; } @@ -526,6 +524,8 @@ public abstract class SponsorBlockUtils { Log.e(TAG, "download segments failed", e); } + timeWithoutSegments = getTimeWithoutSegments(sponsorSegments); + return sponsorSegments.toArray(new SponsorSegment[0]); } @@ -586,36 +586,15 @@ public abstract class SponsorBlockUtils { } } - public static void forceAppendTimeWithoutSegments() { - appendTimeWithoutSegments(true); - } - - public static void appendTimeWithoutSegments() { - appendTimeWithoutSegments(false); - } - - public static void appendTimeWithoutSegments(boolean forceAppend) { - try { - if (!videoHasSegments || (!needToAppendTime && !forceAppend)) { - return; - } - - View layout = XSwipeHelper.nextGenWatchLayout.findViewById(getIdentifier("player_overlays", "id")); - if (layout != null) { - View bar = layout.findViewById(getIdentifier("time_bar_total_time", "id")); - ((TextView) bar).append(getTimeWithoutSegments()); - } - else if (XGlobals.debug){ - Log.d(TAG, "player_overlays was not found"); - } - - needToAppendTime = false; - } catch (Exception e) { - Log.e(TAG, "setting the time without segments failed", e); + public static String appendTimeWithoutSegments(String totalTime) { + if (videoHasSegments && SponsorBlockSettings.showTimeWithoutSegments && !TextUtils.isEmpty(totalTime)) { + return totalTime + timeWithoutSegments; } + + return totalTime; } - public static String getTimeWithoutSegments() { + public static String getTimeWithoutSegments(ArrayList sponsorSegmentsOfCurrentVideo) { if (!SponsorBlockSettings.isSponsorBlockEnabled || !SponsorBlockSettings.showTimeWithoutSegments || sponsorSegmentsOfCurrentVideo == null) { return ""; } @@ -630,7 +609,6 @@ public abstract class SponsorBlockUtils { public static void playerTypeChanged(String playerType) { try { if (videoHasSegments && (playerType.equalsIgnoreCase("NONE"))) { - needToAppendTime = true; PlayerController.setCurrentVideoId(null); return; } From 96561f6c9090df30b2efe3cc013f1e4538480c23 Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 23 Jul 2021 23:50:57 +0200 Subject: [PATCH 46/56] finish merging --- .../java/pl/jakubweg/SponsorBlockUtils.java | 36 +++++++++++++++++-- .../java/pl/jakubweg/requests/Requester.java | 6 ++++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index cc7ece2b..127a07b1 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -15,7 +15,6 @@ import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.ImageView; -import android.widget.TextView; import android.widget.Toast; import java.lang.ref.WeakReference; @@ -56,8 +55,8 @@ public abstract class SponsorBlockUtils { public static final SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT); public static final SimpleDateFormat withoutSegmentsFormatter = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT); public static final SimpleDateFormat withoutSegmentsFormatterH = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT_H); - private static boolean videoHasSegments = false; - private static String timeWithoutSegments = ""; + public static boolean videoHasSegments = false; + public static String timeWithoutSegments = ""; private static final int sponsorBtnId = 1234; public static final View.OnClickListener sponsorBlockBtnListener = v -> { if (debug) { @@ -399,6 +398,37 @@ public abstract class SponsorBlockUtils { } } + public static String appendTimeWithoutSegments(String totalTime) { + if (videoHasSegments && SponsorBlockSettings.showTimeWithoutSegments && !TextUtils.isEmpty(totalTime)) { + return totalTime + timeWithoutSegments; + } + + return totalTime; + } + + public static String getTimeWithoutSegments(List sponsorSegmentsOfCurrentVideo) { + if (!SponsorBlockSettings.isSponsorBlockEnabled || !SponsorBlockSettings.showTimeWithoutSegments || sponsorSegmentsOfCurrentVideo == null) { + return ""; + } + long timeWithoutSegments = PlayerController.getCurrentVideoLength(); + for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) { + timeWithoutSegments -= segment.end - segment.start; + } + Date date = new Date(timeWithoutSegments); + return timeWithoutSegments >= 3600000 ? withoutSegmentsFormatterH.format(date) : withoutSegmentsFormatter.format(date); + } + + public static void playerTypeChanged(String playerType) { + try { + if (videoHasSegments && (playerType.equalsIgnoreCase("NONE"))) { + PlayerController.setCurrentVideoId(null); + } + } + catch (Exception ex) { + Log.e(TAG, "Player type changed caused a crash.", ex); + } + } + public static int countMatches(CharSequence seq, char c) { int count = 0; for (int i = 0; i < seq.length(); i++) { diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index 6c681758..10955180 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -25,6 +25,8 @@ import pl.jakubweg.SponsorBlockUtils.VoteOption; import pl.jakubweg.objects.SponsorSegment; import pl.jakubweg.objects.UserStats; +import static pl.jakubweg.SponsorBlockUtils.timeWithoutSegments; +import static pl.jakubweg.SponsorBlockUtils.videoHasSegments; import static pl.jakubweg.StringRef.str; public class Requester { @@ -38,6 +40,8 @@ public class Requester { try { HttpURLConnection connection = getConnectionFromRoute(Route.GET_SEGMENTS, videoId, SponsorBlockSettings.sponsorBlockUrlCategories); int responseCode = connection.getResponseCode(); + videoHasSegments = false; + timeWithoutSegments = ""; switch (responseCode) { case 200: @@ -57,6 +61,8 @@ public class Requester { segments.add(sponsorSegment); } } + videoHasSegments = true; + timeWithoutSegments = SponsorBlockUtils.getTimeWithoutSegments(segments); break; case 404: break; From cd3edfe07fa655a1ba1fc33c82a16fa713465473 Mon Sep 17 00:00:00 2001 From: xfileFIN Date: Sat, 24 Jul 2021 02:48:33 +0300 Subject: [PATCH 47/56] Skipped video length fixed --- .../java/pl/jakubweg/PlayerController.java | 2 +- .../java/pl/jakubweg/SponsorBlockUtils.java | 46 ++++++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/PlayerController.java b/app/src/main/java/pl/jakubweg/PlayerController.java index 2afd00a5..e884f575 100644 --- a/app/src/main/java/pl/jakubweg/PlayerController.java +++ b/app/src/main/java/pl/jakubweg/PlayerController.java @@ -335,7 +335,7 @@ public class PlayerController { public static void setSponsorBarRect(final Object self) { try { - Field field = self.getClass().getDeclaredField("e"); + Field field = self.getClass().getDeclaredField("replaceMeWithsetSponsorBarRect"); field.setAccessible(true); Rect rect = (Rect) field.get(self); if (rect != null) { diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 127a07b1..4914fb38 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -26,6 +26,7 @@ import java.util.Date; import java.util.List; import java.util.Objects; import java.util.TimeZone; +import java.util.concurrent.TimeUnit; import pl.jakubweg.objects.SponsorSegment; import pl.jakubweg.objects.UserStats; @@ -49,12 +50,8 @@ import static pl.jakubweg.requests.Requester.voteForSegment; public abstract class SponsorBlockUtils { public static final String TAG = "jakubweg.SponsorBlockUtils"; public static final String DATE_FORMAT = "HH:mm:ss.SSS"; - public static final String WITHOUT_SEGMENTS_FORMAT = " (m:ss)"; - public static final String WITHOUT_SEGMENTS_FORMAT_H = " (H:m:ss)"; @SuppressLint("SimpleDateFormat") public static final SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT); - public static final SimpleDateFormat withoutSegmentsFormatter = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT); - public static final SimpleDateFormat withoutSegmentsFormatterH = new SimpleDateFormat(WITHOUT_SEGMENTS_FORMAT_H); public static boolean videoHasSegments = false; public static String timeWithoutSegments = ""; private static final int sponsorBtnId = 1234; @@ -414,8 +411,45 @@ public abstract class SponsorBlockUtils { for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) { timeWithoutSegments -= segment.end - segment.start; } - Date date = new Date(timeWithoutSegments); - return timeWithoutSegments >= 3600000 ? withoutSegmentsFormatterH.format(date) : withoutSegmentsFormatter.format(date); + return String.format(" (%s)", formatToVideoTimeString(TimeUnit.MILLISECONDS.toSeconds(timeWithoutSegments + 500L), 3)); + } + + public static String formatToVideoTimeString(long seconds, int padAmount) { + StringBuilder sb = new StringBuilder(); + sb.append(seconds >= 0L ? "" : "-"); + long abs_seconds = Math.abs(seconds); + long minutes = abs_seconds / 60L; + long hours = minutes / 60L; + if(hours > 0L) { + minutes %= 60L; + padAmount = Math.max(padAmount, 5); + } + + String seconds_str = Long.toString(abs_seconds % 60L); + if(seconds_str.length() == 1) { + String safe_str = String.valueOf(seconds_str); + seconds_str = safe_str.length() == 0 ? new String("0") : "0".concat(safe_str); + } + + String minutes_str = Long.toString(minutes); + if(minutes_str.length() == 1 && padAmount > 3) { + String safe_str = String.valueOf(minutes_str); + minutes_str = safe_str.length() == 0 ? new String("0") : "0".concat(safe_str); + } + + if(padAmount > 4) { + sb.append(hours); + sb.append(':'); + sb.append(minutes_str); + sb.append(':'); + sb.append(seconds_str); + return sb.toString(); + } + + sb.append(minutes_str); + sb.append(':'); + sb.append(seconds_str); + return sb.toString(); } public static void playerTypeChanged(String playerType) { From 79fb5c8c43ac21afc0749c84de5cfcd4f943ce7d Mon Sep 17 00:00:00 2001 From: caneleex Date: Sat, 24 Jul 2021 16:35:09 +0200 Subject: [PATCH 48/56] replace overcomplicated calc with one method --- .../java/pl/jakubweg/SponsorBlockUtils.java | 42 +------------------ 1 file changed, 2 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 4914fb38..ebd58edb 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -11,6 +11,7 @@ import android.preference.Preference; import android.preference.PreferenceCategory; import android.text.Html; import android.text.TextUtils; +import android.text.format.DateUtils; import android.util.Log; import android.view.View; import android.widget.EditText; @@ -26,7 +27,6 @@ import java.util.Date; import java.util.List; import java.util.Objects; import java.util.TimeZone; -import java.util.concurrent.TimeUnit; import pl.jakubweg.objects.SponsorSegment; import pl.jakubweg.objects.UserStats; @@ -411,45 +411,7 @@ public abstract class SponsorBlockUtils { for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) { timeWithoutSegments -= segment.end - segment.start; } - return String.format(" (%s)", formatToVideoTimeString(TimeUnit.MILLISECONDS.toSeconds(timeWithoutSegments + 500L), 3)); - } - - public static String formatToVideoTimeString(long seconds, int padAmount) { - StringBuilder sb = new StringBuilder(); - sb.append(seconds >= 0L ? "" : "-"); - long abs_seconds = Math.abs(seconds); - long minutes = abs_seconds / 60L; - long hours = minutes / 60L; - if(hours > 0L) { - minutes %= 60L; - padAmount = Math.max(padAmount, 5); - } - - String seconds_str = Long.toString(abs_seconds % 60L); - if(seconds_str.length() == 1) { - String safe_str = String.valueOf(seconds_str); - seconds_str = safe_str.length() == 0 ? new String("0") : "0".concat(safe_str); - } - - String minutes_str = Long.toString(minutes); - if(minutes_str.length() == 1 && padAmount > 3) { - String safe_str = String.valueOf(minutes_str); - minutes_str = safe_str.length() == 0 ? new String("0") : "0".concat(safe_str); - } - - if(padAmount > 4) { - sb.append(hours); - sb.append(':'); - sb.append(minutes_str); - sb.append(':'); - sb.append(seconds_str); - return sb.toString(); - } - - sb.append(minutes_str); - sb.append(':'); - sb.append(seconds_str); - return sb.toString(); + return String.format(" (%s)", DateUtils.formatElapsedTime(timeWithoutSegments / 1000)); } public static void playerTypeChanged(String playerType) { From a030e6e2802bd2cf45e4d9fa7bc2826a759e250c Mon Sep 17 00:00:00 2001 From: caneleex Date: Sat, 24 Jul 2021 16:57:42 +0200 Subject: [PATCH 49/56] fix requests not sending sometimes --- app/src/main/java/pl/jakubweg/requests/Requester.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index 10955180..b3ae0cd1 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -184,6 +184,7 @@ public class Requester { String url = SPONSORBLOCK_API_URL + route.compile(params).getCompiledRoute(); HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestMethod(route.getMethod().name()); + connection.getInputStream().close(); // this is required so it properly establishes the connection when not reading the InputStream in any of the routes return connection; } From 518572967b598d53b5b80b630c7e6c8f1bf0a1c7 Mon Sep 17 00:00:00 2001 From: caneleex Date: Sat, 24 Jul 2021 18:53:59 +0200 Subject: [PATCH 50/56] add proper response handling to setUsername --- .../java/pl/jakubweg/SponsorBlockUtils.java | 4 +++- .../java/pl/jakubweg/requests/Requester.java | 15 ++++++++++----- app/src/main/res/values/strings.xml | 19 +++++++++++-------- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 127a07b1..0695dcd1 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -190,6 +190,7 @@ public abstract class SponsorBlockUtils { }; private static final Runnable toastRunnable = () -> { Context context = appContext.get(); + Log.d("cock", String.valueOf(context)); if (context != null && messageToToast != null) Toast.makeText(context, messageToToast, Toast.LENGTH_LONG).show(); }; @@ -452,7 +453,8 @@ public abstract class SponsorBlockUtils { preference.setSummary(str("stats_username_change")); preference.setText(userName); preference.setOnPreferenceChangeListener((preference1, newUsername) -> { - Requester.setUsername((String) newUsername); + appContext = new WeakReference<>(context.getApplicationContext()); + Requester.setUsername((String) newUsername, toastRunnable); return false; }); } diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index b3ae0cd1..acef509c 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -134,9 +134,6 @@ public class Requester { case 403: SponsorBlockUtils.messageToToast = str("vote_failed_forbidden"); break; - case 429: - SponsorBlockUtils.messageToToast = str("vote_failed_rate_limit"); - break; default: SponsorBlockUtils.messageToToast = str("vote_failed_unknown_error", responseCode, connection.getResponseMessage()); break; @@ -170,9 +167,18 @@ public class Requester { }).start(); } - public static void setUsername(String username) { + public static void setUsername(String username, Runnable toastRunnable) { try { HttpURLConnection connection = getConnectionFromRoute(Route.CHANGE_USERNAME, SponsorBlockSettings.uuid, username); + int responseCode = connection.getResponseCode(); + + if (responseCode == 200) { + SponsorBlockUtils.messageToToast = str("stats_username_changed"); + } + else { + SponsorBlockUtils.messageToToast = str("stats_username_change_unknown_error", responseCode, connection.getResponseMessage()); + } + new Handler(Looper.getMainLooper()).post(toastRunnable); connection.disconnect(); } catch (Exception ex) { @@ -184,7 +190,6 @@ public class Requester { String url = SPONSORBLOCK_API_URL + route.compile(params).getCompiledRoute(); HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection(); connection.setRequestMethod(route.getMethod().name()); - connection.getInputStream().close(); // this is required so it properly establishes the connection when not reading the InputStream in any of the routes return connection; } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e561d0ad..2e68d5ec 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -182,18 +182,22 @@ Skip automatically Show a skip button Don\'t do anything + Stats Loading.. SponsorBlock is disabled - Your username: <b>%s</b> + Your username: <b>%s</b> Click to change your username - Submissions: <b>%s</b> - You\'ve saved people from <b>%s</b> segments. - That\'s <b>%s</b> of their lives. Click to see the leaderboard - You\'ve skipped <b>%s</b> segments. - That\'s <b>%s</b>. + Unable to change username: Status: %d %s + Username changed successfully + Submissions: <b>%s</b> + You\'ve saved people from <b>%s</b> segments. + That\'s <b>%s</b> of their lives. Click to see the leaderboard + You\'ve skipped <b>%s</b> segments. + That\'s <b>%s</b>. + About - This app uses the API from Sponsor Block + This app uses the API from SponsorBlock Tap to learn more, and see downloads for other platforms at: sponsor.ajay.app Integration made by JakubWeg Tap to skip @@ -206,7 +210,6 @@ Submitting segment… Unable to vote for segment: Status: %d %s - Can\'t vote for segment.\nRate Limited (Too many from the same user or IP) Can\'t vote for segment.\nA moderator has decided that this segment is correct Voted successfully Voting for segment… From 45f67d4f29843239c42ed09cc8ff9f4b166424ae Mon Sep 17 00:00:00 2001 From: caneleex Date: Sat, 24 Jul 2021 18:55:45 +0200 Subject: [PATCH 51/56] ah yes --- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 0695dcd1..a197c1d1 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -190,7 +190,6 @@ public abstract class SponsorBlockUtils { }; private static final Runnable toastRunnable = () -> { Context context = appContext.get(); - Log.d("cock", String.valueOf(context)); if (context != null && messageToToast != null) Toast.makeText(context, messageToToast, Toast.LENGTH_LONG).show(); }; From 00350bf081526722a95130601ada3cd864104b74 Mon Sep 17 00:00:00 2001 From: caneleex Date: Sat, 24 Jul 2021 20:14:47 +0200 Subject: [PATCH 52/56] mmLul mmLul --- .../main/java/pl/jakubweg/SponsorBlockUtils.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 0a109aff..caa05249 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -11,7 +11,6 @@ import android.preference.Preference; import android.preference.PreferenceCategory; import android.text.Html; import android.text.TextUtils; -import android.text.format.DateUtils; import android.util.Log; import android.view.View; import android.widget.EditText; @@ -36,6 +35,7 @@ import static android.text.Html.fromHtml; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static fi.razerman.youtube.XGlobals.debug; +import static java.lang.String.format; import static pl.jakubweg.PlayerController.getCurrentVideoId; import static pl.jakubweg.PlayerController.getLastKnownVideoTime; import static pl.jakubweg.PlayerController.sponsorSegmentsOfCurrentVideo; @@ -50,6 +50,7 @@ import static pl.jakubweg.requests.Requester.voteForSegment; public abstract class SponsorBlockUtils { public static final String TAG = "jakubweg.SponsorBlockUtils"; public static final String DATE_FORMAT = "HH:mm:ss.SSS"; + public static final String TIME_WITHOUT_SEGMENTS_FORMAT = "%d:%d%02d"; @SuppressLint("SimpleDateFormat") public static final SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT); public static boolean videoHasSegments = false; @@ -329,7 +330,7 @@ public abstract class SponsorBlockUtils { String start = dateFormatter.format(new Date(segment.start)); String end = dateFormatter.format(new Date(segment.end)); StringBuilder htmlBuilder = new StringBuilder(); - htmlBuilder.append(String.format(" %s
%s to %s", + htmlBuilder.append(format(" %s
%s to %s", segment.category.color, segment.category.title, start, end)); if (i + 1 != segmentAmount) // prevents trailing new line after last segment htmlBuilder.append("
"); @@ -411,7 +412,12 @@ public abstract class SponsorBlockUtils { for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) { timeWithoutSegments -= segment.end - segment.start; } - return String.format(" (%s)", DateUtils.formatElapsedTime(timeWithoutSegments / 1000)); + long hours = timeWithoutSegments / 3600000; + long minutes = (timeWithoutSegments / 60000) % 60; + long seconds = (timeWithoutSegments / 1000) % 60; + String format = (hours > 0 ? "%d:%02" : "%") + "d:%02d"; // mmLul + String formatted = hours > 0 ? String.format(format, hours, minutes, seconds) : String.format(format, minutes, seconds); + return String.format(" (%s)", formatted); } public static void playerTypeChanged(String playerType) { @@ -469,7 +475,7 @@ public abstract class SponsorBlockUtils { double saved = stats.getMinutesSaved(); int hoursSaved = (int) (saved / 60); double minutesSaved = saved % 60; - String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); + String formattedSaved = format(SAVED_TEMPLATE, hoursSaved, minutesSaved); preference.setTitle(fromHtml(str("stats_saved", formatted))); preference.setSummary(fromHtml(str("stats_saved_sum", formattedSaved))); @@ -488,7 +494,7 @@ public abstract class SponsorBlockUtils { long hoursSaved = skippedTime / 3600000; double minutesSaved = (skippedTime / 60000d) % 60; - String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); + String formattedSaved = format(SAVED_TEMPLATE, hoursSaved, minutesSaved); preference.setTitle(fromHtml(str("stats_self_saved", formatted))); preference.setSummary(fromHtml(str("stats_self_saved_sum", formattedSaved))); From d3e2f2c5e4ba4f35b164eec2a6f650941c1a8182 Mon Sep 17 00:00:00 2001 From: caneleex Date: Sat, 24 Jul 2021 20:22:31 +0200 Subject: [PATCH 53/56] remove static import for String.format and unused constant --- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index caa05249..20954cb0 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -35,7 +35,6 @@ import static android.text.Html.fromHtml; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static fi.razerman.youtube.XGlobals.debug; -import static java.lang.String.format; import static pl.jakubweg.PlayerController.getCurrentVideoId; import static pl.jakubweg.PlayerController.getLastKnownVideoTime; import static pl.jakubweg.PlayerController.sponsorSegmentsOfCurrentVideo; @@ -50,7 +49,6 @@ import static pl.jakubweg.requests.Requester.voteForSegment; public abstract class SponsorBlockUtils { public static final String TAG = "jakubweg.SponsorBlockUtils"; public static final String DATE_FORMAT = "HH:mm:ss.SSS"; - public static final String TIME_WITHOUT_SEGMENTS_FORMAT = "%d:%d%02d"; @SuppressLint("SimpleDateFormat") public static final SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT); public static boolean videoHasSegments = false; @@ -330,7 +328,7 @@ public abstract class SponsorBlockUtils { String start = dateFormatter.format(new Date(segment.start)); String end = dateFormatter.format(new Date(segment.end)); StringBuilder htmlBuilder = new StringBuilder(); - htmlBuilder.append(format(" %s
%s to %s", + htmlBuilder.append(String.format(" %s
%s to %s", segment.category.color, segment.category.title, start, end)); if (i + 1 != segmentAmount) // prevents trailing new line after last segment htmlBuilder.append("
"); @@ -475,7 +473,7 @@ public abstract class SponsorBlockUtils { double saved = stats.getMinutesSaved(); int hoursSaved = (int) (saved / 60); double minutesSaved = saved % 60; - String formattedSaved = format(SAVED_TEMPLATE, hoursSaved, minutesSaved); + String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); preference.setTitle(fromHtml(str("stats_saved", formatted))); preference.setSummary(fromHtml(str("stats_saved_sum", formattedSaved))); @@ -494,7 +492,7 @@ public abstract class SponsorBlockUtils { long hoursSaved = skippedTime / 3600000; double minutesSaved = (skippedTime / 60000d) % 60; - String formattedSaved = format(SAVED_TEMPLATE, hoursSaved, minutesSaved); + String formattedSaved = String.format(SAVED_TEMPLATE, hoursSaved, minutesSaved); preference.setTitle(fromHtml(str("stats_self_saved", formatted))); preference.setSummary(fromHtml(str("stats_self_saved_sum", formattedSaved))); From c6306b66d0d580d0470594be8f0fd1c6daa580ec Mon Sep 17 00:00:00 2001 From: caneleex Date: Sat, 24 Jul 2021 20:29:21 +0200 Subject: [PATCH 54/56] add 500 millis to the time without segments nobody knows why --- app/src/main/java/pl/jakubweg/SponsorBlockUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 20954cb0..2b96e9fb 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -406,7 +406,7 @@ public abstract class SponsorBlockUtils { if (!SponsorBlockSettings.isSponsorBlockEnabled || !SponsorBlockSettings.showTimeWithoutSegments || sponsorSegmentsOfCurrentVideo == null) { return ""; } - long timeWithoutSegments = PlayerController.getCurrentVideoLength(); + long timeWithoutSegments = PlayerController.getCurrentVideoLength() + 500; // YouTube:tm: for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) { timeWithoutSegments -= segment.end - segment.start; } From 8980480236a78f5f5f652b65c11fd3796fc988c7 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 26 Jul 2021 00:13:33 +0200 Subject: [PATCH 55/56] hopefully fix corrupted string --- .../main/java/pl/jakubweg/ShieldButton.java | 2 +- .../java/pl/jakubweg/SponsorBlockUtils.java | 18 +++++++-- .../main/java/pl/jakubweg/VotingButton.java | 2 +- .../java/pl/jakubweg/requests/Requester.java | 38 +++++++++---------- 4 files changed, 33 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/pl/jakubweg/ShieldButton.java b/app/src/main/java/pl/jakubweg/ShieldButton.java index 6e15540c..9cc0cd4c 100644 --- a/app/src/main/java/pl/jakubweg/ShieldButton.java +++ b/app/src/main/java/pl/jakubweg/ShieldButton.java @@ -102,7 +102,7 @@ public class ShieldButton { } static boolean shouldBeShown() { - return SponsorBlockSettings.isSponsorBlockEnabled && SponsorBlockSettings.isAddNewSegmentEnabled; + return SponsorBlockUtils.isSettingEnabled(SponsorBlockSettings.isAddNewSegmentEnabled); } //region Helpers diff --git a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java index 2b96e9fb..190faf4a 100644 --- a/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java +++ b/app/src/main/java/pl/jakubweg/SponsorBlockUtils.java @@ -40,6 +40,8 @@ import static pl.jakubweg.PlayerController.getLastKnownVideoTime; import static pl.jakubweg.PlayerController.sponsorSegmentsOfCurrentVideo; import static pl.jakubweg.SponsorBlockPreferenceFragment.FORMATTER; import static pl.jakubweg.SponsorBlockPreferenceFragment.SAVED_TEMPLATE; +import static pl.jakubweg.SponsorBlockSettings.isSponsorBlockEnabled; +import static pl.jakubweg.SponsorBlockSettings.showTimeWithoutSegments; import static pl.jakubweg.SponsorBlockSettings.skippedSegments; import static pl.jakubweg.SponsorBlockSettings.skippedTime; import static pl.jakubweg.StringRef.str; @@ -395,18 +397,22 @@ public abstract class SponsorBlockUtils { } public static String appendTimeWithoutSegments(String totalTime) { - if (videoHasSegments && SponsorBlockSettings.showTimeWithoutSegments && !TextUtils.isEmpty(totalTime)) { + if (videoHasSegments && isSettingEnabled(showTimeWithoutSegments) && !TextUtils.isEmpty(totalTime)) { + if (timeWithoutSegments.isEmpty()) { + timeWithoutSegments = getTimeWithoutSegments(sponsorSegmentsOfCurrentVideo); + } return totalTime + timeWithoutSegments; } return totalTime; } - public static String getTimeWithoutSegments(List sponsorSegmentsOfCurrentVideo) { - if (!SponsorBlockSettings.isSponsorBlockEnabled || !SponsorBlockSettings.showTimeWithoutSegments || sponsorSegmentsOfCurrentVideo == null) { + public static String getTimeWithoutSegments(SponsorSegment[] sponsorSegmentsOfCurrentVideo) { + long currentVideoLength = PlayerController.getCurrentVideoLength(); + if (!isSettingEnabled(showTimeWithoutSegments) || sponsorSegmentsOfCurrentVideo == null || currentVideoLength == 1) { return ""; } - long timeWithoutSegments = PlayerController.getCurrentVideoLength() + 500; // YouTube:tm: + long timeWithoutSegments = currentVideoLength + 500; // YouTube:tm: for (SponsorSegment segment : sponsorSegmentsOfCurrentVideo) { timeWithoutSegments -= segment.end - segment.start; } @@ -499,6 +505,10 @@ public abstract class SponsorBlockUtils { } } + public static boolean isSettingEnabled(boolean setting) { + return isSponsorBlockEnabled && setting; + } + public enum VoteOption { UPVOTE(str("vote_upvote")), DOWNVOTE(str("vote_downvote")), diff --git a/app/src/main/java/pl/jakubweg/VotingButton.java b/app/src/main/java/pl/jakubweg/VotingButton.java index 7d5d61aa..f585f968 100644 --- a/app/src/main/java/pl/jakubweg/VotingButton.java +++ b/app/src/main/java/pl/jakubweg/VotingButton.java @@ -102,7 +102,7 @@ public class VotingButton { } static boolean shouldBeShown() { - return SponsorBlockSettings.isVotingEnabled && SponsorBlockSettings.isSponsorBlockEnabled; + return SponsorBlockUtils.isSettingEnabled(SponsorBlockSettings.isVotingEnabled); } //region Helpers diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index acef509c..41954e21 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -43,29 +43,25 @@ public class Requester { videoHasSegments = false; timeWithoutSegments = ""; - switch (responseCode) { - case 200: - JSONArray responseArray = new JSONArray(parseJson(connection)); - int length = responseArray.length(); - for (int i = 0; i < length; i++) { - JSONObject obj = ((JSONObject) responseArray.get(i)); - JSONArray segment = obj.getJSONArray("segment"); - long start = (long) (segment.getDouble(0) * 1000); - long end = (long) (segment.getDouble(1) * 1000); - String category = obj.getString("category"); - String uuid = obj.getString("UUID"); + if (responseCode == 200) { + JSONArray responseArray = new JSONArray(parseJson(connection)); + int length = responseArray.length(); + for (int i = 0; i < length; i++) { + JSONObject obj = ((JSONObject) responseArray.get(i)); + JSONArray segment = obj.getJSONArray("segment"); + long start = (long) (segment.getDouble(0) * 1000); + long end = (long) (segment.getDouble(1) * 1000); + String category = obj.getString("category"); + String uuid = obj.getString("UUID"); - SponsorBlockSettings.SegmentInfo segmentCategory = SponsorBlockSettings.SegmentInfo.byCategoryKey(category); - if (segmentCategory != null && segmentCategory.behaviour.showOnTimeBar) { - SponsorSegment sponsorSegment = new SponsorSegment(start, end, segmentCategory, uuid); - segments.add(sponsorSegment); - } + SponsorBlockSettings.SegmentInfo segmentCategory = SponsorBlockSettings.SegmentInfo.byCategoryKey(category); + if (segmentCategory != null && segmentCategory.behaviour.showOnTimeBar) { + SponsorSegment sponsorSegment = new SponsorSegment(start, end, segmentCategory, uuid); + segments.add(sponsorSegment); } - videoHasSegments = true; - timeWithoutSegments = SponsorBlockUtils.getTimeWithoutSegments(segments); - break; - case 404: - break; + } + videoHasSegments = true; + timeWithoutSegments = SponsorBlockUtils.getTimeWithoutSegments(segments.toArray(new SponsorSegment[0])); } connection.disconnect(); } From 3a4c6e0955fd496c9dc9b3e58d32137c0771c33c Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 26 Jul 2021 00:15:02 +0200 Subject: [PATCH 56/56] add handling of unknown error codes to submitting --- app/src/main/java/pl/jakubweg/requests/Requester.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/pl/jakubweg/requests/Requester.java b/app/src/main/java/pl/jakubweg/requests/Requester.java index 41954e21..7531b0ad 100644 --- a/app/src/main/java/pl/jakubweg/requests/Requester.java +++ b/app/src/main/java/pl/jakubweg/requests/Requester.java @@ -91,6 +91,9 @@ public class Requester { case 429: SponsorBlockUtils.messageToToast = str("submit_failed_rate_limit"); break; + default: + SponsorBlockUtils.messageToToast = str("submit_failed_unknown_error", responseCode, connection.getResponseMessage()); + break; } new Handler(Looper.getMainLooper()).post(toastRunnable); connection.disconnect();