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