Settings added plus some fixes

This commit is contained in:
VancedOfficial 2022-01-16 18:19:59 +02:00
parent 306457ef84
commit e48e16ae69
13 changed files with 279 additions and 10 deletions

View File

@ -25,10 +25,12 @@ import fi.razerman.youtube.XGlobals;
import fi.vanced.libraries.youtube.player.ChannelModel; import fi.vanced.libraries.youtube.player.ChannelModel;
import fi.vanced.libraries.youtube.player.VideoInformation; import fi.vanced.libraries.youtube.player.VideoInformation;
import fi.vanced.utils.ObjectSerializer; import fi.vanced.utils.ObjectSerializer;
import fi.vanced.utils.SharedPrefUtils;
public class VideoAds { public class VideoAds {
public static final String TAG = "VI - VideoAds"; public static final String TAG = "VI - VideoAds";
public static final String PREFERENCES_NAME = "channel-whitelist"; public static final String PREFERENCES_NAME = "channel-whitelist";
public static boolean isEnabled;
private static final String YT_API_URL = "https://www.youtube.com/youtubei/v1"; private static final String YT_API_URL = "https://www.youtube.com/youtubei/v1";
private static final String YT_API_KEY = "replaceMeWithTheYouTubeAPIKey"; private static final String YT_API_KEY = "replaceMeWithTheYouTubeAPIKey";
private static ArrayList<ChannelModel> whiteList; private static ArrayList<ChannelModel> whiteList;
@ -36,6 +38,7 @@ public class VideoAds {
static { static {
whiteList = parseWhitelist(YouTubeTikTokRoot_Application.getAppContext()); whiteList = parseWhitelist(YouTubeTikTokRoot_Application.getAppContext());
isEnabled = SharedPrefUtils.getBoolean(YouTubeTikTokRoot_Application.getAppContext(), "youtube", "vanced_videoadwhitelisting_enabled", false);
} }
// Call to this needs to be injected in YT code // Call to this needs to be injected in YT code
@ -45,6 +48,8 @@ public class VideoAds {
} }
VideoInformation.channelName = channelName; VideoInformation.channelName = channelName;
if (!isEnabled) return;
if (adBlockButton != null) { if (adBlockButton != null) {
adBlockButton.changeEnabled(getShouldShowAds()); adBlockButton.changeEnabled(getShouldShowAds());
} }
@ -108,6 +113,8 @@ public class VideoAds {
} }
public static boolean getShouldShowAds() { public static boolean getShouldShowAds() {
if (!isEnabled) return false;
if (channelName == null || channelName.isEmpty() || channelName.trim().isEmpty()) { if (channelName == null || channelName.isEmpty() || channelName.trim().isEmpty()) {
if (XGlobals.debug) { if (XGlobals.debug) {
Log.d(TAG, "getShouldShowAds skipped because channelId was null"); Log.d(TAG, "getShouldShowAds skipped because channelId was null");
@ -131,6 +138,23 @@ public class VideoAds {
public static boolean addToWhitelist(Context context, String channelName, String channelId) { public static boolean addToWhitelist(Context context, String channelName, String channelId) {
try { try {
// Check that the channel doesn't exist already (can happen if for example the channel changes the name)
// If it exists, remove it
Iterator<ChannelModel> iterator = whiteList.iterator();
while(iterator.hasNext())
{
ChannelModel value = iterator.next();
if (value.getChannelId().equals(channelId))
{
if (XGlobals.debug) {
Log.d(TAG, String.format("Tried whitelisting an existing channel again. Old info (%1$s | %2$s) - New info (%3$s | %4$s)",
value.getAuthor(), value.getChannelId(), channelName, channelId));
}
iterator.remove();
break;
}
}
whiteList.add(new ChannelModel(channelName, channelId)); whiteList.add(new ChannelModel(channelName, channelId));
updateWhitelist(context); updateWhitelist(context);
return true; return true;

View File

@ -0,0 +1,81 @@
package fi.vanced.libraries.youtube.ryd;
import static fi.vanced.libraries.youtube.ryd.RYDSettings.PREFERENCES_KEY_RYD_ENABLED;
import static fi.vanced.libraries.youtube.ryd.RYDSettings.PREFERENCES_NAME;
import static pl.jakubweg.StringRef.str;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceCategory;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;
import android.preference.SwitchPreference;
import fi.vanced.utils.SharedPrefUtils;
public class RYDFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(PREFERENCES_NAME);
final Activity context = this.getActivity();
PreferenceScreen preferenceScreen = getPreferenceManager().createPreferenceScreen(context);
setPreferenceScreen(preferenceScreen);
// RYD enable toggle
{
SwitchPreference preference = new SwitchPreference(context);
preferenceScreen.addPreference(preference);
preference.setKey(PREFERENCES_KEY_RYD_ENABLED);
preference.setDefaultValue(false);
preference.setChecked(SharedPrefUtils.getBoolean(context, PREFERENCES_NAME, PREFERENCES_KEY_RYD_ENABLED));
preference.setTitle(str("vanced_ryd_title"));
preference.setSummary(str("vanced_ryd_summary"));
preference.setOnPreferenceChangeListener((pref, newValue) -> {
final boolean value = (Boolean) newValue;
ReturnYouTubeDislikes.onEnabledChange(value);
return true;
});
}
// About category
addAboutCategory(context, preferenceScreen);
}
private void addAboutCategory(Context context, PreferenceScreen screen) {
PreferenceCategory category = new PreferenceCategory(context);
screen.addPreference(category);
category.setTitle(str("about"));
{
Preference preference = new Preference(context);
screen.addPreference(preference);
preference.setTitle(str("vanced_ryd_attribution_title"));
preference.setSummary(str("vanced_ryd_attribution_summary"));
preference.setOnPreferenceClickListener(pref -> {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("https://returnyoutubedislike.com"));
pref.getContext().startActivity(i);
return false;
});
}
{
Preference preference = new Preference(context);
screen.addPreference(preference);
preference.setTitle("GitHub");
preference.setOnPreferenceClickListener(pref -> {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("https://github.com/Anarios/return-youtube-dislike"));
pref.getContext().startActivity(i);
return false;
});
}
}
}

View File

@ -0,0 +1,7 @@
package fi.vanced.libraries.youtube.ryd;
public class RYDSettings {
public static final String PREFERENCES_NAME = "ryd";
public static final String PREFERENCES_KEY_USERID = "userId";
public static final String PREFERENCES_KEY_RYD_ENABLED = "ryd-enabled";
}

View File

@ -1,6 +1,8 @@
package fi.vanced.libraries.youtube.ryd; package fi.vanced.libraries.youtube.ryd;
import static fi.razerman.youtube.XGlobals.debug; import static fi.razerman.youtube.XGlobals.debug;
import static fi.vanced.libraries.youtube.ryd.RYDSettings.PREFERENCES_KEY_USERID;
import static fi.vanced.libraries.youtube.ryd.RYDSettings.PREFERENCES_NAME;
import static fi.vanced.utils.VancedUtils.getPreferences; import static fi.vanced.utils.VancedUtils.getPreferences;
import static fi.vanced.utils.VancedUtils.parseJson; import static fi.vanced.utils.VancedUtils.parseJson;
import static fi.vanced.utils.VancedUtils.randomString; import static fi.vanced.utils.VancedUtils.randomString;
@ -18,7 +20,6 @@ import java.nio.charset.StandardCharsets;
public class Registration { public class Registration {
private static final String TAG = "VI - RYD - Registration"; private static final String TAG = "VI - RYD - Registration";
public static final String PREFERENCES_NAME = "ryd";
private String userId; private String userId;
private Context context; private Context context;
@ -36,7 +37,7 @@ public class Registration {
if (this.context == null) throw new Exception("Unable to fetch userId because context was null"); if (this.context == null) throw new Exception("Unable to fetch userId because context was null");
SharedPreferences preferences = getPreferences(context, PREFERENCES_NAME); SharedPreferences preferences = getPreferences(context, PREFERENCES_NAME);
this.userId = preferences.getString("userId", null); this.userId = preferences.getString(PREFERENCES_KEY_USERID, null);
if (this.userId == null) { if (this.userId == null) {
this.userId = register(); this.userId = register();
@ -55,7 +56,7 @@ public class Registration {
SharedPreferences preferences = getPreferences(context, PREFERENCES_NAME); SharedPreferences preferences = getPreferences(context, PREFERENCES_NAME);
SharedPreferences.Editor editor = preferences.edit(); SharedPreferences.Editor editor = preferences.edit();
editor.putString("userId", userId).apply(); editor.putString(PREFERENCES_KEY_USERID, userId).apply();
} }
catch (Exception ex) { catch (Exception ex) {
Log.e(TAG, "Unable to save the userId in shared preferences", ex); Log.e(TAG, "Unable to save the userId in shared preferences", ex);

View File

@ -2,6 +2,8 @@ package fi.vanced.libraries.youtube.ryd;
import static fi.razerman.youtube.XGlobals.debug; import static fi.razerman.youtube.XGlobals.debug;
import static fi.vanced.libraries.youtube.player.VideoInformation.currentVideoId; import static fi.vanced.libraries.youtube.player.VideoInformation.currentVideoId;
import static fi.vanced.libraries.youtube.ryd.RYDSettings.PREFERENCES_KEY_RYD_ENABLED;
import static fi.vanced.libraries.youtube.ryd.RYDSettings.PREFERENCES_NAME;
import static fi.vanced.utils.VancedUtils.getIdentifier; import static fi.vanced.utils.VancedUtils.getIdentifier;
import static fi.vanced.utils.VancedUtils.parseJson; import static fi.vanced.utils.VancedUtils.parseJson;
@ -21,8 +23,11 @@ import java.net.URL;
import static fi.vanced.libraries.youtube.player.VideoInformation.dislikeCount; import static fi.vanced.libraries.youtube.player.VideoInformation.dislikeCount;
import fi.vanced.utils.SharedPrefUtils;
public class ReturnYouTubeDislikes { public class ReturnYouTubeDislikes {
public static final String RYD_API_URL = "https://returnyoutubedislikeapi.com"; public static final String RYD_API_URL = "https://returnyoutubedislikeapi.com";
public static boolean isEnabled;
private static final String TAG = "VI - RYD"; private static final String TAG = "VI - RYD";
private static View _dislikeView = null; private static View _dislikeView = null;
private static Thread _dislikeFetchThread = null; private static Thread _dislikeFetchThread = null;
@ -34,15 +39,31 @@ public class ReturnYouTubeDislikes {
private static int votingValue = 0; // 1 = like, -1 = dislike, 0 = no vote private static int votingValue = 0; // 1 = like, -1 = dislike, 0 = no vote
static { static {
isEnabled = SharedPrefUtils.getBoolean(YouTubeTikTokRoot_Application.getAppContext(), PREFERENCES_NAME, PREFERENCES_KEY_RYD_ENABLED, false);
if (isEnabled) {
registration = new Registration(YouTubeTikTokRoot_Application.getAppContext()); registration = new Registration(YouTubeTikTokRoot_Application.getAppContext());
voting = new Voting(YouTubeTikTokRoot_Application.getAppContext(), registration); voting = new Voting(YouTubeTikTokRoot_Application.getAppContext(), registration);
} }
}
public static void onEnabledChange(boolean enabled) {
isEnabled = enabled;
if (registration == null) {
registration = new Registration(YouTubeTikTokRoot_Application.getAppContext());
}
if (voting == null) {
voting = new Voting(YouTubeTikTokRoot_Application.getAppContext(), registration);
}
}
public static void newVideoLoaded(String videoId) { public static void newVideoLoaded(String videoId) {
if (debug) { if (debug) {
Log.d(TAG, "newVideoLoaded - " + videoId); Log.d(TAG, "newVideoLoaded - " + videoId);
} }
dislikeCount = null;
if (!isEnabled) return;
try { try {
if (_dislikeFetchThread != null && _dislikeFetchThread.getState() != Thread.State.TERMINATED) { if (_dislikeFetchThread != null && _dislikeFetchThread.getState() != Thread.State.TERMINATED) {
if (debug) { if (debug) {
@ -93,10 +114,14 @@ public class ReturnYouTubeDislikes {
// Call to this needs to be injected in YT code // Call to this needs to be injected in YT code
public static void setLikeTag(View view) { public static void setLikeTag(View view) {
if (!isEnabled) return;
setTag(view, "like"); setTag(view, "like");
} }
public static void setLikeTag(View view, boolean active) { public static void setLikeTag(View view, boolean active) {
if (!isEnabled) return;
likeActive = active; likeActive = active;
if (likeActive) { if (likeActive) {
votingValue = 1; votingValue = 1;
@ -109,11 +134,15 @@ public class ReturnYouTubeDislikes {
// Call to this needs to be injected in YT code // Call to this needs to be injected in YT code
public static void setDislikeTag(View view) { public static void setDislikeTag(View view) {
if (!isEnabled) return;
_dislikeView = view; _dislikeView = view;
setTag(view, "dislike"); setTag(view, "dislike");
} }
public static void setDislikeTag(View view, boolean active) { public static void setDislikeTag(View view, boolean active) {
if (!isEnabled) return;
dislikeActive = active; dislikeActive = active;
if (dislikeActive) { if (dislikeActive) {
votingValue = -1; votingValue = -1;
@ -127,15 +156,20 @@ public class ReturnYouTubeDislikes {
// Call to this needs to be injected in YT code // Call to this needs to be injected in YT code
public static CharSequence onSetText(View view, CharSequence originalText) { public static CharSequence onSetText(View view, CharSequence originalText) {
if (!isEnabled) return originalText;
return handleOnSetText(view, originalText); return handleOnSetText(view, originalText);
} }
// Call to this needs to be injected in YT code // Call to this needs to be injected in YT code
public static void onClick(View view, boolean inactive) { public static void onClick(View view, boolean inactive) {
if (!isEnabled) return;
handleOnClick(view, inactive); handleOnClick(view, inactive);
} }
private static CharSequence handleOnSetText(View view, CharSequence originalText) { private static CharSequence handleOnSetText(View view, CharSequence originalText) {
if (!isEnabled) return originalText;
try { try {
CharSequence tag = (CharSequence) view.getTag(); CharSequence tag = (CharSequence) view.getTag();
if (debug) { if (debug) {
@ -158,6 +192,8 @@ public class ReturnYouTubeDislikes {
} }
private static void trySetDislikes(String dislikeCount) { private static void trySetDislikes(String dislikeCount) {
if (!isEnabled) return;
try { try {
// Try to set normal video dislike count // Try to set normal video dislike count
if (_dislikeView == null) { if (_dislikeView == null) {
@ -184,6 +220,8 @@ public class ReturnYouTubeDislikes {
} }
private static void handleOnClick(View view, boolean previousState) { private static void handleOnClick(View view, boolean previousState) {
if (!isEnabled) return;
try { try {
String tag = (String) view.getTag(); String tag = (String) view.getTag();
if (debug) { if (debug) {
@ -232,6 +270,8 @@ public class ReturnYouTubeDislikes {
} }
private static void sendVote(int vote) { private static void sendVote(int vote) {
if (!isEnabled) return;
if (debug) { if (debug) {
Log.d(TAG, "sending vote - " + vote + " for video " + currentVideoId); Log.d(TAG, "sending vote - " + vote + " for video " + currentVideoId);
} }
@ -264,6 +304,8 @@ public class ReturnYouTubeDislikes {
} }
private static void setTag(View view, String tag) { private static void setTag(View view, String tag) {
if (!isEnabled) return;
try { try {
if (view == null) { if (view == null) {
if (debug) { if (debug) {

View File

@ -24,6 +24,7 @@ import java.net.URL;
import fi.vanced.libraries.youtube.ads.VideoAds; import fi.vanced.libraries.youtube.ads.VideoAds;
import fi.vanced.libraries.youtube.player.ChannelModel; import fi.vanced.libraries.youtube.player.ChannelModel;
import fi.vanced.libraries.youtube.player.VideoInformation; import fi.vanced.libraries.youtube.player.VideoInformation;
import fi.vanced.utils.SharedPrefUtils;
import fi.vanced.utils.VancedUtils; import fi.vanced.utils.VancedUtils;
public class AdBlock extends SlimButton { public class AdBlock extends SlimButton {
@ -32,7 +33,7 @@ public class AdBlock extends SlimButton {
private static final String YT_API_KEY = "replaceMeWithTheYouTubeAPIKey"; private static final String YT_API_KEY = "replaceMeWithTheYouTubeAPIKey";
public AdBlock(Context context, ViewGroup container) { public AdBlock(Context context, ViewGroup container) {
super(context, container, SlimButton.SLIM_METADATA_BUTTON_ID, true); super(context, container, SlimButton.SLIM_METADATA_BUTTON_ID, SharedPrefUtils.getBoolean(context, "youtube", "vanced_videoadwhitelisting_enabled", false));
initialize(); initialize();
} }

View File

@ -0,0 +1,36 @@
package fi.vanced.libraries.youtube.ui;
import android.content.Context;
import fi.vanced.utils.SharedPrefUtils;
public class ButtonVisibility {
public static Visibility getButtonVisibility(Context context, String key) {
return getButtonVisibility(context, key, "youtube");
}
public static Visibility getButtonVisibility(Context context, String key, String preferenceName) {
String value = SharedPrefUtils.getString(context, preferenceName, key, null);
if (value == null || value.isEmpty()) return Visibility.NONE;
switch (value.toUpperCase()) {
case "PLAYER": return Visibility.PLAYER;
case "BUTTON_CONTAINER": return Visibility.BUTTON_CONTAINER;
case "BOTH": return Visibility.BOTH;
default: return Visibility.NONE;
}
}
public static boolean isVisibleInContainer(Context context, String key) {
return isVisibleInContainer(getButtonVisibility(context, key));
}
public static boolean isVisibleInContainer(Context context, String key, String preferenceName) {
return isVisibleInContainer(getButtonVisibility(context, key, preferenceName));
}
public static boolean isVisibleInContainer(Visibility visibility) {
return visibility == Visibility.BOTH || visibility == Visibility.BUTTON_CONTAINER;
}
}

View File

@ -7,12 +7,11 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import fi.vanced.libraries.youtube.player.VideoHelpers; import fi.vanced.libraries.youtube.player.VideoHelpers;
import fi.vanced.utils.SharedPrefUtils;
import fi.vanced.utils.VancedUtils; import fi.vanced.utils.VancedUtils;
public class CopyButton extends SlimButton { public class CopyButton extends SlimButton {
public CopyButton(Context context, ViewGroup container) { public CopyButton(Context context, ViewGroup container) {
super(context, container, SlimButton.SLIM_METADATA_BUTTON_ID, SharedPrefUtils.getBoolean(context, "youtube", "pref_copy_video_url_button", false)); super(context, container, SlimButton.SLIM_METADATA_BUTTON_ID, ButtonVisibility.isVisibleInContainer(context, "pref_copy_video_url_button_list"));
initialize(); initialize();
} }

View File

@ -5,14 +5,13 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import fi.vanced.libraries.youtube.player.VideoHelpers; import fi.vanced.libraries.youtube.player.VideoHelpers;
import fi.vanced.utils.SharedPrefUtils;
import fi.vanced.utils.VancedUtils; import fi.vanced.utils.VancedUtils;
import static pl.jakubweg.StringRef.str; import static pl.jakubweg.StringRef.str;
public class CopyWithTimestamp extends SlimButton { public class CopyWithTimestamp extends SlimButton {
public CopyWithTimestamp(Context context, ViewGroup container) { public CopyWithTimestamp(Context context, ViewGroup container) {
super(context, container, SlimButton.SLIM_METADATA_BUTTON_ID, SharedPrefUtils.getBoolean(context, "youtube", "pref_copy_video_url_timestamp_button", false)); super(context, container, SlimButton.SLIM_METADATA_BUTTON_ID, ButtonVisibility.isVisibleInContainer(context, "pref_copy_video_url_timestamp_button_list"));
initialize(); initialize();
} }

View File

@ -1,12 +1,17 @@
package fi.vanced.libraries.youtube.ui; package fi.vanced.libraries.youtube.ui;
import static fi.razerman.youtube.XGlobals.debug;
import android.content.Context; import android.content.Context;
import android.content.SharedPreferences;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log; import android.util.Log;
import android.view.ViewGroup; import android.view.ViewGroup;
import com.google.android.apps.youtube.app.ui.SlimMetadataScrollableButtonContainerLayout; import com.google.android.apps.youtube.app.ui.SlimMetadataScrollableButtonContainerLayout;
import fi.vanced.libraries.youtube.ads.VideoAds;
import fi.vanced.utils.SharedPrefUtils;
import fi.vanced.utils.VancedUtils; import fi.vanced.utils.VancedUtils;
public class SlimButtonContainer extends SlimMetadataScrollableButtonContainerLayout { public class SlimButtonContainer extends SlimMetadataScrollableButtonContainerLayout {
@ -15,19 +20,24 @@ public class SlimButtonContainer extends SlimMetadataScrollableButtonContainerLa
private CopyButton copyButton; private CopyButton copyButton;
private CopyWithTimestamp copyWithTimestampButton; private CopyWithTimestamp copyWithTimestampButton;
public static AdBlock adBlockButton; public static AdBlock adBlockButton;
private final Context context;
SharedPreferences.OnSharedPreferenceChangeListener listener;
public SlimButtonContainer(Context context) { public SlimButtonContainer(Context context) {
super(context); super(context);
this.context = context;
this.initialize(context); this.initialize(context);
} }
public SlimButtonContainer(Context context, AttributeSet attrs) { public SlimButtonContainer(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
this.context = context;
this.initialize(context); this.initialize(context);
} }
public SlimButtonContainer(Context context, AttributeSet attrs, int defStyleAttr) { public SlimButtonContainer(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr); super(context, attrs, defStyleAttr);
this.context = context;
this.initialize(context); this.initialize(context);
} }
@ -41,9 +51,40 @@ public class SlimButtonContainer extends SlimMetadataScrollableButtonContainerLa
adBlockButton = new AdBlock(context, this); adBlockButton = new AdBlock(context, this);
new SponsorBlock(context, this); new SponsorBlock(context, this);
new SponsorBlockVoting(context, this); new SponsorBlockVoting(context, this);
addSharedPrefsChangeListener();
} }
catch (Exception ex) { catch (Exception ex) {
Log.e(TAG, "Unable to initialize the button container", ex); Log.e(TAG, "Unable to initialize the button container", ex);
} }
} }
private void addSharedPrefsChangeListener() {
listener = (sharedPreferences, key) -> {
try {
if (debug) {
Log.d(TAG, String.format("SharedPreference changed with key %s", key));
}
if ("pref_copy_video_url_button_list".equals(key) && copyButton != null) {
copyButton.setVisible(ButtonVisibility.isVisibleInContainer(context, "pref_copy_video_url_button_list"));
return;
}
if ("pref_copy_video_url_timestamp_button_list".equals(key) && copyWithTimestampButton != null) {
copyWithTimestampButton.setVisible(ButtonVisibility.isVisibleInContainer(context, "pref_copy_video_url_timestamp_button_list"));
return;
}
if ("vanced_videoadwhitelisting_enabled".equals(key) && adBlockButton != null) {
VideoAds.isEnabled = SharedPrefUtils.getBoolean(context, "youtube", "vanced_videoadwhitelisting_enabled", false);
adBlockButton.setVisible(VideoAds.isEnabled);
return;
}
}
catch (Exception ex) {
Log.e(TAG, "Error handling shared preference change", ex);
}
};
context.getSharedPreferences("youtube", Context.MODE_PRIVATE)
.registerOnSharedPreferenceChangeListener(listener);
}
} }

View File

@ -0,0 +1,8 @@
package fi.vanced.libraries.youtube.ui;
public enum Visibility {
NONE,
PLAYER,
BUTTON_CONTAINER,
BOTH,
}

View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="vanced_button_location_entries">
<item>@string/vanced_button_location_entry_none</item>
<item>@string/vanced_button_location_entry_player</item>
<item>@string/vanced_button_location_entry_buttoncontainer</item>
<item>@string/vanced_button_location_entry_both</item>
</string-array>
<string-array name="vanced_button_location_entry_values">
<item>NONE</item>
<item>PLAYER</item>
<item>BUTTON_CONTAINER</item>
<item>BOTH</item>
</string-array>
</resources>

View File

@ -337,4 +337,19 @@
<string name="action_copy">Copy</string> <string name="action_copy">Copy</string>
<string name="action_tcopy">TCopy</string> <string name="action_tcopy">TCopy</string>
<string name="action_ads">Ads</string> <string name="action_ads">Ads</string>
<string name="vanced_video_ad_settings_title">Video ad settings</string>
<string name="vanced_videoadwhitelisting_title">Video ad whitelisting</string>
<string name="vanced_videoadwhitelisting_summary_off">Video ad whitelisting is turned off</string>
<string name="vanced_videoadwhitelisting_summary_on">Video ad whitelisting is turned on. Use the ad button under the player to whitelist a channel</string>
<string name="vanced_button_location_entry_none">Hidden</string>
<string name="vanced_button_location_entry_player">In player</string>
<string name="vanced_button_location_entry_buttoncontainer">Under player</string>
<string name="vanced_button_location_entry_both">Both</string>
<string name="vanced_ryd_settings_title">RYD settings</string>
<string name="vanced_ryd_settings_summary">Uses the RYD API</string>
<string name="vanced_ryd_title">Enable RYD</string>
<string name="vanced_ryd_summary">Switch this on to see the dislike counts again</string>
<string name="vanced_ryd_attribution_title">Return YouTube Dislike Integration</string>
<string name="vanced_ryd_attribution_summary">This integration uses the RYD API from https://returnyoutubedislike.com. Tap to learn more</string>
</resources> </resources>