Merge pull request #4 from YTVanced/shieldBtnFixes

Shield btn fixes
This commit is contained in:
VancedOfficial 2020-10-15 18:57:28 +03:00 committed by GitHub
commit 81e5843572
22 changed files with 688 additions and 291 deletions

View file

@ -1,139 +1,28 @@
package pl.jakubweg;
import android.annotation.SuppressLint;
import android.content.Context;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import java.lang.ref.WeakReference;
import static fi.vanced.libraries.youtube.sponsors.player.ui.SponsorBlockView.hideNewSegmentLayout;
import static fi.vanced.libraries.youtube.sponsors.player.ui.SponsorBlockView.showNewSegmentLayout;
public class NewSegmentHelperLayout extends LinearLayout implements View.OnClickListener {
private static final int rewindBtnId = 1235;
private static final int forwardBtnId = 1236;
private static final int publishBtnId = 1237;
private static final int hideBtnId = 1238;
private static final int markLocationBtnId = 1239;
private static final int previewBtnId = 1240;
private static final int editByHandBtnId = 1241;
private static WeakReference<NewSegmentHelperLayout> INSTANCE = new WeakReference<>(null);
public class NewSegmentHelperLayout {
public static Context context;
private static boolean isShown = false;
private final int padding;
private final int iconSize;
private final int rippleEffectId;
private final String packageName;
@SuppressLint({"DefaultLocale", "SetTextI18n"})
public NewSegmentHelperLayout(Context context) {
super(context);
INSTANCE = new WeakReference<>(this);
isShown = false;
setVisibility(GONE);
packageName = context.getPackageName();
padding = (int) SkipSegmentView.convertDpToPixel(4f, context);
iconSize = (int) SkipSegmentView.convertDpToPixel(40f, context);
TypedValue rippleEffect = new TypedValue();
getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, rippleEffect, true);
rippleEffectId = rippleEffect.resourceId;
setOrientation(VERTICAL);
@SuppressLint("RtlHardcoded")
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.START | Gravity.LEFT | Gravity.CENTER_VERTICAL
);
this.setBackgroundColor(0x66000000);
this.bringToFront();
this.setLayoutParams(layoutParams);
this.setPadding(padding, padding, padding, padding);
final LinearLayout topLayout = new LinearLayout(context);
final LinearLayout bottomLayout = new LinearLayout(context);
topLayout.setOrientation(HORIZONTAL);
bottomLayout.setOrientation(HORIZONTAL);
this.addView(topLayout);
this.addView(bottomLayout);
topLayout.addView(createTextViewBtn(rewindBtnId, "player_fast_rewind"));
topLayout.addView(createTextViewBtn(forwardBtnId, "player_fast_forward"));
topLayout.addView(createTextViewBtn(markLocationBtnId, "ic_sb_adjust"));
bottomLayout.addView(createTextViewBtn(previewBtnId, "ic_sb_compare"));
bottomLayout.addView(createTextViewBtn(editByHandBtnId, "ic_sb_edit"));
bottomLayout.addView(createTextViewBtn(publishBtnId, "ic_sb_publish"));
// bottomLayout.addView(createTextViewBtn(hideBtnId,"btn_close_light"));
}
public static void show() {
if (isShown) return;
isShown = true;
NewSegmentHelperLayout i = INSTANCE.get();
if (i == null) return;
i.setVisibility(VISIBLE);
i.bringToFront();
i.requestLayout();
i.invalidate();
showNewSegmentLayout();
}
public static void hide() {
if (!isShown) return;
isShown = false;
NewSegmentHelperLayout i = INSTANCE.get();
if (i != null)
i.setVisibility(GONE);
hideNewSegmentLayout();
}
public static void toggle() {
if (isShown) hide();
else show();
}
private View createTextViewBtn(int id, String drawableName) {
int drawableId = getResources().getIdentifier(drawableName, "drawable", packageName);
final ImageView view = new ImageView(getContext());
view.setPadding(padding, padding, padding, padding);
view.setLayoutParams(new LayoutParams(iconSize, iconSize, 1));
view.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
view.setImageResource(drawableId);
view.setId(id);
view.setClickable(true);
view.setFocusable(true);
view.setBackgroundResource(rippleEffectId);
view.setOnClickListener(this);
return view;
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case forwardBtnId:
PlayerController.skipRelativeMilliseconds(SponsorBlockSettings.adjustNewSegmentMillis);
break;
case rewindBtnId:
PlayerController.skipRelativeMilliseconds(-SponsorBlockSettings.adjustNewSegmentMillis);
break;
case markLocationBtnId:
SponsorBlockUtils.onMarkLocationClicked(getContext());
break;
case publishBtnId:
SponsorBlockUtils.onPublishClicked(getContext());
break;
case previewBtnId:
SponsorBlockUtils.onPreviewClicked(getContext());
break;
case editByHandBtnId:
SponsorBlockUtils.onEditByHandClicked(getContext());
break;
case hideBtnId:
hide();
break;
}
}
}

View file

@ -104,11 +104,6 @@ public class PlayerController {
SkipSegmentView.hide();
NewSegmentHelperLayout.hide();
// add image button when starting new video
Activity activity = playerActivity.get();
if (activity != null)
SponsorBlockUtils.addImageButton(activity, 5);
} catch (Exception e) {
Log.e(TAG, "Exception while initializing skip method", e);
}
@ -344,14 +339,13 @@ public class PlayerController {
playerActivity = new WeakReference<>((Activity) view.getContext());
if (VERBOSE)
Log.d(TAG, "addSkipSponsorView15: view=" + view.toString());
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
final ViewGroup viewGroup = (ViewGroup) ((ViewGroup) view).getChildAt(2);
Activity context = ((Activity) viewGroup.getContext());
viewGroup.addView(new SkipSegmentView(context));
viewGroup.addView(new NewSegmentHelperLayout(context));
SponsorBlockUtils.addImageButton(context, 40);
NewSegmentHelperLayout.context = context;
}
}, 500);
}
@ -365,15 +359,7 @@ public class PlayerController {
public void run() {
final ViewGroup viewGroup = (ViewGroup) view.getParent();
Activity activity = (Activity) viewGroup.getContext();
viewGroup.addView(new SkipSegmentView(activity));
viewGroup.addView(new NewSegmentHelperLayout(activity));
// add image button when creating new activity
SponsorBlockUtils.addImageButton(activity, 5);
// InjectedPlugin.printViewStack(viewGroup, 0);
// SponsorBlockUtils.addImageButton(activity);
NewSegmentHelperLayout.context = activity;
}
}, 500);
}

View file

@ -0,0 +1,133 @@
package pl.jakubweg;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import com.google.android.apps.youtube.app.YouTubeApplication;
import java.lang.ref.WeakReference;
import static fi.razerman.youtube.XGlobals.debug;
public class ShieldButton {
static String TAG = "SHIELD";
static RelativeLayout _youtubeControlsLayout;
static WeakReference<ImageView> _shieldBtn = new WeakReference<>(null);
static int fadeDurationFast;
static int fadeDurationScheduled;
static Animation fadeIn;
static Animation fadeOut;
static boolean isShowing;
public static void initialize(Object viewStub) {
try {
if(debug){
Log.d(TAG, "initializing shield button");
}
_youtubeControlsLayout = (RelativeLayout) viewStub;
initButtonVisibilitySettings();
ImageView imageView = (ImageView)_youtubeControlsLayout
.findViewById(getIdentifier("sponsorblock_button", "id"));
if (debug && imageView == null){
Log.d(TAG, "Couldn't find imageView with tag \"sponsorblock_button\"");
}
if (imageView == null) return;
imageView.setOnClickListener(SponsorBlockUtils.sponsorBlockBtnListener);
_shieldBtn = new WeakReference<>(imageView);
// Animations
fadeDurationFast = getInteger("fade_duration_fast");
fadeDurationScheduled = getInteger("fade_duration_scheduled");
fadeIn = getAnimation("fade_in");
fadeIn.setDuration(fadeDurationFast);
fadeOut = getAnimation("fade_out");
fadeOut.setDuration(fadeDurationScheduled);
isShowing = true;
changeVisibilityImmediate(false);
}
catch (Exception ex) {
Log.e(TAG, "Unable to set RelativeLayout", ex);
}
}
public static void changeVisibilityImmediate(boolean visible) {
changeVisibility(visible, true);
}
public static void changeVisibilityNegatedImmediate(boolean visible) {
changeVisibility(!visible, true);
}
public static void changeVisibility(boolean visible) {
changeVisibility(visible, false);
}
public static void changeVisibility(boolean visible, boolean immediate) {
if (isShowing == visible) return;
isShowing = visible;
ImageView iView = _shieldBtn.get();
if (_youtubeControlsLayout == null || iView == null) return;
if (visible && shouldBeShown()) {
if (debug) {
Log.d(TAG, "Fading in");
}
iView.setVisibility(View.VISIBLE);
if (!immediate)
iView.startAnimation(fadeIn);
return;
}
if (iView.getVisibility() == View.VISIBLE) {
if (debug) {
Log.d(TAG, "Fading out");
}
if (!immediate)
iView.startAnimation(fadeOut);
iView.setVisibility(shouldBeShown() ? View.INVISIBLE : View.GONE);
}
}
private static boolean shouldBeShown() {
return SponsorBlockSettings.isSponsorBlockEnabled && SponsorBlockSettings.isAddNewSegmentEnabled;
}
private static void initButtonVisibilitySettings() {
Context context = YouTubeApplication.getAppContext();
if(context == null){
Log.e(TAG, "context is null");
SponsorBlockSettings.isSponsorBlockEnabled = false;
SponsorBlockSettings.isAddNewSegmentEnabled = false;
return;
}
SharedPreferences sharedPreferences = context.getSharedPreferences(SponsorBlockSettings.PREFERENCES_NAME, Context.MODE_PRIVATE);
SponsorBlockSettings.isSponsorBlockEnabled = sharedPreferences.getBoolean(SponsorBlockSettings.PREFERENCES_KEY_SPONSOR_BLOCK_ENABLED, false);
SponsorBlockSettings.isAddNewSegmentEnabled = sharedPreferences.getBoolean(SponsorBlockSettings.PREFERENCES_KEY_NEW_SEGMENT_ENABLED, false);
}
//region Helpers
private static int getIdentifier(String name, String defType) {
Context context = YouTubeApplication.getAppContext();
return context.getResources().getIdentifier(name, defType, context.getPackageName());
}
private static int getInteger(String name) {
return YouTubeApplication.getAppContext().getResources().getInteger(getIdentifier(name, "integer"));
}
private static Animation getAnimation(String name) {
return AnimationUtils.loadAnimation(YouTubeApplication.getAppContext(), getIdentifier(name, "anim"));
}
//endregion
}

View file

@ -4,69 +4,28 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.apps.youtube.app.YouTubeApplication;
import java.lang.ref.WeakReference;
import static fi.vanced.libraries.youtube.sponsors.player.ui.SponsorBlockView.hideSkipButton;
import static fi.vanced.libraries.youtube.sponsors.player.ui.SponsorBlockView.showSkipButton;
import static pl.jakubweg.PlayerController.VERBOSE;
import static pl.jakubweg.StringRef.str;
@SuppressLint({"RtlHardcoded", "SetTextI18n", "LongLogTag", "AppCompatCustomView"})
public class SkipSegmentView extends TextView implements View.OnClickListener {
public class SkipSegmentView {
public static final String TAG = "jakubweg.SkipSegmentView";
private static boolean isVisible = false;
private static WeakReference<SkipSegmentView> view = new WeakReference<>(null);
private static SponsorSegment lastNotifiedSegment;
public SkipSegmentView(Context context) {
super(context);
isVisible = false;
setVisibility(GONE);
view = new WeakReference<>(this);
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
FrameLayout.LayoutParams.WRAP_CONTENT,
FrameLayout.LayoutParams.WRAP_CONTENT,
Gravity.END | Gravity.RIGHT | Gravity.CENTER_VERTICAL
);
this.setLayoutParams(layoutParams);
this.setBackgroundColor(0x66000000);
// this.setBackgroundColor(Color.MAGENTA);
this.setTextColor(0xFFFFFFFF);
int padding = (int) convertDpToPixel(4, context);
setPadding(padding, padding, padding, padding);
this.setText(str("tap_skip"));
setOnClickListener(this);
}
public static void show() {
if (isVisible) return;
SkipSegmentView view = SkipSegmentView.view.get();
if (VERBOSE)
Log.d(TAG, "show; view=" + view);
if (view != null) {
view.setVisibility(VISIBLE);
view.bringToFront();
view.requestLayout();
view.invalidate();
}
isVisible = true;
showSkipButton();
}
public static void hide() {
if (!isVisible) return;
SkipSegmentView view = SkipSegmentView.view.get();
if (VERBOSE)
Log.d(TAG, "hide; view=" + view);
if (view != null)
view.setVisibility(GONE);
isVisible = false;
hideSkipButton();
}
public static void notifySkipped(SponsorSegment segment) {
@ -77,19 +36,15 @@ public class SkipSegmentView extends TextView implements View.OnClickListener {
}
lastNotifiedSegment = segment;
String skipMessage = segment.category.skipMessage.toString();
SkipSegmentView view = SkipSegmentView.view.get();
Context context = YouTubeApplication.getAppContext();
if (VERBOSE)
Log.d(TAG, String.format("notifySkipped; view=%s, message=%s", view, skipMessage));
if (view != null)
Toast.makeText(view.getContext(), skipMessage, Toast.LENGTH_SHORT).show();
Log.d(TAG, String.format("notifySkipped; message=%s", skipMessage));
if (context != null)
Toast.makeText(context, skipMessage, Toast.LENGTH_SHORT).show();
}
public static float convertDpToPixel(float dp, Context context) {
return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}
@Override
public void onClick(View v) {
PlayerController.onSkipSponsorClicked();
}
}

View file

@ -75,12 +75,12 @@ public class SponsorBlockSettings {
NewSegmentHelperLayout.hide();
SponsorBlockUtils.hideButton();
PlayerController.sponsorSegmentsOfCurrentVideo = null;
} else if (isAddNewSegmentEnabled) {
} else if (/*isAddNewSegmentEnabled*/false) {
SponsorBlockUtils.showButton();
}
isAddNewSegmentEnabled = preferences.getBoolean(PREFERENCES_KEY_NEW_SEGMENT_ENABLED, isAddNewSegmentEnabled);
if (!isAddNewSegmentEnabled) {
if (!/*isAddNewSegmentEnabled*/false) {
NewSegmentHelperLayout.hide();
SponsorBlockUtils.hideButton();
} else {

View file

@ -46,6 +46,7 @@ import java.util.TimeZone;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static fi.razerman.youtube.XGlobals.debug;
import static pl.jakubweg.PlayerController.VERBOSE;
import static pl.jakubweg.PlayerController.getCurrentVideoId;
import static pl.jakubweg.PlayerController.getLastKnownVideoTime;
@ -61,9 +62,12 @@ public abstract class SponsorBlockUtils {
@SuppressLint("SimpleDateFormat")
public static final SimpleDateFormat dateFormatter = new SimpleDateFormat(DATE_FORMAT);
private static final int sponsorBtnId = 1234;
private static final View.OnClickListener sponsorBlockBtnListener = new View.OnClickListener() {
public static final View.OnClickListener sponsorBlockBtnListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (debug) {
Log.d(TAG, "Shield button clicked");
}
NewSegmentHelperLayout.toggle();
}
};
@ -280,102 +284,6 @@ public abstract class SponsorBlockUtils {
i.setVisibility(GONE);
}
@SuppressLint("LongLogTag")
public static void addImageButton(final Activity activity, final int attemptsWhenFail) {
if (VERBOSE)
Log.d(TAG, "addImageButton activity=" + activity + ",attemptsWhenFail=" + attemptsWhenFail);
if (activity == null)
return;
final View existingSponsorBtn = activity.findViewById(sponsorBtnId);
if (existingSponsorBtn != null) {
if (VERBOSE)
Log.d(TAG, "addImageButton: sponsorBtn exists");
if (SponsorBlockSettings.isAddNewSegmentEnabled)
showButton();
return;
}
String packageName = activity.getPackageName();
Resources R = activity.getResources();
shareBtnId = R.getIdentifier("player_share_button", "id", packageName);
// final int addToBtnId = R.getIdentifier("player_addto_button", "id", packageName);
final int addToBtnId = R.getIdentifier("live_chat_overlay_button", "id", packageName);
int titleViewId = R.getIdentifier("player_video_title_view", "id", packageName);
// final int iconId = R.getIdentifier("player_fast_forward", "drawable", packageName);
final int iconId = R.getIdentifier("ic_sb_logo", "drawable", packageName);
final View addToBtn = activity.findViewById(addToBtnId);
final ImageView shareBtn = activity.findViewById(shareBtnId);
final TextView titleView = activity.findViewById(titleViewId);
if (addToBtn == null || shareBtn == null || titleView == null) {
if (VERBOSE)
Log.e(TAG, String.format("one of following is null: addToBtn=%s shareBtn=%s titleView=%s",
addToBtn, shareBtn, titleView));
if (attemptsWhenFail > 0)
new Handler(Looper.getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
if (VERBOSE)
Log.i(TAG, "Retrying addImageButton");
addImageButton(PlayerController.playerActivity.get(), attemptsWhenFail - 1);
}
}, 5000);
return;
}
new Handler(Looper.getMainLooper()).post(new Runnable() {
@Override
public void run() {
try {
Class<?> touchImageViewClass = Class.forName("com.google.android.libraries.youtube.common.ui.TouchImageView");
Constructor<?> constructor = touchImageViewClass.getConstructor(Context.class);
final ImageView instance = ((ImageView) constructor.newInstance(activity));
instance.setImageResource(iconId);
instance.setId(sponsorBtnId);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(shareBtn.getLayoutParams());
layoutParams.addRule(RelativeLayout.LEFT_OF, addToBtnId);
instance.setLayoutParams(layoutParams);
((ViewGroup) shareBtn.getParent()).addView(instance, 0);
instance.setPadding(shareBtn.getPaddingLeft(),
shareBtn.getPaddingTop(),
shareBtn.getPaddingRight(),
shareBtn.getPaddingBottom());
RelativeLayout.LayoutParams titleViewLayoutParams = (RelativeLayout.LayoutParams) titleView.getLayoutParams();
titleViewLayoutParams.addRule(RelativeLayout.START_OF, sponsorBtnId);
titleView.requestLayout();
instance.setClickable(true);
instance.setFocusable(true);
Drawable.ConstantState constantState = shareBtn.getBackground().mutate().getConstantState();
if (constantState != null)
instance.setBackground(constantState.newDrawable());
instance.setOnClickListener(sponsorBlockBtnListener);
sponsorBlockBtn = new WeakReference<>(instance);
isShown = true;
if (!SponsorBlockSettings.isAddNewSegmentEnabled)
hideButton();
if (VERBOSE)
Log.i(TAG, "Image Button added");
} catch (Exception e) {
Log.e(TAG, "Error while adding button", e);
}
}
});
}
@SuppressLint("DefaultLocale")
public static void onMarkLocationClicked(Context context) {
newSponsorSegmentDialogShownMillis = PlayerController.getLastKnownVideoTime();
@ -444,7 +352,7 @@ public abstract class SponsorBlockUtils {
}
public static void notifyShareBtnVisibilityChanged(View v) {
if (v.getId() != shareBtnId || !SponsorBlockSettings.isAddNewSegmentEnabled) return;
if (v.getId() != shareBtnId || !/*SponsorBlockSettings.isAddNewSegmentEnabled*/false) return;
// if (VERBOSE)
// Log.d(TAG, "VISIBILITY CHANGED of view " + v);
ImageView sponsorBtn = sponsorBlockBtn.get();