mirror of
https://github.com/revanced/revanced-integrations.git
synced 2024-12-03 17:22:54 +01:00
feat(youtube/copy-video-url): add tap and hold functionality to copy video url buttons (#403)
This commit is contained in:
parent
71e94e8d67
commit
80689eff5b
@ -2,22 +2,46 @@ package app.revanced.integrations.patches;
|
|||||||
|
|
||||||
import static app.revanced.integrations.utils.StringRef.str;
|
import static app.revanced.integrations.utils.StringRef.str;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
import app.revanced.integrations.utils.ReVancedUtils;
|
import app.revanced.integrations.utils.ReVancedUtils;
|
||||||
|
|
||||||
public class CopyVideoUrlPatch {
|
public class CopyVideoUrlPatch {
|
||||||
public static void copyUrl(Boolean withTimestamp) {
|
|
||||||
|
public static void copyUrl(boolean withTimestamp) {
|
||||||
try {
|
try {
|
||||||
String url = String.format("https://youtu.be/%s", VideoInformation.getVideoId());
|
StringBuilder builder = new StringBuilder("https://youtu.be/");
|
||||||
if (withTimestamp) {
|
builder.append(VideoInformation.getVideoId());
|
||||||
long seconds = VideoInformation.getVideoTime() / 1000;
|
final long currentVideoTimeInSeconds = VideoInformation.getVideoTime() / 1000;
|
||||||
url += String.format("?t=%s", seconds);
|
if (withTimestamp && currentVideoTimeInSeconds > 0) {
|
||||||
|
final long hour = currentVideoTimeInSeconds / (60 * 60);
|
||||||
|
final long minute = (currentVideoTimeInSeconds / 60) % 60;
|
||||||
|
final long second = currentVideoTimeInSeconds % 60;
|
||||||
|
builder.append("?t=");
|
||||||
|
if (hour > 0) {
|
||||||
|
builder.append(hour).append("h");
|
||||||
|
}
|
||||||
|
if (minute > 0) {
|
||||||
|
builder.append(minute).append("m");
|
||||||
|
}
|
||||||
|
if (second > 0) {
|
||||||
|
builder.append(second).append("s");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReVancedUtils.setClipboard(url);
|
ReVancedUtils.setClipboard(builder.toString());
|
||||||
ReVancedUtils.showToastShort(str("share_copy_url_success"));
|
// Do not show a toast if using Android 13+ as it shows it's own toast.
|
||||||
|
// But if the user copied with a timestamp then show a toast.
|
||||||
|
// Unfortunately this will show 2 toasts on Android 13+, but no way around this.
|
||||||
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2 || (withTimestamp && currentVideoTimeInSeconds > 0)) {
|
||||||
|
ReVancedUtils.showToastShort(withTimestamp && currentVideoTimeInSeconds > 0
|
||||||
|
? str("revanced_share_copy_url_timestamp_success")
|
||||||
|
: str("revanced_share_copy_url_success"));
|
||||||
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
LogHelper.printException(() -> "Failed to generate video url", e);
|
LogHelper.printException(() -> "Failed to generate video url", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ public enum SettingsEnum {
|
|||||||
"org.schabi.newpipe" /* NewPipe */, parents(EXTERNAL_DOWNLOADER)),
|
"org.schabi.newpipe" /* NewPipe */, parents(EXTERNAL_DOWNLOADER)),
|
||||||
|
|
||||||
// Copy video URL
|
// Copy video URL
|
||||||
COPY_VIDEO_URL("revanced_copy_video_url", BOOLEAN, TRUE),
|
COPY_VIDEO_URL("revanced_copy_video_url", BOOLEAN, FALSE),
|
||||||
COPY_VIDEO_URL_TIMESTAMP("revanced_copy_video_url_timestamp", BOOLEAN, TRUE),
|
COPY_VIDEO_URL_TIMESTAMP("revanced_copy_video_url_timestamp", BOOLEAN, TRUE),
|
||||||
|
|
||||||
// Video
|
// Video
|
||||||
|
@ -4,14 +4,17 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.view.animation.Animation;
|
import android.view.animation.Animation;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import app.revanced.integrations.settings.SettingsEnum;
|
import androidx.annotation.Nullable;
|
||||||
import app.revanced.integrations.utils.LogHelper;
|
|
||||||
import app.revanced.integrations.utils.ReVancedUtils;
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import app.revanced.integrations.settings.SettingsEnum;
|
||||||
|
import app.revanced.integrations.utils.LogHelper;
|
||||||
|
import app.revanced.integrations.utils.ReVancedUtils;
|
||||||
|
|
||||||
public abstract class BottomControlButton {
|
public abstract class BottomControlButton {
|
||||||
private static final Animation fadeIn;
|
private static final Animation fadeIn;
|
||||||
private static final Animation fadeOut;
|
private static final Animation fadeOut;
|
||||||
@ -40,7 +43,8 @@ public abstract class BottomControlButton {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BottomControlButton(@NonNull ViewGroup bottomControlsViewGroup, @NonNull String imageViewButtonId,
|
public BottomControlButton(@NonNull ViewGroup bottomControlsViewGroup, @NonNull String imageViewButtonId,
|
||||||
@NonNull SettingsEnum booleanSetting, @NonNull View.OnClickListener onClickListener) {
|
@NonNull SettingsEnum booleanSetting, @NonNull View.OnClickListener onClickListener,
|
||||||
|
@Nullable View.OnLongClickListener longClickListener) {
|
||||||
LogHelper.printDebug(() -> "Initializing button: " + imageViewButtonId);
|
LogHelper.printDebug(() -> "Initializing button: " + imageViewButtonId);
|
||||||
|
|
||||||
if (booleanSetting.returnType != SettingsEnum.ReturnType.BOOLEAN) {
|
if (booleanSetting.returnType != SettingsEnum.ReturnType.BOOLEAN) {
|
||||||
@ -53,6 +57,9 @@ public abstract class BottomControlButton {
|
|||||||
ReVancedUtils.getResourceIdentifier(imageViewButtonId, "id")
|
ReVancedUtils.getResourceIdentifier(imageViewButtonId, "id")
|
||||||
));
|
));
|
||||||
imageView.setOnClickListener(onClickListener);
|
imageView.setOnClickListener(onClickListener);
|
||||||
|
if (longClickListener != null) {
|
||||||
|
imageView.setOnLongClickListener(longClickListener);
|
||||||
|
}
|
||||||
imageView.setVisibility(View.GONE);
|
imageView.setVisibility(View.GONE);
|
||||||
|
|
||||||
buttonRef = new WeakReference<>(imageView);
|
buttonRef = new WeakReference<>(imageView);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package app.revanced.integrations.videoplayer;
|
package app.revanced.integrations.videoplayer;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -17,16 +18,20 @@ public class CopyVideoUrlButton extends BottomControlButton {
|
|||||||
viewGroup,
|
viewGroup,
|
||||||
"copy_video_url_button",
|
"copy_video_url_button",
|
||||||
SettingsEnum.COPY_VIDEO_URL,
|
SettingsEnum.COPY_VIDEO_URL,
|
||||||
view -> CopyVideoUrlPatch.copyUrl(false)
|
view -> CopyVideoUrlPatch.copyUrl(false),
|
||||||
|
view -> {
|
||||||
|
CopyVideoUrlPatch.copyUrl(true);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static void initializeButton(Object obj) {
|
public static void initializeButton(View view) {
|
||||||
try {
|
try {
|
||||||
instance = new CopyVideoUrlButton((ViewGroup) obj);
|
instance = new CopyVideoUrlButton((ViewGroup) view);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> "initializeButton failure", ex);
|
LogHelper.printException(() -> "initializeButton failure", ex);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package app.revanced.integrations.videoplayer;
|
package app.revanced.integrations.videoplayer;
|
||||||
|
|
||||||
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
@ -17,14 +18,18 @@ public class CopyVideoUrlTimestampButton extends BottomControlButton {
|
|||||||
bottomControlsViewGroup,
|
bottomControlsViewGroup,
|
||||||
"copy_video_url_timestamp_button",
|
"copy_video_url_timestamp_button",
|
||||||
SettingsEnum.COPY_VIDEO_URL_TIMESTAMP,
|
SettingsEnum.COPY_VIDEO_URL_TIMESTAMP,
|
||||||
view -> CopyVideoUrlPatch.copyUrl(true)
|
view -> CopyVideoUrlPatch.copyUrl(true),
|
||||||
|
view -> {
|
||||||
|
CopyVideoUrlPatch.copyUrl(false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static void initializeButton(Object bottomControlsViewGroup) {
|
public static void initializeButton(View bottomControlsViewGroup) {
|
||||||
try {
|
try {
|
||||||
instance = new CopyVideoUrlTimestampButton((ViewGroup) bottomControlsViewGroup);
|
instance = new CopyVideoUrlTimestampButton((ViewGroup) bottomControlsViewGroup);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
|
@ -22,16 +22,17 @@ public class DownloadButton extends BottomControlButton {
|
|||||||
viewGroup,
|
viewGroup,
|
||||||
"download_button",
|
"download_button",
|
||||||
SettingsEnum.EXTERNAL_DOWNLOADER,
|
SettingsEnum.EXTERNAL_DOWNLOADER,
|
||||||
DownloadButton::onDownloadClick
|
DownloadButton::onDownloadClick,
|
||||||
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injection point.
|
* Injection point.
|
||||||
*/
|
*/
|
||||||
public static void initializeButton(Object obj) {
|
public static void initializeButton(View view) {
|
||||||
try {
|
try {
|
||||||
instance = new DownloadButton((ViewGroup) obj);
|
instance = new DownloadButton((ViewGroup) view);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
LogHelper.printException(() -> "initializeButton failure", ex);
|
LogHelper.printException(() -> "initializeButton failure", ex);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user