SponsorBlock: Made changes requested in code review
See: TeamNewPipe#3205
This commit is contained in:
parent
d30178f68f
commit
193a19d9d1
10 changed files with 27 additions and 324 deletions
|
@ -1,6 +1,5 @@
|
|||
package org.schabi.newpipe;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
|
@ -13,39 +12,18 @@ import org.json.JSONObject;
|
|||
import org.schabi.newpipe.util.SponsorTimeInfo;
|
||||
import org.schabi.newpipe.util.TimeFrame;
|
||||
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
import javax.net.ssl.TrustManager;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import okhttp3.ResponseBody;
|
||||
|
||||
public class SponsorBlockApiTask extends AsyncTask<String, Void, JSONObject> {
|
||||
private static final Application APP = App.getApp();
|
||||
private static final String SPONSOR_BLOCK_API_URL = "https://api.sponsor.ajay.app/api/";
|
||||
private static final int TIMEOUT_PERIOD = 30;
|
||||
private static final String SPONSOR_BLOCK_API_URL = "https://sponsor.ajay.app/api/";
|
||||
private static final String TAG = SponsorBlockApiTask.class.getSimpleName();
|
||||
private static final boolean DEBUG = MainActivity.DEBUG;
|
||||
private OkHttpClient client;
|
||||
|
||||
// api methods
|
||||
public SponsorTimeInfo getVideoSponsorTimes(final String url) throws ExecutionException,
|
||||
InterruptedException, JSONException {
|
||||
String videoId = parseIdFromUrl(url);
|
||||
String apiSuffix = "getVideoSponsorTimes?videoID=" + videoId;
|
||||
public SponsorTimeInfo getYouTubeVideoSponsorTimes(final String videoId)
|
||||
throws ExecutionException, InterruptedException, JSONException {
|
||||
|
||||
JSONObject obj = execute(apiSuffix).get();
|
||||
JSONObject obj = execute("getVideoSponsorTimes?videoID=" + videoId).get();
|
||||
JSONArray arrayObj = obj.getJSONArray("sponsorTimes");
|
||||
|
||||
SponsorTimeInfo result = new SponsorTimeInfo();
|
||||
|
@ -64,26 +42,6 @@ public class SponsorBlockApiTask extends AsyncTask<String, Void, JSONObject> {
|
|||
return result;
|
||||
}
|
||||
|
||||
public void postVideoSponsorTimes(final String url, final double startTime,
|
||||
final double endTime, final String userId) {
|
||||
double dStartTime = startTime / 1000.0;
|
||||
double dEndTime = endTime / 1000.0;
|
||||
|
||||
String videoId = parseIdFromUrl(url);
|
||||
String apiSuffix = "postVideoSponsorTimes?videoID="
|
||||
+ videoId
|
||||
+ "&startTime="
|
||||
+ dStartTime
|
||||
+ "&endTime="
|
||||
+ dEndTime
|
||||
+ "&userID=" + (userId == null
|
||||
? getRandomUserId()
|
||||
: userId);
|
||||
|
||||
execute(apiSuffix);
|
||||
}
|
||||
|
||||
// task methods
|
||||
@Override
|
||||
protected JSONObject doInBackground(final String... strings) {
|
||||
if (isCancelled() || !isConnected()) {
|
||||
|
@ -91,23 +49,13 @@ public class SponsorBlockApiTask extends AsyncTask<String, Void, JSONObject> {
|
|||
}
|
||||
|
||||
try {
|
||||
if (client == null) {
|
||||
client = getUnsafeOkHttpClient()
|
||||
.newBuilder()
|
||||
.readTimeout(TIMEOUT_PERIOD, TimeUnit.SECONDS)
|
||||
.build();
|
||||
}
|
||||
String responseBody =
|
||||
DownloaderImpl
|
||||
.getInstance()
|
||||
.get(SPONSOR_BLOCK_API_URL + strings[0])
|
||||
.responseBody();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(SPONSOR_BLOCK_API_URL + strings[0])
|
||||
.build();
|
||||
|
||||
Response response = client.newCall(request).execute();
|
||||
ResponseBody responseBody = response.body();
|
||||
|
||||
return responseBody == null
|
||||
? null
|
||||
: new JSONObject(responseBody.string());
|
||||
return new JSONObject(responseBody);
|
||||
|
||||
} catch (Exception ex) {
|
||||
if (DEBUG) {
|
||||
|
@ -118,70 +66,10 @@ public class SponsorBlockApiTask extends AsyncTask<String, Void, JSONObject> {
|
|||
return null;
|
||||
}
|
||||
|
||||
// helper methods
|
||||
private boolean isConnected() {
|
||||
ConnectivityManager cm =
|
||||
(ConnectivityManager) APP.getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||
return cm.getActiveNetworkInfo() != null
|
||||
&& cm.getActiveNetworkInfo().isConnected();
|
||||
}
|
||||
|
||||
private OkHttpClient getUnsafeOkHttpClient()
|
||||
throws NoSuchAlgorithmException, KeyManagementException {
|
||||
final TrustManager[] trustAllCerts = new TrustManager[] {
|
||||
new X509TrustManager() {
|
||||
@SuppressLint("TrustAllX509TrustManager")
|
||||
@Override
|
||||
public void checkClientTrusted(final java.security.cert.X509Certificate[] chain,
|
||||
final String authType) {
|
||||
}
|
||||
|
||||
@SuppressLint("TrustAllX509TrustManager")
|
||||
@Override
|
||||
public void checkServerTrusted(final java.security.cert.X509Certificate[] chain,
|
||||
final String authType) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
|
||||
return new java.security.cert.X509Certificate[] {};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
SSLContext sslContext = SSLContext.getInstance("SSL");
|
||||
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
|
||||
|
||||
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
|
||||
|
||||
return new OkHttpClient
|
||||
.Builder()
|
||||
.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0])
|
||||
.hostnameVerifier((hostname, session) -> true)
|
||||
.build();
|
||||
}
|
||||
|
||||
private String parseIdFromUrl(final String youTubeUrl) {
|
||||
String pattern = "(?<=youtu.be/|watch\\?v=|/videos/|embed/)[^#&?]*";
|
||||
Pattern compiledPattern = Pattern.compile(pattern);
|
||||
Matcher matcher = compiledPattern.matcher(youTubeUrl);
|
||||
if (matcher.find()) {
|
||||
return matcher.group();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private String getRandomUserId() {
|
||||
String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
|
||||
StringBuilder salt = new StringBuilder();
|
||||
Random random = new Random();
|
||||
|
||||
while (salt.length() < 36) {
|
||||
int index = (int) (random.nextFloat() * chars.length());
|
||||
salt.append(chars.charAt(index));
|
||||
}
|
||||
|
||||
return salt.toString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1060,11 +1060,13 @@ public abstract class BasePlayer implements
|
|||
initThumbnail(info.getThumbnailUrl());
|
||||
registerView();
|
||||
|
||||
if (mPrefs.getBoolean(context.getString(R.string.sponsorblock_enable), false)) {
|
||||
if (info.getUrl().startsWith("https://www.youtube.com")
|
||||
&& mPrefs.getBoolean(context.getString(R.string.sponsorblock_enable), false)) {
|
||||
try {
|
||||
sponsorTimeInfo = new SponsorBlockApiTask().getVideoSponsorTimes(getVideoUrl());
|
||||
sponsorTimeInfo = new SponsorBlockApiTask()
|
||||
.getYouTubeVideoSponsorTimes(info.getId());
|
||||
} catch (Exception e) {
|
||||
Log.e("SPONSOR_BLOCK", "Error getting video sponsor times.", e);
|
||||
Log.e("SPONSOR_BLOCK", "Error getting YouTube video sponsor times.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
|
||||
package org.schabi.newpipe.player;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
|
@ -71,7 +70,6 @@ import com.google.android.exoplayer2.ui.AspectRatioFrameLayout;
|
|||
import com.google.android.exoplayer2.ui.SubtitleView;
|
||||
|
||||
import org.schabi.newpipe.R;
|
||||
import org.schabi.newpipe.SponsorBlockApiTask;
|
||||
import org.schabi.newpipe.extractor.stream.VideoStream;
|
||||
import org.schabi.newpipe.fragments.OnScrollBelowItemsListener;
|
||||
import org.schabi.newpipe.player.helper.PlaybackParameterDialog;
|
||||
|
@ -89,15 +87,10 @@ import org.schabi.newpipe.util.ListHelper;
|
|||
import org.schabi.newpipe.util.NavigationHelper;
|
||||
import org.schabi.newpipe.util.PermissionHelper;
|
||||
import org.schabi.newpipe.util.ShareUtils;
|
||||
import org.schabi.newpipe.util.SponsorTimeInfo;
|
||||
import org.schabi.newpipe.util.StateSaver;
|
||||
import org.schabi.newpipe.util.ThemeHelper;
|
||||
import org.schabi.newpipe.util.TimeFrame;
|
||||
import org.schabi.newpipe.views.FocusOverlayView;
|
||||
import org.schabi.newpipe.views.MarkableSeekBar;
|
||||
import org.schabi.newpipe.views.SeekBarMarker;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.UUID;
|
||||
|
@ -557,7 +550,6 @@ public final class MainVideoPlayer extends AppCompatActivity
|
|||
private ImageButton switchPopupButton;
|
||||
private ImageButton switchBackgroundButton;
|
||||
private ImageButton muteButton;
|
||||
private ImageButton submitSponsorTimesButton;
|
||||
|
||||
private RelativeLayout windowRootLayout;
|
||||
private View secondaryControls;
|
||||
|
@ -595,17 +587,6 @@ public final class MainVideoPlayer extends AppCompatActivity
|
|||
this.toggleOrientationButton = view.findViewById(R.id.toggleOrientation);
|
||||
this.switchBackgroundButton = view.findViewById(R.id.switchBackground);
|
||||
this.muteButton = view.findViewById(R.id.switchMute);
|
||||
|
||||
this.submitSponsorTimesButton = view.findViewById(R.id.submitSponsorTimes);
|
||||
this.submitSponsorTimesButton.setTag(false);
|
||||
this.submitSponsorTimesButton.setOnLongClickListener(v -> {
|
||||
onSponsorBlockButtonLongClicked();
|
||||
return true;
|
||||
});
|
||||
if (!defaultPreferences.getBoolean(getString(R.string.sponsorblock_enable), false)) {
|
||||
this.submitSponsorTimesButton.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
this.switchPopupButton = view.findViewById(R.id.switchPopup);
|
||||
|
||||
this.queueLayout = findViewById(R.id.playQueuePanel);
|
||||
|
@ -655,7 +636,6 @@ public final class MainVideoPlayer extends AppCompatActivity
|
|||
toggleOrientationButton.setOnClickListener(this);
|
||||
switchBackgroundButton.setOnClickListener(this);
|
||||
muteButton.setOnClickListener(this);
|
||||
submitSponsorTimesButton.setOnClickListener(this);
|
||||
switchPopupButton.setOnClickListener(this);
|
||||
|
||||
getRootView().addOnLayoutChangeListener((view, l, t, r, b, ol, ot, or, ob) -> {
|
||||
|
@ -836,110 +816,6 @@ public final class MainVideoPlayer extends AppCompatActivity
|
|||
setMuteButton(muteButton, playerImpl.isMuted());
|
||||
}
|
||||
|
||||
private void onSponsorBlockButtonClicked() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onSponsorBlockButtonClicked() called");
|
||||
}
|
||||
if (playerImpl.getPlayer() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((boolean) submitSponsorTimesButton.getTag()) {
|
||||
TimeFrame customTimeFrame =
|
||||
new TimeFrame(customSponsorStartTime, simpleExoPlayer.getCurrentPosition());
|
||||
customTimeFrame.tag = "custom";
|
||||
|
||||
SponsorTimeInfo sponsorTimeInfo = getSponsorTimeInfo();
|
||||
if (sponsorTimeInfo == null) {
|
||||
sponsorTimeInfo = new SponsorTimeInfo();
|
||||
|
||||
setSponsorTimeInfo(sponsorTimeInfo);
|
||||
}
|
||||
|
||||
sponsorTimeInfo.timeFrames.add(customTimeFrame);
|
||||
|
||||
SeekBarMarker marker =
|
||||
new SeekBarMarker(customTimeFrame.startTime, customTimeFrame.endTime,
|
||||
(int) simpleExoPlayer.getDuration(), Color.BLUE);
|
||||
marker.tag = "custom";
|
||||
|
||||
MarkableSeekBar markableSeekBar = (MarkableSeekBar) getPlaybackSeekBar();
|
||||
markableSeekBar.seekBarMarkers.add(marker);
|
||||
markableSeekBar.invalidate();
|
||||
|
||||
submitSponsorTimesButton.setTag(false);
|
||||
submitSponsorTimesButton.setImageResource(R.drawable.ic_sponsor_block);
|
||||
} else {
|
||||
customSponsorStartTime = (int) simpleExoPlayer.getCurrentPosition();
|
||||
|
||||
submitSponsorTimesButton.setTag(true);
|
||||
submitSponsorTimesButton.setImageResource(R.drawable.ic_sponsor_block_stop);
|
||||
}
|
||||
}
|
||||
|
||||
private void onSponsorBlockButtonLongClicked() {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "onSponsorBlockButtonLongClicked() called");
|
||||
}
|
||||
if (playerImpl.getPlayer() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<SeekBarMarker> customMarkers = new ArrayList<>();
|
||||
ArrayList<TimeFrame> customTimeFrames = new ArrayList<>();
|
||||
|
||||
for (SeekBarMarker marker : ((MarkableSeekBar) getPlaybackSeekBar()).seekBarMarkers) {
|
||||
if (marker.tag == "custom") {
|
||||
customMarkers.add(marker);
|
||||
}
|
||||
}
|
||||
|
||||
if (customMarkers.size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SponsorTimeInfo sponsorTimeInfo = getSponsorTimeInfo();
|
||||
if (sponsorTimeInfo != null) {
|
||||
for (TimeFrame timeFrame : sponsorTimeInfo.timeFrames) {
|
||||
if (timeFrame.tag == "custom") {
|
||||
customTimeFrames.add(timeFrame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new AlertDialog
|
||||
.Builder(context)
|
||||
.setMessage("Submit " + customMarkers.size() + " sponsor time segment(s)?")
|
||||
.setPositiveButton("Yes", (dialog, id) -> {
|
||||
String username = defaultPreferences
|
||||
.getString(getString(R.string.sponsorblock_username), null);
|
||||
for (TimeFrame timeFrame : customTimeFrames) {
|
||||
try {
|
||||
new SponsorBlockApiTask()
|
||||
.postVideoSponsorTimes(getVideoUrl(), timeFrame.startTime,
|
||||
timeFrame.endTime, username);
|
||||
} catch (Exception e) {
|
||||
Log.e("SPONSOR_BLOCK", "Error getting video sponsor times.", e);
|
||||
}
|
||||
}
|
||||
})
|
||||
.setNegativeButton("No", null)
|
||||
.setNeutralButton("Clear", (dialog, id) -> {
|
||||
for (SeekBarMarker marker : customMarkers) {
|
||||
((MarkableSeekBar) getPlaybackSeekBar()).seekBarMarkers.remove(marker);
|
||||
}
|
||||
|
||||
if (sponsorTimeInfo != null) {
|
||||
for (TimeFrame timeFrame : customTimeFrames) {
|
||||
sponsorTimeInfo.timeFrames.remove(timeFrame);
|
||||
}
|
||||
}
|
||||
})
|
||||
.create()
|
||||
.show();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(final View v) {
|
||||
super.onClick(v);
|
||||
|
@ -970,10 +846,6 @@ public final class MainVideoPlayer extends AppCompatActivity
|
|||
onPlayBackgroundButtonClicked();
|
||||
} else if (v.getId() == muteButton.getId()) {
|
||||
onMuteUnmuteButtonClicked();
|
||||
|
||||
} else if (v.getId() == submitSponsorTimesButton.getId()) {
|
||||
onSponsorBlockButtonClicked();
|
||||
|
||||
} else if (v.getId() == closeButton.getId()) {
|
||||
onPlaybackShutdown();
|
||||
return;
|
||||
|
|
|
@ -625,7 +625,7 @@ public abstract class VideoPlayer extends BasePlayer
|
|||
|
||||
super.onPrepared(playWhenReady);
|
||||
|
||||
tryMarkSponsorTimes();
|
||||
markSponsorTimes();
|
||||
|
||||
if (simpleExoPlayer.getCurrentPosition() != 0 && !isControlsVisible()) {
|
||||
controlsVisibilityHandler.removeCallbacksAndMessages(null);
|
||||
|
@ -634,7 +634,7 @@ public abstract class VideoPlayer extends BasePlayer
|
|||
}
|
||||
}
|
||||
|
||||
private void tryMarkSponsorTimes() {
|
||||
private void markSponsorTimes() {
|
||||
SponsorTimeInfo sponsorTimeInfo = getSponsorTimeInfo();
|
||||
|
||||
if (sponsorTimeInfo == null) {
|
||||
|
|
|
@ -148,15 +148,6 @@ public class ContentSettingsFragment extends BasePreferenceFragment {
|
|||
startActivity(i);
|
||||
return true;
|
||||
});
|
||||
|
||||
Preference sponsorblockLeaderboardsPreference =
|
||||
findPreference(getString(R.string.sponsorblock_leaderboards));
|
||||
sponsorblockLeaderboardsPreference.setOnPreferenceClickListener((Preference p) -> {
|
||||
Intent i = new Intent(Intent.ACTION_VIEW,
|
||||
Uri.parse("https://api.sponsor.ajay.app/stats"));
|
||||
startActivity(i);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -414,22 +414,6 @@
|
|||
android:contentDescription="@string/switch_to_background"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/submitSponsorTimes"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_toLeftOf="@id/switchMute"
|
||||
android:layout_centerVertical="true"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="5dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_sponsor_block"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:contentDescription="@string/submit_sponsor_times"
|
||||
tools:ignore="RtlHardcoded"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -406,22 +406,6 @@
|
|||
android:contentDescription="@string/switch_to_background"
|
||||
tools:ignore="RtlHardcoded" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/submitSponsorTimes"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginRight="4dp"
|
||||
android:layout_toLeftOf="@id/switchMute"
|
||||
android:layout_centerVertical="true"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="5dp"
|
||||
android:scaleType="fitXY"
|
||||
android:src="@drawable/ic_sponsor_block"
|
||||
android:background="?attr/selectableItemBackground"
|
||||
android:contentDescription="@string/submit_sponsor_times"
|
||||
tools:ignore="RtlHardcoded"/>
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -223,21 +223,9 @@
|
|||
<string name="downloads_storage_ask" translatable="false">downloads_storage_ask</string>
|
||||
<string name="storage_use_saf" translatable="false">storage_use_saf</string>
|
||||
|
||||
<string name="sponsorblock_enable">skip_sponsors</string>
|
||||
<string name="sponsorblock_enable_title">Skip Sponsors</string>
|
||||
<string name="sponsorblock_enable_summary">Use the SponsorBlock API to automatically skip sponsors in videos.</string>
|
||||
<string name="sponsorblock_notifications">sponsorblock_notifications</string>
|
||||
<string name="sponsorblock_notifications_title">Notify when sponsors are skipped</string>
|
||||
<string name="sponsorblock_notifications_summary">Send a notification to your device when a sponsor is automatically skipped.</string>
|
||||
<string name="sponsorblock_username">sponsorblock_username</string>
|
||||
<string name="sponsorblock_username_title">Set Username</string>
|
||||
<string name="sponsorblock_username_summary">Set a username used when submitting sponsor times. Leave empty to use a default randomized username.</string>
|
||||
<string name="sponsorblock_status">sponsorblock_status</string>
|
||||
<string name="sponsorblock_status_title">View Online Status</string>
|
||||
<string name="sponsorblock_status_summary">View the online status of the SponsorBlock servers.</string>
|
||||
<string name="sponsorblock_leaderboards">sponsorblock_leaderboards</string>
|
||||
<string name="sponsorblock_leaderboards_title">View Leaderboards</string>
|
||||
<string name="sponsorblock_leaderboards_summary">View the online leaderboards for SponsorBlock.</string>
|
||||
<string name="sponsorblock_enable" translatable="false">skip_sponsors</string>
|
||||
<string name="sponsorblock_notifications" translatable="false">sponsorblock_notifications</string>
|
||||
<string name="sponsorblock_status" translatable="false">sponsorblock_status</string>
|
||||
|
||||
<!-- FileName Downloads -->
|
||||
<string name="settings_file_charset_key" translatable="false">file_rename_charset</string>
|
||||
|
|
|
@ -661,4 +661,11 @@
|
|||
<string name="channel_created_by">Created by %s</string>
|
||||
<string name="video_detail_by">By %s</string>
|
||||
<string name="playlist_page_summary">Playlist page</string>
|
||||
<!-- SponsorBlock -->
|
||||
<string name="sponsorblock_enable_title">Skip Sponsors</string>
|
||||
<string name="sponsorblock_enable_summary">Use the SponsorBlock API to automatically skip sponsors in videos.</string>
|
||||
<string name="sponsorblock_notifications_title">Notify when sponsors are skipped</string>
|
||||
<string name="sponsorblock_notifications_summary">Send a notification to your device when a sponsor is automatically skipped.</string>
|
||||
<string name="sponsorblock_status_title">View Online Status</string>
|
||||
<string name="sponsorblock_status_summary">View the online status of the SponsorBlock servers.</string>
|
||||
</resources>
|
|
@ -137,23 +137,10 @@
|
|||
android:title="@string/sponsorblock_notifications_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<EditTextPreference
|
||||
android:dependency="@string/sponsorblock_enable"
|
||||
android:key="@string/sponsorblock_username"
|
||||
android:summary="@string/sponsorblock_username_summary"
|
||||
android:title="@string/sponsorblock_username_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<Preference
|
||||
android:key="@string/sponsorblock_status"
|
||||
android:summary="@string/sponsorblock_status_summary"
|
||||
android:title="@string/sponsorblock_status_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
|
||||
<Preference
|
||||
android:key="@string/sponsorblock_leaderboards"
|
||||
android:summary="@string/sponsorblock_leaderboards_summary"
|
||||
android:title="@string/sponsorblock_leaderboards_title"
|
||||
app:iconSpaceReserved="false" />
|
||||
</PreferenceCategory>
|
||||
</PreferenceScreen>
|
||||
|
|
Loading…
Reference in a new issue