From e88cf5143dbd9188bc06b271a5005863195551f3 Mon Sep 17 00:00:00 2001 From: caneleex Date: Mon, 19 Jul 2021 16:19:47 +0200 Subject: [PATCH 01/14] 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 02/14] 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 03/14] 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 04/14] 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 05/14] 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 06/14] 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 07/14] 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 08/14] 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 09/14] 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 10/14] 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 11/14] 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 12/14] 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 13/14] 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 96561f6c9090df30b2efe3cc013f1e4538480c23 Mon Sep 17 00:00:00 2001 From: caneleex Date: Fri, 23 Jul 2021 23:50:57 +0200 Subject: [PATCH 14/14] 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;