mirror of
https://github.com/inotia00/revanced-patches.git
synced 2025-04-30 06:34:37 +02:00
feat(YouTube - SponsorBlock): Add opacity setting to category segment colors
This commit is contained in:
parent
9d37e31a24
commit
efead108f9
@ -10,6 +10,8 @@ import android.util.AttributeSet;
|
|||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import app.revanced.extension.shared.settings.Setting;
|
import app.revanced.extension.shared.settings.Setting;
|
||||||
@ -19,6 +21,12 @@ import app.revanced.extension.shared.utils.Utils;
|
|||||||
@SuppressWarnings({"unused", "deprecation"})
|
@SuppressWarnings({"unused", "deprecation"})
|
||||||
public class ResettableEditTextPreference extends EditTextPreference {
|
public class ResettableEditTextPreference extends EditTextPreference {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Setting to reset.
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
private Setting<?> setting;
|
||||||
|
|
||||||
public ResettableEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
public ResettableEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
@ -35,6 +43,10 @@ public class ResettableEditTextPreference extends EditTextPreference {
|
|||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setSetting(@Nullable Setting<?> setting) {
|
||||||
|
this.setting = setting;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||||
Utils.setEditTextDialogTheme(builder);
|
Utils.setEditTextDialogTheme(builder);
|
||||||
@ -44,7 +56,12 @@ public class ResettableEditTextPreference extends EditTextPreference {
|
|||||||
if (title != null) {
|
if (title != null) {
|
||||||
builder.setTitle(getTitle());
|
builder.setTitle(getTitle());
|
||||||
}
|
}
|
||||||
final Setting<?> setting = Setting.getSettingFromPath(getKey());
|
if (setting == null) {
|
||||||
|
String key = getKey();
|
||||||
|
if (key != null) {
|
||||||
|
setting = Setting.getSettingFromPath(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (setting != null) {
|
if (setting != null) {
|
||||||
builder.setNeutralButton(str("revanced_extended_settings_reset"), null);
|
builder.setNeutralButton(str("revanced_extended_settings_reset"), null);
|
||||||
}
|
}
|
||||||
@ -65,8 +82,7 @@ public class ResettableEditTextPreference extends EditTextPreference {
|
|||||||
}
|
}
|
||||||
button.setOnClickListener(v -> {
|
button.setOnClickListener(v -> {
|
||||||
try {
|
try {
|
||||||
Setting<?> setting = Objects.requireNonNull(Setting.getSettingFromPath(getKey()));
|
String defaultStringValue = Objects.requireNonNull(setting).defaultValue.toString();
|
||||||
String defaultStringValue = setting.defaultValue.toString();
|
|
||||||
EditText editText = getEditText();
|
EditText editText = getEditText();
|
||||||
editText.setText(defaultStringValue);
|
editText.setText(defaultStringValue);
|
||||||
editText.setSelection(defaultStringValue.length()); // move cursor to end of text
|
editText.setSelection(defaultStringValue.length()); // move cursor to end of text
|
||||||
|
@ -618,24 +618,34 @@ public class Settings extends BaseSettings {
|
|||||||
|
|
||||||
public static final StringSetting SB_CATEGORY_SPONSOR = new StringSetting("sb_sponsor", SKIP_AUTOMATICALLY.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_SPONSOR = new StringSetting("sb_sponsor", SKIP_AUTOMATICALLY.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color", "#00D400");
|
public static final StringSetting SB_CATEGORY_SPONSOR_COLOR = new StringSetting("sb_sponsor_color", "#00D400");
|
||||||
|
public static final FloatSetting SB_CATEGORY_SPONSOR_OPACITY = new FloatSetting("sb_sponsor_opacity", 0.8f);
|
||||||
public static final StringSetting SB_CATEGORY_SELF_PROMO = new StringSetting("sb_selfpromo", SKIP_AUTOMATICALLY.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_SELF_PROMO = new StringSetting("sb_selfpromo", SKIP_AUTOMATICALLY.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color", "#FFFF00");
|
public static final StringSetting SB_CATEGORY_SELF_PROMO_COLOR = new StringSetting("sb_selfpromo_color", "#FFFF00");
|
||||||
|
public static final FloatSetting SB_CATEGORY_SELF_PROMO_OPACITY = new FloatSetting("sb_selfpromo_opacity", 0.8f);
|
||||||
public static final StringSetting SB_CATEGORY_INTERACTION = new StringSetting("sb_interaction", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_INTERACTION = new StringSetting("sb_interaction", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color", "#CC00FF");
|
public static final StringSetting SB_CATEGORY_INTERACTION_COLOR = new StringSetting("sb_interaction_color", "#CC00FF");
|
||||||
|
public static final FloatSetting SB_CATEGORY_INTERACTION_OPACITY = new FloatSetting("sb_interaction_opacity", 0.8f);
|
||||||
public static final StringSetting SB_CATEGORY_HIGHLIGHT = new StringSetting("sb_highlight", MANUAL_SKIP.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_HIGHLIGHT = new StringSetting("sb_highlight", MANUAL_SKIP.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color", "#FF1684");
|
public static final StringSetting SB_CATEGORY_HIGHLIGHT_COLOR = new StringSetting("sb_highlight_color", "#FF1684");
|
||||||
|
public static final FloatSetting SB_CATEGORY_HIGHLIGHT_OPACITY = new FloatSetting("sb_highlight_opacity", 0.8f);
|
||||||
public static final StringSetting SB_CATEGORY_INTRO = new StringSetting("sb_intro", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_INTRO = new StringSetting("sb_intro", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color", "#00FFFF");
|
public static final StringSetting SB_CATEGORY_INTRO_COLOR = new StringSetting("sb_intro_color", "#00FFFF");
|
||||||
|
public static final FloatSetting SB_CATEGORY_INTRO_OPACITY = new FloatSetting("sb_intro_opacity", 0.8f);
|
||||||
public static final StringSetting SB_CATEGORY_OUTRO = new StringSetting("sb_outro", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_OUTRO = new StringSetting("sb_outro", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color", "#0202ED");
|
public static final StringSetting SB_CATEGORY_OUTRO_COLOR = new StringSetting("sb_outro_color", "#0202ED");
|
||||||
|
public static final FloatSetting SB_CATEGORY_OUTRO_OPACITY = new FloatSetting("sb_outro_opacity", 0.8f);
|
||||||
public static final StringSetting SB_CATEGORY_PREVIEW = new StringSetting("sb_preview", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_PREVIEW = new StringSetting("sb_preview", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color", "#008FD6");
|
public static final StringSetting SB_CATEGORY_PREVIEW_COLOR = new StringSetting("sb_preview_color", "#008FD6");
|
||||||
|
public static final FloatSetting SB_CATEGORY_PREVIEW_OPACITY = new FloatSetting("sb_preview_opacity", 0.8f);
|
||||||
public static final StringSetting SB_CATEGORY_FILLER = new StringSetting("sb_filler", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_FILLER = new StringSetting("sb_filler", SKIP_AUTOMATICALLY_ONCE.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color", "#7300FF");
|
public static final StringSetting SB_CATEGORY_FILLER_COLOR = new StringSetting("sb_filler_color", "#7300FF");
|
||||||
|
public static final FloatSetting SB_CATEGORY_FILLER_OPACITY = new FloatSetting("sb_filler_opacity", 0.8f);
|
||||||
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC = new StringSetting("sb_music_offtopic", MANUAL_SKIP.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC = new StringSetting("sb_music_offtopic", MANUAL_SKIP.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color", "#FF9900");
|
public static final StringSetting SB_CATEGORY_MUSIC_OFFTOPIC_COLOR = new StringSetting("sb_music_offtopic_color", "#FF9900");
|
||||||
|
public static final FloatSetting SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY = new FloatSetting("sb_music_offtopic_opacity", 0.8f);
|
||||||
public static final StringSetting SB_CATEGORY_UNSUBMITTED = new StringSetting("sb_unsubmitted", SKIP_AUTOMATICALLY.reVancedKeyValue);
|
public static final StringSetting SB_CATEGORY_UNSUBMITTED = new StringSetting("sb_unsubmitted", SKIP_AUTOMATICALLY.reVancedKeyValue);
|
||||||
public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color", "#FFFFFF");
|
public static final StringSetting SB_CATEGORY_UNSUBMITTED_COLOR = new StringSetting("sb_unsubmitted_color", "#FFFFFF");
|
||||||
|
public static final FloatSetting SB_CATEGORY_UNSUBMITTED_OPACITY = new FloatSetting("sb_unsubmitted_opacity", 1.0f);
|
||||||
|
|
||||||
// SB Setting not exported
|
// SB Setting not exported
|
||||||
public static final LongSetting SB_LAST_VIP_CHECK = new LongSetting("sb_last_vip_check", 0L, false, false);
|
public static final LongSetting SB_LAST_VIP_CHECK = new LongSetting("sb_last_vip_check", 0L, false, false);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package app.revanced.extension.youtube.settings.preference;
|
package app.revanced.extension.youtube.settings.preference;
|
||||||
|
|
||||||
import static app.revanced.extension.shared.utils.StringRef.str;
|
import static app.revanced.extension.shared.utils.StringRef.str;
|
||||||
|
import static app.revanced.extension.youtube.sponsorblock.objects.SegmentCategory.applyOpacityToColor;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
@ -12,11 +13,10 @@ import android.text.InputType;
|
|||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.GridLayout;
|
||||||
import android.widget.TableLayout;
|
|
||||||
import android.widget.TableRow;
|
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import app.revanced.extension.shared.utils.Logger;
|
import app.revanced.extension.shared.utils.Logger;
|
||||||
@ -27,26 +27,38 @@ import app.revanced.extension.youtube.sponsorblock.objects.SegmentCategory;
|
|||||||
|
|
||||||
@SuppressWarnings({"unused", "deprecation"})
|
@SuppressWarnings({"unused", "deprecation"})
|
||||||
public class SegmentCategoryListPreference extends ListPreference {
|
public class SegmentCategoryListPreference extends ListPreference {
|
||||||
private SegmentCategory mCategory;
|
private SegmentCategory category;
|
||||||
private EditText mEditText;
|
private TextView colorDotView;
|
||||||
private int mClickedDialogEntryIndex;
|
private EditText colorEditText;
|
||||||
|
private EditText opacityEditText;
|
||||||
|
/**
|
||||||
|
* #RRGGBB
|
||||||
|
*/
|
||||||
|
private int categoryColor;
|
||||||
|
/**
|
||||||
|
* [0, 1]
|
||||||
|
*/
|
||||||
|
private float categoryOpacity;
|
||||||
|
private int selectedDialogEntryIndex;
|
||||||
|
|
||||||
private void init() {
|
private void init() {
|
||||||
final SegmentCategory segmentCategory = SegmentCategory.byCategoryKey(getKey());
|
final SegmentCategory segmentCategory = SegmentCategory.byCategoryKey(getKey());
|
||||||
final boolean isHighlightCategory = segmentCategory == SegmentCategory.HIGHLIGHT;
|
category = Objects.requireNonNull(segmentCategory);
|
||||||
mCategory = Objects.requireNonNull(segmentCategory);
|
|
||||||
// Edit: Using preferences to sync together multiple pieces
|
// Edit: Using preferences to sync together multiple pieces
|
||||||
// of code together is messy and should be rethought.
|
// of code is messy and should be rethought.
|
||||||
setKey(segmentCategory.behaviorSetting.key);
|
setKey(segmentCategory.behaviorSetting.key);
|
||||||
setDefaultValue(segmentCategory.behaviorSetting.defaultValue);
|
setDefaultValue(segmentCategory.behaviorSetting.defaultValue);
|
||||||
|
|
||||||
|
final boolean isHighlightCategory = category == SegmentCategory.HIGHLIGHT;
|
||||||
setEntries(isHighlightCategory
|
setEntries(isHighlightCategory
|
||||||
? CategoryBehaviour.getBehaviorDescriptionsWithoutSkipOnce()
|
? CategoryBehaviour.getBehaviorDescriptionsWithoutSkipOnce()
|
||||||
: CategoryBehaviour.getBehaviorDescriptions());
|
: CategoryBehaviour.getBehaviorDescriptions());
|
||||||
setEntryValues(isHighlightCategory
|
setEntryValues(isHighlightCategory
|
||||||
? CategoryBehaviour.getBehaviorKeyValuesWithoutSkipOnce()
|
? CategoryBehaviour.getBehaviorKeyValuesWithoutSkipOnce()
|
||||||
: CategoryBehaviour.getBehaviorKeyValues());
|
: CategoryBehaviour.getBehaviorKeyValues());
|
||||||
updateTitle();
|
|
||||||
|
updateTitleFromCategory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public SegmentCategoryListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
public SegmentCategoryListPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
@ -73,28 +85,41 @@ public class SegmentCategoryListPreference extends ListPreference {
|
|||||||
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
|
||||||
try {
|
try {
|
||||||
Utils.setEditTextDialogTheme(builder);
|
Utils.setEditTextDialogTheme(builder);
|
||||||
super.onPrepareDialogBuilder(builder);
|
|
||||||
|
categoryColor = category.getColorNoOpacity();
|
||||||
|
categoryOpacity = category.getOpacity();
|
||||||
|
|
||||||
Context context = builder.getContext();
|
Context context = builder.getContext();
|
||||||
TableLayout table = new TableLayout(context);
|
GridLayout gridLayout = new GridLayout(context);
|
||||||
table.setOrientation(LinearLayout.HORIZONTAL);
|
gridLayout.setPadding(70, 0, 150, 0); // Padding for the entire layout.
|
||||||
table.setPadding(70, 0, 150, 0);
|
gridLayout.setColumnCount(3);
|
||||||
|
gridLayout.setRowCount(2);
|
||||||
TableRow row = new TableRow(context);
|
|
||||||
|
|
||||||
|
GridLayout.LayoutParams gridParams = new GridLayout.LayoutParams();
|
||||||
|
gridParams.rowSpec = GridLayout.spec(0); // First row.
|
||||||
|
gridParams.columnSpec = GridLayout.spec(0); // First column.
|
||||||
TextView colorTextLabel = new TextView(context);
|
TextView colorTextLabel = new TextView(context);
|
||||||
colorTextLabel.setText(str("revanced_sb_color_dot_label"));
|
colorTextLabel.setText(str("revanced_sb_color_dot_label"));
|
||||||
row.addView(colorTextLabel);
|
colorTextLabel.setLayoutParams(gridParams);
|
||||||
|
gridLayout.addView(colorTextLabel);
|
||||||
|
|
||||||
TextView colorDotView = new TextView(context);
|
gridParams = new GridLayout.LayoutParams();
|
||||||
colorDotView.setText(mCategory.getCategoryColorDot());
|
gridParams.rowSpec = GridLayout.spec(0); // First row.
|
||||||
colorDotView.setPadding(30, 0, 30, 0);
|
gridParams.columnSpec = GridLayout.spec(1); // Second column.
|
||||||
row.addView(colorDotView);
|
gridParams.setMargins(0, 0, 10, 0);
|
||||||
|
colorDotView = new TextView(context);
|
||||||
|
colorDotView.setLayoutParams(gridParams);
|
||||||
|
gridLayout.addView(colorDotView);
|
||||||
|
updateCategoryColorDot();
|
||||||
|
|
||||||
mEditText = new EditText(context);
|
gridParams = new GridLayout.LayoutParams();
|
||||||
mEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
|
gridParams.rowSpec = GridLayout.spec(0); // First row.
|
||||||
mEditText.setText(mCategory.colorString());
|
gridParams.columnSpec = GridLayout.spec(2); // Third column.
|
||||||
mEditText.addTextChangedListener(new TextWatcher() {
|
colorEditText = new EditText(context);
|
||||||
|
colorEditText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS);
|
||||||
|
colorEditText.setTextLocale(Locale.US);
|
||||||
|
colorEditText.setText(category.getColorString());
|
||||||
|
colorEditText.addTextChangedListener(new TextWatcher() {
|
||||||
@Override
|
@Override
|
||||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
}
|
}
|
||||||
@ -104,44 +129,111 @@ public class SegmentCategoryListPreference extends ListPreference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable edit) {
|
||||||
try {
|
try {
|
||||||
String colorString = s.toString();
|
String colorString = edit.toString();
|
||||||
|
final int colorStringLength = colorString.length();
|
||||||
|
|
||||||
if (!colorString.startsWith("#")) {
|
if (!colorString.startsWith("#")) {
|
||||||
s.insert(0, "#"); // recursively calls back into this method
|
edit.insert(0, "#"); // Recursively calls back into this method.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (colorString.length() > 7) {
|
|
||||||
s.delete(7, colorString.length());
|
final int maxColorStringLength = 7; // #RRGGBB
|
||||||
|
if (colorStringLength > maxColorStringLength) {
|
||||||
|
edit.delete(maxColorStringLength, colorStringLength);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final int color = Color.parseColor(colorString);
|
|
||||||
colorDotView.setText(SegmentCategory.getCategoryColorDot(color));
|
categoryColor = Color.parseColor(colorString);
|
||||||
|
updateCategoryColorDot();
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
// ignore
|
// Ignore.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mEditText.setLayoutParams(new TableRow.LayoutParams(0, TableRow.LayoutParams.WRAP_CONTENT, 1f));
|
colorEditText.setLayoutParams(gridParams);
|
||||||
row.addView(mEditText);
|
gridLayout.addView(colorEditText);
|
||||||
|
|
||||||
table.addView(row);
|
gridParams = new GridLayout.LayoutParams();
|
||||||
builder.setView(table);
|
gridParams.rowSpec = GridLayout.spec(1); // Second row.
|
||||||
builder.setTitle(mCategory.title.toString());
|
gridParams.columnSpec = GridLayout.spec(0, 1); // First and second column.
|
||||||
|
TextView opacityLabel = new TextView(context);
|
||||||
|
opacityLabel.setText(str("revanced_sb_color_opacity_label"));
|
||||||
|
opacityLabel.setLayoutParams(gridParams);
|
||||||
|
gridLayout.addView(opacityLabel);
|
||||||
|
|
||||||
|
gridParams = new GridLayout.LayoutParams();
|
||||||
|
gridParams.rowSpec = GridLayout.spec(1); // Second row.
|
||||||
|
gridParams.columnSpec = GridLayout.spec(2); // Third column.
|
||||||
|
opacityEditText = new EditText(context);
|
||||||
|
opacityEditText.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
|
||||||
|
opacityEditText.addTextChangedListener(new TextWatcher() {
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable edit) {
|
||||||
|
try {
|
||||||
|
String editString = edit.toString();
|
||||||
|
final int opacityStringLength = editString.length();
|
||||||
|
|
||||||
|
final int maxOpacityStringLength = 4; // [0.00, 1.00]
|
||||||
|
if (opacityStringLength > maxOpacityStringLength) {
|
||||||
|
edit.delete(maxOpacityStringLength, opacityStringLength);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final float opacity = opacityStringLength == 0
|
||||||
|
? 0
|
||||||
|
: Float.parseFloat(editString);
|
||||||
|
if (opacity < 0) {
|
||||||
|
categoryOpacity = 0;
|
||||||
|
edit.replace(0, opacityStringLength, "0");
|
||||||
|
return;
|
||||||
|
} else if (opacity > 1.0f) {
|
||||||
|
categoryOpacity = 1;
|
||||||
|
edit.replace(0, opacityStringLength, "1.0");
|
||||||
|
return;
|
||||||
|
} else if (!editString.endsWith(".")) {
|
||||||
|
// Ignore "0." and "1." until the user finishes entering a valid number.
|
||||||
|
categoryOpacity = opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCategoryColorDot();
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
// Should never happen.
|
||||||
|
Logger.printException(() -> "Could not parse opacity string", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
opacityEditText.setLayoutParams(gridParams);
|
||||||
|
gridLayout.addView(opacityEditText);
|
||||||
|
updateOpacityText();
|
||||||
|
|
||||||
|
builder.setView(gridLayout);
|
||||||
|
builder.setTitle(category.title.toString());
|
||||||
|
|
||||||
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> onClick(dialog, DialogInterface.BUTTON_POSITIVE));
|
builder.setPositiveButton(android.R.string.ok, (dialog, which) -> onClick(dialog, DialogInterface.BUTTON_POSITIVE));
|
||||||
builder.setNeutralButton(str("revanced_sb_reset_color"), (dialog, which) -> {
|
builder.setNeutralButton(str("revanced_sb_reset_color"), (dialog, which) -> {
|
||||||
try {
|
try {
|
||||||
mCategory.resetColor();
|
category.resetColorAndOpacity();
|
||||||
updateTitle();
|
updateTitleFromCategory();
|
||||||
Utils.showToastShort(str("revanced_sb_color_reset"));
|
Utils.showToastShort(str("revanced_sb_color_reset"));
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "setNeutralButton failure", ex);
|
Logger.printException(() -> "setNeutralButton failure", ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton(android.R.string.cancel, null);
|
builder.setNegativeButton(android.R.string.cancel, null);
|
||||||
mClickedDialogEntryIndex = findIndexOfValue(getValue());
|
|
||||||
builder.setSingleChoiceItems(getEntries(), mClickedDialogEntryIndex, (dialog, which) -> mClickedDialogEntryIndex = which);
|
selectedDialogEntryIndex = findIndexOfValue(getValue());
|
||||||
|
builder.setSingleChoiceItems(getEntries(), selectedDialogEntryIndex,
|
||||||
|
(dialog, which) -> selectedDialogEntryIndex = which);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "onPrepareDialogBuilder failure", ex);
|
Logger.printException(() -> "onPrepareDialogBuilder failure", ex);
|
||||||
}
|
}
|
||||||
@ -150,31 +242,51 @@ public class SegmentCategoryListPreference extends ListPreference {
|
|||||||
@Override
|
@Override
|
||||||
protected void onDialogClosed(boolean positiveResult) {
|
protected void onDialogClosed(boolean positiveResult) {
|
||||||
try {
|
try {
|
||||||
if (positiveResult && mClickedDialogEntryIndex >= 0 && getEntryValues() != null) {
|
if (positiveResult && selectedDialogEntryIndex >= 0 && getEntryValues() != null) {
|
||||||
String value = getEntryValues()[mClickedDialogEntryIndex].toString();
|
String value = getEntryValues()[selectedDialogEntryIndex].toString();
|
||||||
if (callChangeListener(value)) {
|
if (callChangeListener(value)) {
|
||||||
setValue(value);
|
setValue(value);
|
||||||
mCategory.setBehaviour(Objects.requireNonNull(CategoryBehaviour.byReVancedKeyValue(value)));
|
category.setBehaviour(Objects.requireNonNull(CategoryBehaviour.byReVancedKeyValue(value)));
|
||||||
SegmentCategory.updateEnabledCategories();
|
SegmentCategory.updateEnabledCategories();
|
||||||
}
|
}
|
||||||
String colorString = mEditText.getText().toString();
|
|
||||||
try {
|
try {
|
||||||
if (!colorString.equals(mCategory.colorString())) {
|
String colorString = colorEditText.getText().toString();
|
||||||
mCategory.setColor(colorString);
|
if (!colorString.equals(category.getColorString()) || categoryOpacity != category.getOpacity()) {
|
||||||
|
category.setColor(colorString);
|
||||||
|
category.setOpacity(categoryOpacity);
|
||||||
Utils.showToastShort(str("revanced_sb_color_changed"));
|
Utils.showToastShort(str("revanced_sb_color_changed"));
|
||||||
}
|
}
|
||||||
} catch (IllegalArgumentException ex) {
|
} catch (IllegalArgumentException ex) {
|
||||||
Utils.showToastShort(str("revanced_sb_color_invalid"));
|
Utils.showToastShort(str("revanced_sb_color_invalid"));
|
||||||
}
|
}
|
||||||
updateTitle();
|
|
||||||
|
updateTitleFromCategory();
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "onDialogClosed failure", ex);
|
Logger.printException(() -> "onDialogClosed failure", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTitle() {
|
private void applyOpacityToCategoryColor() {
|
||||||
setTitle(mCategory.getTitleWithColorDot());
|
categoryColor = applyOpacityToColor(categoryColor, categoryOpacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateTitleFromCategory() {
|
||||||
|
categoryColor = category.getColorNoOpacity();
|
||||||
|
categoryOpacity = category.getOpacity();
|
||||||
|
applyOpacityToCategoryColor();
|
||||||
|
|
||||||
|
setTitle(category.getTitleWithColorDot(categoryColor));
|
||||||
setEnabled(Settings.SB_ENABLED.get());
|
setEnabled(Settings.SB_ENABLED.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateCategoryColorDot() {
|
||||||
|
applyOpacityToCategoryColor();
|
||||||
|
|
||||||
|
colorDotView.setText(SegmentCategory.getCategoryColorDot(categoryColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateOpacityText() {
|
||||||
|
opacityEditText.setText(String.format(Locale.US, "%.2f", categoryOpacity));
|
||||||
|
}
|
||||||
}
|
}
|
@ -139,7 +139,7 @@ public class SponsorBlockSettings {
|
|||||||
for (SegmentCategory category : categories) {
|
for (SegmentCategory category : categories) {
|
||||||
JSONObject categoryObject = new JSONObject();
|
JSONObject categoryObject = new JSONObject();
|
||||||
String categoryKey = category.keyValue;
|
String categoryKey = category.keyValue;
|
||||||
categoryObject.put("color", category.colorString());
|
categoryObject.put("color", category.getColorString());
|
||||||
barTypesObject.put(categoryKey, categoryObject);
|
barTypesObject.put(categoryKey, categoryObject);
|
||||||
|
|
||||||
if (category.behaviour != CategoryBehaviour.IGNORE) {
|
if (category.behaviour != CategoryBehaviour.IGNORE) {
|
||||||
|
@ -6,7 +6,12 @@ import android.annotation.TargetApi;
|
|||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.text.Html;
|
import android.graphics.Color;
|
||||||
|
import android.text.Spannable;
|
||||||
|
import android.text.SpannableString;
|
||||||
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
import android.text.style.StyleSpan;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
@ -33,10 +38,9 @@ import app.revanced.extension.youtube.sponsorblock.ui.SponsorBlockViewController
|
|||||||
/**
|
/**
|
||||||
* Not thread safe. All fields/methods must be accessed from the main thread.
|
* Not thread safe. All fields/methods must be accessed from the main thread.
|
||||||
*
|
*
|
||||||
* @noinspection deprecation
|
|
||||||
*/
|
*/
|
||||||
public class SponsorBlockUtils {
|
public class SponsorBlockUtils {
|
||||||
private static final String LOCKED_COLOR = "#FFC83D";
|
private static final int LOCKED_COLOR = Color.parseColor("#FFC83D");
|
||||||
|
|
||||||
private static final String MANUAL_EDIT_TIME_TEXT_HINT = "hh:mm:ss.sss";
|
private static final String MANUAL_EDIT_TIME_TEXT_HINT = "hh:mm:ss.sss";
|
||||||
private static final Pattern manualEditTimePattern
|
private static final Pattern manualEditTimePattern
|
||||||
@ -162,28 +166,34 @@ public class SponsorBlockUtils {
|
|||||||
SegmentVote[] voteOptions = (segment.category == SegmentCategory.HIGHLIGHT)
|
SegmentVote[] voteOptions = (segment.category == SegmentCategory.HIGHLIGHT)
|
||||||
? SegmentVote.voteTypesWithoutCategoryChange // highlight segments cannot change category
|
? SegmentVote.voteTypesWithoutCategoryChange // highlight segments cannot change category
|
||||||
: SegmentVote.values();
|
: SegmentVote.values();
|
||||||
CharSequence[] items = new CharSequence[voteOptions.length];
|
final int voteOptionsLength = voteOptions.length;
|
||||||
|
final boolean userIsVip = Settings.SB_USER_IS_VIP.get();
|
||||||
|
CharSequence[] items = new CharSequence[voteOptionsLength];
|
||||||
|
|
||||||
for (int i = 0; i < voteOptions.length; i++) {
|
for (int i = 0; i < voteOptionsLength; i++) {
|
||||||
SegmentVote voteOption = voteOptions[i];
|
SegmentVote voteOption = voteOptions[i];
|
||||||
String title = voteOption.title.toString();
|
CharSequence title = voteOption.title.toString();
|
||||||
if (Settings.SB_USER_IS_VIP.get() && segment.isLocked && voteOption.shouldHighlight) {
|
if (userIsVip && segment.isLocked && voteOption.highlightIfVipAndVideoIsLocked) {
|
||||||
items[i] = Html.fromHtml(String.format("<font color=\"%s\">%s</font>", LOCKED_COLOR, title));
|
SpannableString coloredTitle = new SpannableString(title);
|
||||||
} else {
|
coloredTitle.setSpan(new ForegroundColorSpan(LOCKED_COLOR),
|
||||||
|
0, title.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
title = coloredTitle;
|
||||||
|
}
|
||||||
items[i] = title;
|
items[i] = title;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
new AlertDialog.Builder(context)
|
new AlertDialog.Builder(context).setItems(items, (dialog1, which1) -> {
|
||||||
.setItems(items, (dialog1, which1) -> {
|
|
||||||
SegmentVote voteOption = voteOptions[which1];
|
SegmentVote voteOption = voteOptions[which1];
|
||||||
switch (voteOption) {
|
switch (voteOption) {
|
||||||
case UPVOTE, DOWNVOTE ->
|
case UPVOTE:
|
||||||
|
case DOWNVOTE:
|
||||||
SBRequester.voteForSegmentOnBackgroundThread(segment, voteOption);
|
SBRequester.voteForSegmentOnBackgroundThread(segment, voteOption);
|
||||||
case CATEGORY_CHANGE -> onNewCategorySelect(segment, context);
|
break;
|
||||||
|
case CATEGORY_CHANGE:
|
||||||
|
onNewCategorySelect(segment, context);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
})
|
}).show();
|
||||||
.show();
|
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "segmentVoteClickListener failure", ex);
|
Logger.printException(() -> "segmentVoteClickListener failure", ex);
|
||||||
}
|
}
|
||||||
@ -287,22 +297,33 @@ public class SponsorBlockUtils {
|
|||||||
if (segment.category == SegmentCategory.UNSUBMITTED) {
|
if (segment.category == SegmentCategory.UNSUBMITTED) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
StringBuilder htmlBuilder = new StringBuilder();
|
|
||||||
htmlBuilder.append(String.format("<b><font color=\"#%06X\">⬤</font> %s<br>",
|
SpannableStringBuilder spannableBuilder = new SpannableStringBuilder();
|
||||||
segment.category.color, segment.category.title));
|
|
||||||
htmlBuilder.append(formatSegmentTime(segment.start));
|
spannableBuilder.append(segment.category.getTitleWithColorDot());
|
||||||
if (segment.category != SegmentCategory.HIGHLIGHT) {
|
spannableBuilder.append('\n');
|
||||||
htmlBuilder.append(" to ").append(formatSegmentTime(segment.end));
|
|
||||||
}
|
String startTime = formatSegmentTime(segment.start);
|
||||||
htmlBuilder.append("</b>");
|
if (segment.category == SegmentCategory.HIGHLIGHT) {
|
||||||
if (i + 1 != numberOfSegments) // prevents trailing new line after last segment
|
spannableBuilder.append(startTime);
|
||||||
htmlBuilder.append("<br>");
|
} else {
|
||||||
titles[i] = Html.fromHtml(htmlBuilder.toString());
|
String toFromString = str("revanced_sb_vote_segment_time_to_from",
|
||||||
|
startTime, formatSegmentTime(segment.end));
|
||||||
|
spannableBuilder.append(toFromString);
|
||||||
}
|
}
|
||||||
|
|
||||||
new AlertDialog.Builder(context)
|
if (i + 1 != numberOfSegments) {
|
||||||
.setItems(titles, segmentVoteClickListener)
|
// prevents trailing new line after last segment
|
||||||
.show();
|
spannableBuilder.append('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
spannableBuilder.setSpan(new StyleSpan(android.graphics.Typeface.BOLD),
|
||||||
|
0, spannableBuilder.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
|
||||||
|
titles[i] = spannableBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
|
new AlertDialog.Builder(context).setItems(titles, segmentVoteClickListener).show();
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "onVotingClicked failure", ex);
|
Logger.printException(() -> "onVotingClicked failure", ex);
|
||||||
}
|
}
|
||||||
|
@ -1,32 +1,14 @@
|
|||||||
package app.revanced.extension.youtube.sponsorblock.objects;
|
package app.revanced.extension.youtube.sponsorblock.objects;
|
||||||
|
|
||||||
import static app.revanced.extension.shared.utils.StringRef.sf;
|
import static app.revanced.extension.shared.utils.StringRef.sf;
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_FILLER;
|
import static app.revanced.extension.youtube.settings.Settings.*;
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_FILLER_COLOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_HIGHLIGHT;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_HIGHLIGHT_COLOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTERACTION;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTERACTION_COLOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTRO;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_INTRO_COLOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_MUSIC_OFFTOPIC;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_MUSIC_OFFTOPIC_COLOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_OUTRO;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_OUTRO_COLOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_PREVIEW;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_PREVIEW_COLOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SELF_PROMO;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SELF_PROMO_COLOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SPONSOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_SPONSOR_COLOR;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_UNSUBMITTED;
|
|
||||||
import static app.revanced.extension.youtube.settings.Settings.SB_CATEGORY_UNSUBMITTED_COLOR;
|
|
||||||
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Paint;
|
import android.graphics.Paint;
|
||||||
import android.text.Html;
|
import android.text.Spannable;
|
||||||
import android.text.Spanned;
|
import android.text.SpannableString;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
|
import android.text.style.ForegroundColorSpan;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -34,44 +16,46 @@ import androidx.annotation.Nullable;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import app.revanced.extension.shared.settings.FloatSetting;
|
||||||
import app.revanced.extension.shared.settings.StringSetting;
|
import app.revanced.extension.shared.settings.StringSetting;
|
||||||
import app.revanced.extension.shared.utils.Logger;
|
import app.revanced.extension.shared.utils.Logger;
|
||||||
import app.revanced.extension.shared.utils.StringRef;
|
import app.revanced.extension.shared.utils.StringRef;
|
||||||
import app.revanced.extension.shared.utils.Utils;
|
import app.revanced.extension.shared.utils.Utils;
|
||||||
import app.revanced.extension.youtube.settings.Settings;
|
import app.revanced.extension.youtube.settings.Settings;
|
||||||
|
|
||||||
@SuppressWarnings({"deprecation", "StaticFieldLeak"})
|
@SuppressWarnings("StaticFieldLeak")
|
||||||
public enum SegmentCategory {
|
public enum SegmentCategory {
|
||||||
SPONSOR("sponsor", sf("revanced_sb_segments_sponsor"), sf("revanced_sb_skip_button_sponsor"), sf("revanced_sb_skipped_sponsor"),
|
SPONSOR("sponsor", sf("revanced_sb_segments_sponsor"), sf("revanced_sb_skip_button_sponsor"), sf("revanced_sb_skipped_sponsor"),
|
||||||
SB_CATEGORY_SPONSOR, SB_CATEGORY_SPONSOR_COLOR),
|
SB_CATEGORY_SPONSOR, SB_CATEGORY_SPONSOR_COLOR, SB_CATEGORY_SPONSOR_OPACITY),
|
||||||
SELF_PROMO("selfpromo", sf("revanced_sb_segments_selfpromo"), sf("revanced_sb_skip_button_selfpromo"), sf("revanced_sb_skipped_selfpromo"),
|
SELF_PROMO("selfpromo", sf("revanced_sb_segments_selfpromo"), sf("revanced_sb_skip_button_selfpromo"), sf("revanced_sb_skipped_selfpromo"),
|
||||||
SB_CATEGORY_SELF_PROMO, SB_CATEGORY_SELF_PROMO_COLOR),
|
SB_CATEGORY_SELF_PROMO, SB_CATEGORY_SELF_PROMO_COLOR, SB_CATEGORY_SELF_PROMO_OPACITY),
|
||||||
INTERACTION("interaction", sf("revanced_sb_segments_interaction"), sf("revanced_sb_skip_button_interaction"), sf("revanced_sb_skipped_interaction"),
|
INTERACTION("interaction", sf("revanced_sb_segments_interaction"), sf("revanced_sb_skip_button_interaction"), sf("revanced_sb_skipped_interaction"),
|
||||||
SB_CATEGORY_INTERACTION, SB_CATEGORY_INTERACTION_COLOR),
|
SB_CATEGORY_INTERACTION, SB_CATEGORY_INTERACTION_COLOR, SB_CATEGORY_INTERACTION_OPACITY),
|
||||||
/**
|
/**
|
||||||
* Unique category that is treated differently than the rest.
|
* Unique category that is treated differently than the rest.
|
||||||
*/
|
*/
|
||||||
HIGHLIGHT("poi_highlight", sf("revanced_sb_segments_highlight"), sf("revanced_sb_skip_button_highlight"), sf("revanced_sb_skipped_highlight"),
|
HIGHLIGHT("poi_highlight", sf("revanced_sb_segments_highlight"), sf("revanced_sb_skip_button_highlight"), sf("revanced_sb_skipped_highlight"),
|
||||||
SB_CATEGORY_HIGHLIGHT, SB_CATEGORY_HIGHLIGHT_COLOR),
|
SB_CATEGORY_HIGHLIGHT, SB_CATEGORY_HIGHLIGHT_COLOR, SB_CATEGORY_HIGHLIGHT_OPACITY),
|
||||||
INTRO("intro", sf("revanced_sb_segments_intro"),
|
INTRO("intro", sf("revanced_sb_segments_intro"),
|
||||||
sf("revanced_sb_skip_button_intro_beginning"), sf("revanced_sb_skip_button_intro_middle"), sf("revanced_sb_skip_button_intro_end"),
|
sf("revanced_sb_skip_button_intro_beginning"), sf("revanced_sb_skip_button_intro_middle"), sf("revanced_sb_skip_button_intro_end"),
|
||||||
sf("revanced_sb_skipped_intro_beginning"), sf("revanced_sb_skipped_intro_middle"), sf("revanced_sb_skipped_intro_end"),
|
sf("revanced_sb_skipped_intro_beginning"), sf("revanced_sb_skipped_intro_middle"), sf("revanced_sb_skipped_intro_end"),
|
||||||
SB_CATEGORY_INTRO, SB_CATEGORY_INTRO_COLOR),
|
SB_CATEGORY_INTRO, SB_CATEGORY_INTRO_COLOR, SB_CATEGORY_INTRO_OPACITY),
|
||||||
OUTRO("outro", sf("revanced_sb_segments_outro"), sf("revanced_sb_skip_button_outro"), sf("revanced_sb_skipped_outro"),
|
OUTRO("outro", sf("revanced_sb_segments_outro"), sf("revanced_sb_skip_button_outro"), sf("revanced_sb_skipped_outro"),
|
||||||
SB_CATEGORY_OUTRO, SB_CATEGORY_OUTRO_COLOR),
|
SB_CATEGORY_OUTRO, SB_CATEGORY_OUTRO_COLOR, SB_CATEGORY_OUTRO_OPACITY),
|
||||||
PREVIEW("preview", sf("revanced_sb_segments_preview"),
|
PREVIEW("preview", sf("revanced_sb_segments_preview"),
|
||||||
sf("revanced_sb_skip_button_preview_beginning"), sf("revanced_sb_skip_button_preview_middle"), sf("revanced_sb_skip_button_preview_end"),
|
sf("revanced_sb_skip_button_preview_beginning"), sf("revanced_sb_skip_button_preview_middle"), sf("revanced_sb_skip_button_preview_end"),
|
||||||
sf("revanced_sb_skipped_preview_beginning"), sf("revanced_sb_skipped_preview_middle"), sf("revanced_sb_skipped_preview_end"),
|
sf("revanced_sb_skipped_preview_beginning"), sf("revanced_sb_skipped_preview_middle"), sf("revanced_sb_skipped_preview_end"),
|
||||||
SB_CATEGORY_PREVIEW, SB_CATEGORY_PREVIEW_COLOR),
|
SB_CATEGORY_PREVIEW, SB_CATEGORY_PREVIEW_COLOR, SB_CATEGORY_PREVIEW_OPACITY),
|
||||||
FILLER("filler", sf("revanced_sb_segments_filler"), sf("revanced_sb_skip_button_filler"), sf("revanced_sb_skipped_filler"),
|
FILLER("filler", sf("revanced_sb_segments_filler"), sf("revanced_sb_skip_button_filler"), sf("revanced_sb_skipped_filler"),
|
||||||
SB_CATEGORY_FILLER, SB_CATEGORY_FILLER_COLOR),
|
SB_CATEGORY_FILLER, SB_CATEGORY_FILLER_COLOR, SB_CATEGORY_FILLER_OPACITY),
|
||||||
MUSIC_OFFTOPIC("music_offtopic", sf("revanced_sb_segments_nomusic"), sf("revanced_sb_skip_button_nomusic"), sf("revanced_sb_skipped_nomusic"),
|
MUSIC_OFFTOPIC("music_offtopic", sf("revanced_sb_segments_nomusic"), sf("revanced_sb_skip_button_nomusic"), sf("revanced_sb_skipped_nomusic"),
|
||||||
SB_CATEGORY_MUSIC_OFFTOPIC, SB_CATEGORY_MUSIC_OFFTOPIC_COLOR),
|
SB_CATEGORY_MUSIC_OFFTOPIC, SB_CATEGORY_MUSIC_OFFTOPIC_COLOR, SB_CATEGORY_MUSIC_OFFTOPIC_OPACITY),
|
||||||
UNSUBMITTED("unsubmitted", StringRef.empty, sf("revanced_sb_skip_button_unsubmitted"), sf("revanced_sb_skipped_unsubmitted"),
|
UNSUBMITTED("unsubmitted", StringRef.empty, sf("revanced_sb_skip_button_unsubmitted"), sf("revanced_sb_skipped_unsubmitted"),
|
||||||
SB_CATEGORY_UNSUBMITTED, SB_CATEGORY_UNSUBMITTED_COLOR),
|
SB_CATEGORY_UNSUBMITTED, SB_CATEGORY_UNSUBMITTED_COLOR, SB_CATEGORY_UNSUBMITTED_OPACITY);
|
||||||
;
|
;
|
||||||
|
|
||||||
private static final StringRef skipSponsorTextCompact = sf("revanced_sb_skip_button_compact");
|
private static final StringRef skipSponsorTextCompact = sf("revanced_sb_skip_button_compact");
|
||||||
@ -111,12 +95,10 @@ public enum SegmentCategory {
|
|||||||
mValuesMap.put(value.keyValue, value);
|
mValuesMap.put(value.keyValue, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static SegmentCategory[] categoriesWithoutUnsubmitted() {
|
public static SegmentCategory[] categoriesWithoutUnsubmitted() {
|
||||||
return categoriesWithoutUnsubmitted;
|
return categoriesWithoutUnsubmitted;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public static SegmentCategory[] categoriesWithoutHighlights() {
|
public static SegmentCategory[] categoriesWithoutHighlights() {
|
||||||
return categoriesWithoutHighlights;
|
return categoriesWithoutHighlights;
|
||||||
}
|
}
|
||||||
@ -127,7 +109,7 @@ public enum SegmentCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Must be called if behavior of any category is changed
|
* Must be called if behavior of any category is changed.
|
||||||
*/
|
*/
|
||||||
public static void updateEnabledCategories() {
|
public static void updateEnabledCategories() {
|
||||||
Utils.verifyOnMainThread();
|
Utils.verifyOnMainThread();
|
||||||
@ -154,30 +136,32 @@ public enum SegmentCategory {
|
|||||||
updateEnabledCategories();
|
updateEnabledCategories();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
public static int applyOpacityToColor(int color, float opacity) {
|
||||||
public final String keyValue;
|
if (opacity < 0 || opacity > 1.0f) {
|
||||||
@NonNull
|
throw new IllegalArgumentException("Invalid opacity: " + opacity);
|
||||||
public final StringSetting behaviorSetting;
|
}
|
||||||
@NonNull
|
final int opacityInt = (int) (255 * opacity);
|
||||||
private final StringSetting colorSetting;
|
return (color & 0x00FFFFFF) | (opacityInt << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final String keyValue;
|
||||||
|
public final StringSetting behaviorSetting; // TODO: Replace with EnumSetting.
|
||||||
|
private final StringSetting colorSetting;
|
||||||
|
private final FloatSetting opacitySetting;
|
||||||
|
|
||||||
@NonNull
|
|
||||||
public final StringRef title;
|
public final StringRef title;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Skip button text, if the skip occurs in the first quarter of the video
|
* Skip button text, if the skip occurs in the first quarter of the video
|
||||||
*/
|
*/
|
||||||
@NonNull
|
|
||||||
public final StringRef skipButtonTextBeginning;
|
public final StringRef skipButtonTextBeginning;
|
||||||
/**
|
/**
|
||||||
* Skip button text, if the skip occurs in the middle half of the video
|
* Skip button text, if the skip occurs in the middle half of the video
|
||||||
*/
|
*/
|
||||||
@NonNull
|
|
||||||
public final StringRef skipButtonTextMiddle;
|
public final StringRef skipButtonTextMiddle;
|
||||||
/**
|
/**
|
||||||
* Skip button text, if the skip occurs in the last quarter of the video
|
* Skip button text, if the skip occurs in the last quarter of the video
|
||||||
*/
|
*/
|
||||||
@NonNull
|
|
||||||
public final StringRef skipButtonTextEnd;
|
public final StringRef skipButtonTextEnd;
|
||||||
/**
|
/**
|
||||||
* Skipped segment toast, if the skip occurred in the first quarter of the video
|
* Skipped segment toast, if the skip occurred in the first quarter of the video
|
||||||
@ -198,10 +182,7 @@ public enum SegmentCategory {
|
|||||||
@NonNull
|
@NonNull
|
||||||
public final Paint paint;
|
public final Paint paint;
|
||||||
|
|
||||||
/**
|
private int color;
|
||||||
* Value must be changed using {@link #setColor(String)}.
|
|
||||||
*/
|
|
||||||
public int color;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Value must be changed using {@link #setBehaviour(CategoryBehaviour)}.
|
* Value must be changed using {@link #setBehaviour(CategoryBehaviour)}.
|
||||||
@ -213,17 +194,20 @@ public enum SegmentCategory {
|
|||||||
SegmentCategory(String keyValue, StringRef title,
|
SegmentCategory(String keyValue, StringRef title,
|
||||||
StringRef skipButtonText,
|
StringRef skipButtonText,
|
||||||
StringRef skippedToastText,
|
StringRef skippedToastText,
|
||||||
StringSetting behavior, StringSetting color) {
|
StringSetting behavior,
|
||||||
|
StringSetting color, FloatSetting opacity) {
|
||||||
this(keyValue, title,
|
this(keyValue, title,
|
||||||
skipButtonText, skipButtonText, skipButtonText,
|
skipButtonText, skipButtonText, skipButtonText,
|
||||||
skippedToastText, skippedToastText, skippedToastText,
|
skippedToastText, skippedToastText, skippedToastText,
|
||||||
behavior, color);
|
behavior,
|
||||||
|
color, opacity);
|
||||||
}
|
}
|
||||||
|
|
||||||
SegmentCategory(String keyValue, StringRef title,
|
SegmentCategory(String keyValue, StringRef title,
|
||||||
StringRef skipButtonTextBeginning, StringRef skipButtonTextMiddle, StringRef skipButtonTextEnd,
|
StringRef skipButtonTextBeginning, StringRef skipButtonTextMiddle, StringRef skipButtonTextEnd,
|
||||||
StringRef skippedToastBeginning, StringRef skippedToastMiddle, StringRef skippedToastEnd,
|
StringRef skippedToastBeginning, StringRef skippedToastMiddle, StringRef skippedToastEnd,
|
||||||
StringSetting behavior, StringSetting color) {
|
StringSetting behavior,
|
||||||
|
StringSetting color, FloatSetting opacity) {
|
||||||
this.keyValue = Objects.requireNonNull(keyValue);
|
this.keyValue = Objects.requireNonNull(keyValue);
|
||||||
this.title = Objects.requireNonNull(title);
|
this.title = Objects.requireNonNull(title);
|
||||||
this.skipButtonTextBeginning = Objects.requireNonNull(skipButtonTextBeginning);
|
this.skipButtonTextBeginning = Objects.requireNonNull(skipButtonTextBeginning);
|
||||||
@ -234,6 +218,7 @@ public enum SegmentCategory {
|
|||||||
this.skippedToastEnd = Objects.requireNonNull(skippedToastEnd);
|
this.skippedToastEnd = Objects.requireNonNull(skippedToastEnd);
|
||||||
this.behaviorSetting = Objects.requireNonNull(behavior);
|
this.behaviorSetting = Objects.requireNonNull(behavior);
|
||||||
this.colorSetting = Objects.requireNonNull(color);
|
this.colorSetting = Objects.requireNonNull(color);
|
||||||
|
this.opacitySetting = Objects.requireNonNull(opacity);
|
||||||
this.paint = new Paint();
|
this.paint = new Paint();
|
||||||
loadFromSettings();
|
loadFromSettings();
|
||||||
}
|
}
|
||||||
@ -250,11 +235,14 @@ public enum SegmentCategory {
|
|||||||
this.behaviour = savedBehavior;
|
this.behaviour = savedBehavior;
|
||||||
|
|
||||||
String colorString = colorSetting.get();
|
String colorString = colorSetting.get();
|
||||||
|
final float opacity = opacitySetting.get();
|
||||||
try {
|
try {
|
||||||
setColor(colorString);
|
setColor(colorString);
|
||||||
|
setOpacity(opacity);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
Logger.printException(() -> "Invalid color: " + colorString, ex);
|
Logger.printException(() -> "Invalid color: " + colorString + " opacity: " + opacity, ex);
|
||||||
colorSetting.resetToDefault();
|
colorSetting.resetToDefault();
|
||||||
|
opacitySetting.resetToDefault();
|
||||||
loadFromSettings();
|
loadFromSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -264,45 +252,77 @@ public enum SegmentCategory {
|
|||||||
this.behaviorSetting.save(behaviour.reVancedKeyValue);
|
this.behaviorSetting.save(behaviour.reVancedKeyValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void updateColor() {
|
||||||
* @return HTML color format string
|
color = applyOpacityToColor(color, opacitySetting.get());
|
||||||
*/
|
|
||||||
@NonNull
|
|
||||||
public String colorString() {
|
|
||||||
return String.format("#%06X", color);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setColor(@NonNull String colorString) throws IllegalArgumentException {
|
|
||||||
final int color = Color.parseColor(colorString) & 0xFFFFFF;
|
|
||||||
this.color = color;
|
|
||||||
paint.setColor(color);
|
paint.setColor(color);
|
||||||
paint.setAlpha(255);
|
|
||||||
colorSetting.save(colorString); // Save after parsing.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetColor() {
|
/**
|
||||||
|
* @param opacity Segment color opacity between [0, 1].
|
||||||
|
*/
|
||||||
|
public void setOpacity(float opacity) throws IllegalArgumentException {
|
||||||
|
if (opacity < 0 || opacity > 1) {
|
||||||
|
throw new IllegalArgumentException("Invalid opacity: " + opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
opacitySetting.save(opacity);
|
||||||
|
updateColor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float getOpacity() {
|
||||||
|
return opacitySetting.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetColorAndOpacity() {
|
||||||
setColor(colorSetting.defaultValue);
|
setColor(colorSetting.defaultValue);
|
||||||
|
setOpacity(opacitySetting.defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
/**
|
||||||
private static String getCategoryColorDotHTML(int color) {
|
* @param colorString Segment color with #RRGGBB format.
|
||||||
color &= 0xFFFFFF;
|
*/
|
||||||
return String.format("<font color=\"#%06X\">⬤</font>", color);
|
public void setColor(String colorString) throws IllegalArgumentException {
|
||||||
|
color = Color.parseColor(colorString);
|
||||||
|
colorSetting.save(colorString);
|
||||||
|
|
||||||
|
updateColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
/**
|
||||||
public static Spanned getCategoryColorDot(int color) {
|
* @return Integer color of #RRGGBB format.
|
||||||
return Html.fromHtml(getCategoryColorDotHTML(color));
|
*/
|
||||||
|
public int getColorNoOpacity() {
|
||||||
|
return color & 0x00FFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
/**
|
||||||
public Spanned getCategoryColorDot() {
|
* @return Hex color string of #RRGGBB format with no opacity level.
|
||||||
|
*/
|
||||||
|
public String getColorString() {
|
||||||
|
return String.format(Locale.US, "#%06X", getColorNoOpacity());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SpannableString getCategoryColorDotSpan(String text, int color) {
|
||||||
|
SpannableString dotSpan = new SpannableString('⬤' + text);
|
||||||
|
dotSpan.setSpan(new ForegroundColorSpan(color), 0, 1,
|
||||||
|
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
return dotSpan;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SpannableString getCategoryColorDot(int color) {
|
||||||
|
return getCategoryColorDotSpan("", color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpannableString getCategoryColorDot() {
|
||||||
return getCategoryColorDot(color);
|
return getCategoryColorDot(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NonNull
|
public SpannableString getTitleWithColorDot(int categoryColor) {
|
||||||
public Spanned getTitleWithColorDot() {
|
return getCategoryColorDotSpan(" " + title, categoryColor);
|
||||||
return Html.fromHtml(getCategoryColorDotHTML(color) + " " + title);
|
}
|
||||||
|
|
||||||
|
public SpannableString getTitleWithColorDot() {
|
||||||
|
return getTitleWithColorDot(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -310,7 +330,6 @@ public enum SegmentCategory {
|
|||||||
* @param videoLength length of the video
|
* @param videoLength length of the video
|
||||||
* @return the skip button text
|
* @return the skip button text
|
||||||
*/
|
*/
|
||||||
@NonNull
|
|
||||||
StringRef getSkipButtonText(long segmentStartTime, long videoLength) {
|
StringRef getSkipButtonText(long segmentStartTime, long videoLength) {
|
||||||
if (Settings.SB_COMPACT_SKIP_BUTTON.get()) {
|
if (Settings.SB_COMPACT_SKIP_BUTTON.get()) {
|
||||||
return (this == SegmentCategory.HIGHLIGHT)
|
return (this == SegmentCategory.HIGHLIGHT)
|
||||||
@ -319,7 +338,7 @@ public enum SegmentCategory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (videoLength == 0) {
|
if (videoLength == 0) {
|
||||||
return skipButtonTextBeginning; // video is still loading. Assume it's the beginning
|
return skipButtonTextBeginning; // Video is still loading. Assume it's the beginning.
|
||||||
}
|
}
|
||||||
final float position = segmentStartTime / (float) videoLength;
|
final float position = segmentStartTime / (float) videoLength;
|
||||||
if (position < 0.25f) {
|
if (position < 0.25f) {
|
||||||
@ -335,10 +354,9 @@ public enum SegmentCategory {
|
|||||||
* @param videoLength length of the video
|
* @param videoLength length of the video
|
||||||
* @return 'skipped segment' toast message
|
* @return 'skipped segment' toast message
|
||||||
*/
|
*/
|
||||||
@NonNull
|
|
||||||
StringRef getSkippedToastText(long segmentStartTime, long videoLength) {
|
StringRef getSkippedToastText(long segmentStartTime, long videoLength) {
|
||||||
if (videoLength == 0) {
|
if (videoLength == 0) {
|
||||||
return skippedToastBeginning; // video is still loading. Assume it's the beginning
|
return skippedToastBeginning; // Video is still loading. Assume it's the beginning.
|
||||||
}
|
}
|
||||||
final float position = segmentStartTime / (float) videoLength;
|
final float position = segmentStartTime / (float) videoLength;
|
||||||
if (position < 0.25f) {
|
if (position < 0.25f) {
|
||||||
|
@ -24,12 +24,15 @@ public class SponsorSegment implements Comparable<SponsorSegment> {
|
|||||||
@NonNull
|
@NonNull
|
||||||
public final StringRef title;
|
public final StringRef title;
|
||||||
public final int apiVoteType;
|
public final int apiVoteType;
|
||||||
public final boolean shouldHighlight;
|
/**
|
||||||
|
* If the option should be highlighted for VIP users.
|
||||||
|
*/
|
||||||
|
public final boolean highlightIfVipAndVideoIsLocked;
|
||||||
|
|
||||||
SegmentVote(@NonNull StringRef title, int apiVoteType, boolean shouldHighlight) {
|
SegmentVote(@NonNull StringRef title, int apiVoteType, boolean highlightIfVipAndVideoIsLocked) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
this.apiVoteType = apiVoteType;
|
this.apiVoteType = apiVoteType;
|
||||||
this.shouldHighlight = shouldHighlight;
|
this.highlightIfVipAndVideoIsLocked = highlightIfVipAndVideoIsLocked;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1964,6 +1964,7 @@ Click to see how to issue an API key."</string>
|
|||||||
<string name="revanced_sb_skip_seekbaronly">Show in seekbar</string>
|
<string name="revanced_sb_skip_seekbaronly">Show in seekbar</string>
|
||||||
<string name="revanced_sb_skip_ignore">Disable</string>
|
<string name="revanced_sb_skip_ignore">Disable</string>
|
||||||
|
|
||||||
|
<string name="revanced_sb_color_opacity_label">Opacity:</string>
|
||||||
<string name="revanced_sb_color_dot_label">Color:</string>
|
<string name="revanced_sb_color_dot_label">Color:</string>
|
||||||
<string name="revanced_sb_color_changed">Color changed.</string>
|
<string name="revanced_sb_color_changed">Color changed.</string>
|
||||||
<string name="revanced_sb_color_reset">Color reset.</string>
|
<string name="revanced_sb_color_reset">Color reset.</string>
|
||||||
@ -2036,6 +2037,8 @@ Click to see how to issue an API key."</string>
|
|||||||
<string name="revanced_sb_vote_downvote">Downvote</string>
|
<string name="revanced_sb_vote_downvote">Downvote</string>
|
||||||
<string name="revanced_sb_vote_category">Change category</string>
|
<string name="revanced_sb_vote_category">Change category</string>
|
||||||
<string name="revanced_sb_vote_no_segments">There are no segments to vote for.</string>
|
<string name="revanced_sb_vote_no_segments">There are no segments to vote for.</string>
|
||||||
|
<!-- A segment start and end time, such as "02:10 to 03:40" -->
|
||||||
|
<string name="revanced_sb_vote_segment_time_to_from">%1$s to %2$s</string>
|
||||||
|
|
||||||
<string name="revanced_sb_new_segment_choose_category">Choose the segment category</string>
|
<string name="revanced_sb_new_segment_choose_category">Choose the segment category</string>
|
||||||
<string name="revanced_sb_new_segment_disabled_category">Category is disabled in settings. Enable category to submit.</string>
|
<string name="revanced_sb_new_segment_disabled_category">Category is disabled in settings. Enable category to submit.</string>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user