Update to 7.9.0 (2384)

This commit is contained in:
DrKLO 2021-07-30 21:49:55 +07:00
parent 7a60f948ae
commit 3e5d2ba92b
170 changed files with 4697 additions and 1390 deletions

View file

@ -25,6 +25,11 @@ import android.os.Build;
import android.text.SpannableString;
import android.text.TextPaint;
import android.text.TextUtils;
import android.transition.ChangeBounds;
import android.transition.Fade;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.transition.TransitionValues;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
@ -33,11 +38,13 @@ import android.view.ViewPropertyAnimator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import org.checkerframework.checker.units.qual.A;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.ui.Adapters.FiltersView;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EllipsizeSpanAnimator;
import org.telegram.ui.Components.FireworksEffect;
import org.telegram.ui.Components.LayoutHelper;
@ -110,6 +117,8 @@ public class ActionBar extends FrameLayout {
private boolean overlayTitleAnimation;
private boolean titleAnimationRunning;
private boolean fromBottom;
private boolean centerScale;
private CharSequence subtitle;
EllipsizeSpanAnimator ellipsizeSpanAnimator = new EllipsizeSpanAnimator(this);
@ -318,9 +327,13 @@ public class ActionBar extends FrameLayout {
createSubtitleTextView();
}
if (subtitleTextView != null) {
subtitleTextView.setVisibility(!TextUtils.isEmpty(value) && !isSearchFieldVisible ? VISIBLE : GONE);
boolean isEmpty = TextUtils.isEmpty(value);
subtitleTextView.setVisibility(!isEmpty && !isSearchFieldVisible ? VISIBLE : GONE);
subtitleTextView.setAlpha(1f);
subtitleTextView.setText(value);
if (!isEmpty) {
subtitleTextView.setText(value);
}
subtitle = value;
}
}
@ -417,10 +430,10 @@ public class ActionBar extends FrameLayout {
}
public String getSubtitle() {
if (subtitleTextView == null) {
if (subtitleTextView == null || subtitle == null) {
return null;
}
return subtitleTextView.getText().toString();
return subtitle.toString();
}
public ActionBarMenu createMenu() {
@ -563,7 +576,7 @@ public class ActionBar extends FrameLayout {
if (titleTextView[0] != null) {
titleTextView[0].setVisibility(INVISIBLE);
}
if (subtitleTextView != null && !TextUtils.isEmpty(subtitleTextView.getText())) {
if (subtitleTextView != null && !TextUtils.isEmpty(subtitle)) {
subtitleTextView.setVisibility(INVISIBLE);
}
if (menu != null) {
@ -632,7 +645,7 @@ public class ActionBar extends FrameLayout {
if (titleTextView[0] != null) {
titleTextView[0].setVisibility(INVISIBLE);
}
if (subtitleTextView != null && !TextUtils.isEmpty(subtitleTextView.getText())) {
if (subtitleTextView != null && !TextUtils.isEmpty(subtitle)) {
subtitleTextView.setVisibility(INVISIBLE);
}
if (menu != null) {
@ -723,7 +736,7 @@ public class ActionBar extends FrameLayout {
if (titleTextView[0] != null) {
titleTextView[0].setVisibility(VISIBLE);
}
if (subtitleTextView != null && !TextUtils.isEmpty(subtitleTextView.getText())) {
if (subtitleTextView != null && !TextUtils.isEmpty(subtitle)) {
subtitleTextView.setVisibility(VISIBLE);
}
}
@ -807,7 +820,7 @@ public class ActionBar extends FrameLayout {
viewsToHide.add(titleTextView[0]);
}
if (subtitleTextView != null && !TextUtils.isEmpty(subtitleTextView.getText())) {
if (subtitleTextView != null && !TextUtils.isEmpty(subtitle)) {
viewsToHide.add(subtitleTextView);
subtitleTextView.setVisibility(visible ? INVISIBLE : VISIBLE);
}
@ -824,7 +837,8 @@ public class ActionBar extends FrameLayout {
searchVisibleAnimator.playTogether(ObjectAnimator.ofFloat(view, View.SCALE_Y, visible ? 0.95f : 1f));
searchVisibleAnimator.playTogether(ObjectAnimator.ofFloat(view, View.SCALE_X, visible ? 0.95f : 1f));
}
centerScale = true;
requestLayout();
searchVisibleAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@ -1002,10 +1016,15 @@ public class ActionBar extends FrameLayout {
}
if (titleTextView[i] != null && titleTextView[i].getVisibility() != GONE) {
CharSequence text = titleTextView[i].getText();
titleTextView[i].setPivotX(titleTextView[i].getTextPaint().measureText(text, 0, text.length()) / 2f);
titleTextView[i].setPivotY((AndroidUtilities.dp(24) >> 1));
titleTextView[i].measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(24), MeasureSpec.AT_MOST));
if (centerScale) {
CharSequence text = titleTextView[i].getText();
titleTextView[i].setPivotX(titleTextView[i].getTextPaint().measureText(text, 0, text.length()) / 2f);
titleTextView[i].setPivotY((AndroidUtilities.dp(24) >> 1));
} else {
titleTextView[i].setPivotX(0);
titleTextView[i].setPivotY(0);
}
}
if (subtitleTextView != null && subtitleTextView.getVisibility() != GONE) {
subtitleTextView.measure(MeasureSpec.makeMeasureSpec(availableWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(20), MeasureSpec.AT_MOST));
@ -1209,6 +1228,8 @@ public class ActionBar extends FrameLayout {
} else {
animator.scaleY(0.7f).scaleX(0.7f);
}
requestLayout();
centerScale = true;
animator.setDuration(220).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@ -1322,7 +1343,7 @@ public class ActionBar extends FrameLayout {
setTitle(title);
return;
}
boolean crossfade = overlayTitleAnimation && !TextUtils.isEmpty(subtitleTextView.getText());
boolean crossfade = overlayTitleAnimation && !TextUtils.isEmpty(subtitle);
if (crossfade) {
if (subtitleTextView.getVisibility() != View.VISIBLE) {
subtitleTextView.setVisibility(View.VISIBLE);
@ -1410,4 +1431,68 @@ public class ActionBar extends FrameLayout {
public void setOverlayTitleAnimation(boolean ovelayTitleAnimation) {
this.overlayTitleAnimation = ovelayTitleAnimation;
}
public void beginDelayedTransition() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
TransitionSet transitionSet = new TransitionSet();
transitionSet.setOrdering(TransitionSet.ORDERING_TOGETHER);
transitionSet.addTransition(new Fade());
transitionSet.addTransition(new ChangeBounds() {
public void captureStartValues(TransitionValues transitionValues) {
super.captureStartValues(transitionValues);
if (transitionValues.view instanceof SimpleTextView) {
float textSize = ((SimpleTextView) transitionValues.view).getTextPaint().getTextSize();
transitionValues.values.put("text_size", textSize);
}
}
public void captureEndValues(TransitionValues transitionValues) {
super.captureEndValues(transitionValues);
if (transitionValues.view instanceof SimpleTextView) {
float textSize= ((SimpleTextView) transitionValues.view).getTextPaint().getTextSize();
transitionValues.values.put("text_size", textSize);
}
}
@Override
public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues, TransitionValues endValues) {
if (startValues.view instanceof SimpleTextView) {
AnimatorSet animatorSet = new AnimatorSet();
Animator animator = super.createAnimator(sceneRoot, startValues, endValues);
float s = (float) startValues.values.get("text_size") / (float) endValues.values.get("text_size");
startValues.view.setScaleX(s);
startValues.view.setScaleY(s);
if (animator != null) {
animatorSet.playTogether(animator);
}
animatorSet.playTogether(ObjectAnimator.ofFloat(startValues.view, SCALE_X, 1f));
animatorSet.playTogether(ObjectAnimator.ofFloat(startValues.view, SCALE_Y, 1f));
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
startValues.view.setLayerType(LAYER_TYPE_HARDWARE, null);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
startValues.view.setLayerType(LAYER_TYPE_NONE, null);
}
});
return animatorSet;
} else {
return super.createAnimator(sceneRoot, startValues, endValues);
}
}
});
centerScale = false;
transitionSet.setDuration(220);
transitionSet.setInterpolator(CubicBezierInterpolator.DEFAULT);
TransitionManager.beginDelayedTransition(this, transitionSet);
}
}
}

View file

@ -271,7 +271,7 @@ public class ActionBarMenuItem extends FrameLayout {
delegate.onItemClick((Integer) selectedMenuView.getTag());
}
popupWindow.dismiss(allowCloseAnimation);
} else {
} else if (showSubmenuByMove) {
popupWindow.dismiss();
}
} else {
@ -1540,6 +1540,16 @@ public class ActionBarMenuItem extends FrameLayout {
}
}
public void hideAllSubItems() {
if (popupLayout == null) {
return;
}
for (int a = 0, N = popupLayout.getItemsCount(); a < N; a++) {
popupLayout.getItemAt(a).setVisibility(GONE);
}
measurePopup = true;
}
public boolean isSubItemVisible(int id) {
if (popupLayout == null) {
return false;

View file

@ -23,6 +23,7 @@ public class ActionBarMenuSubItem extends FrameLayout {
private TextView subtextView;
private ImageView imageView;
private ImageView checkView;
private ImageView rightIcon;
private int textColor = Theme.getColor(Theme.key_actionBarDefaultSubmenuItem);
private int iconColor = Theme.getColor(Theme.key_actionBarDefaultSubmenuItemIcon);
@ -88,6 +89,20 @@ public class ActionBarMenuSubItem extends FrameLayout {
checkView.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
}
public void setRightIcon(int icon) {
if (rightIcon == null) {
rightIcon = new ImageView(getContext());
rightIcon.setScaleType(ImageView.ScaleType.CENTER);
rightIcon.setColorFilter(textColor, PorterDuff.Mode.MULTIPLY);
if (LocaleController.isRTL) {
rightIcon.setScaleX(-1);
}
addView(rightIcon, LayoutHelper.createFrame(24, LayoutHelper.MATCH_PARENT, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.LEFT : Gravity.RIGHT)));
}
setPadding(AndroidUtilities.dp(LocaleController.isRTL ? 8 : 18), 0, AndroidUtilities.dp(LocaleController.isRTL ? 18 : 8), 0);
rightIcon.setImageResource(icon);
}
public void setTextAndIcon(CharSequence text, int icon) {
setTextAndIcon(text, icon, null);
}
@ -108,9 +123,10 @@ public class ActionBarMenuSubItem extends FrameLayout {
}
}
public void setColors(int textColor, int iconColor) {
public ActionBarMenuSubItem setColors(int textColor, int iconColor) {
setTextColor(textColor);
setIconColor(iconColor);
return this;
}
public void setTextColor(int textColor) {

View file

@ -14,6 +14,8 @@ import android.view.Window;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import androidx.recyclerview.widget.ChatListItemAnimator;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.SharedConfig;
@ -24,7 +26,7 @@ import java.util.ArrayList;
public class AdjustPanLayoutHelper {
public final static Interpolator keyboardInterpolator = CubicBezierInterpolator.DEFAULT;
public final static Interpolator keyboardInterpolator = ChatListItemAnimator.DEFAULT_INTERPOLATOR;
public final static long keyboardDuration = 250;
private final View parent;
@ -33,6 +35,15 @@ public class AdjustPanLayoutHelper {
private ViewGroup contentView;
private View resizableView;
private boolean animationInProgress;
private boolean needDelay;
private Runnable delayedAnimationRunnable = new Runnable() {
@Override
public void run() {
if (animator != null && !animator.isRunning()) {
animator.start();
}
}
};
int previousHeight = -1;
int previousContentHeight = -1;
@ -148,11 +159,16 @@ public class AdjustPanLayoutHelper {
onTransitionEnd();
}
});
animator.setDuration(220);
animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
animator.setDuration(keyboardDuration);
animator.setInterpolator(keyboardInterpolator);
notificationsIndex = NotificationCenter.getInstance(selectedAccount).setAnimationInProgress(notificationsIndex, null);
animator.start();
if (needDelay) {
needDelay = false;
AndroidUtilities.runOnUIThread(delayedAnimationRunnable, 100);
} else {
animator.start();
}
}
private void setViewHeight(int height) {
@ -269,4 +285,13 @@ public class AdjustPanLayoutHelper {
public void setCheckHierarchyHeight(boolean checkHierarchyHeight) {
this.checkHierarchyHeight = checkHierarchyHeight;
}
public void delayAnimation() {
needDelay = true;
}
public void runDelayedAnimation() {
AndroidUtilities.cancelRunOnUIThread(delayedAnimationRunnable);
delayedAnimationRunnable.run();
}
}

View file

@ -17,6 +17,7 @@ import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MotionEvent;

View file

@ -32,6 +32,7 @@ import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.PorterDuffXfermode;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
@ -100,6 +101,7 @@ import org.telegram.ui.Components.StatusDrawable;
import org.telegram.messenger.SvgHelper;
import org.telegram.ui.Components.ThemeEditorView;
import org.telegram.ui.Components.TypingDotsDrawable;
import org.telegram.ui.RoundVideoProgressShadow;
import java.io.File;
import java.io.FileInputStream;
@ -121,6 +123,7 @@ import java.util.concurrent.CountDownLatch;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
public class Theme {
@ -2218,6 +2221,9 @@ public class Theme {
public static Paint chat_composeBackgroundPaint;
public static Paint chat_radialProgressPaint;
public static Paint chat_radialProgress2Paint;
public static Paint chat_radialProgressPausedPaint;
public static Paint chat_radialProgressPausedSeekbarPaint;
public static TextPaint chat_msgTextPaint;
public static TextPaint chat_actionTextPaint;
public static TextPaint chat_msgBotButtonPaint;
@ -3163,6 +3169,9 @@ public class Theme {
private static ThreadLocal<float[]> hsvTemp4Local = new ThreadLocal<>();
private static ThreadLocal<float[]> hsvTemp5Local = new ThreadLocal<>();
private static FragmentContextViewWavesDrawable fragmentContextViewWavesDrawable;
private static RoundVideoProgressShadow roundPlayDrawable;
static {
defaultColors.put(key_dialogBackground, 0xffffffff);
defaultColors.put(key_dialogBackgroundGray, 0xfff0f0f0);
@ -7462,6 +7471,8 @@ public class Theme {
chat_contextResult_titleTextPaint.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
chat_contextResult_descriptionTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
chat_composeBackgroundPaint = new Paint();
chat_radialProgressPausedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
chat_radialProgressPausedSeekbarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
}
}
@ -9007,12 +9018,17 @@ public class Theme {
return statusDrawable;
}
private static FragmentContextViewWavesDrawable fragmentContextViewWavesDrawable;
public static FragmentContextViewWavesDrawable getFragmentContextViewWavesDrawable() {
if (fragmentContextViewWavesDrawable == null) {
fragmentContextViewWavesDrawable = new FragmentContextViewWavesDrawable();
}
return fragmentContextViewWavesDrawable;
}
public static RoundVideoProgressShadow getRadialSeekbarShadowDrawable() {
if (roundPlayDrawable == null) {
roundPlayDrawable = new RoundVideoProgressShadow();
}
return roundPlayDrawable;
}
}

View file

@ -8,8 +8,11 @@
package org.telegram.ui;
import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;
@ -22,17 +25,23 @@ import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.camera.CameraController;
import org.telegram.ui.ActionBar.ActionBarLayout;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.DrawerLayoutContainer;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.PasscodeView;
import org.telegram.ui.Components.ThemeEditorView;
import java.util.ArrayList;
@ -231,6 +240,106 @@ public class BubbleActivity extends Activity implements ActionBarLayout.ActionBa
onFinish();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ThemeEditorView editorView = ThemeEditorView.getInstance();
if (editorView != null) {
editorView.onActivityResult(requestCode, resultCode, data);
}
if (actionBarLayout.fragmentsStack.size() != 0) {
BaseFragment fragment = actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1);
fragment.onActivityResultFragment(requestCode, resultCode, data);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults == null) {
grantResults = new int[0];
}
if (permissions == null) {
permissions = new String[0];
}
boolean granted = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (requestCode == 104) {
if (granted) {
if (GroupCallActivity.groupCallInstance != null) {
GroupCallActivity.groupCallInstance.enableCamera();
}
} else {
showPermissionErrorAlert(LocaleController.getString("VoipNeedCameraPermission", R.string.VoipNeedCameraPermission));
}
} else if (requestCode == 4) {
if (!granted) {
showPermissionErrorAlert(LocaleController.getString("PermissionStorage", R.string.PermissionStorage));
} else {
ImageLoader.getInstance().checkMediaPaths();
}
} else if (requestCode == 5) {
if (!granted) {
showPermissionErrorAlert(LocaleController.getString("PermissionContacts", R.string.PermissionContacts));
return;
} else {
ContactsController.getInstance(currentAccount).forceImportContacts();
}
} else if (requestCode == 3) {
boolean audioGranted = true;
boolean cameraGranted = true;
for (int i = 0, size = Math.min(permissions.length, grantResults.length); i < size; i++) {
if (Manifest.permission.RECORD_AUDIO.equals(permissions[i])) {
audioGranted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
} else if (Manifest.permission.CAMERA.equals(permissions[i])) {
cameraGranted = grantResults[i] == PackageManager.PERMISSION_GRANTED;
}
}
if (!audioGranted) {
showPermissionErrorAlert(LocaleController.getString("PermissionNoAudio", R.string.PermissionNoAudio));
} else if (!cameraGranted) {
showPermissionErrorAlert(LocaleController.getString("PermissionNoCamera", R.string.PermissionNoCamera));
} else {
if (SharedConfig.inappCamera) {
CameraController.getInstance().initCamera(null);
}
return;
}
} else if (requestCode == 18 || requestCode == 19 || requestCode == 20 || requestCode == 22) {
if (!granted) {
showPermissionErrorAlert(LocaleController.getString("PermissionNoCamera", R.string.PermissionNoCamera));
}
} else if (requestCode == 2) {
if (granted) {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.locationPermissionGranted);
}
}
if (actionBarLayout.fragmentsStack.size() != 0) {
BaseFragment fragment = actionBarLayout.fragmentsStack.get(actionBarLayout.fragmentsStack.size() - 1);
fragment.onRequestPermissionsResultFragment(requestCode, permissions, grantResults);
}
VoIPFragment.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
private void showPermissionErrorAlert(String message) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));
builder.setMessage(message);
builder.setNegativeButton(LocaleController.getString("PermissionOpenSettings", R.string.PermissionOpenSettings), (dialog, which) -> {
try {
Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + ApplicationLoader.applicationContext.getPackageName()));
startActivity(intent);
} catch (Exception e) {
FileLog.e(e);
}
});
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), null);
builder.show();
}
@Override
protected void onResume() {
super.onResume();

View file

@ -96,7 +96,11 @@ public class AboutLinkCell extends FrameLayout {
if (TextUtils.isEmpty(text) || TextUtils.equals(text, oldText)) {
return;
}
oldText = text;
try {
oldText = AndroidUtilities.getSafeString(text);
} catch (Throwable e) {
oldText = text;
}
stringBuilder = new SpannableStringBuilder(oldText);
MessageObject.addLinks(false, stringBuilder, false, false, !parseLinks);
Emoji.replaceEmoji(stringBuilder, Theme.profile_aboutTextPaint.getFontMetricsInt(), AndroidUtilities.dp(20), false);

View file

@ -10,7 +10,6 @@ import android.view.ViewGroup;
import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.FileLog;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.BottomPagesView;
import org.telegram.ui.Components.LayoutHelper;
@ -54,12 +53,12 @@ public class ArchiveHintCell extends FrameLayout {
@Override
public void onPageSelected(int i) {
FileLog.d("test1");
}
@Override
public void onPageScrollStateChanged(int i) {
FileLog.d("test1");
}
});

View file

@ -34,10 +34,11 @@ public abstract class BaseCell extends ViewGroup {
if (checkingForLongPress && getParent() != null && currentPressCount == pressCount) {
checkingForLongPress = false;
performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
onLongPress();
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
onTouchEvent(event);
event.recycle();
if (onLongPress()) {
MotionEvent event = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
onTouchEvent(event);
event.recycle();
}
}
}
}
@ -99,7 +100,7 @@ public abstract class BaseCell extends ViewGroup {
return false;
}
protected void onLongPress() {
protected boolean onLongPress() {
return true;
}
}

View file

@ -78,7 +78,7 @@ public class BotHelpCell extends View {
if (text != null && text.equals(oldText)) {
return;
}
oldText = text;
oldText = AndroidUtilities.getSafeString(text);
setVisibility(VISIBLE);
int maxWidth;
if (AndroidUtilities.isTablet()) {

View file

@ -246,10 +246,11 @@ public class ChatActionCell extends BaseCell implements DownloadController.FileD
}
@Override
protected void onLongPress() {
protected boolean onLongPress() {
if (delegate != null) {
delegate.didLongPress(this, lastTouchX, lastTouchY);
}
return true;
}
@Override

View file

@ -19,6 +19,7 @@ import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@ -28,13 +29,16 @@ import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.RadialGradient;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.RippleDrawable;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
@ -67,6 +71,8 @@ import android.widget.Toast;
import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.util.Log;
import org.telegram.PhoneFormat.PhoneFormat;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
@ -92,6 +98,7 @@ import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.WebFile;
import org.telegram.messenger.browser.Browser;
import org.telegram.messenger.video.VideoPlayerRewinder;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
@ -112,6 +119,7 @@ import org.telegram.ui.Components.LinkPath;
import org.telegram.ui.Components.MediaActionDrawable;
import org.telegram.ui.Components.MessageBackgroundDrawable;
import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.PlayPauseDrawable;
import org.telegram.ui.Components.Point;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RadialProgress2;
@ -128,8 +136,10 @@ import org.telegram.ui.Components.URLSpanBotCommand;
import org.telegram.ui.Components.URLSpanBrowser;
import org.telegram.ui.Components.URLSpanMono;
import org.telegram.ui.Components.URLSpanNoUnderline;
import org.telegram.ui.Components.VideoForwardDrawable;
import org.telegram.ui.PhotoViewer;
import org.telegram.ui.PinchToZoomHelper;
import org.telegram.ui.RoundVideoProgressShadow;
import org.telegram.ui.SecretMediaViewer;
import java.io.File;
@ -184,7 +194,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
default void didPressUrl(ChatMessageCell cell, CharacterStyle url, boolean longPress) {
}
default void needOpenWebView(String url, String title, String description, String originalUrl, int w, int h) {
default void needOpenWebView(MessageObject message, String url, String title, String description, String originalUrl, int w, int h) {
}
default void didPressImage(ChatMessageCell cell, float x, float y) {
@ -266,6 +276,13 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return null;
}
default boolean keyboardIsOpened() {
return false;
}
default boolean isLandscape() {
return false;
}
}
private final static int DOCUMENT_ATTACH_TYPE_NONE = 0;
@ -792,9 +809,27 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
};
private SparseArray<Rect> accessibilityVirtualViewBounds = new SparseArray<>();
private boolean isRoundVideo;
private boolean isPlayingRound;
private float roundProgressAlpha;
private float roundToPauseProgress;
private float roundToPauseProgress2;
private float roundPlayingDrawableProgress;
private long lastSeekUpdateTime;
float seekbarRoundX;
float seekbarRoundY;
float lastDrawingPlayPauseAlpha;
int roundSeekbarTouched;
float roundSeekbarOutProgress;
float roundSeekbarOutAlpha;
private float lastDrawingAudioProgress;
private int currentFocusedVirtualView = -1;
public boolean drawFromPinchToZoom;
VideoForwardDrawable videoForwardDrawable;
VideoPlayerRewinder videoPlayerRewinder;
public ChatMessageCell(Context context) {
super(context);
@ -1365,7 +1400,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
TLRPC.WebPage webPage = currentMessageObject.messageOwner.media.webpage;
if (webPage != null && !TextUtils.isEmpty(webPage.embed_url)) {
delegate.needOpenWebView(webPage.embed_url, webPage.site_name, webPage.title, webPage.url, webPage.embed_width, webPage.embed_height);
delegate.needOpenWebView(currentMessageObject, webPage.embed_url, webPage.site_name, webPage.title, webPage.url, webPage.embed_width, webPage.embed_height);
} else if (buttonState == -1 || buttonState == 3) {
delegate.didPressImage(this, lastTouchX, lastTouchY);
playSoundEffect(SoundEffectConstants.CLICK);
@ -1703,6 +1738,74 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return result;
}
private boolean checkRoundSeekbar(MotionEvent event) {
if (!MediaController.getInstance().isPlayingMessage(currentMessageObject) || !MediaController.getInstance().isMessagePaused()) {
return false;
}
int x = (int) event.getX();
int y = (int) event.getY();
if (event.getAction() == MotionEvent.ACTION_DOWN) {
if (x >= seekbarRoundX - AndroidUtilities.dp(20) && x <= seekbarRoundX + AndroidUtilities.dp(20) && y >= seekbarRoundY - AndroidUtilities.dp(20) && y <= seekbarRoundY + AndroidUtilities.dp(20)) {
getParent().requestDisallowInterceptTouchEvent(true);
cancelCheckLongPress();
roundSeekbarTouched = 1;
invalidate();
} else {
float localX = x - photoImage.getCenterX();
float localY = y - photoImage.getCenterY();
float r2 = (photoImage.getImageWidth() - AndroidUtilities.dp(64)) / 2;
if (localX * localX + localY * localY < photoImage.getImageWidth() / 2 * photoImage.getImageWidth() / 2 && localX * localX + localY * localY > r2 * r2) {
getParent().requestDisallowInterceptTouchEvent(true);
cancelCheckLongPress();
roundSeekbarTouched = 1;
invalidate();
}
}
} else if (roundSeekbarTouched == 1 && event.getAction() == MotionEvent.ACTION_MOVE) {
float localX = x - photoImage.getCenterX();
float localY = y - photoImage.getCenterY();
float a = (float) Math.toDegrees(Math.atan2(localY, localX)) + 90;
if (a < 0) {
a += 360;
}
float p = a / 360f;
if (Math.abs(currentMessageObject.audioProgress - p) > 0.9f) {
if (roundSeekbarOutAlpha == 0) {
performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP);
}
roundSeekbarOutAlpha = 1f;
roundSeekbarOutProgress = currentMessageObject.audioProgress;
}
long currentTime = System.currentTimeMillis();
if (currentTime - lastSeekUpdateTime > 100) {
MediaController.getInstance().seekToProgress(currentMessageObject, p);
lastSeekUpdateTime = currentTime;
}
currentMessageObject.audioProgress = p;
updatePlayingMessageProgress();
} if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
if (roundSeekbarTouched != 0) {
if (event.getAction() == MotionEvent.ACTION_UP) {
float localX = x - photoImage.getCenterX();
float localY = y - photoImage.getCenterY();
float a = (float) Math.toDegrees(Math.atan2(localY, localX)) + 90;
if (a < 0) {
a += 360;
}
float p = a / 360f;
currentMessageObject.audioProgress = p;
MediaController.getInstance().seekToProgress(currentMessageObject, p);
updatePlayingMessageProgress();
}
MediaController.getInstance().playMessage(currentMessageObject);
roundSeekbarTouched = 0;
getParent().requestDisallowInterceptTouchEvent(false);
}
}
return roundSeekbarTouched != 0;
}
private boolean checkPhotoImageMotionEvent(MotionEvent event) {
if (!drawPhotoImage && documentAttachType != DOCUMENT_ATTACH_TYPE_DOCUMENT || currentMessageObject.isSending() && buttonState != 1) {
return false;
@ -1740,8 +1843,15 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
} else if (!currentMessageObject.isAnyKindOfSticker() || currentMessageObject.getInputStickerSet() != null || currentMessageObject.isAnimatedEmoji() || currentMessageObject.isDice()) {
if (x >= photoImage.getImageX() && x <= photoImage.getImageX() + photoImage.getImageWidth() && y >= photoImage.getImageY() && y <= photoImage.getImageY() + photoImage.getImageHeight()) {
imagePressed = true;
result = true;
if (isRoundVideo) {
if ((x - photoImage.getCenterX()) * (x - photoImage.getCenterX()) + (y - photoImage.getCenterY()) * (y - photoImage.getCenterY()) < (photoImage.getImageWidth() / 2f) * (photoImage.getImageWidth() / 2)) {
imagePressed = true;
result = true;
}
} else {
imagePressed = true;
result = true;
}
}
if (currentMessageObject.type == 12) {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(currentMessageObject.messageOwner.media.user_id);
@ -1942,6 +2052,19 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return true;
}
if (checkRoundSeekbar(event)) {
return true;
}
if (videoPlayerRewinder != null && videoPlayerRewinder.rewindCount > 0) {
if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
getParent().requestDisallowInterceptTouchEvent(false);
videoPlayerRewinder.cancelRewind();
return false;
}
return true;
}
disallowLongPress = false;
lastTouchX = event.getX();
lastTouchY = event.getY();
@ -2324,7 +2447,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentMessageObject == null) {
return;
}
if (videoPlayerRewinder != null && videoPlayerRewinder.rewindCount != 0 && videoPlayerRewinder.rewindByBackSeek) {
currentMessageObject.audioProgress = videoPlayerRewinder.getVideoProgress();
}
if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO) {
if (infoLayout != null && (PhotoViewer.isPlayingMessage(currentMessageObject) || MediaController.getInstance().isGoingToShowMessageObject(currentMessageObject))) {
return;
@ -2374,8 +2499,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
String timeString = AndroidUtilities.formatLongDuration(duration);
timeWidthAudio = (int) Math.ceil(Theme.chat_timePaint.measureText(timeString));
durationLayout = new StaticLayout(timeString, Theme.chat_timePaint, timeWidthAudio, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, false);
invalidate();
}
if (currentMessageObject.audioProgress != 0) {
lastDrawingAudioProgress = currentMessageObject.audioProgress;
if (lastDrawingAudioProgress > 0.9f) {
lastDrawingAudioProgress = 1f;
}
}
invalidate();
} else if (documentAttach != null) {
if (useSeekBarWaweform) {
if (!seekBarWaveform.isDragging()) {
@ -2566,7 +2697,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
TLRPC.WebPage webPage = currentMessageObject.messageOwner.media.webpage;
if (webPage != null) {
if (webPage.embed_url != null && webPage.embed_url.length() != 0) {
delegate.needOpenWebView(webPage.embed_url, webPage.site_name, webPage.description, webPage.url, webPage.embed_width, webPage.embed_height);
delegate.needOpenWebView(currentMessageObject, webPage.embed_url, webPage.site_name, webPage.description, webPage.url, webPage.embed_width, webPage.embed_height);
} else {
Browser.openUrl(getContext(), webPage.url);
}
@ -2880,7 +3011,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
updateButtonState(false, false, false);
}
if (currentMessageObject != null && (isRoundVideo || currentMessageObject.isVideo())) {
checkVideoPlayback(true);
checkVideoPlayback(true, null);
}
if (documentAttachType == DOCUMENT_ATTACH_TYPE_VIDEO && autoPlayingMedia) {
animatingNoSoundPlaying = MediaController.getInstance().isPlayingMessage(currentMessageObject);
@ -2909,7 +3040,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
lastHeight = AndroidUtilities.displaySize.y;
isRoundVideo = messageObject != null && messageObject.isRoundVideo();
boolean messageIdChanged = currentMessageObject == null || currentMessageObject.getId() != messageObject.getId();
boolean messageChanged = currentMessageObject != messageObject || messageObject.forceUpdate;
boolean messageChanged = currentMessageObject != messageObject || messageObject.forceUpdate || (isRoundVideo && isPlayingRound != (MediaController.getInstance().isPlayingMessage(currentMessageObject) && delegate != null && !delegate.keyboardIsOpened()));
boolean dataChanged = currentMessageObject != null && currentMessageObject.getId() == messageObject.getId() && lastSendState == MessageObject.MESSAGE_SEND_STATE_EDITING && messageObject.isSent()
|| currentMessageObject == messageObject && (isUserDataChanged() || photoNotSet)
|| lastPostAuthor != messageObject.messageOwner.post_author
@ -2990,6 +3121,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawPinnedBottom = pinnedBottom && (currentPosition == null || (currentPosition.flags & MessageObject.POSITION_FLAG_BOTTOM) != 0);
}
isPlayingRound = isRoundVideo && MediaController.getInstance().isPlayingMessage(currentMessageObject) && delegate != null && !delegate.keyboardIsOpened() && !delegate.isLandscape();
photoImage.setCrossfadeWithOldImage(false);
photoImage.setCrossfadeDuration(ImageReceiver.DEFAULT_CROSSFADE_DURATION);
photoImage.setGradientBitmap(null);
@ -5037,7 +5169,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
int w;
int h;
if (messageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
w = h = AndroidUtilities.roundMessageSize;
if (isPlayingRound) {
w = h = AndroidUtilities.roundPlayingMessageSize;
} else {
w = h = AndroidUtilities.roundMessageSize;
}
} else {
TLRPC.PhotoSize size = currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb;
int imageW = 0;
@ -5462,7 +5598,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (localFile == 0 && videoSize != null && (currentPhotoObject == null || currentPhotoObjectThumb == null)) {
/*TODO*/photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForDocument(videoSize, documentAttach), null, ImageLocation.getForDocument(currentPhotoObject != null ? currentPhotoObject : currentPhotoObjectThumb, documentAttach), currentPhotoObject != null ? currentPhotoFilter : currentPhotoFilterThumb, null, document.size, null, messageObject, 0);
} else {
/*TODO*/photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, null, document.size, null, messageObject, 0);
if (isRoundVideo && !messageIdChanged && photoImage.hasStaticThumb()) {
/*TODO*/photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, null, null, photoImage.getStaticThumb(), document.size, null, messageObject, 0);
} else {
/*TODO*/photoImage.setImage(ImageLocation.getForDocument(document), ImageLoader.AUTOPLAY_FILTER, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, null, document.size, null, messageObject, 0);
}
}
} else if (localFile == 1) {
/*TODO*/photoImage.setImage(ImageLocation.getForPath(messageObject.isSendError() ? null : messageObject.messageOwner.attachPath), null, ImageLocation.getForObject(currentPhotoObject, photoParentObject), currentPhotoFilter, ImageLocation.getForObject(currentPhotoObjectThumb, photoParentObject), currentPhotoFilterThumb, null, 0, null, messageObject, 0);
@ -5923,9 +6063,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
delegate.getTextSelectionHelper().checkDataChanged(messageObject);
}
accessibilityVirtualViewBounds.clear();
transitionParams.updatePhotoImageX = true;
}
public void checkVideoPlayback(boolean allowStart) {
public void checkVideoPlayback(boolean allowStart, Bitmap thumb) {
if (currentMessageObject.isVideo()) {
if (MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
photoImage.setAllowStartAnimation(false);
@ -5940,28 +6081,81 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
allowStart = playingMessage == null || !playingMessage.isRoundVideo();
}
photoImage.setAllowStartAnimation(allowStart);
if (thumb != null) {
photoImage.startCrossfadeFromStaticThumb(thumb);
}
if (allowStart) {
photoImage.startAnimation();
} else {
photoImage.stopAnimation();
}
}
}
@Override
protected void onLongPress() {
protected boolean onLongPress() {
if (isRoundVideo && isPlayingRound && MediaController.getInstance().isPlayingMessage(currentMessageObject)) {
float touchRadius = (lastTouchX - photoImage.getCenterX()) * (lastTouchX - photoImage.getCenterX()) + (lastTouchY - photoImage.getCenterY()) * (lastTouchY - photoImage.getCenterY());
float r1 = (photoImage.getImageWidth() / 2f) * (photoImage.getImageWidth() / 2f);
if (touchRadius < r1 && (lastTouchX > photoImage.getCenterX() + photoImage.getImageWidth() / 4f || lastTouchX < photoImage.getCenterX() - photoImage.getImageWidth() / 4f)) {
boolean forward = lastTouchX > photoImage.getCenterX();
if (videoPlayerRewinder == null) {
videoForwardDrawable = new VideoForwardDrawable(true);
videoPlayerRewinder = new VideoPlayerRewinder() {
@Override
protected void onRewindCanceled() {
onTouchEvent(MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0));
videoForwardDrawable.setShowing(false);
}
@Override
protected void updateRewindProgressUi(long timeDiff, float progress, boolean rewindByBackSeek) {
videoForwardDrawable.setTime(Math.abs(timeDiff));
if (rewindByBackSeek) {
currentMessageObject.audioProgress = progress;
updatePlayingMessageProgress();
}
}
@Override
protected void onRewindStart(boolean rewindForward) {
videoForwardDrawable.setDelegate(new VideoForwardDrawable.VideoForwardDrawableDelegate() {
@Override
public void onAnimationEnd() {
}
@Override
public void invalidate() {
ChatMessageCell.this.invalidate();
}
});
videoForwardDrawable.setOneShootAnimation(false);
videoForwardDrawable.setLeftSide(!rewindForward);
videoForwardDrawable.setShowing(true);
invalidate();
}
};
getParent().requestDisallowInterceptTouchEvent(true);
}
videoPlayerRewinder.startRewind(MediaController.getInstance().getVideoPlayer(), forward, MediaController.getInstance().getPlaybackSpeed(false));
return false;
}
}
if (pressedLink instanceof URLSpanMono) {
delegate.didPressUrl(this, pressedLink, true);
return;
return true;
} else if (pressedLink instanceof URLSpanNoUnderline) {
URLSpanNoUnderline url = (URLSpanNoUnderline) pressedLink;
if (ChatActivity.isClickableLink(url.getURL()) || url.getURL().startsWith("/")) {
delegate.didPressUrl(this, pressedLink, true);
return;
return true;
}
} else if (pressedLink instanceof URLSpan) {
delegate.didPressUrl(this, pressedLink, true);
return;
return true;
}
resetPressedLink(-1);
if (buttonPressed != 0 || miniButtonPressed != 0 || videoButtonPressed != 0 || pressedBotButton != -1) {
@ -6020,6 +6214,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
delegate.didLongPress(this, lastTouchX, lastTouchY);
}
}
return true;
}
public void showHintButton(boolean show, boolean animated, int type) {
@ -6706,6 +6901,9 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (!currentMessageObject.isOutOwner() && (!mediaBackground || captionLayout != null) && SharedConfig.bubbleRadius > 11) {
return AndroidUtilities.dp((SharedConfig.bubbleRadius - 11) / 1.5f);
}
if (!currentMessageObject.isOutOwner() && isPlayingRound && isAvatarVisible && currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
return (int) ((AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f);
}
return 0;
}
@ -6897,7 +7095,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
x = layoutWidth - backgroundWidth + AndroidUtilities.dp(6);
}
} else {
if (isChat && isAvatarVisible) {
if (isChat && isAvatarVisible && !isPlayingRound) {
x = AndroidUtilities.dp(63);
} else {
x = AndroidUtilities.dp(15);
@ -6918,7 +7116,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (currentMessageObject.type != 0) {
x -= AndroidUtilities.dp(2);
}
photoImage.setImageCoords((float) x, photoImage.getImageY(), photoImage.getImageWidth(), photoImage.getImageHeight());
if (!transitionParams.imageChangeBoundsTransition || transitionParams.updatePhotoImageX) {
transitionParams.updatePhotoImageX = false;
photoImage.setImageCoords((float) x, photoImage.getImageY(), photoImage.getImageWidth(), photoImage.getImageHeight());
}
buttonX = (int) (x + (photoImage.getImageWidth() - AndroidUtilities.dp(48)) / 2.0f);
buttonY = (int) (photoImage.getImageY() + (photoImage.getImageHeight() - AndroidUtilities.dp(48)) / 2);
radialProgress.setProgressRect(buttonX, buttonY, buttonX + AndroidUtilities.dp(48), buttonY + AndroidUtilities.dp(48));
@ -6936,8 +7137,105 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
public void drawRoundProgress(Canvas canvas) {
rect.set(photoImage.getImageX() + AndroidUtilities.dpf2(1.5f), photoImage.getImageY() + AndroidUtilities.dpf2(1.5f), photoImage.getImageX2() - AndroidUtilities.dpf2(1.5f), photoImage.getImageY2() - AndroidUtilities.dpf2(1.5f));
canvas.drawArc(rect, -90, 360 * currentMessageObject.audioProgress, false, Theme.chat_radialProgressPaint);
float inset = isPlayingRound ? AndroidUtilities.dp(4) : 0;
boolean drawPause = MediaController.getInstance().isPlayingMessage(currentMessageObject) && MediaController.getInstance().isMessagePaused();
boolean drawTouchedSeekbar = drawPause && roundSeekbarTouched == 1;
if (drawPause && roundToPauseProgress != 1f) {
roundToPauseProgress += 16 / 220f;
if (roundToPauseProgress > 1f) {
roundToPauseProgress = 1f;
} else {
invalidate();
}
} else if (!drawPause && roundToPauseProgress != 0f){
roundToPauseProgress -= 16 / 150f;
if (roundToPauseProgress < 0) {
roundToPauseProgress = 0f;
} else {
invalidate();
}
}
if (drawTouchedSeekbar && roundToPauseProgress2 != 1f) {
roundToPauseProgress2 += 16 / 150f;
if (roundToPauseProgress2 > 1f) {
roundToPauseProgress2 = 1f;
} else {
invalidate();
}
} else if (!drawTouchedSeekbar && roundToPauseProgress2 != 0f){
roundToPauseProgress2 -= 16 / 150f;
if (roundToPauseProgress2 < 0) {
roundToPauseProgress2 = 0f;
} else {
invalidate();
}
}
float pauseProgress = drawPause ? AndroidUtilities.overshootInterpolator.getInterpolation(roundToPauseProgress) : roundToPauseProgress;
if (transitionParams.animatePlayingRound) {
inset = (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)) * AndroidUtilities.dp(4);
}
inset += AndroidUtilities.dp(16) * pauseProgress;
if (roundToPauseProgress > 0) {
float r = photoImage.getImageWidth() / 2f;
Theme.getRadialSeekbarShadowDrawable().draw(canvas, photoImage.getCenterX(), photoImage.getCenterY(), r, roundToPauseProgress);
}
rect.set(photoImage.getImageX() + AndroidUtilities.dpf2(1.5f) + inset, photoImage.getImageY() + AndroidUtilities.dpf2(1.5f) + inset, photoImage.getImageX2() - AndroidUtilities.dpf2(1.5f) - inset, photoImage.getImageY2() - AndroidUtilities.dpf2(1.5f) - inset);
int oldAplha = -1;
if (roundProgressAlpha != 1f) {
oldAplha = Theme.chat_radialProgressPaint.getAlpha();
Theme.chat_radialProgressPaint.setAlpha((int) (roundProgressAlpha * oldAplha));
}
if (videoForwardDrawable != null && videoForwardDrawable.isAnimating()) {
videoForwardDrawable.setBounds((int) photoImage.getImageX(), (int) photoImage.getImageY(), (int) (photoImage.getImageX() + photoImage.getImageWidth()), (int) (photoImage.getImageY() + photoImage.getImageHeight()));
videoForwardDrawable.draw(canvas);
}
int paintAlpha = Theme.chat_radialProgressPaint.getAlpha();
float paintWidth = Theme.chat_radialProgressPaint.getStrokeWidth();
float audioProgress = roundProgressAlpha == 1f ? currentMessageObject.audioProgress : lastDrawingAudioProgress;
if (pauseProgress > 0) {
float radius = rect.width() / 2f;
Theme.chat_radialProgressPaint.setStrokeWidth(paintWidth + paintWidth * 0.5f * roundToPauseProgress);
Theme.chat_radialProgressPaint.setAlpha((int) (paintAlpha * roundToPauseProgress * 0.3f));
canvas.drawCircle(rect.centerX(), rect.centerY(), radius, Theme.chat_radialProgressPaint);
Theme.chat_radialProgressPaint.setAlpha(paintAlpha);
seekbarRoundX = (float) (rect.centerX() + Math.sin(Math.toRadians(-360 * audioProgress + 180)) * radius);
seekbarRoundY = (float) (rect.centerY() + Math.cos(Math.toRadians(-360 * audioProgress + 180)) * radius);
Theme.chat_radialProgressPausedSeekbarPaint.setColor(Color.WHITE);
Theme.chat_radialProgressPausedSeekbarPaint.setAlpha((int) (255 * Math.min(1f, pauseProgress)));
canvas.drawCircle(seekbarRoundX, seekbarRoundY, AndroidUtilities.dp(3) + AndroidUtilities.dp(5) * pauseProgress + AndroidUtilities.dp(3) * roundToPauseProgress2, Theme.chat_radialProgressPausedSeekbarPaint);
}
if (roundSeekbarOutAlpha != 0f) {
roundSeekbarOutAlpha -= 16f / 150f;
if (roundSeekbarOutAlpha < 0) {
roundSeekbarOutAlpha = 0f;
} else {
invalidate();
}
}
if (roundSeekbarOutAlpha != 0f) {
if (oldAplha == -1) {
oldAplha = Theme.chat_radialProgressPaint.getAlpha();
}
Theme.chat_radialProgressPaint.setAlpha((int) (paintAlpha * (1f - roundSeekbarOutAlpha)));
canvas.drawArc(rect, -90, 360 * audioProgress, false, Theme.chat_radialProgressPaint);
Theme.chat_radialProgressPaint.setAlpha((int) (paintAlpha * roundSeekbarOutAlpha));
canvas.drawArc(rect, -90, 360 * roundSeekbarOutProgress, false, Theme.chat_radialProgressPaint);
} else {
canvas.drawArc(rect, -90, 360 * audioProgress, false, Theme.chat_radialProgressPaint);
}
if (oldAplha != -1) {
Theme.chat_radialProgressPaint.setAlpha(oldAplha);
}
Theme.chat_radialProgressPaint.setStrokeWidth(paintWidth);
}
private void updatePollAnimations(long dt) {
@ -7023,7 +7321,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
radialProgress.setProgressRect((int) buttonX, (int) buttonY, (int) buttonX + AndroidUtilities.dp(44), (int) buttonY + AndroidUtilities.dp(44));
}
if (transitionParams.animateBackgroundBoundsInner && documentAttachType == DOCUMENT_ATTACH_TYPE_AUDIO) {
int backgroundWidth = this.backgroundWidth - transitionParams.deltaLeft + transitionParams.deltaRight;
int backgroundWidth = (int) (this.backgroundWidth - transitionParams.deltaLeft + transitionParams.deltaRight);
seekBarWaveform.setSize(backgroundWidth - AndroidUtilities.dp(92 + (hasLinkPreview ? 10 : 0)), AndroidUtilities.dp(30));
seekBar.setSize(backgroundWidth - AndroidUtilities.dp(72 + (hasLinkPreview ? 10 : 0)), AndroidUtilities.dp(30));
}
@ -7124,10 +7422,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawTime = true;
} else {
if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO && Theme.chat_roundVideoShadow != null) {
int x = (int) (photoImage.getImageX() - AndroidUtilities.dp(3));
int y = (int) (photoImage.getImageY() - AndroidUtilities.dp(2));
float x = photoImage.getImageX() - AndroidUtilities.dp(3);
float y = photoImage.getImageY() - AndroidUtilities.dp(2);
Theme.chat_roundVideoShadow.setAlpha(255/*(int) (photoImage.getCurrentAlpha() * 255)*/);
Theme.chat_roundVideoShadow.setBounds(x, y, x + AndroidUtilities.roundMessageSize + AndroidUtilities.dp(6), y + AndroidUtilities.roundMessageSize + AndroidUtilities.dp(6));
Theme.chat_roundVideoShadow.setBounds((int) x, (int) y, (int) (x + photoImage.getImageWidth() + AndroidUtilities.dp(6)), (int) (y + photoImage.getImageHeight() + AndroidUtilities.dp(6)));
Theme.chat_roundVideoShadow.draw(canvas);
if (!photoImage.hasBitmapImage() || photoImage.getCurrentAlpha() != 1) {
@ -7235,57 +7533,20 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
if (durationLayout != null) {
int x1;
int y1;
boolean playing = MediaController.getInstance().isPlayingMessage(currentMessageObject);
if (playing && currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
drawRoundProgress(canvas);
drawOverlays(canvas);
}
if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
x1 = backgroundDrawableLeft + AndroidUtilities.dp(8);
y1 = layoutHeight - AndroidUtilities.dp(28 - (drawPinnedBottom ? 2 : 0));
rect.set(x1, y1, x1 + timeWidthAudio + AndroidUtilities.dp(8 + 12 + 2), y1 + AndroidUtilities.dp(17));
int oldAlpha = Theme.chat_actionBackgroundPaint.getAlpha();
Theme.chat_actionBackgroundPaint.setAlpha((int) (oldAlpha * timeAlpha));
Theme.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, getX(), viewTop);
canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), Theme.chat_actionBackgroundPaint);
if (Theme.hasGradientService()) {
int oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * timeAlpha));
canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), Theme.chat_actionBackgroundGradientDarkenPaint);
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
}
Theme.chat_actionBackgroundPaint.setAlpha(oldAlpha);
if (!playing && currentMessageObject.isContentUnread()) {
Theme.chat_docBackPaint.setColor(Theme.getColor(Theme.key_chat_serviceText));
Theme.chat_docBackPaint.setAlpha((int) (255 * timeAlpha));
canvas.drawCircle(x1 + timeWidthAudio + AndroidUtilities.dp(12), y1 + AndroidUtilities.dp(8.3f), AndroidUtilities.dp(3), Theme.chat_docBackPaint);
if (playing || roundProgressAlpha != 0) {
if (playing) {
roundProgressAlpha = 1f;
} else {
if (playing && !MediaController.getInstance().isMessagePaused()) {
roundVideoPlayingDrawable.start();
roundProgressAlpha -= 16 / 150f;
if (roundProgressAlpha < 0) {
roundProgressAlpha = 0;
} else {
roundVideoPlayingDrawable.stop();
invalidate();
}
setDrawableBounds(roundVideoPlayingDrawable, x1 + timeWidthAudio + AndroidUtilities.dp(6), y1 + AndroidUtilities.dp(2.3f));
roundVideoPlayingDrawable.draw(canvas);
}
x1 += AndroidUtilities.dp(4);
y1 += AndroidUtilities.dp(1.7f);
} else {
x1 = backgroundDrawableLeft + AndroidUtilities.dp(currentMessageObject.isOutOwner() || drawPinnedBottom ? 12 : 18);
y1 = layoutHeight - AndroidUtilities.dp(6.3f - (drawPinnedBottom ? 2 : 0)) - timeLayout.getHeight();
drawRoundProgress(canvas);
}
Theme.chat_timePaint.setAlpha((int) (255 * timeAlpha));
canvas.save();
canvas.translate(x1, y1);
durationLayout.draw(canvas);
canvas.restore();
Theme.chat_timePaint.setAlpha(255);
}
} else if (documentAttachType == DOCUMENT_ATTACH_TYPE_MUSIC) {
if (currentMessageObject.isOutOwner()) {
@ -7720,11 +7981,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (alpha != 1f) {
photoImage.setAlpha(alpha);
imageDrawn = photoImage.draw(canvas);
photoImage.setAlpha(255);
photoImage.setAlpha(1f);
} else {
imageDrawn = photoImage.draw(canvas);
}
}
}
linkPreviewY += photoImage.getImageHeight() + AndroidUtilities.dp(6);
@ -7812,7 +8072,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (alpha != 1f) {
photoImage.setAlpha(alpha);
imageDrawn = photoImage.draw(canvas);
photoImage.setAlpha(255);
photoImage.setAlpha(1f);
} else {
imageDrawn = photoImage.draw(canvas);
}
@ -7940,7 +8200,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
for (int a = 0; a < botButtons.size(); a++) {
BotButton button = botButtons.get(a);
int y = button.y + layoutHeight - AndroidUtilities.dp(2) + transitionParams.deltaBottom;
float y = button.y + layoutHeight - AndroidUtilities.dp(2) + transitionParams.deltaBottom;
rect.set(button.x + addX, y, button.x + addX + button.width, y + button.height);
Theme.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, getX(), viewTop);
@ -9838,7 +10098,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
public void setDrawableBoundsInner(Drawable drawable, int x, int y, int w, int h) {
if (drawable != null) {
drawable.setBounds(x + transitionParams.deltaLeft, y + transitionParams.deltaTop, x + w + transitionParams.deltaRight, y + h + transitionParams.deltaBottom);
drawable.setBounds((int) (x + transitionParams.deltaLeft), (int) (y + transitionParams.deltaTop), (int) (x + w + transitionParams.deltaRight), (int) (y + h + transitionParams.deltaBottom));
}
}
@ -10247,16 +10507,18 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
rect.set(left, top, right, bottom);
restore = canvas.saveLayerAlpha(rect, (int) (255 * alphaInternal), Canvas.ALL_SAVE_FLAG);
}
if (transitionParams.animateBackgroundBoundsInner && currentBackgroundDrawable != null) {
boolean clipContent = false;
if (transitionParams.animateBackgroundBoundsInner && currentBackgroundDrawable != null && !isRoundVideo) {
Rect r = currentBackgroundDrawable.getBounds();
canvas.save();
canvas.clipRect(
r.left + AndroidUtilities.dp(4), r.top + AndroidUtilities.dp(4),
r.right - AndroidUtilities.dp(4), r.bottom - AndroidUtilities.dp(4)
);
clipContent = true;
}
drawContent(canvas);
if (transitionParams.animateBackgroundBoundsInner && currentBackgroundDrawable != null) {
if (clipContent) {
canvas.restore();
}
@ -10288,6 +10550,14 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
sideStartY -= getTranslationY();
}
}
if (!currentMessageObject.isOutOwner() && isRoundVideo && isAvatarVisible) {
float offsetSize = (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.7f;
float offsetX = isPlayingRound ? offsetSize : 0;
if (transitionParams.animatePlayingRound) {
offsetX = (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)) * offsetSize;
}
sideStartX -= offsetX;
}
if (drawSideButton == 3) {
if (!(enterTransitionInPorgress && !currentMessageObject.isVoice())) {
drawCommentButton(canvas, 1f);
@ -10346,7 +10616,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
drawNamesLayout(canvas, 1f);
}
if (!autoPlayingMedia || !MediaController.getInstance().isPlayingMessageAndReadyToDraw(currentMessageObject) && !transitionParams.animateBackgroundBoundsInner) {
if ((!autoPlayingMedia || !MediaController.getInstance().isPlayingMessageAndReadyToDraw(currentMessageObject) || isRoundVideo) && !transitionParams.animateBackgroundBoundsInner) {
drawOverlays(canvas);
}
if ((drawTime || !mediaBackground) && !forceNotDrawTime && !transitionParams.animateBackgroundBoundsInner && !(enterTransitionInPorgress && !currentMessageObject.isVoice())) {
@ -11379,7 +11649,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
boolean bigRadius = false;
float layoutHeight = this.layoutHeight + transitionParams.deltaBottom;
float timeTitleTimeX = (transitionParams.shouldAnimateTimeX ? this.timeX : timeX) + transitionParams.deltaRight;
float timeTitleTimeX = timeX;
if (transitionParams.shouldAnimateTimeX) {
timeTitleTimeX = transitionParams.animateFromTimeX * (1f - transitionParams.animateChangeProgress) + this.timeX * transitionParams.animateChangeProgress;
}
if (currentMessagesGroup != null && currentMessagesGroup.transitionParams.backgroundChangeBounds) {
layoutHeight -= getTranslationY();
timeX += currentMessagesGroup.transitionParams.offsetRight;
@ -11392,6 +11665,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
timeX += animationOffsetX;
timeTitleTimeX += animationOffsetX;
}
int timeYOffset;
if (shouldDrawTimeOnMedia()) {
timeYOffset = -(drawCommentButton ? AndroidUtilities.dp(41.3f) : 0);
@ -11413,7 +11687,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
} else {
r = AndroidUtilities.dp(4);
}
float x1 = timeX - AndroidUtilities.dp(bigRadius ? 6 : 4) + transitionParams.deltaRight;
float x1 = timeX - AndroidUtilities.dp(bigRadius ? 6 : 4);
float timeY = photoImage.getImageY2() + additionalTimeOffsetY;
float y1 = timeY - AndroidUtilities.dp(23);
rect.set(x1, y1, x1 + timeWidth + AndroidUtilities.dp((bigRadius ? 12 : 8) + (currentMessageObject.isOutOwner() ? 20 : 0)), y1 + AndroidUtilities.dp(17));
@ -12158,7 +12432,6 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
updatePlayingMessageProgress();
}
if ((infoLayout != null || loadingProgressLayout != null) && (!forceNotDrawTime || autoPlayingMedia || drawVideoImageButton || animatingLoadingProgressProgress != 0 || (fullWidth && docTitleLayout != null) || (loadingProgressLayout != null && currentPosition != null && (buttonState == 1 || (buttonState == 3 && miniButtonState == 1))))) {
boolean drawLoadingProgress;
float alpha = 0;
@ -12870,6 +13143,92 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
}
mediaCheckBox.draw(canvas);
}
if (documentAttachType == DOCUMENT_ATTACH_TYPE_ROUND) {
float x1, y1;
boolean playing = MediaController.getInstance().isPlayingMessage(currentMessageObject);
if (currentMessageObject.type == MessageObject.TYPE_ROUND_VIDEO) {
float offsetX = 0f;
if (currentMessageObject.isOutOwner()) {
float offsetSize = (AndroidUtilities.roundPlayingMessageSize - AndroidUtilities.roundMessageSize) * 0.2f;
offsetX = isPlayingRound ? offsetSize : 0;
if (transitionParams.animatePlayingRound) {
offsetX = (isPlayingRound ? transitionParams.animateChangeProgress : (1f - transitionParams.animateChangeProgress)) * offsetSize;
}
}
x1 = backgroundDrawableLeft + transitionParams.deltaLeft + AndroidUtilities.dp(8) + roundPlayingDrawableProgress + offsetX;
y1 = layoutHeight + transitionParams.deltaBottom - AndroidUtilities.dp(28 - (drawPinnedBottom ? 2 : 0));
rect.set(x1, y1, x1 + timeWidthAudio + AndroidUtilities.dp(8 + 12 + 2), y1 + AndroidUtilities.dp(17));
int oldAlpha = Theme.chat_actionBackgroundPaint.getAlpha();
Theme.chat_actionBackgroundPaint.setAlpha((int) (oldAlpha * timeAlpha));
Theme.applyServiceShaderMatrix(getMeasuredWidth(), backgroundHeight, getX(), viewTop);
canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), Theme.chat_actionBackgroundPaint);
if (Theme.hasGradientService()) {
int oldAlpha2 = Theme.chat_actionBackgroundGradientDarkenPaint.getAlpha();
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha((int) (oldAlpha2 * timeAlpha));
canvas.drawRoundRect(rect, AndroidUtilities.dp(6), AndroidUtilities.dp(6), Theme.chat_actionBackgroundGradientDarkenPaint);
Theme.chat_actionBackgroundGradientDarkenPaint.setAlpha(oldAlpha2);
}
Theme.chat_actionBackgroundPaint.setAlpha(oldAlpha);
boolean showPlayingDrawable = playing || !currentMessageObject.isContentUnread();
if (showPlayingDrawable && roundPlayingDrawableProgress != 1f) {
roundPlayingDrawableProgress += 16f / 150f;
if (roundPlayingDrawableProgress > 1f) {
roundPlayingDrawableProgress = 1f;
} else {
invalidate();
}
} else if (!showPlayingDrawable && roundPlayingDrawableProgress != 0) {
roundPlayingDrawableProgress -= 16f / 150f;
if (roundPlayingDrawableProgress < 0f) {
roundPlayingDrawableProgress = 0f;
} else {
invalidate();
}
}
if (showPlayingDrawable) {
if (playing && !MediaController.getInstance().isMessagePaused()) {
roundVideoPlayingDrawable.start();
} else {
roundVideoPlayingDrawable.stop();
}
}
if (roundPlayingDrawableProgress < 1f) {
float cx = x1 + timeWidthAudio + AndroidUtilities.dp(12);
float cy = y1 + AndroidUtilities.dp(8.3f);
canvas.save();
canvas.scale((1f - roundPlayingDrawableProgress), (1f - roundPlayingDrawableProgress), cx, cy);
Theme.chat_docBackPaint.setColor(Theme.getColor(Theme.key_chat_serviceText));
Theme.chat_docBackPaint.setAlpha((int) (255 * timeAlpha * (1f - roundPlayingDrawableProgress)));
canvas.drawCircle(cx, cy, AndroidUtilities.dp(3), Theme.chat_docBackPaint);
canvas.restore();
}
if (roundPlayingDrawableProgress > 0f) {
setDrawableBounds(roundVideoPlayingDrawable, x1 + timeWidthAudio + AndroidUtilities.dp(6), y1 + AndroidUtilities.dp(2.3f));
canvas.save();
canvas.scale(roundPlayingDrawableProgress, roundPlayingDrawableProgress, roundVideoPlayingDrawable.getBounds().centerX(), roundVideoPlayingDrawable.getBounds().centerY());
roundVideoPlayingDrawable.setAlpha((int) (255 * roundPlayingDrawableProgress));
roundVideoPlayingDrawable.draw(canvas);
canvas.restore();
}
x1 += AndroidUtilities.dp(4);
y1 += AndroidUtilities.dp(1.7f);
} else {
x1 = backgroundDrawableLeft + AndroidUtilities.dp(currentMessageObject.isOutOwner() || drawPinnedBottom ? 12 : 18);
y1 = layoutHeight - AndroidUtilities.dp(6.3f - (drawPinnedBottom ? 2 : 0)) - timeLayout.getHeight();
}
Theme.chat_timePaint.setAlpha((int) (255 * timeAlpha));
canvas.save();
canvas.translate(x1, y1);
durationLayout.draw(canvas);
canvas.restore();
Theme.chat_timePaint.setAlpha(255);
}
}
@Override
@ -13741,6 +14100,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
return textY;
}
public boolean isPlayingRound() {
return isRoundVideo && isPlayingRound;
}
public class TransitionParams {
public float lastDrawingImageX, lastDrawingImageY, lastDrawingImageW, lastDrawingImageH;
@ -13754,6 +14117,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
public float lastDrawLocationExpireProgress;
public StaticLayout lastDrawDocTitleLayout;
public StaticLayout lastDrawInfoLayout;
public boolean updatePhotoImageX;
private boolean lastIsPinned;
private boolean animatePinned;
@ -13792,10 +14156,10 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private String lastSignMessage;
public boolean imageChangeBoundsTransition;
public int deltaLeft;
public int deltaRight;
public int deltaBottom;
public int deltaTop;
public float deltaLeft;
public float deltaRight;
public float deltaBottom;
public float deltaTop;
public float animateToImageX, animateToImageY, animateToImageW, animateToImageH;
public float captionFromX, captionFromY;
@ -13856,6 +14220,8 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
private boolean lastShouldDrawMenuDrawable;
private boolean animateShouldDrawMenuDrawable;
private StaticLayout lastTimeLayout;
private boolean lastIsPlayingRound;
public boolean animatePlayingRound;
public int lastTopOffset;
@ -13915,6 +14281,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
lastShouldDrawMenuDrawable = shouldDrawMenuDrawable();
lastLocatinIsExpired = locationExpired;
lastIsPlayingRound = isPlayingRound;
}
public boolean animateChange() {
@ -14067,6 +14434,11 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
if (lastLocatinIsExpired != locationExpired) {
animateLocationIsExpired = true;
}
if (lastIsPlayingRound != isPlayingRound) {
animatePlayingRound = true;
changed = true;
}
return changed;
}
@ -14122,6 +14494,7 @@ public class ChatMessageCell extends BaseCell implements SeekBar.SeekBarDelegate
animateSign = false;
animateDrawingTimeAlpha = false;
animateLocationIsExpired = false;
animatePlayingRound = false;
}
public boolean supportChangeAnimation() {

View file

@ -46,7 +46,7 @@ import java.util.Locale;
public class SharedLinkCell extends FrameLayout {
public interface SharedLinkCellDelegate {
void needOpenWebView(TLRPC.WebPage webPage);
void needOpenWebView(TLRPC.WebPage webPage, MessageObject messageObject);
boolean canPerformActions();
void onLinkPress(final String urlFinal, boolean longPress);
}
@ -448,6 +448,10 @@ public class SharedLinkCell extends FrameLayout {
requestLayout();
}
public ImageReceiver getLinkImageView() {
return linkImageView;
}
public void setDelegate(SharedLinkCellDelegate sharedLinkCellDelegate) {
delegate = sharedLinkCellDelegate;
}
@ -504,7 +508,7 @@ public class SharedLinkCell extends FrameLayout {
try {
TLRPC.WebPage webPage = pressedLink == 0 && message.messageOwner.media != null ? message.messageOwner.media.webpage : null;
if (webPage != null && webPage.embed_url != null && webPage.embed_url.length() != 0) {
delegate.needOpenWebView(webPage);
delegate.needOpenWebView(webPage, message);
} else {
delegate.onLinkPress(links.get(pressedLink), false);
}

View file

@ -425,7 +425,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
if (messageObject1.isVoice() || messageObject1.isMusic()) {
cell.updateButtonState(false, true, false);
} else if (messageObject1.isRoundVideo()) {
cell.checkVideoPlayback(false);
cell.checkVideoPlayback(false, null);
if (!MediaController.getInstance().isPlayingMessage(messageObject1)) {
if (messageObject1.audioProgress != 0) {
messageObject1.resetPlayingProgress();
@ -450,7 +450,7 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
cell.updateButtonState(false, true, false);
} else if (messageObject.isRoundVideo()) {
if (!MediaController.getInstance().isPlayingMessage(messageObject)) {
cell.checkVideoPlayback(true);
cell.checkVideoPlayback(true, null);
}
}
}
@ -2217,8 +2217,8 @@ public class ChannelAdminLogActivity extends BaseFragment implements Notificatio
}
@Override
public void needOpenWebView(String url, String title, String description, String originalUrl, int w, int h) {
EmbedBottomSheet.show(mContext, title, description, originalUrl, url, w, h, false);
public void needOpenWebView(MessageObject message, String url, String title, String description, String originalUrl, int w, int h) {
EmbedBottomSheet.show(getParentActivity(), message, provider, title, description, originalUrl, url, w, h, false);
}
@Override

View file

@ -56,6 +56,7 @@ import android.text.TextUtils;
import android.text.style.CharacterStyle;
import android.text.style.ForegroundColorSpan;
import android.text.style.URLSpan;
import android.util.Log;
import android.util.LongSparseArray;
import android.util.Property;
import android.util.SparseArray;
@ -619,6 +620,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
private boolean scrollToVideo;
private Path aspectPath;
private Paint aspectPaint;
private Runnable destroyTextureViewRunnable = new Runnable() {
@Override
public void run() {
destroyTextureView();
}
};
private Paint scrimPaint;
private View scrimView;
@ -2471,7 +2478,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
invalidateChatListViewTopPadding();
invalidateMessagesVisiblePart();
}
chatListView.setItemAnimator(null);
chatListView.invalidate();
updateBulletinLayout();
}
@ -2611,9 +2617,12 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (Theme.chat_roundVideoShadow != null && aspectRatioFrameLayout.isDrawingReady()) {
int x = (int) child.getX() - AndroidUtilities.dp(3);
int y = (int) child.getY() - AndroidUtilities.dp(2);
canvas.save();
canvas.scale(videoPlayerContainer.getScaleX(), videoPlayerContainer.getScaleY(), child.getX(), child.getY());
Theme.chat_roundVideoShadow.setAlpha(255);
Theme.chat_roundVideoShadow.setBounds(x, y, x + AndroidUtilities.roundMessageSize + AndroidUtilities.dp(6), y + AndroidUtilities.roundMessageSize + AndroidUtilities.dp(6));
Theme.chat_roundVideoShadow.setBounds(x, y, x + AndroidUtilities.roundPlayingMessageSize + AndroidUtilities.dp(6), y + AndroidUtilities.roundPlayingMessageSize + AndroidUtilities.dp(6));
Theme.chat_roundVideoShadow.draw(canvas);
canvas.restore();
}
result = super.drawChild(canvas, child, drawingTime);
} else {
@ -2635,7 +2644,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
canvas.translate(drawLaterRoundProgressCell.getX(), drawLaterRoundProgressCell.getTop() + chatListView.getY());
if (isRoundVideo) {
drawLaterRoundProgressCell.drawRoundProgress(canvas);
drawLaterRoundProgressCell.drawOverlays(canvas);
invalidate();
drawLaterRoundProgressCell.invalidate();
// drawLaterRoundProgressCell.drawOverlays(canvas);
} else {
drawLaterRoundProgressCell.drawOverlays(canvas);
if (drawLaterRoundProgressCell.needDrawTime()) {
@ -2684,6 +2695,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
invalidateMessagesVisiblePart = false;
updateMessagesVisiblePart(false);
}
updateTextureViewPosition(false);
super.dispatchDraw(canvas);
if (fragmentContextView != null && fragmentContextView.isCallStyle()) {
canvas.save();
@ -2925,6 +2937,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (actionBar.getVisibility() == VISIBLE) {
heightSize -= actionBarHeight;
}
int keyboardHeightOld = keyboardHeight + chatEmojiViewPadding;
boolean keyboardVisibleOld = keyboardHeight + chatEmojiViewPadding >= AndroidUtilities.dp(20);
if (lastHeight != allHeight) {
measureKeyboardHeight();
}
@ -2938,9 +2952,34 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatEmojiViewPadding = 0;
}
}
setEmojiKeyboardHeight(chatEmojiViewPadding);
boolean keyboardVisible = keyboardHeight + chatEmojiViewPadding >= AndroidUtilities.dp(20);
boolean waitingChatListItemAnimator = false;
if (MediaController.getInstance().getPlayingMessageObject() != null && MediaController.getInstance().getPlayingMessageObject().isRoundVideo() && keyboardVisibleOld != keyboardVisible) {
for (int i = 0; i < chatListView.getChildCount(); i++) {
View child = chatListView.getChildAt(i);
if (child instanceof ChatMessageCell) {
MessageObject messageObject = ((ChatMessageCell) child).getMessageObject();
if (messageObject.isRoundVideo() && MediaController.getInstance().isPlayingMessage(messageObject)) {
int p = chatListView.getChildAdapterPosition(child);
if (p >= 0) {
chatLayoutManager.scrollToPositionWithOffset(p, (int) ((chatListView.getMeasuredHeight() - chatListViewPaddingTop + (keyboardHeight + chatEmojiViewPadding - keyboardHeightOld) - (keyboardVisible ? AndroidUtilities.roundMessageSize : AndroidUtilities.roundPlayingMessageSize)) / 2), false);
chatAdapter.notifyItemChanged(p);
adjustPanLayoutHelper.delayAnimation();
waitingChatListItemAnimator = true;
break;
}
}
}
}
}
if (!waitingChatListItemAnimator) {
chatActivityEnterView.runEmojiPanelAnimation();
}
int childCount = getChildCount();
measureChildWithMargins(chatActivityEnterView, widthMeasureSpec, 0, heightMeasureSpec, 0);
@ -3094,7 +3133,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
final int count = getChildCount();
int keyboardSize = getKeyboardHeight();
int paddingBottom;
long time = System.currentTimeMillis();
if (fixedKeyboardHeight > 0 && keyboardSize <= AndroidUtilities.dp(20)) {
paddingBottom = fixedKeyboardHeight;
} else {
@ -3102,10 +3141,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
if (!SharedConfig.smoothKeyboard) {
setBottomClip(paddingBottom);
} else if (!inPreviewMode && chatActivityEnterView.getEmojiPadding() == 0) {
setBottomClip(AndroidUtilities.dp(48));
} else {
setBottomClip(0);
}
for (int i = 0; i < count; i++) {
@ -3692,10 +3727,6 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
drawReplyButton(c);
}
if (chatListView.isFastScrollAnimationRunning()) {
updateTextureViewPosition(false);
}
}
ArrayList<MessageObject.GroupedMessages> drawingGroups = new ArrayList<>(10);
@ -4231,11 +4262,22 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
float tx = chatMessageCell.getSlidingOffsetX() + chatMessageCell.getCheckBoxTranslation();
int y = (int) ((replaceAnimation ? child.getTop() : child.getY()) + chatMessageCell.getLayoutHeight());
int y = (int) ((replaceAnimation ? child.getTop() : child.getY()) + chatMessageCell.getLayoutHeight() + chatMessageCell.getTransitionParams().deltaBottom);
int maxY = chatListView.getMeasuredHeight() - chatListView.getPaddingBottom();
if (y > maxY) {
y = maxY;
if (chatMessageCell.isPlayingRound() || chatMessageCell.getTransitionParams().animatePlayingRound) {
if (chatMessageCell.getTransitionParams().animatePlayingRound) {
float progressLocal = chatMessageCell.getTransitionParams().animateChangeProgress;
if (!chatMessageCell.isPlayingRound()) {
progressLocal = 1f - progressLocal;
}
int fromY = y;
int toY = y > maxY ? maxY : y;
y = (int) (fromY * progressLocal + toY * (1f - progressLocal));
}
} else {
if (y > maxY) {
y = maxY;
}
}
if (!replaceAnimation && child.getTranslationY() != 0) {
@ -4324,7 +4366,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
y = top + AndroidUtilities.dp(48);
}
if (!chatMessageCell.drawPinnedBottom()) {
int cellBottom = replaceAnimation ? chatMessageCell.getBottom() : (int) (chatMessageCell.getY() + chatMessageCell.getMeasuredHeight());
int cellBottom = replaceAnimation ? chatMessageCell.getBottom() : (int) (chatMessageCell.getY() + chatMessageCell.getMeasuredHeight() + chatMessageCell.getTransitionParams().deltaBottom);
if (y > cellBottom) {
y = cellBottom;
}
@ -4417,6 +4459,8 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (BuildVars.LOGS_ENABLED) {
FileLog.d("chatItemAnimator disable notifications");
}
chatActivityEnterView.getAdjustPanLayoutHelper().runDelayedAnimation();
chatActivityEnterView.runEmojiPanelAnimation();
}
@Override
@ -5735,7 +5779,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
if (result.type.equals("video") || result.type.equals("web_player_video")) {
int[] size = MessageObject.getInlineResultWidthAndHeight(result);
EmbedBottomSheet.show(getParentActivity(), result.title != null ? result.title : "", result.description, result.content.url, result.content.url, size[0], size[1], isKeyboardVisible());
EmbedBottomSheet.show(getParentActivity(), null, botContextProvider, result.title != null ? result.title : "", result.description, result.content.url, result.content.url, size[0], size[1], isKeyboardVisible());
} else {
processExternalUrl(0, result.content.url, false);
}
@ -5965,8 +6009,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
contentView.addView(fragmentLocationContextView = new FragmentContextView(context, this, true), LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0));
contentView.addView(fragmentContextView = new FragmentContextView(context, this, false) {
@Override
protected void playbackSpeedChanged(boolean enabled) {
undoView.showWithAction(0, enabled ? UndoView.ACTION_PLAYBACK_SPEED_ENABLED : UndoView.ACTION_PLAYBACK_SPEED_DISABLED, null);
protected void playbackSpeedChanged(float value) {
if (Math.abs(value - 1.0f) < 0.001f || Math.abs(value - 1.8f) < 0.001f) {
undoView.showWithAction(0, Math.abs(value - 1.0f) > 0.001f ? UndoView.ACTION_PLAYBACK_SPEED_ENABLED : UndoView.ACTION_PLAYBACK_SPEED_DISABLED, value, null, null);
}
}
}, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0));
fragmentContextView.setAdditionalContextView(fragmentLocationContextView);
@ -7876,6 +7922,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (parentLayout == null) {
return null;
}
AndroidUtilities.cancelRunOnUIThread(destroyTextureViewRunnable);
if (videoPlayerContainer == null) {
if (Build.VERSION.SDK_INT >= 21) {
videoPlayerContainer = new FrameLayout(getParentActivity()) {
@ -7899,7 +7946,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
outline.setRoundRect(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight(), maxRad);
} else {
outline.setOval(0, 0, AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize);
outline.setOval(0, 0, AndroidUtilities.roundPlayingMessageSize, AndroidUtilities.roundPlayingMessageSize);
}
}
});
@ -7973,7 +8020,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
parent = null;
}
if (parent == null) {
contentView.addView(videoPlayerContainer, 1, new FrameLayout.LayoutParams(AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize));
contentView.addView(videoPlayerContainer, 1, new FrameLayout.LayoutParams(AndroidUtilities.roundPlayingMessageSize, AndroidUtilities.roundPlayingMessageSize));
}
videoPlayerContainer.setTag(null);
aspectRatioFrameLayout.setDrawingReady(false);
@ -7984,12 +8031,13 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (videoPlayerContainer == null || videoPlayerContainer.getParent() == null) {
return;
}
contentView.removeView(videoPlayerContainer);
chatListView.invalidateViews();
aspectRatioFrameLayout.setDrawingReady(false);
videoPlayerContainer.setTag(null);
if (Build.VERSION.SDK_INT < 21) {
videoPlayerContainer.setLayerType(View.LAYER_TYPE_NONE, null);
}
contentView.removeView(videoPlayerContainer);
}
private void openForward() {
@ -10312,12 +10360,21 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) videoPlayerContainer.getLayoutParams();
if (messageObject.isRoundVideo()) {
videoPlayerContainer.setTag(R.id.parent_tag, null);
if (layoutParams.width != AndroidUtilities.roundMessageSize || layoutParams.height != AndroidUtilities.roundMessageSize) {
layoutParams.width = layoutParams.height = AndroidUtilities.roundMessageSize;
if (layoutParams.width != AndroidUtilities.roundPlayingMessageSize || layoutParams.height != AndroidUtilities.roundPlayingMessageSize) {
layoutParams.width = layoutParams.height = AndroidUtilities.roundPlayingMessageSize;
aspectRatioFrameLayout.setResizeMode(AspectRatioFrameLayout.RESIZE_MODE_FIT);
videoPlayerContainer.setLayoutParams(layoutParams);
}
float scale = (AndroidUtilities.roundMessageSize + AndroidUtilities.roundMessageInset * 2) / (float) AndroidUtilities.roundMessageSize;
float scale = (AndroidUtilities.roundPlayingMessageSize + AndroidUtilities.roundMessageInset * 2) / (float) AndroidUtilities.roundPlayingMessageSize;
float transitionScale = messageCell.getPhotoImage().getImageWidth() / AndroidUtilities.roundPlayingMessageSize;
if (videoPlayerContainer.getScaleX() != transitionScale) {
videoPlayerContainer.invalidate();
fragmentView.invalidate();
}
videoPlayerContainer.setPivotX(0);
videoPlayerContainer.setPivotY(0);
videoPlayerContainer.setScaleX(transitionScale);
videoPlayerContainer.setScaleY(transitionScale);
videoTextureView.setScaleX(scale);
videoTextureView.setScaleY(scale);
} else {
@ -10345,9 +10402,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (checkTextureViewPosition && messageObject.isVideo()) {
MediaController.getInstance().cleanupPlayer(true, true);
} else {
videoPlayerContainer.setTranslationY(-AndroidUtilities.roundMessageSize - 100);
videoPlayerContainer.setTranslationY(-AndroidUtilities.roundPlayingMessageSize - 100);
fragmentView.invalidate();
if (messageObject != null && (messageObject.isRoundVideo() || messageObject.isVideo())) {
if (messageObject.isRoundVideo() || messageObject.isVideo()) {
if (checkTextureViewPosition || PipRoundVideoView.getInstance() != null) {
MediaController.getInstance().setCurrentVideoVisible(false);
} else {
@ -10358,7 +10415,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
MediaController.getInstance().setCurrentVideoVisible(true);
if (messageObject.isRoundVideo() || scrollToVideo) {
scrollToMessageId(messageObject.getId(), 0, false, 0, true, 0);
// scrollToMessageId(messageObject.getId(), 0, false, 0, true, 0);
} else {
chatListView.invalidate();
}
@ -10504,9 +10561,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
foundTextureViewMessage = true;
}
}
if (startFromVideoTimestamp >= 0 && fragmentOpened && !chatListView.isFastScrollAnimationRunning() && startFromVideoMessageId == messageObject.getId()) {
if (startFromVideoTimestamp >= 0 && fragmentOpened && !chatListView.isFastScrollAnimationRunning() && startFromVideoMessageId == messageObject.getId() && (messageObject.isVideo() || messageObject.isRoundVideo() || messageObject.isVoice() || messageObject.isMusic())) {
messageObject.forceSeekTo = startFromVideoTimestamp / (float) messageObject.getDuration();
openPhotoViewerForMessage(messageCell, messageObject);
MessageObject finalMessage = messageObject;
AndroidUtilities.runOnUIThread(() -> {
if (finalMessage.isVideo()) {
openPhotoViewerForMessage(null, finalMessage);
} else {
MediaController.getInstance().playMessage(finalMessage);
}
}, 40);
startFromVideoTimestamp = -1;
}
} else if (view instanceof ChatActionCell) {
@ -10603,7 +10667,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (checkTextureViewPosition && messageObject.isVideo()) {
MediaController.getInstance().cleanupPlayer(true, true);
} else {
videoPlayerContainer.setTranslationY(-AndroidUtilities.roundMessageSize - 100);
videoPlayerContainer.setTranslationY(-AndroidUtilities.roundPlayingMessageSize - 100);
fragmentView.invalidate();
if ((messageObject.isRoundVideo() || messageObject.isVideo()) && messageObject.eventId == 0 && checkTextureViewPosition && !chatListView.isFastScrollAnimationRunning()) {
MediaController.getInstance().setCurrentVideoVisible(false);
@ -14038,7 +14102,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
if (messageObject1 != null) {
boolean isVideo = messageObject1.isVideo();
if (messageObject1.isRoundVideo() || isVideo) {
cell.checkVideoPlayback(!messageObject.equals(messageObject1));
cell.checkVideoPlayback(!messageObject.equals(messageObject1), null);
if (!MediaController.getInstance().isPlayingMessage(messageObject1)) {
if (isVideo && !MediaController.getInstance().isGoingToShowMessageObject(messageObject1)) {
AnimatedFileDrawable animation = cell.getPhotoImage().getAnimation();
@ -14053,6 +14117,16 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else if (isVideo) {
cell.updateButtonState(false, true, false);
}
if (messageObject1.isRoundVideo()) {
int position = chatListView.getChildAdapterPosition(cell);
if (position >= 0) {
if (MediaController.getInstance().isPlayingMessage(messageObject1)) {
boolean keyboardIsVisible = contentView.getKeyboardHeight() >= AndroidUtilities.dp(20);
chatLayoutManager.scrollToPositionWithOffset(position, (int) ((chatListView.getMeasuredHeight() - chatListViewPaddingTop - (keyboardIsVisible ? AndroidUtilities.roundMessageSize : AndroidUtilities.roundPlayingMessageSize)) / 2), false);
}
chatAdapter.notifyItemChanged(position);
}
}
} else if (messageObject1.isVoice() || messageObject1.isMusic()) {
cell.updateButtonState(false, true, false);
}
@ -14111,8 +14185,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
} else if (id == NotificationCenter.messagePlayingDidReset || id == NotificationCenter.messagePlayingPlayStateChanged) {
if (id == NotificationCenter.messagePlayingDidReset) {
destroyTextureView();
AndroidUtilities.runOnUIThread(destroyTextureViewRunnable);
}
int messageId = (int) args[0];
if (chatListView != null) {
int count = chatListView.getChildCount();
for (int a = 0; a < count; a++) {
@ -14133,7 +14208,19 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
} else if (messageObject.isRoundVideo()) {
if (!MediaController.getInstance().isPlayingMessage(messageObject)) {
cell.checkVideoPlayback(true);
Bitmap bitmap = null;
if (id == NotificationCenter.messagePlayingDidReset && cell.getMessageObject().getId() == messageId && videoTextureView != null) {
bitmap = videoTextureView.getBitmap();
if (bitmap != null && bitmap.getPixel(0, 0) == Color.TRANSPARENT) {
bitmap = null;
}
}
cell.checkVideoPlayback(true, bitmap);
}
int position = chatListView.getChildAdapterPosition(cell);
messageObject.forceUpdate = true;
if (position >= 0) {
chatAdapter.notifyItemChanged(position);
}
}
}
@ -21043,18 +21130,19 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
hideFieldPanel(false);
}
}
} else if (messageObject != null && str.startsWith("video")) {
} else if (messageObject != null && str.startsWith("video") && !longPress) {
int seekTime = Utilities.parseInt(str);
TLRPC.WebPage webPage;
if (messageObject.isYouTubeVideo()) {
webPage = messageObject.messageOwner.media.webpage;
} else if (messageObject.replyMessageObject != null && messageObject.replyMessageObject.isYouTubeVideo()) {
webPage = messageObject.replyMessageObject.messageOwner.media.webpage;
messageObject = messageObject.replyMessageObject;
} else {
webPage = null;
}
if (webPage != null) {
EmbedBottomSheet.show(getParentActivity(), webPage.site_name, webPage.title, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height, seekTime, isKeyboardVisible());
EmbedBottomSheet.show(getParentActivity(), messageObject, photoViewerProvider, webPage.site_name, webPage.title, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height, seekTime, isKeyboardVisible());
} else {
if (!messageObject.isVideo() && messageObject.replyMessageObject != null) {
MessageObject obj = messagesDict[messageObject.replyMessageObject.getDialogId() == dialog_id ? 0 : 1].get(messageObject.replyMessageObject.getId());
@ -21130,12 +21218,59 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else {
if (longPress) {
BottomSheet.Builder builder = new BottomSheet.Builder(getParentActivity());
builder.setTitle(str);
int timestamp = -1;
if (str.startsWith("video?")) {
timestamp = Utilities.parseInt(str);
}
if (timestamp >= 0) {
builder.setTitle(AndroidUtilities.formatDuration(timestamp, false));
} else {
builder.setTitle(str);
}
final int finalTimestamp = timestamp;
ChatMessageCell finalCell = cell;
MessageObject finalMessageObject = messageObject;
builder.setItems(new CharSequence[]{LocaleController.getString("Open", R.string.Open), LocaleController.getString("Copy", R.string.Copy)}, (dialog, which) -> {
if (which == 0) {
openClickableLink(str);
if (str.startsWith("video?")) {
didPressMessageUrl(url, false, finalMessageObject, finalCell);
} else {
openClickableLink(str);
}
} else if (which == 1) {
AndroidUtilities.addToClipboard(str);
if (str.startsWith("video?") && finalMessageObject != null && !finalMessageObject.scheduled) {
MessageObject messageObject1 = finalMessageObject;
boolean isMedia = finalMessageObject.isVideo() || finalMessageObject.isRoundVideo() || finalMessageObject.isVoice() || finalMessageObject.isMusic();
if (!isMedia && finalMessageObject.replyMessageObject != null) {
messageObject1 = finalMessageObject.replyMessageObject;
}
int lower_id = (int) messageObject1.getDialogId();
int messageId = messageObject1.getId();
String link = null;
if (messageObject1.messageOwner.fwd_from != null) {
lower_id = MessageObject.getPeerId(messageObject1.messageOwner.fwd_from.saved_from_peer);
messageId = messageObject1.messageOwner.fwd_from.saved_from_msg_id;
}
if (lower_id < 0) {
TLRPC.Chat currentChat = MessagesController.getInstance(currentAccount).getChat(-lower_id);
if (currentChat != null && currentChat.username != null) {
link = "https://t.me/" + currentChat.username + "/" + messageId + "?t=" + finalTimestamp;
}
} else {
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(lower_id);
if (user != null && user.username != null) {
link = "https://t.me/" + user.username + "/" + messageId + "?t=" + finalTimestamp;
}
}
if (link == null) {
return;
}
AndroidUtilities.addToClipboard(link);
} else {
AndroidUtilities.addToClipboard(str);
}
if (str.startsWith("@")) {
undoView.showWithAction(0, UndoView.ACTION_USERNAME_COPIED, null);
} else if (str.startsWith("#") || str.startsWith("$")) {
@ -21162,14 +21297,18 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
} else if (which == 1) {
String url1 = urlFinal;
boolean tel = false;
boolean mail = false;
if (url1.startsWith("mailto:")) {
url1 = url1.substring(7);
mail = true;
} else if (url1.startsWith("tel:")) {
url1 = url1.substring(4);
tel = true;
}
AndroidUtilities.addToClipboard(url1);
if (tel) {
if (mail) {
undoView.showWithAction(0, UndoView.ACTION_EMAIL_COPIED, null);
} else if (tel) {
undoView.showWithAction(0, UndoView.ACTION_PHONE_COPIED, null);
} else {
undoView.showWithAction(0, UndoView.ACTION_LINK_COPIED, null);
@ -21203,7 +21342,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
}
void openPhotoViewerForMessage(ChatMessageCell cell, MessageObject message) {
void openPhotoViewerForMessage(ChatMessageCell cell, MessageObject message) {
if (cell == null) {
int count = chatListView.getChildCount();
for (int a = 0; a < count; a++) {
@ -21796,9 +21935,9 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
@Override
public void needOpenWebView(String url, String title, String description, String originalUrl, int w, int h) {
public void needOpenWebView(MessageObject message, String url, String title, String description, String originalUrl, int w, int h) {
try {
EmbedBottomSheet.show(mContext, title, description, originalUrl, url, w, h, isKeyboardVisible());
EmbedBottomSheet.show(getParentActivity(), message, photoViewerProvider, title, description, originalUrl, url, w, h, isKeyboardVisible());
} catch (Throwable e) {
FileLog.e(e);
}
@ -22025,6 +22164,15 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
public PinchToZoomHelper getPinchToZoomHelper() {
return pinchToZoomHelper;
}
@Override
public boolean keyboardIsOpened() {
return contentView.getKeyboardHeight() + chatEmojiViewPadding >= AndroidUtilities.dp(20);
}
public boolean isLandscape() {
return contentView.getMeasuredWidth() > contentView.getMeasuredHeight();
}
});
if (currentEncryptedChat == null) {
chatMessageCell.setAllowAssistant(true);
@ -22326,6 +22474,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
allAnimators.setStartDelay(120);
allAnimators.setDuration(180);
instantCameraView.setIsMessageTransition(true);
allAnimators.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@ -22353,6 +22502,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
instantCameraView.setIsMessageTransition(false);
instantCameraView.hideCamera(true);
instantCameraView.setVisibility(View.INVISIBLE);
}
@ -22911,6 +23061,10 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
chatActivityDelegate.openReplyMessage(messageId);
finishFragment();
} else {
startFromVideoTimestamp = LaunchActivity.getTimestampFromLink(data);
if (startFromVideoTimestamp >= 0) {
startFromVideoMessageId = messageId;
}
scrollToMessageId(messageId, fromMessageId, true, 0, false, 0);
}
}
@ -23033,7 +23187,7 @@ public class ChatActivity extends BaseFragment implements NotificationCenter.Not
}
public static boolean isClickableLink(String str) {
return str.startsWith("https://") || str.startsWith("@") || str.startsWith("#") || str.startsWith("$");
return str.startsWith("https://") || str.startsWith("@") || str.startsWith("#") || str.startsWith("$") || str.startsWith("video?");
}
public SimpleTextView getReplyNameTextView() {

View file

@ -122,7 +122,8 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
private LineProgressView progressView;
private SeekBarView seekBarView;
private SimpleTextView timeTextView;
private ImageView playbackSpeedButton;
private ActionBarMenuItem playbackSpeedButton;
private ActionBarMenuSubItem[] speedItems = new ActionBarMenuSubItem[4];
private TextView durationTextView;
private ActionBarMenuItem repeatButton;
private ActionBarMenuSubItem repeatSongItem;
@ -172,6 +173,11 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
long lastRewindingTime;
long lastUpdateRewindingPlayerTime;
private final static int menu_speed_slow = 1;
private final static int menu_speed_normal = 2;
private final static int menu_speed_fast = 3;
private final static int menu_speed_veryfast = 4;
private final Runnable forwardSeek = new Runnable() {
@Override
public void run() {
@ -663,23 +669,47 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
durationTextView.setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_NO);
playerLayout.addView(durationTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.RIGHT, 0, 96, 20, 0));
playbackSpeedButton = new ImageView(context);
playbackSpeedButton.setScaleType(ImageView.ScaleType.CENTER);
playbackSpeedButton.setImageResource(R.drawable.voice2x);
playbackSpeedButton = new ActionBarMenuItem(context, null, 0, Theme.getColor(Theme.key_dialogTextBlack));
playbackSpeedButton.setLongClickEnabled(false);
playbackSpeedButton.setShowSubmenuByMove(false);
playbackSpeedButton.setAdditionalYOffset(-AndroidUtilities.dp(224));
playbackSpeedButton.setContentDescription(LocaleController.getString("AccDescrPlayerSpeed", R.string.AccDescrPlayerSpeed));
if (AndroidUtilities.density >= 3.0f) {
playbackSpeedButton.setPadding(0, 1, 0, 0);
}
playerLayout.addView(playbackSpeedButton, LayoutHelper.createFrame(36, 36, Gravity.TOP | Gravity.RIGHT, 0, 86, 20, 0));
playbackSpeedButton.setOnClickListener(v -> {
float currentPlaybackSpeed = MediaController.getInstance().getPlaybackSpeed(true);
if (currentPlaybackSpeed > 1) {
playbackSpeedButton.setDelegate(id -> {
float oldSpeed = MediaController.getInstance().getPlaybackSpeed(true);
if (id == menu_speed_slow) {
MediaController.getInstance().setPlaybackSpeed(true, 0.5f);
} else if (id == menu_speed_normal) {
MediaController.getInstance().setPlaybackSpeed(true, 1.0f);
} else if (id == menu_speed_fast) {
MediaController.getInstance().setPlaybackSpeed(true, 1.5f);
} else {
MediaController.getInstance().setPlaybackSpeed(true, 1.8f);
}
updatePlaybackButton();
});
speedItems[0] = playbackSpeedButton.addSubItem(menu_speed_slow, R.drawable.msg_speed_0_5, LocaleController.getString("SpeedSlow", R.string.SpeedSlow));
speedItems[1] = playbackSpeedButton.addSubItem(menu_speed_normal, R.drawable.msg_speed_1, LocaleController.getString("SpeedNormal", R.string.SpeedNormal));
speedItems[2] = playbackSpeedButton.addSubItem(menu_speed_fast, R.drawable.msg_speed_1_5, LocaleController.getString("SpeedFast", R.string.SpeedFast));
speedItems[3] = playbackSpeedButton.addSubItem(menu_speed_veryfast, R.drawable.msg_speed_2, LocaleController.getString("SpeedVeryFast", R.string.SpeedVeryFast));
if (AndroidUtilities.density >= 3.0f) {
playbackSpeedButton.setPadding(0, 1, 0, 0);
}
playbackSpeedButton.setAdditionalXOffset(AndroidUtilities.dp(8));
playbackSpeedButton.setShowedFromBottom(true);
playerLayout.addView(playbackSpeedButton, LayoutHelper.createFrame(36, 36, Gravity.TOP | Gravity.RIGHT, 0, 86, 20, 0));
playbackSpeedButton.setOnClickListener(v -> {
float currentPlaybackSpeed = MediaController.getInstance().getPlaybackSpeed(true);
if (Math.abs(currentPlaybackSpeed - 1.0f) > 0.001f) {
MediaController.getInstance().setPlaybackSpeed(true, 1.0f);
} else {
MediaController.getInstance().setPlaybackSpeed(true, MediaController.getInstance().getFastPlaybackSpeed(true));
}
updatePlaybackButton();
});
playbackSpeedButton.setOnLongClickListener(view -> {
playbackSpeedButton.toggleSubMenu();
return true;
});
updatePlaybackButton();
FrameLayout bottomView = new FrameLayout(context) {
@ -1272,12 +1302,34 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
private void updatePlaybackButton() {
float currentPlaybackSpeed = MediaController.getInstance().getPlaybackSpeed(true);
if (currentPlaybackSpeed > 1) {
playbackSpeedButton.setTag(Theme.key_inappPlayerPlayPause);
playbackSpeedButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_inappPlayerPlayPause), PorterDuff.Mode.MULTIPLY));
String key;
if (Math.abs(currentPlaybackSpeed - 1.0f) > 0.001f) {
key = Theme.key_inappPlayerPlayPause;
} else {
playbackSpeedButton.setTag(Theme.key_inappPlayerClose);
playbackSpeedButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(Theme.key_inappPlayerClose), PorterDuff.Mode.MULTIPLY));
key = Theme.key_inappPlayerClose;
}
playbackSpeedButton.setTag(key);
float speed = MediaController.getInstance().getFastPlaybackSpeed(true);
if (Math.abs(speed - 1.8f) < 0.001f) {
playbackSpeedButton.setIcon(R.drawable.voice_mini_2_0);
} else if (Math.abs(speed - 1.5f) < 0.001f) {
playbackSpeedButton.setIcon(R.drawable.voice_mini_1_5);
} else {
playbackSpeedButton.setIcon(R.drawable.voice_mini_0_5);
}
playbackSpeedButton.setIconColor(Theme.getColor(key));
if (Build.VERSION.SDK_INT >= 21) {
playbackSpeedButton.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(key) & 0x19ffffff, 1, AndroidUtilities.dp(14)));
}
for (int a = 0; a < speedItems.length; a++) {
if (a == 0 && Math.abs(currentPlaybackSpeed - 0.5f) < 0.001f ||
a == 1 && Math.abs(currentPlaybackSpeed - 1.0f) < 0.001f ||
a == 2 && Math.abs(currentPlaybackSpeed - 1.5f) < 0.001f ||
a == 3 && Math.abs(currentPlaybackSpeed - 1.8f) < 0.001f) {
speedItems[a].setColors(Theme.getColor(Theme.key_inappPlayerPlayPause), Theme.getColor(Theme.key_inappPlayerPlayPause));
} else {
speedItems[a].setColors(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem), Theme.getColor(Theme.key_actionBarDefaultSubmenuItemIcon));
}
}
}
@ -1422,9 +1474,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
if (path == null || path.length() == 0) {
path = FileLoader.getPathToMessage(messageObject.messageOwner).toString();
}
MediaController.saveFile(path, parentActivity, 3, fileName, messageObject.getDocument() != null ? messageObject.getDocument().mime_type : "", () -> {
BulletinFactory.of((FrameLayout) containerView).createDownloadBulletin(BulletinFactory.FileType.AUDIO).show();
});
MediaController.saveFile(path, parentActivity, 3, fileName, messageObject.getDocument() != null ? messageObject.getDocument().mime_type : "", () -> BulletinFactory.of((FrameLayout) containerView).createDownloadBulletin(BulletinFactory.FileType.AUDIO).show());
}
}
@ -1844,7 +1894,7 @@ public class AudioPlayerAlert extends BottomSheet implements NotificationCenter.
durationTextView.setText(duration != 0 ? AndroidUtilities.formatShortDuration(duration) : "-:--");
}
if (duration > 60 * 20) {
if (duration > 60 * 10) {
playbackSpeedButton.setVisibility(View.VISIBLE);
} else {
playbackSpeedButton.setVisibility(View.GONE);

View file

@ -284,7 +284,7 @@ public final class Bulletin {
layout.onExitTransitionEnd();
layout.onHide();
if (containerLayout != null) {
containerLayout.removeView(parentLayout);
AndroidUtilities.runOnUIThread(() -> containerLayout.removeView(parentLayout));
}
layout.onDetach();
}

View file

@ -755,6 +755,15 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
private Drawable lockShadowDrawable;
private Runnable runEmojiPanelAnimation = new Runnable() {
@Override
public void run() {
if (panelAnimation != null && !panelAnimation.isRunning()) {
panelAnimation.start();
}
}
};
public class RecordCircle extends View {
private float scale;
@ -996,9 +1005,9 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
tooltipWidth = w;
}
}
if (tooltipLayout.getLineCount() > 1) {
h += tooltipLayout.getHeight() - tooltipLayout.getLineBottom(0);
}
}
if (tooltipLayout != null && tooltipLayout.getLineCount() > 1) {
h += tooltipLayout.getHeight() - tooltipLayout.getLineBottom(0);
}
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY));
@ -2250,7 +2259,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
if (isInScheduleMode()) {
AlertsCreator.createScheduleDatePickerDialog(parentActivity, dialog_id, (notify, scheduleDate) -> {
SendMessagesHelper.getInstance(currentAccount).sendMessage((String) command, dialog_id, replyingMessageObject, getThreadMessage(), null, false, null, null, null, notify, scheduleDate, null);
SendMessagesHelper.getInstance(currentAccount).sendMessage(command, dialog_id, replyingMessageObject, getThreadMessage(), null, false, null, null, null, notify, scheduleDate, null);
setFieldText("");
botCommandsMenuContainer.dismiss();
});
@ -6863,7 +6872,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
requestLayout();
}
});
panelAnimation.start();
AndroidUtilities.runOnUIThread(runEmojiPanelAnimation, 50);
notificationsIndex = NotificationCenter.getInstance(currentAccount).setAnimationInProgress(notificationsIndex, null);
requestLayout();
}
@ -6907,7 +6916,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
});
notificationsIndex = NotificationCenter.getInstance(currentAccount).setAnimationInProgress(notificationsIndex, null);
panelAnimation.start();
AndroidUtilities.runOnUIThread(runEmojiPanelAnimation, 50);
requestLayout();
} else {
if (delegate != null) {
@ -6954,7 +6963,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
});
notificationsIndex = NotificationCenter.getInstance(currentAccount).setAnimationInProgress(notificationsIndex, null);
panelAnimation.start();
AndroidUtilities.runOnUIThread(runEmojiPanelAnimation, 50);
requestLayout();
} else {
if (!waitingForKeyboardOpen) {
@ -7246,7 +7255,7 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
NotificationCenter.getInstance(currentAccount).onAnimationFinish(notificationsIndex);
}
});
panelAnimation.start();
AndroidUtilities.runOnUIThread(runEmojiPanelAnimation, 50);
notificationsIndex = NotificationCenter.getInstance(currentAccount).setAnimationInProgress(notificationsIndex, null);
requestLayout();
}
@ -7288,6 +7297,10 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
return emojiPadding;
}
public int getVisibleEmojiPadding() {
return emojiViewVisible ? emojiPadding : 0;
}
private MessageObject getThreadMessage() {
return parentFragment != null ? parentFragment.getThreadMessage() : null;
}
@ -8356,4 +8369,9 @@ public class ChatActivityEnterView extends FrameLayout implements NotificationCe
}
return 0;
}
public void runEmojiPanelAnimation() {
AndroidUtilities.cancelRunOnUIThread(runEmojiPanelAnimation);
runEmojiPanelAnimation.run();
}
}

View file

@ -621,8 +621,10 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
chatActivity = null;
type = 4;
}
AndroidUtilities.hideKeyboard(parentAlert.baseFragment.getFragmentView().findFocus());
AndroidUtilities.hideKeyboard(parentAlert.getContainer().findFocus());
if (!parentAlert.delegate.needEnterComment()) {
AndroidUtilities.hideKeyboard(parentAlert.baseFragment.getFragmentView().findFocus());
AndroidUtilities.hideKeyboard(parentAlert.getContainer().findFocus());
}
PhotoViewer.getInstance().openPhotoForSelect(arrayList, position, type, false, photoViewerProvider, chatActivity);
} else {
if (SharedConfig.inappCamera) {
@ -1418,7 +1420,7 @@ public class ChatAttachAlertPhotoLayout extends ChatAttachAlert.AttachAlertLayou
return false;
}
int locked = Settings.System.getInt(parentAlert.baseFragment.getParentActivity().getContentResolver(), Settings.System.ACCELEROMETER_ROTATION, 0);
return true;//sameTakePictureOrientation || locked == 1;
return sameTakePictureOrientation || locked == 1;
}
@Override

View file

@ -24,7 +24,6 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.BuildVars;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
@ -123,8 +122,10 @@ public class ClearHistoryAlert extends BottomSheet {
newTimer = currentTimer = 0;
} else if (ttl == 24 * 60 * 60) {
newTimer = currentTimer = 1;
} else {
} else if (ttl == 7 * 24 * 60 * 60) {
newTimer = currentTimer = 2;
} else {
newTimer = currentTimer = 3;
}
shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow_round).mutate();
@ -345,7 +346,8 @@ public class ClearHistoryAlert extends BottomSheet {
String[] strings = new String[]{
LocaleController.getString("AutoDeleteNever", R.string.AutoDeleteNever),
LocaleController.getString("AutoDelete24Hours", R.string.AutoDelete24Hours),
LocaleController.getString("AutoDelete7Days", R.string.AutoDelete7Days)
LocaleController.getString("AutoDelete7Days", R.string.AutoDelete7Days),
LocaleController.getString("AutoDelete1Month", R.string.AutoDelete1Month)
};
slideChooseView.setOptions(currentTimer, strings);
linearLayout.addView(slideChooseView, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 8, 0, 0));
@ -379,7 +381,10 @@ public class ClearHistoryAlert extends BottomSheet {
dismissedDelayed = true;
int time;
int action;
if (newTimer == 2) {
if (newTimer == 3) {
time = 31 * 24 * 60 * 60;
action = UndoView.ACTION_AUTO_DELETE_ON;
} else if (newTimer == 2) {
time = 7 * 24 * 60 * 60;
action = UndoView.ACTION_AUTO_DELETE_ON;
} else if (newTimer == 1) {

View file

@ -89,6 +89,9 @@ public class CounterView extends View {
if (count > 0) {
setVisibility(View.VISIBLE);
}
if (Math.abs(count - currentCount) > 99) {
animated = false;
}
if (!animated) {
currentCount = count;
if (count == 0) {

View file

@ -764,12 +764,11 @@ public class EditTextBoldCursor extends EditText {
private boolean updateCursorPosition() {
final Layout layout = getLayout();
final int offset = getSelectionStart();
if (offset != lastOffset || lastText != layout.getText()) {
final int line = layout.getLineForOffset(offset);
final int top = layout.getLineTop(line);
final int bottom = layout.getLineTop(line + 1);
updateCursorPosition(top, bottom, layout.getPrimaryHorizontal(offset));
}
final int line = layout.getLineForOffset(offset);
final int top = layout.getLineTop(line);
final int bottom = layout.getLineTop(line + 1);
updateCursorPosition(top, bottom, layout.getPrimaryHorizontal(offset));
lastText = layout.getText();
lastOffset = offset;
return true;

View file

@ -53,6 +53,7 @@ import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BringAppForegroundService;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
@ -60,6 +61,7 @@ import org.telegram.messenger.browser.Browser;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PhotoViewer;
import java.util.HashMap;
import java.util.Locale;
@ -217,17 +219,23 @@ public class EmbedBottomSheet extends BottomSheet {
@SuppressLint("StaticFieldLeak")
private static EmbedBottomSheet instance;
public static void show(Context context, String title, String description, String originalUrl, final String url, int w, int h, boolean keyboardVisible) {
show(context, title, description, originalUrl, url, w, h, -1, keyboardVisible);
public static void show(Activity activity, MessageObject message, PhotoViewer.PhotoViewerProvider photoViewerProvider, String title, String description, String originalUrl, final String url, int w, int h, boolean keyboardVisible) {
show(activity, message, photoViewerProvider, title, description, originalUrl, url, w, h, -1, keyboardVisible);
}
public static void show(Context context, String title, String description, String originalUrl, final String url, int w, int h, int seekTime, boolean keyboardVisible) {
public static void show(Activity activity, MessageObject message, PhotoViewer.PhotoViewerProvider photoViewerProvider, String title, String description, String originalUrl, final String url, int w, int h, int seekTime, boolean keyboardVisible) {
if (instance != null) {
instance.destroy();
}
EmbedBottomSheet sheet = new EmbedBottomSheet(context, title, description, originalUrl, url, w, h, seekTime);
sheet.setCalcMandatoryInsets(keyboardVisible);
sheet.show();
String youtubeId = message != null && message.messageOwner.media != null && message.messageOwner.media.webpage != null ? WebPlayerView.getYouTubeVideoId(url) : null;
if (youtubeId != null) {
PhotoViewer.getInstance().setParentActivity(activity);
PhotoViewer.getInstance().openPhoto(message, seekTime, null, 0, 0, photoViewerProvider);
} else {
EmbedBottomSheet sheet = new EmbedBottomSheet(activity, title, description, originalUrl, url, w, h, seekTime);
sheet.setCalcMandatoryInsets(keyboardVisible);
sheet.show();
}
}
@SuppressLint("SetJavaScriptEnabled")
@ -259,10 +267,8 @@ public class EmbedBottomSheet extends BottomSheet {
fullscreenVideoContainer.setFitsSystemWindows(true);
}
fullscreenVideoContainer.setOnTouchListener((v, event) -> true);
container.addView(fullscreenVideoContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
fullscreenVideoContainer.setVisibility(View.INVISIBLE);
fullscreenVideoContainer.setOnTouchListener((v, event) -> true);
containerLayout = new FrameLayout(context) {
@Override

View file

@ -66,6 +66,8 @@ import org.telegram.messenger.UserObject;
import org.telegram.messenger.voip.VoIPService;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
@ -94,7 +96,8 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
private RLottieImageView muteButton;
private RLottieDrawable muteDrawable;
private ImageView closeButton;
private ImageView playbackSpeedButton;
private ActionBarMenuItem playbackSpeedButton;
private ActionBarMenuSubItem[] speedItems = new ActionBarMenuSubItem[4];
private FragmentContextView additionalContextView;
private TextView joinButton;
@ -168,6 +171,11 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
private boolean checkPlayerAfterAnimation;
private boolean checkImportAfterAnimation;
private final static int menu_speed_slow = 1;
private final static int menu_speed_normal = 2;
private final static int menu_speed_fast = 3;
private final static int menu_speed_veryfast = 4;
@Override
public void onAudioSettingsChanged() {
boolean newMuted = VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().isMicMute();
@ -349,22 +357,49 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
joinButton.setOnClickListener(v -> FragmentContextView.this.callOnClick());
if (!location) {
playbackSpeedButton = new ImageView(context);
playbackSpeedButton.setScaleType(ImageView.ScaleType.CENTER);
playbackSpeedButton.setImageResource(R.drawable.voice2x);
playbackSpeedButton = new ActionBarMenuItem(context, null, 0, Theme.getColor(Theme.key_dialogTextBlack));
playbackSpeedButton.setLongClickEnabled(false);
playbackSpeedButton.setShowSubmenuByMove(false);
playbackSpeedButton.setContentDescription(LocaleController.getString("AccDescrPlayerSpeed", R.string.AccDescrPlayerSpeed));
if (AndroidUtilities.density >= 3.0f) {
playbackSpeedButton.setPadding(0, 1, 0, 0);
}
addView(playbackSpeedButton, LayoutHelper.createFrame(36, 36, Gravity.TOP | Gravity.RIGHT, 0, 0, 36, 0));
playbackSpeedButton.setOnClickListener(v -> {
float currentPlaybackSpeed = MediaController.getInstance().getPlaybackSpeed(isMusic);
if (currentPlaybackSpeed > 1) {
playbackSpeedButton.setDelegate(id -> {
float oldSpeed = MediaController.getInstance().getPlaybackSpeed(isMusic);
if (id == menu_speed_slow) {
MediaController.getInstance().setPlaybackSpeed(isMusic, 0.5f);
} else if (id == menu_speed_normal) {
MediaController.getInstance().setPlaybackSpeed(isMusic, 1.0f);
} else if (id == menu_speed_fast) {
MediaController.getInstance().setPlaybackSpeed(isMusic, 1.5f);
} else {
MediaController.getInstance().setPlaybackSpeed(isMusic, 1.8f);
}
playbackSpeedChanged(currentPlaybackSpeed <= 1);
float newSpeed = MediaController.getInstance().getPlaybackSpeed(isMusic);
if (oldSpeed != newSpeed) {
playbackSpeedChanged(newSpeed);
}
updatePlaybackButton();
});
speedItems[0] = playbackSpeedButton.addSubItem(menu_speed_slow, R.drawable.msg_speed_0_5, LocaleController.getString("SpeedSlow", R.string.SpeedSlow));
speedItems[1] = playbackSpeedButton.addSubItem(menu_speed_normal, R.drawable.msg_speed_1, LocaleController.getString("SpeedNormal", R.string.SpeedNormal));
speedItems[2] = playbackSpeedButton.addSubItem(menu_speed_fast, R.drawable.msg_speed_1_5, LocaleController.getString("SpeedFast", R.string.SpeedFast));
speedItems[3] = playbackSpeedButton.addSubItem(menu_speed_veryfast, R.drawable.msg_speed_2, LocaleController.getString("SpeedVeryFast", R.string.SpeedVeryFast));
if (AndroidUtilities.density >= 3.0f) {
playbackSpeedButton.setPadding(0, 1, 0, 0);
}
playbackSpeedButton.setAdditionalXOffset(AndroidUtilities.dp(8));
addView(playbackSpeedButton, LayoutHelper.createFrame(36, 36, Gravity.TOP | Gravity.RIGHT, 0, 0, 36, 0));
playbackSpeedButton.setOnClickListener(v -> {
float currentPlaybackSpeed = MediaController.getInstance().getPlaybackSpeed(isMusic);
float newSpeed;
if (Math.abs(currentPlaybackSpeed - 1.0f) > 0.001f) {
MediaController.getInstance().setPlaybackSpeed(isMusic, newSpeed = 1.0f);
} else {
MediaController.getInstance().setPlaybackSpeed(isMusic, newSpeed = MediaController.getInstance().getFastPlaybackSpeed(isMusic));
}
playbackSpeedChanged(newSpeed);
});
playbackSpeedButton.setOnLongClickListener(view -> {
playbackSpeedButton.toggleSubMenu();
return true;
});
updatePlaybackButton();
}
@ -647,15 +682,33 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
}
float currentPlaybackSpeed = MediaController.getInstance().getPlaybackSpeed(isMusic);
String key;
if (currentPlaybackSpeed > 1) {
if (Math.abs(currentPlaybackSpeed - 1.0f) > 0.001f) {
key = Theme.key_inappPlayerPlayPause;
} else {
key = Theme.key_inappPlayerClose;
}
playbackSpeedButton.setColorFilter(new PorterDuffColorFilter(Theme.getColor(key), PorterDuff.Mode.MULTIPLY));
float speed = MediaController.getInstance().getFastPlaybackSpeed(isMusic);
if (Math.abs(speed - 1.8f) < 0.001f) {
playbackSpeedButton.setIcon(R.drawable.voice_mini_2_0);
} else if (Math.abs(speed - 1.5f) < 0.001f) {
playbackSpeedButton.setIcon(R.drawable.voice_mini_1_5);
} else {
playbackSpeedButton.setIcon(R.drawable.voice_mini_0_5);
}
playbackSpeedButton.setIconColor(Theme.getColor(key));
if (Build.VERSION.SDK_INT >= 21) {
playbackSpeedButton.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(key) & 0x19ffffff, 1, AndroidUtilities.dp(14)));
}
for (int a = 0; a < speedItems.length; a++) {
if (a == 0 && Math.abs(currentPlaybackSpeed - 0.5f) < 0.001f ||
a == 1 && Math.abs(currentPlaybackSpeed - 1.0f) < 0.001f ||
a == 2 && Math.abs(currentPlaybackSpeed - 1.5f) < 0.001f ||
a == 3 && Math.abs(currentPlaybackSpeed - 1.8f) < 0.001f) {
speedItems[a].setColors(Theme.getColor(Theme.key_inappPlayerPlayPause), Theme.getColor(Theme.key_inappPlayerPlayPause));
} else {
speedItems[a].setColors(Theme.getColor(Theme.key_actionBarDefaultSubmenuItem), Theme.getColor(Theme.key_actionBarDefaultSubmenuItemIcon));
}
}
}
public void setAdditionalContextView(FragmentContextView contextView) {
@ -721,7 +774,7 @@ public class FragmentContextView extends FrameLayout implements NotificationCent
}
}
protected void playbackSpeedChanged(boolean enabled) {
protected void playbackSpeedChanged(float value) {
}

View file

@ -0,0 +1,20 @@
package org.telegram.ui.Components;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.View;
public class HideViewAfterAnimation extends AnimatorListenerAdapter {
private final View view;
public HideViewAfterAnimation(View view) {
this.view = view;
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
view.setVisibility(View.GONE);
}
}

View file

@ -20,6 +20,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Outline;
import android.graphics.Paint;
@ -57,6 +58,8 @@ import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.ExoPlayer;
import org.telegram.messenger.AndroidUtilities;
@ -68,6 +71,7 @@ import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageReceiver;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MediaController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
@ -84,6 +88,7 @@ import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.Components.voip.CellFlickerDrawable;
import java.io.File;
import java.io.FileOutputStream;
@ -152,6 +157,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
private TextureView textureView;
private BackupImageView textureOverlayView;
private CameraSession cameraSession;
private boolean needDrawFlickerStub;
private float panTranslationY;
private float animationTranslationY;
@ -212,6 +218,8 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
boolean maybePinchToZoomTouchMode;
private int pointerId1, pointerId2;
private int textureViewSize;
private boolean isMessageTransition;
@SuppressLint("ClickableViewAccessibility")
public InstantCameraView(Context context, ChatActivity parentFragment) {
@ -254,7 +262,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void getOutline(View view, Outline outline) {
outline.setOval(0, 0, AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize);
outline.setOval(0, 0, textureViewSize, textureViewSize);
}
});
cameraContainer.setClipToOutline(true);
@ -294,7 +302,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
cameraContainer.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
addView(cameraContainer, new FrameLayout.LayoutParams(AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize, Gravity.CENTER));
addView(cameraContainer, new FrameLayout.LayoutParams(AndroidUtilities.roundPlayingMessageSize, AndroidUtilities.roundPlayingMessageSize, Gravity.CENTER));
switchCameraButton = new ImageView(context);
switchCameraButton.setScaleType(ImageView.ScaleType.CENTER);
@ -321,16 +329,55 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
muteImageView.setImageResource(R.drawable.video_mute);
muteImageView.setAlpha(0.0f);
addView(muteImageView, LayoutHelper.createFrame(48, 48, Gravity.CENTER));
((LayoutParams) muteImageView.getLayoutParams()).topMargin = AndroidUtilities.roundMessageSize / 2 - AndroidUtilities.dp(24);
textureOverlayView = new BackupImageView(getContext());
textureOverlayView.setRoundRadius(AndroidUtilities.roundMessageSize / 2);
addView(textureOverlayView, new FrameLayout.LayoutParams(AndroidUtilities.roundMessageSize, AndroidUtilities.roundMessageSize, Gravity.CENTER));
Paint blackoutPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
blackoutPaint.setColor(ColorUtils.setAlphaComponent(Color.BLACK, 40));
textureOverlayView = new BackupImageView(getContext()) {
CellFlickerDrawable flickerDrawable = new CellFlickerDrawable();
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (needDrawFlickerStub) {
flickerDrawable.setParentWidth(textureViewSize);
AndroidUtilities.rectTmp.set(0, 0, textureViewSize, textureViewSize);
float rad = AndroidUtilities.rectTmp.width() / 2f;
canvas.drawRoundRect(AndroidUtilities.rectTmp, rad, rad, blackoutPaint);
AndroidUtilities.rectTmp.inset(AndroidUtilities.dp(1), AndroidUtilities.dp(1));
flickerDrawable.draw(canvas, AndroidUtilities.rectTmp, rad);
invalidate();
}
}
};
addView(textureOverlayView, new FrameLayout.LayoutParams(AndroidUtilities.roundPlayingMessageSize, AndroidUtilities.roundPlayingMessageSize, Gravity.CENTER));
setVisibility(INVISIBLE);
blurBehindDrawable = new BlurBehindDrawable(parentView, this);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int newSize;
if (MeasureSpec.getSize(heightMeasureSpec) > MeasureSpec.getSize(widthMeasureSpec)) {
newSize = AndroidUtilities.roundPlayingMessageSize;
} else {
newSize = AndroidUtilities.roundMessageSize;
}
if (newSize != textureViewSize) {
textureViewSize = newSize;
textureOverlayView.getLayoutParams().width = textureOverlayView.getLayoutParams().height = textureViewSize;
cameraContainer.getLayoutParams().width = cameraContainer.getLayoutParams().height = textureViewSize;
((LayoutParams) muteImageView.getLayoutParams()).topMargin = textureViewSize / 2 - AndroidUtilities.dp(24);
textureOverlayView.setRoundRadius(textureViewSize / 2);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
cameraContainer.invalidateOutline();
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private boolean checkPointerIds(MotionEvent ev) {
if (ev.getPointerCount() < 2) {
return false;
@ -418,9 +465,13 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
int x1 = (int) x - AndroidUtilities.dp(3);
int y1 = (int) y - AndroidUtilities.dp(2);
canvas.save();
canvas.scale(cameraContainer.getScaleX(), cameraContainer.getScaleY(), x1 + AndroidUtilities.roundMessageSize / 2 + AndroidUtilities.dp(3), y1 + AndroidUtilities.roundMessageSize / 2 + AndroidUtilities.dp(3));
if (isMessageTransition) {
canvas.scale(cameraContainer.getScaleX(), cameraContainer.getScaleY(), x, y);
} else {
canvas.scale(cameraContainer.getScaleX(), cameraContainer.getScaleY(), x + textureViewSize / 2f, y + textureViewSize / 2f);
}
Theme.chat_roundVideoShadow.setAlpha((int) (cameraContainer.getAlpha() * 255));
Theme.chat_roundVideoShadow.setBounds(x1, y1, x1 + AndroidUtilities.roundMessageSize + AndroidUtilities.dp(6), y1 + AndroidUtilities.roundMessageSize + AndroidUtilities.dp(6));
Theme.chat_roundVideoShadow.setBounds(x1, y1, x1 + textureViewSize + AndroidUtilities.dp(6), y1 + textureViewSize + AndroidUtilities.dp(6));
Theme.chat_roundVideoShadow.draw(canvas);
canvas.restore();
}
@ -466,6 +517,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
switchCameraButton.setImageResource(R.drawable.camera_revert1);
textureOverlayView.setAlpha(1.0f);
textureOverlayView.invalidate();
if (lastBitmap == null) {
try {
File file = new File(ApplicationLoader.getFilesDirFixed(), "icthumb.jpg");
@ -489,6 +541,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
encryptedFile = null;
key = null;
iv = null;
needDrawFlickerStub = true;
if (!initCamera()) {
return;
@ -662,7 +715,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
long endTime = videoEditedInfo.endTime >= 0 ? videoEditedInfo.endTime : videoEditedInfo.estimatedDuration;
videoEditedInfo.estimatedDuration = endTime - startTime;
videoEditedInfo.estimatedSize = Math.max(1, (long) (size * (videoEditedInfo.estimatedDuration / totalDuration)));
videoEditedInfo.bitrate = 400000;
videoEditedInfo.bitrate = 1000000;
if (videoEditedInfo.startTime > 0) {
videoEditedInfo.startTime *= 1000;
}
@ -716,7 +769,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
private void saveLastCameraBitmap() {
Bitmap bitmap = textureView.getBitmap();
if (bitmap != null && bitmap.getPixel(0, 0) != 0) {
lastBitmap = Bitmap.createScaledBitmap(textureView.getBitmap(), 80, 80, true);
lastBitmap = Bitmap.createScaledBitmap(textureView.getBitmap(), 50, 50, true);
if (lastBitmap != null) {
Utilities.blurBitmap(lastBitmap, 7, 1, lastBitmap.getWidth(), lastBitmap.getHeight(), lastBitmap.getRowBytes());
try {
@ -791,6 +844,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
private void switchCamera() {
saveLastCameraBitmap();
if (lastBitmap != null) {
needDrawFlickerStub = false;
textureOverlayView.setImageBitmap(lastBitmap);
textureOverlayView.setAlpha(1f);
}
@ -857,7 +911,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
Size preview = previewSizes.get(a);
for (int b = pictureSizes.size() - 1; b >= 0; b--) {
Size picture = pictureSizes.get(b);
if (preview.mWidth >= 240 && preview.mHeight >= 240 && preview.mWidth == picture.mWidth && preview.mHeight == picture.mHeight) {
if (preview.mWidth >= 360 && preview.mHeight >= 360 && preview.mWidth == picture.mWidth && preview.mHeight == picture.mHeight) {
previewSize = preview;
pictureSize = picture;
found = true;
@ -979,6 +1033,10 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
return textureView;
}
public void setIsMessageTransition(boolean isMessageTransition) {
this.isMessageTransition = isMessageTransition;
}
public class CameraGLThread extends DispatchQueue {
private final static int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
@ -1598,19 +1656,8 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
};
public void startRecording(File outputFile, android.opengl.EGLContext sharedContext) {
int resolution;
int bitrate;
String model = Build.DEVICE;
if (model == null) {
model = "";
}
if (model.startsWith("zeroflte") || model.startsWith("zenlte")) {
resolution = 320;
bitrate = 600000;
} else {
resolution = 240;
bitrate = 400000;
}
int resolution = MessagesController.getInstance(currentAccount).roundVideoSize;
int bitrate = MessagesController.getInstance(currentAccount).roundVideoBitrate * 1024;
videoFile = outputFile;
videoWidth = resolution;
@ -1980,8 +2027,8 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
videoEditedInfo.iv = iv;
videoEditedInfo.estimatedSize = Math.max(1, size);
videoEditedInfo.framerate = 25;
videoEditedInfo.resultWidth = videoEditedInfo.originalWidth = 240;
videoEditedInfo.resultHeight = videoEditedInfo.originalHeight = 240;
videoEditedInfo.resultWidth = videoEditedInfo.originalWidth = 360;
videoEditedInfo.resultHeight = videoEditedInfo.originalHeight = 360;
videoEditedInfo.originalPath = videoFile.getAbsolutePath();
if (send == 1) {
if (baseFragment.isInScheduleMode()) {
@ -2103,7 +2150,7 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
audioFormat.setString(MediaFormat.KEY_MIME, AUDIO_MIME_TYPE);
audioFormat.setInteger(MediaFormat.KEY_SAMPLE_RATE, 44100);
audioFormat.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, 32000);
audioFormat.setInteger(MediaFormat.KEY_BIT_RATE, MessagesController.getInstance(currentAccount).roundAudioBitrate * 1024);
audioFormat.setInteger(MediaFormat.KEY_MAX_INPUT_SIZE, 2048 * AudioBufferInfo.MAX_SAMPLES);
audioEncoder = MediaCodec.createEncoderByType(AUDIO_MIME_TYPE);
@ -2456,6 +2503,10 @@ public class InstantCameraView extends FrameLayout implements NotificationCenter
}
if (imageReceiver != null) {
canvas.save();
if (imageReceiver.getImageWidth() != textureViewSize) {
float s = textureViewSize / imageReceiver.getImageWidth();
canvas.scale(s, s);
}
canvas.translate(-imageReceiver.getImageX(), -imageReceiver.getImageY());
float oldAlpha = imageReceiver.getAlpha();
imageReceiver.setAlpha(imageProgress);

View file

@ -883,9 +883,9 @@ public class PasscodeView extends FrameLayout {
numbersFrameLayout.setVisibility(INVISIBLE);
}
AndroidUtilities.hideKeyboard(passwordEditText);
AndroidUtilities.cancelRunOnUIThread(checkRunnable);
AndroidUtilities.runOnUIThread(checkRunnable, 100);
}
AndroidUtilities.cancelRunOnUIThread(checkRunnable);
AndroidUtilities.runOnUIThread(checkRunnable, 100);
} else {
AndroidUtilities.cancelRunOnUIThread(checkRunnable);
if (passwordFrameLayout.getVisibility() != VISIBLE) {

View file

@ -0,0 +1,376 @@
package org.telegram.ui.Components;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.net.Uri;
import android.os.Build;
import android.provider.Settings;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.CookieManager;
import android.webkit.JavascriptInterface;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.BringAppForegroundService;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.UserConfig;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.browser.Browser;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.PhotoViewer;
import java.util.HashMap;
import java.util.Locale;
public class PhotoViewerWebView extends FrameLayout {
private int currentAccount = UserConfig.selectedAccount;
private PipVideoView pipVideoView;
private WebView webView;
private View progressBarBlackBackground;
private RadialProgressView progressBar;
private View pipItem;
private boolean isYouTube;
private TLRPC.WebPage currentWebpage;
private float playbackSpeed;
private boolean setPlaybackSpeed;
private class YoutubeProxy {
@JavascriptInterface
public void postEvent(final String eventName, final String eventData) {
if ("loaded".equals(eventName)) {
AndroidUtilities.runOnUIThread(() -> {
progressBar.setVisibility(View.INVISIBLE);
progressBarBlackBackground.setVisibility(View.INVISIBLE);
if (setPlaybackSpeed) {
setPlaybackSpeed = false;
setPlaybackSpeed(playbackSpeed);
}
pipItem.setEnabled(true);
pipItem.setAlpha(1.0f);
});
}
}
}
private static final String youtubeFrame = "<!DOCTYPE html><html><head><style>" +
"body { margin: 0; width:100%%; height:100%%; background-color:#000; }" +
"html { width:100%%; height:100%%; background-color:#000; }" +
".embed-container iframe," +
".embed-container object," +
" .embed-container embed {" +
" position: absolute;" +
" top: 0;" +
" left: 0;" +
" width: 100%% !important;" +
" height: 100%% !important;" +
" }" +
" </style></head><body>" +
" <div class=\"embed-container\">" +
" <div id=\"player\"></div>" +
" </div>" +
" <script src=\"https://www.youtube.com/iframe_api\"></script>" +
" <script>" +
" var player;" +
" var posted = false;" +
" YT.ready(function() {" +
" player = new YT.Player(\"player\", {" +
" \"width\" : \"100%%\"," +
" \"events\" : {" +
" \"onReady\" : \"onReady\"," +
" \"onError\" : \"onError\"," +
" \"onStateChange\" : \"onStateChange\"," +
" }," +
" \"videoId\" : \"%1$s\"," +
" \"height\" : \"100%%\"," +
" \"playerVars\" : {" +
" \"start\" : %2$d," +
" \"rel\" : 1," +
" \"showinfo\" : 0," +
" \"modestbranding\" : 0," +
" \"iv_load_policy\" : 3," +
" \"autohide\" : 1," +
" \"autoplay\" : 1," +
" \"cc_load_policy\" : 1," +
" \"playsinline\" : 1," +
" \"controls\" : 1" +
" }" +
" });" +
" player.setSize(window.innerWidth, window.innerHeight);" +
" });" +
" function setPlaybackSpeed(speed) { " +
" player.setPlaybackRate(speed);" +
" }" +
" function onError(event) {" +
" if (!posted) {" +
" if (window.YoutubeProxy !== undefined) {" +
" YoutubeProxy.postEvent(\"loaded\", null); " +
" }" +
" posted = true;" +
" }" +
" }" +
" function onStateChange(event) {" +
" if (event.data == YT.PlayerState.PLAYING && !posted) {" +
" if (window.YoutubeProxy !== undefined) {" +
" YoutubeProxy.postEvent(\"loaded\", null); " +
" }" +
" posted = true;" +
" }" +
" }" +
" function onReady(event) {" +
" player.playVideo();" +
" }" +
" window.onresize = function() {" +
" player.setSize(window.innerWidth, window.innerHeight);" +
" player.playVideo();" +
" }" +
" </script>" +
"</body>" +
"</html>";
@SuppressLint("SetJavaScriptEnabled")
public PhotoViewerWebView(Context context, View pip) {
super(context);
pipItem = pip;
webView = new WebView(context) {
@Override
public boolean onTouchEvent(MotionEvent event) {
processTouch(event);
return super.onTouchEvent(event);
}
};
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
if (Build.VERSION.SDK_INT >= 17) {
webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
}
if (Build.VERSION.SDK_INT >= 21) {
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptThirdPartyCookies(webView, true);
}
webView.setWebViewClient(new WebViewClient() {
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
if (!isYouTube || Build.VERSION.SDK_INT < 17) {
progressBar.setVisibility(View.INVISIBLE);
progressBarBlackBackground.setVisibility(View.INVISIBLE);
pipItem.setEnabled(true);
pipItem.setAlpha(1.0f);
}
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (isYouTube) {
Browser.openUrl(view.getContext(), url);
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
});
addView(webView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
progressBarBlackBackground = new View(context) {
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
drawBlackBackground(canvas, getMeasuredWidth(), getMeasuredHeight());
}
};
progressBarBlackBackground.setBackgroundColor(0xff000000);
progressBarBlackBackground.setVisibility(View.INVISIBLE);
addView(progressBarBlackBackground, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
progressBar = new RadialProgressView(context);
progressBar.setVisibility(View.INVISIBLE);
addView(progressBar, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER));
}
private void runJsCode(String code) {
if (Build.VERSION.SDK_INT >= 21) {
webView.evaluateJavascript(code, null);
} else {
try {
webView.loadUrl("javascript:" + code);
} catch (Exception e) {
FileLog.e(e);
}
}
}
protected void processTouch(MotionEvent event) {
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (webView.getParent() == this) {
int w = currentWebpage.embed_width != 0 ? currentWebpage.embed_width : 100;
int h = currentWebpage.embed_height != 0 ? currentWebpage.embed_height : 100;
int viewWidth = MeasureSpec.getSize(widthMeasureSpec);
int viewHeight = MeasureSpec.getSize(heightMeasureSpec);
float minScale = Math.min(viewWidth / (float) w, viewHeight / (float) h);
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) webView.getLayoutParams();
layoutParams.width = (int) (w * minScale);
layoutParams.height = (int) (h * minScale);
layoutParams.topMargin = (viewHeight - layoutParams.height) / 2;
layoutParams.leftMargin = (viewWidth - layoutParams.width) / 2;
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
protected void drawBlackBackground(Canvas canvas, int w, int h) {
}
public boolean isLoaded() {
return progressBar.getVisibility() != View.VISIBLE;
}
public PipVideoView openInPip() {
boolean inAppOnly = isYouTube && "inapp".equals(MessagesController.getInstance(currentAccount).youtubePipType);
if (!inAppOnly && !checkInlinePermissions()) {
return null;
}
if (progressBar.getVisibility() == View.VISIBLE) {
return null;
}
boolean animated = false;
pipVideoView = new PipVideoView(inAppOnly);
pipVideoView.show((Activity) getContext(), PhotoViewer.getInstance(), currentWebpage.embed_width != 0 && currentWebpage.embed_height != 0 ? currentWebpage.embed_width / (float) currentWebpage.embed_height : 1.0f, 0, webView);
return pipVideoView;
}
public void setPlaybackSpeed(float speed) {
playbackSpeed = speed;
if (progressBar.getVisibility() != View.VISIBLE) {
if (isYouTube) {
runJsCode("setPlaybackSpeed(" + speed + ");");
}
} else {
setPlaybackSpeed = true;
}
}
@SuppressLint("AddJavascriptInterface")
public void init(int seekTime, TLRPC.WebPage webPage) {
currentWebpage = webPage;
String currentYoutubeId = WebPlayerView.getYouTubeVideoId(webPage.embed_url);
String originalUrl = webPage.url;
requestLayout();
try {
if (currentYoutubeId != null) {
progressBarBlackBackground.setVisibility(View.VISIBLE);
isYouTube = true;
if (Build.VERSION.SDK_INT >= 17) {
webView.addJavascriptInterface(new YoutubeProxy(), "YoutubeProxy");
}
int seekToTime = 0;
if (originalUrl != null) {
try {
Uri uri = Uri.parse(originalUrl);
String t = seekTime > 0 ? "" + seekTime : null;
if (t == null) {
t = uri.getQueryParameter("t");
if (t == null) {
t = uri.getQueryParameter("time_continue");
}
}
if (t != null) {
if (t.contains("m")) {
String[] arg = t.split("m");
seekToTime = Utilities.parseInt(arg[0]) * 60 + Utilities.parseInt(arg[1]);
} else {
seekToTime = Utilities.parseInt(t);
}
}
} catch (Exception e) {
FileLog.e(e);
}
}
webView.loadDataWithBaseURL("https://messenger.telegram.org/", String.format(Locale.US, youtubeFrame, currentYoutubeId, seekToTime), "text/html", "UTF-8", "https://youtube.com");
} else {
HashMap<String, String> args = new HashMap<>();
args.put("Referer", "messenger.telegram.org");
webView.loadUrl(webPage.embed_url, args);
}
} catch (Exception e) {
FileLog.e(e);
}
pipItem.setEnabled(false);
pipItem.setAlpha(0.5f);
progressBar.setVisibility(View.VISIBLE);
if (currentYoutubeId != null) {
progressBarBlackBackground.setVisibility(View.VISIBLE);
}
webView.setVisibility(View.VISIBLE);
webView.setKeepScreenOn(true);
if (currentYoutubeId != null && "disabled".equals(MessagesController.getInstance(currentAccount).youtubePipType)) {
pipItem.setVisibility(View.GONE);
}
}
public boolean checkInlinePermissions() {
if (Build.VERSION.SDK_INT < 23 || Settings.canDrawOverlays(getContext())) {
return true;
} else {
AlertsCreator.createDrawOverlayPermissionDialog((Activity) getContext(), null);
}
return false;
}
public void exitFromPip() {
if (webView == null || pipVideoView == null) {
return;
}
if (ApplicationLoader.mainInterfacePaused) {
try {
getContext().startService(new Intent(ApplicationLoader.applicationContext, BringAppForegroundService.class));
} catch (Throwable e) {
FileLog.e(e);
}
}
ViewGroup parent = (ViewGroup) webView.getParent();
if (parent != null) {
parent.removeView(webView);
}
addView(webView, 0, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT));
pipVideoView.close();
pipVideoView = null;
}
public void release() {
webView.stopLoading();
webView.loadUrl("about:blank");
webView.destroy();
}
}

View file

@ -278,6 +278,10 @@ public class PipVideoView {
return show(activity, null, sheet, controls, aspectRatio, rotation, webview);
}
public TextureView show(Activity activity, PhotoViewer viewer, float aspectRatio, int rotation, WebView webview) {
return show(activity, viewer, null, null, aspectRatio, rotation, webview);
}
public TextureView show(Activity activity, PhotoViewer viewer, float aspectRatio, int rotation) {
return show(activity, viewer, null, null, aspectRatio, rotation, null);
}
@ -432,7 +436,6 @@ public class PipVideoView {
return null;
}
return textureView;
}

View file

@ -1944,7 +1944,7 @@ public class RecyclerListView extends RecyclerView {
@Override
public boolean onTouchEvent(MotionEvent e) {
if (multiSelectionGesture && e.getAction() != MotionEvent.ACTION_UP && e.getAction() != MotionEvent.ACTION_CANCEL) {
if (multiSelectionGesture && e.getAction() != MotionEvent.ACTION_DOWN &&e.getAction() != MotionEvent.ACTION_UP && e.getAction() != MotionEvent.ACTION_CANCEL) {
if (lastX == Float.MAX_VALUE && lastY == Float.MAX_VALUE) {
lastX = e.getX();
lastY = e.getY();

View file

@ -30,6 +30,7 @@ public class RoundVideoPlayingDrawable extends Drawable {
private int progress2Direction = 1;
private int progress3Direction = 1;
private View parentView;
int alpha = 255;
public RoundVideoPlayingDrawable(View view) {
super();
@ -92,6 +93,9 @@ public class RoundVideoPlayingDrawable extends Drawable {
@Override
public void draw(Canvas canvas) {
paint.setColor(Theme.getColor(Theme.key_chat_serviceText));
if (alpha != 255) {
paint.setAlpha((int) (alpha * (paint.getAlpha() / 255f)));
}
int x = getBounds().left;
int y = getBounds().top;
for (int a = 0; a < 3; a++) {
@ -106,7 +110,7 @@ public class RoundVideoPlayingDrawable extends Drawable {
@Override
public void setAlpha(int alpha) {
this.alpha = alpha;
}
@Override

View file

@ -422,9 +422,9 @@ public class ScrollSlidingTextTabStrip extends HorizontalScrollView {
int currentScrollX = getScrollX();
int left = child.getLeft();
int width = child.getMeasuredWidth();
if (left < currentScrollX) {
smoothScrollTo(left, 0);
} else if (left + width > currentScrollX + getWidth()) {
if (left - AndroidUtilities.dp(50) < currentScrollX) {
smoothScrollTo(left - AndroidUtilities.dp(50), 0);
} else if (left + width + AndroidUtilities.dp(21) > currentScrollX + getWidth()) {
smoothScrollTo(left + width, 0);
}
}

View file

@ -481,7 +481,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
@Override
public PhotoViewer.PlaceProviderObject getPlaceForPhoto(MessageObject messageObject, TLRPC.FileLocation fileLocation, int index, boolean needPreview) {
if (messageObject == null || mediaPages[0].selectedType != 0 && mediaPages[0].selectedType != 1 && mediaPages[0].selectedType != 5) {
if (messageObject == null || mediaPages[0].selectedType != 0 && mediaPages[0].selectedType != 1 && mediaPages[0].selectedType != 3 && mediaPages[0].selectedType != 5) {
return null;
}
final RecyclerListView listView = mediaPages[0].listView;
@ -537,6 +537,13 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
imageReceiver = cell.getPhotoImage();
cell.getLocationInWindow(coords);
}
} else if (view instanceof SharedLinkCell) {
SharedLinkCell cell = (SharedLinkCell) view;
MessageObject message = cell.getMessage();
if (message != null && message.getId() == messageObject.getId()) {
imageReceiver = cell.getLinkImageView();
cell.getLocationInWindow(coords);
}
}
if (imageReceiver != null) {
PhotoViewer.PlaceProviderObject object = new PhotoViewer.PlaceProviderObject();
@ -2969,7 +2976,7 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
ArticleViewer.getInstance().open(message);
return;
} else if (webPage.embed_url != null && webPage.embed_url.length() != 0) {
openWebView(webPage);
openWebView(webPage, message);
return;
} else {
link = webPage.url;
@ -2996,8 +3003,8 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
}
}
private void openWebView(TLRPC.WebPage webPage) {
EmbedBottomSheet.show(profileActivity.getParentActivity(), webPage.site_name, webPage.description, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height, false);
private void openWebView(TLRPC.WebPage webPage, MessageObject message) {
EmbedBottomSheet.show(profileActivity.getParentActivity(), message, provider, webPage.site_name, webPage.description, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height, false);
}
private void recycleAdapter(RecyclerView.Adapter adapter) {
@ -3037,8 +3044,8 @@ public class SharedMediaLayout extends FrameLayout implements NotificationCenter
SharedLinkCell.SharedLinkCellDelegate sharedLinkCellDelegate = new SharedLinkCell.SharedLinkCellDelegate() {
@Override
public void needOpenWebView(TLRPC.WebPage webPage) {
openWebView(webPage);
public void needOpenWebView(TLRPC.WebPage webPage, MessageObject message) {
openWebView(webPage, message);
}
@Override

View file

@ -66,6 +66,11 @@ public class TimerDrawable extends Drawable {
if (timeString.length() < 2) {
timeString += LocaleController.getString("SecretChatTimerDays", R.string.SecretChatTimerDays);
}
} else if (time >= 30 * 60 * 60 * 24 && time <= 60 * 60 * 24 * 31) {
timeString = "" + value / 60 / 60 / 24 / 30;
if (timeString.length() < 2) {
timeString += LocaleController.getString("SecretChatTimerMonths", R.string.SecretChatTimerMonths);
}
} else {
timeString = "" + value / 60 / 60 / 24 / 7;
if (timeString.length() < 2) {
@ -74,11 +79,6 @@ public class TimerDrawable extends Drawable {
timeString = "c";
}
}
/*
<string name="SecretChatTimerDays">d</string>
<string name="SecretChatTimerSeconds">s</string>
<string name="SecretChatTimerMinutes">m</string>
*/
timeWidth = timePaint.measureText(timeString);
try {

View file

@ -163,6 +163,7 @@ public class UndoView extends FrameLayout {
public final static int ACTION_PAYMENT_SUCCESS = 77;
public final static int ACTION_PIN_DIALOGS = 78;
public final static int ACTION_UNPIN_DIALOGS = 79;
public final static int ACTION_EMAIL_COPIED = 80;
private CharSequence infoText;
private int hideAnimationType = 1;
@ -821,7 +822,7 @@ public class UndoView extends FrameLayout {
currentAction == ACTION_FWD_MESSAGES || currentAction == ACTION_NOTIFY_ON || currentAction == ACTION_NOTIFY_OFF || currentAction == ACTION_USERNAME_COPIED ||
currentAction == ACTION_HASHTAG_COPIED || currentAction == ACTION_TEXT_COPIED || currentAction == ACTION_LINK_COPIED || currentAction == ACTION_PHONE_COPIED ||
currentAction == ACTION_AUTO_DELETE_OFF || currentAction == ACTION_AUTO_DELETE_ON || currentAction == ACTION_GIGAGROUP_CANCEL || currentAction == ACTION_GIGAGROUP_SUCCESS ||
currentAction == ACTION_VOIP_INVITE_LINK_SENT || currentAction == ACTION_PIN_DIALOGS || currentAction == ACTION_UNPIN_DIALOGS || currentAction == ACTION_SHARE_BACKGROUND) {
currentAction == ACTION_VOIP_INVITE_LINK_SENT || currentAction == ACTION_PIN_DIALOGS || currentAction == ACTION_UNPIN_DIALOGS || currentAction == ACTION_SHARE_BACKGROUND || currentAction == ACTION_EMAIL_COPIED) {
undoImageView.setVisibility(GONE);
leftImageView.setVisibility(VISIBLE);
@ -844,7 +845,9 @@ public class UndoView extends FrameLayout {
int ttl = (Integer) infoObject2;
String time;
subinfoTextView.setSingleLine(false);
if (ttl > 24 * 60 * 60) {
if (ttl >= 30 * 24 * 60 * 60) {
time = LocaleController.formatPluralString("Months", ttl / (30 * 24 * 60 * 60));
} else if (ttl > 24 * 60 * 60) {
time = LocaleController.formatPluralString("Days", ttl / (24 * 60 * 60));
} else if (ttl >= 60 * 60) {
time = LocaleController.formatPluralString("Hours", ttl / (60 * 60));
@ -894,9 +897,11 @@ public class UndoView extends FrameLayout {
leftImageView.setAnimation(R.raw.audio_speed, 36, 36);
timeLeft = 3000;
infoTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
} else if (currentAction == ACTION_MESSAGE_COPIED || currentAction == ACTION_USERNAME_COPIED || currentAction == ACTION_HASHTAG_COPIED || currentAction == ACTION_TEXT_COPIED || currentAction == ACTION_LINK_COPIED || currentAction == ACTION_PHONE_COPIED) {
} else if (currentAction == ACTION_MESSAGE_COPIED || currentAction == ACTION_USERNAME_COPIED || currentAction == ACTION_HASHTAG_COPIED || currentAction == ACTION_TEXT_COPIED || currentAction == ACTION_LINK_COPIED || currentAction == ACTION_PHONE_COPIED || currentAction == ACTION_EMAIL_COPIED) {
int iconRawId = R.raw.copy;
if (currentAction == ACTION_PHONE_COPIED) {
if (currentAction == ACTION_EMAIL_COPIED) {
infoTextView.setText(LocaleController.getString("EmailCopied", R.string.EmailCopied));
} else if (currentAction == ACTION_PHONE_COPIED) {
infoTextView.setText(LocaleController.getString("PhoneCopied", R.string.PhoneCopied));
} else if (currentAction == ACTION_USERNAME_COPIED) {
infoTextView.setText(LocaleController.getString("UsernameCopied", R.string.UsernameCopied));

View file

@ -17,6 +17,9 @@ public class VideoForwardDrawable extends Drawable {
private TextPaint textPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
private Path path1 = new Path();
private boolean leftSide;
private boolean isRound;
private Path clippingPath;
private int lastClippingPath;
private final static int[] playPath = new int[] {10, 7, 26, 16, 10, 25};
@ -46,7 +49,8 @@ public class VideoForwardDrawable extends Drawable {
void invalidate();
}
public VideoForwardDrawable() {
public VideoForwardDrawable(boolean isRound) {
this.isRound = isRound;
paint.setColor(0xffffffff);
textPaint.setColor(0xffffffff);
textPaint.setTextSize(AndroidUtilities.dp(12));
@ -131,7 +135,21 @@ public class VideoForwardDrawable extends Drawable {
}
canvas.save();
canvas.clipRect(rect.left, rect.top, rect.right, rect.bottom);
if (isRound) {
if (clippingPath == null) {
clippingPath = new Path();
}
int clippingPathHash = rect.left + (rect.top << 8) + (rect.bottom << 16) + (rect.right << 24);
if (lastClippingPath != clippingPathHash) {
clippingPath.reset();
AndroidUtilities.rectTmp.set(rect);
clippingPath.addOval(AndroidUtilities.rectTmp, Path.Direction.CCW);
lastClippingPath = clippingPathHash;
}
canvas.clipPath(clippingPath);
} else {
canvas.clipRect(rect.left, rect.top, rect.right, rect.bottom);
}
if (!isOneShootAnimation) {
paint.setAlpha((int) (80 * enterAnimationProgress));
textPaint.setAlpha((int) (255 * enterAnimationProgress));

View file

@ -54,8 +54,8 @@ public class ViewPagerFixed extends FrameLayout {
int currentPosition;
int nextPosition;
private View viewPages[];
private int viewTypes[];
private View[] viewPages;
private int[] viewTypes;
protected SparseArray<View> viewsByType = new SparseArray<>();
@ -947,11 +947,6 @@ public class ViewPagerFixed extends FrameLayout {
startSmoothScroll(linearSmoothScroller);
}
@Override
public int scrollHorizontallyBy(int dx, RecyclerView.Recycler recycler, RecyclerView.State state) {
return super.scrollHorizontallyBy(dx, recycler, state);
}
@Override
public void onInitializeAccessibilityNodeInfo(@NonNull RecyclerView.Recycler recycler, @NonNull RecyclerView.State state, @NonNull AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(recycler, state, info);

View file

@ -2071,7 +2071,7 @@ public class WebPlayerView extends ViewGroup implements VideoPlayer.VideoPlayerD
return inFullscreen;
}
public String getYouTubeVideoId(String url) {
public static String getYouTubeVideoId(String url) {
Matcher matcher = youtubeIdRegex.matcher(url);
String id = null;
if (matcher.find()) {

View file

@ -1144,6 +1144,7 @@ public class GroupCallRenderersContainer extends FrameLayout {
super.onAnimationEnd(animation);
swipeToBackAnimator = null;
swipeToBackDy = 0;
invalidate();
}
});
swipeToBackAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);

View file

@ -0,0 +1,585 @@
package org.telegram.ui.Components.voip;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Parcelable;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.voip.VideoCapturerDevice;
import org.telegram.messenger.voip.VoIPService;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.BackDrawable;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.LaunchActivity;
import org.webrtc.RendererCommon;
import java.io.File;
import java.io.FileOutputStream;
import androidx.core.graphics.ColorUtils;
import androidx.viewpager.widget.PagerAdapter;
import androidx.viewpager.widget.ViewPager;
@TargetApi(21)
public abstract class PrivateVideoPreviewDialog extends FrameLayout implements VoIPService.StateListener {
private boolean isDismissed;
private float outProgress;
private ViewPager viewPager;
private TextView positiveButton;
private ActionBar actionBar;
private LinearLayout titlesLayout;
private RLottieImageView micIconView;
private TextView[] titles;
private VoIPTextureView textureView;
private int currentTexturePage = 1;
private int visibleCameraPage = 1;
private boolean cameraReady;
public boolean micEnabled;
private float pageOffset;
private int currentPage;
private boolean needScreencast;
public PrivateVideoPreviewDialog(Context context, boolean mic, boolean screencast) {
super(context);
needScreencast = screencast;
titles = new TextView[needScreencast ? 3 : 2];
viewPager = new ViewPager(context);
AndroidUtilities.setViewPagerEdgeEffectColor(viewPager, 0x7f000000);
viewPager.setAdapter(new Adapter());
viewPager.setPageMargin(0);
viewPager.setOffscreenPageLimit(1);
addView(viewPager, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
private int scrollState = ViewPager.SCROLL_STATE_IDLE;
private int willSetPage;
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
currentPage = position;
pageOffset = positionOffset;
updateTitlesLayout();
}
@Override
public void onPageSelected(int i) {
if (scrollState == ViewPager.SCROLL_STATE_IDLE) {
if (i <= (needScreencast ? 1 : 0)) {
currentTexturePage = 1;
} else {
currentTexturePage = 2;
}
onFinishMoveCameraPage();
} else {
if (i <= (needScreencast ? 1 : 0)) {
willSetPage = 1;
} else {
willSetPage = 2;
}
}
}
@Override
public void onPageScrollStateChanged(int state) {
scrollState = state;
if (state == ViewPager.SCROLL_STATE_IDLE) {
currentTexturePage = willSetPage;
onFinishMoveCameraPage();
}
}
});
textureView = new VoIPTextureView(context, false, false);
textureView.renderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL);
textureView.scaleType = VoIPTextureView.SCALE_TYPE_FIT;
textureView.clipToTexture = true;
textureView.renderer.setAlpha(0);
textureView.renderer.setRotateTextureWitchScreen(true);
textureView.renderer.setUseCameraRotation(true);
addView(textureView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
actionBar = new ActionBar(context);
actionBar.setBackButtonDrawable(new BackDrawable(false));
actionBar.setBackgroundColor(Color.TRANSPARENT);
actionBar.setItemsColor(Theme.getColor(Theme.key_voipgroup_actionBarItems), false);
actionBar.setOccupyStatusBar(true);
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
dismiss(false, false);
}
}
});
addView(actionBar);
positiveButton = new TextView(getContext()) {
private Paint[] gradientPaint = new Paint[titles.length];
{
for (int a = 0; a < gradientPaint.length; a++) {
gradientPaint[a] = new Paint(Paint.ANTI_ALIAS_FLAG);
}
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
for (int a = 0; a < gradientPaint.length; a++) {
int color1;
int color2;
int color3;
if (a == 0 && needScreencast) {
color1 = 0xff77E55C;
color2 = 0xff56C7FE;
color3 = 0;
} else if (a == 0 || a == 1 && needScreencast) {
color1 = 0xff57A4FE;
color2 = 0xff766EE9;
color3 = 0;
} else {
color1 = 0xff766EE9;
color2 = 0xffF05459;
color3 = 0xffE4A756;
}
Shader gradient;
if (color3 != 0) {
gradient = new LinearGradient(0, 0, getMeasuredWidth(), 0, new int[]{color1, color2, color3}, null, Shader.TileMode.CLAMP);
} else {
gradient = new LinearGradient(0, 0, getMeasuredWidth(), 0, new int[]{color1, color2}, null, Shader.TileMode.CLAMP);
}
gradientPaint[a].setShader(gradient);
}
}
@Override
protected void onDraw(Canvas canvas) {
AndroidUtilities.rectTmp.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
gradientPaint[currentPage].setAlpha(255);
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(6), AndroidUtilities.dp(6), gradientPaint[currentPage]);
if (pageOffset > 0 && currentPage + 1 < gradientPaint.length) {
gradientPaint[currentPage + 1].setAlpha((int) (255 * pageOffset));
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(6), AndroidUtilities.dp(6), gradientPaint[currentPage + 1]);
}
super.onDraw(canvas);
}
};
positiveButton.setMinWidth(AndroidUtilities.dp(64));
positiveButton.setTag(Dialog.BUTTON_POSITIVE);
positiveButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
positiveButton.setTextColor(Theme.getColor(Theme.key_voipgroup_nameText));
positiveButton.setGravity(Gravity.CENTER);
positiveButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
positiveButton.setText(LocaleController.getString("VoipShareVideo", R.string.VoipShareVideo));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
positiveButton.setForeground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_nameText), (int) (255 * 0.3f))));
}
positiveButton.setPadding(0, AndroidUtilities.dp(12), 0, AndroidUtilities.dp(12));
positiveButton.setOnClickListener(view -> {
if (isDismissed) {
return;
}
if (currentPage == 0 && needScreencast) {
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getContext().getSystemService(Context.MEDIA_PROJECTION_SERVICE);
((Activity) getContext()).startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), LaunchActivity.SCREEN_CAPTURE_REQUEST_CODE);
} else {
dismiss(false, true);
}
});
addView(positiveButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM, 0, 0, 0, 64));
titlesLayout = new LinearLayout(context);
addView(titlesLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 64, Gravity.BOTTOM));
for (int a = 0; a < titles.length; a++) {
titles[a] = new TextView(context);
titles[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
titles[a].setTextColor(0xffffffff);
titles[a].setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
titles[a].setPadding(AndroidUtilities.dp(10), 0, AndroidUtilities.dp(10), 0);
titles[a].setGravity(Gravity.CENTER_VERTICAL);
titles[a].setSingleLine(true);
titlesLayout.addView(titles[a], LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT));
if (a == 0 && needScreencast) {
titles[a].setText(LocaleController.getString("VoipPhoneScreen", R.string.VoipPhoneScreen));
} else if (a == 0 || a == 1 && needScreencast) {
titles[a].setText(LocaleController.getString("VoipFrontCamera", R.string.VoipFrontCamera));
} else {
titles[a].setText(LocaleController.getString("VoipBackCamera", R.string.VoipBackCamera));
}
int num = a;
titles[a].setOnClickListener(view -> viewPager.setCurrentItem(num, true));
}
setAlpha(0);
setTranslationX(AndroidUtilities.dp(32));
animate().alpha(1f).translationX(0).setDuration(150).start();
setWillNotDraw(false);
VoIPService service = VoIPService.getSharedInstance();
if (service != null) {
textureView.renderer.setMirror(service.isFrontFaceCamera());
textureView.renderer.init(VideoCapturerDevice.getEglBase().getEglBaseContext(), new RendererCommon.RendererEvents() {
@Override
public void onFirstFrameRendered() {
}
@Override
public void onFrameResolutionChanged(int videoWidth, int videoHeight, int rotation) {
}
});
service.setLocalSink(textureView.renderer, false);
}
viewPager.setCurrentItem(needScreencast ? 1 : 0);
if (mic) {
micIconView = new RLottieImageView(context);
micIconView.setPadding(AndroidUtilities.dp(9), AndroidUtilities.dp(9), AndroidUtilities.dp(9), AndroidUtilities.dp(9));
micIconView.setBackground(Theme.createCircleDrawable(AndroidUtilities.dp(48), ColorUtils.setAlphaComponent(Color.BLACK, (int) (255 * 0.3f))));
RLottieDrawable micIcon = new RLottieDrawable(R.raw.voice_mini, "" + R.raw.voice_mini, AndroidUtilities.dp(24), AndroidUtilities.dp(24), true, null);
micIconView.setAnimation(micIcon);
micIconView.setScaleType(ImageView.ScaleType.FIT_CENTER);
micEnabled = true;
micIcon.setCurrentFrame(micEnabled ? 69 : 36);
micIconView.setOnClickListener(v -> {
micEnabled = !micEnabled;
if (micEnabled) {
micIcon.setCurrentFrame(36);
micIcon.setCustomEndFrame(69);
} else {
micIcon.setCurrentFrame(69);
micIcon.setCustomEndFrame(99);
}
micIcon.start();
});
addView(micIconView, LayoutHelper.createFrame(48, 48, Gravity.LEFT | Gravity.BOTTOM, 24, 0, 0, 136));
}
}
public void setBottomPadding(int padding) {
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) positiveButton.getLayoutParams();
layoutParams.bottomMargin = AndroidUtilities.dp(64) + padding;
layoutParams = (FrameLayout.LayoutParams) titlesLayout.getLayoutParams();
layoutParams.bottomMargin = padding;
}
private void updateTitlesLayout() {
View current = titles[currentPage];
View next = currentPage < titles.length - 1 ? titles[currentPage + 1] : null;
float cx = getMeasuredWidth() / 2;
float currentCx = current.getLeft() + current.getMeasuredWidth() / 2;
float tx = getMeasuredWidth() / 2 - currentCx;
if (next != null) {
float nextCx = next.getLeft() + next.getMeasuredWidth() / 2;
tx -= (nextCx - currentCx) * pageOffset;
}
for (int a = 0; a < titles.length; a++) {
float alpha;
float scale;
if (a < currentPage || a > currentPage + 1) {
alpha = 0.7f;
scale = 0.9f;
} else if (a == currentPage) {
alpha = 1.0f - 0.3f * pageOffset;
scale = 1.0f - 0.1f * pageOffset;
} else {
alpha = 0.7f + 0.3f * pageOffset;
scale = 0.9f + 0.1f * pageOffset;
}
titles[a].setAlpha(alpha);
titles[a].setScaleX(scale);
titles[a].setScaleY(scale);
}
titlesLayout.setTranslationX(tx);
positiveButton.invalidate();
if (needScreencast && currentPage == 0 && pageOffset <= 0) {
textureView.setVisibility(INVISIBLE);
} else {
textureView.setVisibility(VISIBLE);
if (currentPage + (needScreencast ? 0 : 1) == currentTexturePage) {
textureView.setTranslationX(-pageOffset * getMeasuredWidth());
} else {
textureView.setTranslationX((1.0f - pageOffset) * getMeasuredWidth());
}
}
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
VoIPService service = VoIPService.getSharedInstance();
if (service != null) {
service.registerStateListener(this);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
VoIPService service = VoIPService.getSharedInstance();
if (service != null) {
service.unregisterStateListener(this);
}
}
private void onFinishMoveCameraPage() {
VoIPService service = VoIPService.getSharedInstance();
if (currentTexturePage == visibleCameraPage || service == null) {
return;
}
boolean currentFrontface = service.isFrontFaceCamera();
if (currentTexturePage == 1 && !currentFrontface || currentTexturePage == 2 && currentFrontface) {
saveLastCameraBitmap();
cameraReady = false;
VoIPService.getSharedInstance().switchCamera();
textureView.setAlpha(0.0f);
}
visibleCameraPage = currentTexturePage;
}
private void saveLastCameraBitmap() {
if (!cameraReady) {
return;
}
try {
Bitmap bitmap = textureView.renderer.getBitmap();
if (bitmap != null) {
Bitmap newBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), textureView.renderer.getMatrix(), true);
bitmap.recycle();
bitmap = newBitmap;
Bitmap lastBitmap = Bitmap.createScaledBitmap(bitmap, 80, (int) (bitmap.getHeight() / (bitmap.getWidth() / 80.0f)), true);
if (lastBitmap != null) {
if (lastBitmap != bitmap) {
bitmap.recycle();
}
Utilities.blurBitmap(lastBitmap, 7, 1, lastBitmap.getWidth(), lastBitmap.getHeight(), lastBitmap.getRowBytes());
File file = new File(ApplicationLoader.getFilesDirFixed(), "cthumb" + visibleCameraPage + ".jpg");
FileOutputStream stream = new FileOutputStream(file);
lastBitmap.compress(Bitmap.CompressFormat.JPEG, 87, stream);
View view = viewPager.findViewWithTag(visibleCameraPage - (needScreencast ? 0 : 1));
if (view instanceof ImageView) {
((ImageView) view).setImageBitmap(lastBitmap);
}
}
}
} catch (Throwable ignore) {
}
}
@Override
public void onCameraFirstFrameAvailable() {
if (!cameraReady) {
cameraReady = true;
textureView.animate().alpha(1f).setDuration(250);
}
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
updateTitlesLayout();
}
public void dismiss(boolean screencast, boolean apply) {
if (isDismissed) {
return;
}
isDismissed = true;
saveLastCameraBitmap();
onDismiss(screencast, apply);
animate().alpha(0f).translationX(AndroidUtilities.dp(32)).setDuration(150).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (getParent() != null) {
((ViewGroup) getParent()).removeView(PrivateVideoPreviewDialog.this);
}
}
});
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return true;
}
protected void onDismiss(boolean screencast, boolean apply) {
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
boolean isLandscape = MeasureSpec.getSize(widthMeasureSpec) > MeasureSpec.getSize(heightMeasureSpec);
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) positiveButton.getLayoutParams();
if (isLandscape) {
marginLayoutParams.rightMargin = marginLayoutParams.leftMargin = AndroidUtilities.dp(80);
} else {
marginLayoutParams.rightMargin = marginLayoutParams.leftMargin = AndroidUtilities.dp(16);
}
if (micIconView != null) {
marginLayoutParams = (MarginLayoutParams) micIconView.getLayoutParams();
if (isLandscape) {
marginLayoutParams.rightMargin = marginLayoutParams.leftMargin = AndroidUtilities.dp(88);
} else {
marginLayoutParams.rightMargin = marginLayoutParams.leftMargin = AndroidUtilities.dp(24);
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureChildWithMargins(titlesLayout, MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(64), MeasureSpec.EXACTLY), 0);
}
public int getBackgroundColor() {
int color = Theme.getColor(Theme.key_voipgroup_actionBar);
color = ColorUtils.setAlphaComponent(color, (int) (255 * (getAlpha() * (1f - outProgress))));
return color;
}
@Override
public void invalidate() {
super.invalidate();
if (getParent() != null) {
((View) getParent()).invalidate();
}
}
public void update() {
if (VoIPService.getSharedInstance() != null) {
textureView.renderer.setMirror(VoIPService.getSharedInstance().isFrontFaceCamera());
}
}
private class Adapter extends PagerAdapter {
@Override
public int getCount() {
return titles.length;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
View view;
if (needScreencast && position == 0) {
FrameLayout frameLayout = new FrameLayout(getContext());
frameLayout.setBackground(new MotionBackgroundDrawable(0xff212E3A, 0xff2B5B4D, 0xff245863, 0xff274558, true));
view = frameLayout;
ImageView imageView = new ImageView(getContext());
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setImageResource(R.drawable.screencast_big);
frameLayout.addView(imageView, LayoutHelper.createFrame(82, 82, Gravity.CENTER, 0, 0, 0, 60));
TextView textView = new TextView(getContext());
textView.setText(LocaleController.getString("VoipVideoPrivateScreenSharing", R.string.VoipVideoPrivateScreenSharing));
textView.setGravity(Gravity.CENTER);
textView.setLineSpacing(AndroidUtilities.dp(2), 1.0f);
textView.setTextColor(0xffffffff);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 21, 28, 21, 0));
} else {
ImageView imageView = new ImageView(getContext());
imageView.setImageResource(R.drawable.icplaceholder);
imageView.setTag(position);
Bitmap bitmap = null;
try {
File file = new File(ApplicationLoader.getFilesDirFixed(), "cthumb" + (position == 0 || position == 1 && needScreencast ? 1 : 2) + ".jpg");
bitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
} catch (Throwable ignore) {
}
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
imageView.setImageResource(R.drawable.icplaceholder);
}
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
view = imageView;
}
if (view.getParent() != null) {
ViewGroup parent = (ViewGroup) view.getParent();
parent.removeView(view);
}
container.addView(view, 0);
return view;
}
@Override
public void destroyItem(ViewGroup container, int position, Object object) {
container.removeView((View) object);
}
@Override
public void setPrimaryItem(ViewGroup container, int position, Object object) {
super.setPrimaryItem(container, position, object);
}
@Override
public boolean isViewFromObject(View view, Object object) {
return view.equals(object);
}
@Override
public void restoreState(Parcelable arg0, ClassLoader arg1) {
}
@Override
public Parcelable saveState() {
return null;
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
if (observer != null) {
super.unregisterDataSetObserver(observer);
}
}
}
}

View file

@ -1,394 +0,0 @@
package org.telegram.ui.Components.voip;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Shader;
import android.os.Build;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.core.graphics.ColorUtils;
import com.google.android.exoplayer2.C;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.voip.VideoCapturerDevice;
import org.telegram.messenger.voip.VoIPService;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.BackDrawable;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.GroupCallActivity;
import org.webrtc.RendererCommon;
public abstract class VideoPreviewDialog extends FrameLayout {
VoIPTextureView textureView;
Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
boolean isDismissed;
float outProgress;
FrameLayout container;
View negativeButton;
View positiveButton;
private final LinearLayout buttonsLayout;
private final ActionBar actionBar;
private final RLottieImageView flipIconView;
private final RLottieImageView micIconView;
int flipIconEndFrame;
private final TextView subtitle;
public boolean micEnabled;
CellFlickerDrawable drawable = new CellFlickerDrawable();
public VideoPreviewDialog(@NonNull Context context, RecyclerListView listView, RecyclerListView fullscreenListView) {
super(context);
backgroundPaint.setColor(Theme.getColor(Theme.key_voipgroup_dialogBackground));
actionBar = new ActionBar(context);
actionBar.setBackButtonDrawable(new BackDrawable(false));
actionBar.setBackgroundColor(Color.TRANSPARENT);
actionBar.setItemsColor(Theme.getColor(Theme.key_voipgroup_actionBarItems), false);
actionBar.setTitle(LocaleController.getString("CallVideoPreviewTitle", R.string.CallVideoPreviewTitle));
actionBar.setOccupyStatusBar(false);
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
dismiss(false);
}
super.onItemClick(id);
}
});
container = new FrameLayout(context);
container.setClipChildren(false);
addView(container, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
container.addView(actionBar);
textureView = new VoIPTextureView(context, false, false);
textureView.renderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT);
textureView.setRoundCorners(AndroidUtilities.dp(8));
if (VoIPService.getSharedInstance() != null) {
textureView.renderer.setMirror(VoIPService.getSharedInstance().isFrontFaceCamera());
}
textureView.scaleType = VoIPTextureView.SCALE_TYPE_FIT;
textureView.clipToTexture = true;
textureView.renderer.setAlpha(0);
textureView.renderer.setRotateTextureWitchScreen(true);
textureView.renderer.setUseCameraRotation(true);
subtitle = new TextView(context);
subtitle.setTextColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_nameText), (int) (255 * 0.4f)));
subtitle.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
subtitle.setText(LocaleController.getString("VideoPreviewDesrciption", R.string.VideoPreviewDesrciption));
subtitle.setGravity(Gravity.CENTER_HORIZONTAL);
container.addView(subtitle, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM, 24, 0, 24, 108));
buttonsLayout = new LinearLayout(context);
buttonsLayout.setOrientation(LinearLayout.HORIZONTAL);
TextView negative = new TextView(getContext()) {
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
setAlpha(enabled ? 1.0f : 0.5f);
}
@Override
public void setTextColor(int color) {
super.setTextColor(color);
setBackgroundDrawable(Theme.getRoundRectSelectorDrawable(color));
}
};
negative.setMinWidth(AndroidUtilities.dp(64));
negative.setTag(Dialog.BUTTON_POSITIVE);
negative.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
negative.setTextColor(Theme.getColor(Theme.key_voipgroup_nameText));
negative.setGravity(Gravity.CENTER);
negative.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
negative.setText(LocaleController.getString("Cancel", R.string.Cancel));
negative.setBackgroundDrawable(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Theme.getColor(Theme.key_voipgroup_listViewBackground), ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_nameText), (int) (255 * 0.3f))));
negative.setPadding(0, AndroidUtilities.dp(12), 0, AndroidUtilities.dp(12));
negativeButton = negative;
TextView positive = new TextView(getContext()) {
Paint gradientPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Shader gradient = new LinearGradient(0, 0, getMeasuredWidth(), 0, new int[]{Theme.getColor(Theme.key_voipgroup_unmuteButton), Theme.getColor(Theme.key_voipgroup_unmuteButton2)}, null, Shader.TileMode.CLAMP);
gradientPaint.setShader(gradient);
}
@Override
protected void onDraw(Canvas canvas) {
AndroidUtilities.rectTmp.set(0, 0, getMeasuredWidth(), getMeasuredHeight());
canvas.drawRoundRect(AndroidUtilities.rectTmp, AndroidUtilities.dp(6), AndroidUtilities.dp(6), gradientPaint);
super.onDraw(canvas);
}
};
positive.setMinWidth(AndroidUtilities.dp(64));
positive.setTag(Dialog.BUTTON_POSITIVE);
positive.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
positive.setTextColor(Theme.getColor(Theme.key_voipgroup_nameText));
positive.setGravity(Gravity.CENTER);
positive.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
positive.setText(LocaleController.getString("ShareVideo", R.string.ShareVideo));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
positive.setForeground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(6), Color.TRANSPARENT, ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_nameText), (int) (255 * 0.3f))));
}
positive.setPadding(0, AndroidUtilities.dp(12), 0, AndroidUtilities.dp(12));
positiveButton = positive;
buttonsLayout.addView(negative, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, 1f, 0, 4, 0, 4, 0));
buttonsLayout.addView(positive, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 48, 1f, 0, 4, 0, 4, 0));
addView(textureView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
container.addView(buttonsLayout, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM));
if (VoIPService.getSharedInstance() != null) {
textureView.renderer.init(VideoCapturerDevice.getEglBase().getEglBaseContext(), new RendererCommon.RendererEvents() {
@Override
public void onFirstFrameRendered() {
textureView.animate().alpha(1f).setDuration(250);
}
@Override
public void onFrameResolutionChanged(int videoWidth, int videoHeight, int rotation) {
}
});
VoIPService.getSharedInstance().setLocalSink(textureView.renderer, false);
}
negative.setOnClickListener(view -> {
dismiss(false);
});
positive.setOnClickListener(view -> {
if (isDismissed) {
return;
}
dismiss(true);
});
setAlpha(0);
setTranslationX(AndroidUtilities.dp(32));
animate().alpha(1f).translationX(0).setDuration(150).start();
flipIconView = new RLottieImageView(context);
flipIconView.setPadding(AndroidUtilities.dp(10), AndroidUtilities.dp(10), AndroidUtilities.dp(10), AndroidUtilities.dp(10));
flipIconView.setBackground(Theme.createCircleDrawable(AndroidUtilities.dp(48), ColorUtils.setAlphaComponent(Color.BLACK, (int) (255 * 0.3f))));
RLottieDrawable flipIcon = new RLottieDrawable(R.raw.camera_flip, "" + R.raw.camera_flip, AndroidUtilities.dp(24), AndroidUtilities.dp(24), true, null);
flipIconView.setAnimation(flipIcon);
flipIconView.setScaleType(ImageView.ScaleType.FIT_CENTER);
flipIconView.setOnClickListener(v -> {
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().switchCamera();
if (flipIconEndFrame == 18) {
flipIcon.setCustomEndFrame(flipIconEndFrame = 39);
flipIcon.start();
} else {
flipIcon.setCurrentFrame(0, false);
flipIcon.setCustomEndFrame(flipIconEndFrame = 18);
flipIcon.start();
}
}
});
addView(flipIconView, LayoutHelper.createFrame(48, 48));
micIconView = new RLottieImageView(context);
micIconView.setPadding(AndroidUtilities.dp(9), AndroidUtilities.dp(9), AndroidUtilities.dp(9), AndroidUtilities.dp(9));
micIconView.setBackground(Theme.createCircleDrawable(AndroidUtilities.dp(48), ColorUtils.setAlphaComponent(Color.BLACK, (int) (255 * 0.3f))));
RLottieDrawable micIcon = new RLottieDrawable(R.raw.voice_mini, "" + R.raw.voice_mini, AndroidUtilities.dp(24), AndroidUtilities.dp(24), true, null);
micIconView.setAnimation(micIcon);
micIconView.setScaleType(ImageView.ScaleType.FIT_CENTER);
micEnabled = true;
micIcon.setCurrentFrame(micEnabled ? 69 : 36);
micIconView.setOnClickListener(v -> {
micEnabled = !micEnabled;
if (micEnabled) {
micIcon.setCurrentFrame(36);
micIcon.setCustomEndFrame(69);
} else {
micIcon.setCurrentFrame(69);
micIcon.setCustomEndFrame(99);
}
micIcon.start();
});
addView(micIconView, LayoutHelper.createFrame(48, 48));
setWillNotDraw(false);
}
public void dismiss(boolean apply) {
if (isDismissed) {
return;
}
isDismissed = true;
animate().alpha(0f).translationX(AndroidUtilities.dp(32)).setDuration(150).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
if (getParent() != null) {
((ViewGroup) getParent()).removeView(VideoPreviewDialog.this);
}
onDismiss(apply);
}
});
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
float x = textureView.getRight() - AndroidUtilities.dp(48 + 12) - textureView.currentClipHorizontal;
float y = textureView.getBottom() - AndroidUtilities.dp(48 + 12) - textureView.currentClipVertical;
flipIconView.setTranslationX(x);
flipIconView.setTranslationY(y);
flipIconView.setScaleX(textureView.getScaleX());
flipIconView.setScaleY(textureView.getScaleY());
flipIconView.setPivotX(getMeasuredWidth() / 2f - x);
flipIconView.setPivotY(getMeasuredHeight() / 2f - y);
flipIconView.setAlpha(textureView.renderer.getAlpha() * (1f - outProgress));
x = textureView.getLeft() + AndroidUtilities.dp(12) + textureView.currentClipHorizontal;
micIconView.setTranslationX(x);
micIconView.setTranslationY(y);
micIconView.setScaleX(textureView.getScaleX());
micIconView.setScaleY(textureView.getScaleY());
micIconView.setPivotX(getMeasuredWidth() / 2f - x);
micIconView.setPivotY(getMeasuredHeight() / 2f - y);
micIconView.setAlpha(textureView.renderer.getAlpha() * (1f - outProgress));
canvas.drawColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_actionBar), (int) (255 * (1f - outProgress))));
if (isDismissed || textureView.renderer.getAlpha() != 1f) {
invalidate();
}
if (!textureView.renderer.isFirstFrameRendered() && textureView.renderer.getAlpha() != 1f) {
MarginLayoutParams layoutParams = (MarginLayoutParams) textureView.getLayoutParams();
AndroidUtilities.rectTmp.set(layoutParams.leftMargin, layoutParams.topMargin, getMeasuredWidth() - layoutParams.rightMargin, getMeasuredHeight() - layoutParams.bottomMargin);
float k = !GroupCallActivity.isLandscapeMode ? 9f / 16f : 16f / 9f;
if (AndroidUtilities.rectTmp.width() / AndroidUtilities.rectTmp.height() > k) {
float padding = (AndroidUtilities.rectTmp.width() - AndroidUtilities.rectTmp.height() * k) / 2f;
AndroidUtilities.rectTmp.left += padding;
AndroidUtilities.rectTmp.right -= padding;
} else {
float padding = (AndroidUtilities.rectTmp.height() - AndroidUtilities.rectTmp.width() * k) / 2f;
AndroidUtilities.rectTmp.top += padding;
AndroidUtilities.rectTmp.bottom -= padding;
}
drawable.setParentWidth(getMeasuredWidth());
drawable.draw(canvas, AndroidUtilities.rectTmp, AndroidUtilities.dp(8));
invalidate();
}
super.onDraw(canvas);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return true;
}
protected void onDismiss(boolean apply) {
}
boolean ignoreLayout = false;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
boolean isLandscape = MeasureSpec.getSize(widthMeasureSpec) > MeasureSpec.getSize(heightMeasureSpec);
ignoreLayout = true;
if (isLandscape) {
actionBar.setTitle(null);
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) textureView.getLayoutParams();
marginLayoutParams.topMargin = AndroidUtilities.dp(8);
marginLayoutParams.bottomMargin = AndroidUtilities.dp(76);
marginLayoutParams.rightMargin = marginLayoutParams.leftMargin = AndroidUtilities.dp(48);
negativeButton.setVisibility(View.VISIBLE);
subtitle.setVisibility(View.GONE);
marginLayoutParams = (MarginLayoutParams) buttonsLayout.getLayoutParams();
marginLayoutParams.rightMargin = marginLayoutParams.leftMargin = AndroidUtilities.dp(80);
marginLayoutParams.bottomMargin = AndroidUtilities.dp(16);
} else {
MarginLayoutParams marginLayoutParams = (MarginLayoutParams) textureView.getLayoutParams();
actionBar.setTitle(LocaleController.getString("CallVideoPreviewTitle", R.string.CallVideoPreviewTitle));
marginLayoutParams.topMargin = ActionBar.getCurrentActionBarHeight() + AndroidUtilities.dp(8);
marginLayoutParams.bottomMargin = AndroidUtilities.dp(168);
marginLayoutParams.rightMargin = marginLayoutParams.leftMargin = AndroidUtilities.dp(12);
negativeButton.setVisibility(View.GONE);
subtitle.setVisibility(View.VISIBLE);
marginLayoutParams = (MarginLayoutParams) buttonsLayout.getLayoutParams();
marginLayoutParams.rightMargin = marginLayoutParams.leftMargin = marginLayoutParams.bottomMargin = AndroidUtilities.dp(16);
}
ignoreLayout = false;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public void requestLayout() {
if (ignoreLayout) {
return;
}
super.requestLayout();
}
public int getBackgroundColor() {
int color = Theme.getColor(Theme.key_voipgroup_actionBar);
color = ColorUtils.setAlphaComponent(color, (int) (255 * (getAlpha() * (1f - outProgress))));
return color;
}
@Override
public void invalidate() {
super.invalidate();
if (getParent() != null) {
((View) getParent()).invalidate();
}
}
public void update() {
if (VoIPService.getSharedInstance() != null) {
textureView.renderer.setMirror(VoIPService.getSharedInstance().isFrontFaceCamera());
}
}
}

View file

@ -67,7 +67,7 @@ public class VoIPFloatingLayout extends FrameLayout {
private boolean floatingMode;
private boolean setedFloatingMode;
private boolean switchingToFloatingMode;
private boolean measuredAsFloatingMode;
public boolean measuredAsFloatingMode;
private float overrideCornerRadius = -1f;
private boolean active = true;
@ -81,9 +81,15 @@ public class VoIPFloatingLayout extends FrameLayout {
Drawable outerShadow;
ValueAnimator switchToFloatingModeAnimator;
private ValueAnimator.AnimatorUpdateListener progressUpdateListener = valueAnimator -> {
toFloatingModeProgress = (float) valueAnimator.getAnimatedValue();
invalidate();
private ValueAnimator.AnimatorUpdateListener progressUpdateListener = new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
toFloatingModeProgress = (float) valueAnimator.getAnimatedValue();
if (delegate != null) {
delegate.onChange(toFloatingModeProgress, measuredAsFloatingMode);
}
invalidate();
}
};
ValueAnimator mutedAnimator;
@ -94,6 +100,11 @@ public class VoIPFloatingLayout extends FrameLayout {
OnClickListener tapListener;
private VoIPFloatingLayoutDelegate delegate;
public interface VoIPFloatingLayoutDelegate {
void onChange(float progress, boolean value);
}
public VoIPFloatingLayout(@NonNull Context context) {
super(context);
@ -139,6 +150,9 @@ public class VoIPFloatingLayout extends FrameLayout {
setTranslationY(0);
}
}
if (delegate != null) {
delegate.onChange(toFloatingModeProgress, measuredAsFloatingMode);
}
super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
@ -166,6 +180,10 @@ public class VoIPFloatingLayout extends FrameLayout {
return true;
}
public void setDelegate(VoIPFloatingLayoutDelegate voIPFloatingLayoutDelegate) {
delegate = voIPFloatingLayoutDelegate;
}
long startTime;
@Override

View file

@ -448,6 +448,8 @@ public class VoIPPiPView implements VoIPService.StateListener, NotificationCente
callingUserIsVideo = service.getRemoteVideoState() == Instance.VIDEO_STATE_ACTIVE;
currentUserIsVideo = service.getVideoState(false) == Instance.VIDEO_STATE_ACTIVE || service.getVideoState(false) == Instance.VIDEO_STATE_PAUSED;
currentUserTextureView.renderer.setMirror(service.isFrontFaceCamera());
currentUserTextureView.setIsScreencast(service.isScreencast());
currentUserTextureView.setScreenshareMiniProgress(1.0f, false);
}
if (!animated) {

View file

@ -10,6 +10,7 @@ import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Outline;
import android.os.Build;
import android.util.TypedValue;
import android.view.Display;
import android.view.Gravity;
import android.view.TextureView;
@ -18,13 +19,18 @@ import android.view.ViewOutlineProvider;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ApplicationLoader;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.R;
import org.telegram.messenger.Utilities;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.MotionBackgroundDrawable;
import org.telegram.ui.GroupCallActivity;
import org.webrtc.RendererCommon;
import org.webrtc.TextureViewRenderer;
@ -39,10 +45,15 @@ public class VoIPTextureView extends FrameLayout {
float roundRadius;
private boolean screencast;
public final TextureViewRenderer renderer;
public TextureView blurRenderer;
public final ImageView imageView;
public View backgroundView;
private FrameLayout screencastView;
private ImageView screencastImage;
private TextView screencastText;
private Bitmap thumb;
public Bitmap cameraLastBitmap;
@ -139,6 +150,25 @@ public class VoIPTextureView extends FrameLayout {
blurRenderer.setOpaque(false);
}
screencastView = new FrameLayout(getContext());
screencastView.setBackground(new MotionBackgroundDrawable(0xff212E3A, 0xff2B5B4D, 0xff245863, 0xff274558, true));
addView(screencastView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
screencastView.setVisibility(GONE);
screencastImage = new ImageView(getContext());
screencastImage.setScaleType(ImageView.ScaleType.CENTER);
screencastImage.setImageResource(R.drawable.screencast_big);
screencastView.addView(screencastImage, LayoutHelper.createFrame(82, 82, Gravity.CENTER, 0, 0, 0, 60));
screencastText = new TextView(getContext());
screencastText.setText(LocaleController.getString("VoipVideoScreenSharing", R.string.VoipVideoScreenSharing));
screencastText.setGravity(Gravity.CENTER);
screencastText.setLineSpacing(AndroidUtilities.dp(2), 1.0f);
screencastText.setTextColor(0xffffffff);
screencastText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
screencastText.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
screencastView.addView(screencastText, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER, 21, 28, 21, 0));
if (applyRoundRadius) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
setOutlineProvider(new ViewOutlineProvider() {
@ -179,6 +209,40 @@ public class VoIPTextureView extends FrameLayout {
}
}
public void setScreenshareMiniProgress(float progress, boolean value) {
if (!screencast) {
return;
}
float scale = ((View) getParent()).getScaleX();
screencastText.setAlpha(1.0f - progress);
float sc;
if (!value) {
sc = 1.0f / scale - 0.4f / scale * progress;
} else {
sc = 1.0f - 0.4f * progress;
}
screencastImage.setScaleX(sc);
screencastImage.setScaleY(sc);
screencastImage.setTranslationY(AndroidUtilities.dp(60) * progress);
}
public void setIsScreencast(boolean value) {
screencast = value;
screencastView.setVisibility(screencast ? VISIBLE : GONE);
if (screencast) {
renderer.setVisibility(GONE);
if (blurRenderer != null) {
blurRenderer.setVisibility(GONE);
}
imageView.setVisibility(GONE);
} else {
renderer.setVisibility(VISIBLE);
if (blurRenderer != null) {
blurRenderer.setVisibility(VISIBLE);
}
}
}
protected void onFirstFrameRendered() {
VoIPTextureView.this.invalidate();
if (renderer.getAlpha() != 1f) {
@ -233,6 +297,9 @@ public class VoIPTextureView extends FrameLayout {
}
public void setStub(VoIPTextureView from) {
if (screencast) {
return;
}
Bitmap bitmap = from.renderer.getBitmap();
if (bitmap == null || bitmap.getPixel(0, 0) == 0) {
imageView.setImageDrawable(from.imageView.getDrawable());

View file

@ -3172,8 +3172,10 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
fragmentContextView = new FragmentContextView(context, this, false) {
@Override
protected void playbackSpeedChanged(boolean enabled) {
getUndoView().showWithAction(0, enabled ? UndoView.ACTION_PLAYBACK_SPEED_ENABLED : UndoView.ACTION_PLAYBACK_SPEED_DISABLED, null);
protected void playbackSpeedChanged(float value) {
if (Math.abs(value - 1.0f) > 0.001f || Math.abs(value - 1.8f) > 0.001f) {
getUndoView().showWithAction(0, Math.abs(value - 1.0f) > 0.001f ? UndoView.ACTION_PLAYBACK_SPEED_ENABLED : UndoView.ACTION_PLAYBACK_SPEED_DISABLED, value, null, null);
}
}
};
fragmentContextView.setLayoutParams(LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 38, Gravity.TOP | Gravity.LEFT, 0, -36, 0, 0));
@ -4136,7 +4138,7 @@ public class DialogsActivity extends BaseFragment implements NotificationCenter.
if (searchIsShowed) {
AndroidUtilities.requestAdjustResize(getParentActivity(), classGuid);
}
updateVisibleRows(0);
viewPages[0].dialogsAdapter.notifyDataSetChanged();
}
@Override

View file

@ -1037,7 +1037,7 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
ArticleViewer.getInstance().open(message);
return;
} else if (webPage.embed_url != null && webPage.embed_url.length() != 0) {
openWebView(webPage);
openWebView(webPage, message);
return;
} else {
link = webPage.url;
@ -1062,8 +1062,8 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
private final SharedLinkCell.SharedLinkCellDelegate sharedLinkCellDelegate = new SharedLinkCell.SharedLinkCellDelegate() {
@Override
public void needOpenWebView(TLRPC.WebPage webPage) {
openWebView(webPage);
public void needOpenWebView(TLRPC.WebPage webPage, MessageObject message) {
openWebView(webPage, message);
}
@Override
@ -1434,8 +1434,8 @@ public class FilteredSearchView extends FrameLayout implements NotificationCente
}
}
private void openWebView(TLRPC.WebPage webPage) {
EmbedBottomSheet.show(parentActivity, webPage.site_name, webPage.description, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height, false);
private void openWebView(TLRPC.WebPage webPage, MessageObject message) {
EmbedBottomSheet.show(parentActivity, message, provider, webPage.site_name, webPage.description, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height, false);
}
int lastAccount;

View file

@ -142,7 +142,7 @@ import org.telegram.ui.Components.voip.GroupCallGridCell;
import org.telegram.ui.Components.voip.GroupCallMiniTextureView;
import org.telegram.ui.Components.voip.GroupCallRenderersContainer;
import org.telegram.ui.Components.voip.GroupCallStatusIcon;
import org.telegram.ui.Components.voip.VideoPreviewDialog;
import org.telegram.ui.Components.voip.PrivateVideoPreviewDialog;
import org.telegram.ui.Components.voip.VoIPToggleButton;
import java.io.File;
@ -225,7 +225,6 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
private int buttonsVisibility;
private TextView speakingMembersSubtitle;
public final ArrayList<ChatObject.VideoParticipant> visibleVideoParticipants = new ArrayList<>();
float progressToHideUi;
@ -244,7 +243,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
private float scrollOffsetY;
VideoPreviewDialog previewDialog;
PrivateVideoPreviewDialog previewDialog;
private TLRPC.Peer selfPeer;
private TLObject userSwitchObject;
@ -1285,6 +1284,9 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
AndroidUtilities.updateVisibleRows(listView);
}
} else if (id == NotificationCenter.groupCallScreencastStateChanged) {
if (previewDialog != null) {
previewDialog.dismiss(true, true);
}
updateItems();
}
}
@ -1362,7 +1364,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
try {
UpdateCallback updateCallback = new UpdateCallback(listAdapter);
setOldRows(listAdapter.addMemberRow, listAdapter.usersStartRow, listAdapter.usersEndRow, listAdapter.invitedStartRow, listAdapter.invitedEndRow, listAdapter.usersVideoGridStartRow, listAdapter.usersVideoGridEndRow, listAdapter.videoGridDividerRow);
setOldRows(listAdapter.addMemberRow, listAdapter.usersStartRow, listAdapter.usersEndRow, listAdapter.invitedStartRow, listAdapter.invitedEndRow, listAdapter.usersVideoGridStartRow, listAdapter.usersVideoGridEndRow, listAdapter.videoGridDividerRow, listAdapter.videoNotAvailableRow);
listAdapter.updateRows();
DiffUtil.calculateDiff(diffUtilsCallback).dispatchUpdatesTo(updateCallback);
} catch (Exception e) {
@ -3024,7 +3026,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
for (int a = 0, N = getChildCount(); a < N; a++) {
View child = getChildAt(a);
ViewHolder holder = findContainingViewHolder(child);
if (holder == null || holder.getItemViewType() == 3 || holder.getItemViewType() == 4 || holder.getItemViewType() == 5) {
if (holder == null || holder.getItemViewType() == 3 || holder.getItemViewType() == 4 || holder.getItemViewType() == 5 || holder.getItemViewType() == 6) {
continue;
}
@ -3849,7 +3851,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
canvas.restore();
if (isLandscapeMode && switchToButtonInt2 == 0) {
paint.setAlpha((int) (255));
paint.setAlpha(255);
float x = scheduleButtonTextView.getX() - getX();
float y = scheduleButtonTextView.getY() - getY();
rect.set(x, y, x + scheduleButtonTextView.getMeasuredWidth(), y + scheduleButtonTextView.getMeasuredHeight());
@ -4978,18 +4980,24 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
if (VoIPService.getSharedInstance().getVideoState(false) != Instance.VIDEO_STATE_ACTIVE) {
undoView[0].hide(false, 1);
if (previewDialog == null) {
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().createCaptureDevice(false);
VoIPService voIPService = VoIPService.getSharedInstance();
if (voIPService != null) {
voIPService.createCaptureDevice(false);
}
previewDialog = new VideoPreviewDialog(context, listView, fullscreenUsersListView) {
previewDialog = new PrivateVideoPreviewDialog(context, true, VoIPService.getSharedInstance().getVideoState(true) != Instance.VIDEO_STATE_ACTIVE) {
@Override
public void onDismiss(boolean apply) {
public void onDismiss(boolean screencast, boolean apply) {
boolean showMicIcon = previewDialog.micEnabled;
previewDialog = null;
VoIPService service = VoIPService.getSharedInstance();
if (apply) {
if (service != null) {
service.setupCaptureDevice(false, showMicIcon);
service.setupCaptureDevice(screencast, showMicIcon);
}
if (screencast) {
if (service != null) {
service.setVideoState(false, Instance.VIDEO_STATE_INACTIVE);
}
}
updateState(true, false);
call.sortParticipants();
@ -4997,14 +5005,14 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
buttonsContainer.requestLayout();
} else {
if (service != null) {
VoIPService.getSharedInstance().setVideoState(false, Instance.VIDEO_STATE_INACTIVE);
service.setVideoState(false, Instance.VIDEO_STATE_INACTIVE);
}
}
}
};
containerView.addView(previewDialog);
if (!VoIPService.getSharedInstance().isFrontFaceCamera()) {
VoIPService.getSharedInstance().switchCamera();
container.addView(previewDialog);
if (voIPService != null && !voIPService.isFrontFaceCamera()) {
voIPService.switchCamera();
}
}
} else {
@ -5763,6 +5771,8 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
}
}
ObjectAnimator subtitleYAnimator;
private void updateLayout(boolean animated) {
float minY = Integer.MAX_VALUE;
int N = listView.getChildCount();
@ -5799,11 +5809,22 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
.setInterpolator(CubicBezierInterpolator.DEFAULT)
.start();
actionBar.getSubtitleTextView().animate()
.translationY(show ? 0.0f : AndroidUtilities.dp(20))
.setDuration(300)
.setInterpolator(CubicBezierInterpolator.DEFAULT)
.start();
if (subtitleYAnimator != null) {
subtitleYAnimator.removeAllListeners();
subtitleYAnimator.cancel();
}
subtitleYAnimator = ObjectAnimator.ofFloat(actionBar.getSubtitleTextView(), View.TRANSLATION_Y, actionBar.getSubtitleTextView().getTranslationY(), show ? 0.0f : AndroidUtilities.dp(20));
subtitleYAnimator.setDuration(300);
subtitleYAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
subtitleYAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
subtitleYAnimator = null;
actionBar.getSubtitleTextView().setTranslationY(show ? 0.0f : AndroidUtilities.dp(20));
}
});
subtitleYAnimator.start();
actionBar.getAdditionalSubtitleTextView().animate()
.translationY(show ? 0.0f : AndroidUtilities.dp(20))
@ -7337,7 +7358,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
private int usersVideoGridStartRow;
private int usersVideoGridEndRow;
private int videoGridDividerRow;
private int videoCount;
private int videoNotAvailableRow;
private boolean hasSelfUser;
@ -7368,13 +7389,18 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
rowsCount += visibleVideoParticipants.size();
usersVideoGridEndRow = rowsCount;
videoCount = visibleVideoParticipants.size();
int videoCount = visibleVideoParticipants.size();
if (videoCount > 0) {
videoGridDividerRow = rowsCount++;
} else {
videoGridDividerRow = -1;
}
if (!visibleVideoParticipants.isEmpty() && ChatObject.canManageCalls(currentChat) && call.call.participants_count > accountInstance.getMessagesController().groipCallVideoMaxParticipants) {
videoNotAvailableRow = rowsCount++;
} else {
videoNotAvailableRow = -1;
}
usersStartRow = rowsCount;
rowsCount += call.visibleParticipants.size();
usersEndRow = rowsCount;
@ -7579,7 +7605,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
int type = holder.getItemViewType();
if (type == 1) {
return true;
} else if (type == 3 || type == 4 || type == 5) {
} else if (type == 3 || type == 4 || type == 5 || type == 6) {
return false;
}
return true;
@ -7658,6 +7684,15 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
}
};
break;
case 6:
TextView textView = new TextView(mContext);
textView.setTextColor(0xff7B8389);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 13);
textView.setGravity(Gravity.CENTER_HORIZONTAL);
textView.setPadding(0, 0, 0, AndroidUtilities.dp(10));
textView.setText(LocaleController.formatString("VoipVideoNotAvailableAdmin", R.string.VoipVideoNotAvailableAdmin, LocaleController.formatPluralString("Members", accountInstance.getMessagesController().groipCallVideoMaxParticipants)));
view = textView;
break;
case 3:
default:
view = new View(mContext);
@ -7672,18 +7707,16 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
public int getItemViewType(int position) {
if (position == lastRow) {
return 3;
}
if (position == addMemberRow) {
} else if (position == addMemberRow) {
return 0;
}
if (position == videoGridDividerRow) {
} else if (position == videoGridDividerRow) {
return 5;
}
if (position >= usersStartRow && position < usersEndRow) {
} else if (position >= usersStartRow && position < usersEndRow) {
return 1;
}
if (position >= usersVideoGridStartRow && position < usersVideoGridEndRow) {
} else if (position >= usersVideoGridStartRow && position < usersVideoGridEndRow) {
return 4;
} else if (position == videoNotAvailableRow) {
return 6;
}
return 2;
}
@ -7711,8 +7744,9 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
private int oldUsersVideoStartRow;
private int oldUsersVideoEndRow;
private int oldVideoDividerRow;
private int oldVideoNotAvailableRow;
public void setOldRows(int addMemberRow, int usersStartRow, int usersEndRow, int invitedStartRow, int invitedEndRow, int usersVideoStartRow, int usersVideoEndRow, int videoDividerRow) {
public void setOldRows(int addMemberRow, int usersStartRow, int usersEndRow, int invitedStartRow, int invitedEndRow, int usersVideoStartRow, int usersVideoEndRow, int videoDividerRow, int videoNotAvailableRow) {
oldAddMemberRow = addMemberRow;
oldUsersStartRow = usersStartRow;
oldUsersEndRow = usersEndRow;
@ -7721,6 +7755,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
oldUsersVideoStartRow = usersVideoStartRow;
oldUsersVideoEndRow = usersVideoEndRow;
oldVideoDividerRow = videoDividerRow;
oldVideoNotAvailableRow = videoNotAvailableRow;
}
private DiffUtil.Callback diffUtilsCallback = new DiffUtil.Callback() {
@ -7745,6 +7780,14 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
return false;
}
}
if (listAdapter.videoNotAvailableRow >= 0) {
if (oldItemPosition == oldVideoNotAvailableRow && newItemPosition == listAdapter.videoNotAvailableRow) {
return true;
} else if (oldItemPosition == oldVideoNotAvailableRow && newItemPosition != listAdapter.videoNotAvailableRow ||
oldItemPosition != oldVideoNotAvailableRow && newItemPosition == listAdapter.videoNotAvailableRow) {
return false;
}
}
if (listAdapter.videoGridDividerRow >= 0 && listAdapter.videoGridDividerRow == newItemPosition && oldItemPosition == oldVideoDividerRow) {
return true;
}
@ -7827,7 +7870,7 @@ public class GroupCallActivity extends BottomSheet implements NotificationCenter
@Override
public void onBackPressed() {
if (previewDialog != null) {
previewDialog.dismiss(false);
previewDialog.dismiss(false, false);
return;
}
if (avatarsPreviewShowed) {

View file

@ -266,12 +266,6 @@ public class IntroActivity extends Activity implements NotificationCenter.Notifi
destroyed = true;
finish();
});
if (BuildVars.DEBUG_PRIVATE_VERSION) {
startMessagingButton.setOnLongClickListener(v -> {
ConnectionsManager.getInstance(currentAccount).switchBackend();
return true;
});
}
bottomPages = new BottomPagesView(this, viewPager, 6);
frameLayout.addView(bottomPages, LayoutHelper.createFrame(66, 5, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 350, 0, 0));

View file

@ -1719,17 +1719,8 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
}
}
}
if (messageId != null && segments.contains("video")) {
String str = data.getQuery();
DateFormat dateFormat = new SimpleDateFormat("mm:ss");
Date reference = null;
try {
reference = dateFormat.parse("00:00");
Date date = dateFormat.parse(str);
videoTimestamp = (int) ((date.getTime() - reference.getTime()) / 1000L);
} catch (ParseException e) {
e.printStackTrace();
}
if (messageId != null) {
videoTimestamp = getTimestampFromLink(data);
}
botUser = data.getQueryParameter("start");
botChat = data.getQueryParameter("startgroup");
@ -2461,6 +2452,36 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
return pushOpened;
}
public static int getTimestampFromLink(Uri data) {
List<String> segments = data.getPathSegments();
String timestampStr = null;
if (segments.contains("video")) {
timestampStr = data.getQuery();
} else if (data.getQueryParameter("t") != null) {
timestampStr = data.getQueryParameter("t");
}
int videoTimestamp = -1;
if (timestampStr != null) {
try {
videoTimestamp = Integer.parseInt(timestampStr);
} catch (Throwable ignore) {
}
if (videoTimestamp == - 1) {
DateFormat dateFormat = new SimpleDateFormat("mm:ss");
Date reference = null;
try {
reference = dateFormat.parse("00:00");
Date date = dateFormat.parse(timestampStr);
videoTimestamp = (int) ((date.getTime() - reference.getTime()) / 1000L);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
return videoTimestamp;
}
private void openDialogsToSend(boolean animated) {
Bundle args = new Bundle();
args.putBoolean("onlySelect", true);
@ -4003,7 +4024,7 @@ public class LaunchActivity extends Activity implements ActionBarLayout.ActionBa
if (requestCode == SCREEN_CAPTURE_REQUEST_CODE) {
if (resultCode == Activity.RESULT_OK) {
VoIPService service = VoIPService.getSharedInstance();
if (service != null && service.groupCall != null) {
if (service != null) {
VideoCapturerDevice.mediaProjectionPermissionResultData = data;
service.createCaptureDevice(true);
}

View file

@ -138,6 +138,7 @@ public class LoginActivity extends BaseFragment {
private boolean checkShowPermissions = true;
private boolean newAccount;
private boolean syncContacts = true;
private boolean testBackend = false;
private int scrollHeight;
@ -1122,6 +1123,7 @@ public class LoginActivity extends BaseFragment {
private TextView textView;
private TextView textView2;
private CheckBoxCell checkBoxCell;
private CheckBoxCell testBackendCheckBox;
private int countryState = 0;
@ -1431,6 +1433,20 @@ public class LoginActivity extends BaseFragment {
});
}
if (BuildVars.DEBUG_PRIVATE_VERSION) {
testBackendCheckBox = new CheckBoxCell(context, 2);
testBackendCheckBox.setText("Test Backend", "", testBackend, false);
addView(testBackendCheckBox, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.MATCH_PARENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
testBackendCheckBox.setOnClickListener(v -> {
if (getParentActivity() == null) {
return;
}
CheckBoxCell cell = (CheckBoxCell) v;
testBackend = !testBackend;
cell.setChecked(testBackend, true);
});
}
HashMap<String, String> languageMap = new HashMap<>();
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(getResources().getAssets().open("countries.txt")));
@ -1613,6 +1629,11 @@ public class LoginActivity extends BaseFragment {
return;
}
String phone = PhoneFormat.stripExceptNumbers("" + codeField.getText() + phoneField.getText());
boolean isTestBakcend = getConnectionsManager().isTestBackend();
if (isTestBakcend != testBackend) {
getConnectionsManager().switchBackend(false);
isTestBakcend = testBackend;
}
if (getParentActivity() instanceof LaunchActivity) {
for (int a = 0; a < UserConfig.MAX_ACCOUNT_COUNT; a++) {
UserConfig userConfig = UserConfig.getInstance(a);
@ -1620,7 +1641,7 @@ public class LoginActivity extends BaseFragment {
continue;
}
String userPhone = userConfig.getCurrentUser().phone;
if (PhoneNumberUtils.compare(phone, userPhone)) {
if (PhoneNumberUtils.compare(phone, userPhone) && ConnectionsManager.getInstance(a).isTestBackend() == isTestBakcend) {
final int num = a;
AlertDialog.Builder builder = new AlertDialog.Builder(getParentActivity());
builder.setTitle(LocaleController.getString("AppName", R.string.AppName));

View file

@ -1975,7 +1975,7 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
ArticleViewer.getInstance().open(message);
return;
} else if (webPage.embed_url != null && webPage.embed_url.length() != 0) {
openWebView(webPage);
openWebView(webPage, message);
return;
} else {
link = webPage.url;
@ -2002,8 +2002,8 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
}
}
private void openWebView(TLRPC.WebPage webPage) {
EmbedBottomSheet.show(getParentActivity(), webPage.site_name, webPage.description, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height, false);
private void openWebView(TLRPC.WebPage webPage, MessageObject messageObject) {
EmbedBottomSheet.show(getParentActivity(), messageObject, provider, webPage.site_name, webPage.description, webPage.url, webPage.embed_url, webPage.embed_width, webPage.embed_height, false);
}
private void recycleAdapter(RecyclerView.Adapter adapter) {
@ -2063,8 +2063,8 @@ public class MediaActivity extends BaseFragment implements NotificationCenter.No
SharedLinkCell.SharedLinkCellDelegate sharedLinkCellDelegate = new SharedLinkCell.SharedLinkCellDelegate() {
@Override
public void needOpenWebView(TLRPC.WebPage webPage) {
MediaActivity.this.openWebView(webPage);
public void needOpenWebView(TLRPC.WebPage webPage, MessageObject message) {
MediaActivity.this.openWebView(webPage, message);
}
@Override

File diff suppressed because it is too large Load diff

View file

@ -2633,7 +2633,7 @@ public class ProfileActivity extends BaseFragment implements NotificationCenter.
SharedConfig.pushAuthKey = null;
SharedConfig.pushAuthKeyId = null;
SharedConfig.saveConfig();
getConnectionsManager().switchBackend();
getConnectionsManager().switchBackend(true);
});
builder1.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
showDialog(builder1.create());

View file

@ -0,0 +1,36 @@
package org.telegram.ui;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RadialGradient;
import android.graphics.Shader;
import androidx.core.graphics.ColorUtils;
public class RoundVideoProgressShadow {
RadialGradient radialGradient = new RadialGradient(0, 0, 100, new int[]{Color.TRANSPARENT, Color.TRANSPARENT, ColorUtils.setAlphaComponent(Color.BLACK, 40)}, new float[]{0, 0.7f, 1f}, Shader.TileMode.CLAMP);
Paint shaderPaint = new Paint();
Matrix matrix = new Matrix();
int lastSizesHash;
public RoundVideoProgressShadow() {
shaderPaint.setShader(radialGradient);
}
public void draw(Canvas canvas, float cx, float cy, float radius, float alpha) {
int sizesHash = (int) cx + ((int) cy << 12) + ((int) radius << 24);
if (sizesHash != lastSizesHash) {
matrix.reset();
float s = radius / 100f;
matrix.setTranslate(cx, cy);
matrix.preScale(s, s);
radialGradient.setLocalMatrix(matrix);
}
shaderPaint.setAlpha((int) (255 * alpha));
canvas.drawCircle(cx, cy, radius, shaderPaint);
}
}

View file

@ -72,6 +72,7 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
float toXOffsetRtl;
boolean crossfade;
boolean changeColor;
StaticLayout layout;
StaticLayout rtlLayout;
@ -102,6 +103,9 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
float replyNameDx;
float replyMessageDx;
int fromColor;
int toColor;
@SuppressLint("WrongConstant")
public TextMessageEnterTransition(ChatMessageCell messageView, ChatActivity chatActivity, RecyclerListView listView, MessageEnterTransitionContainer container) {
currentAccount = UserConfig.selectedAccount;
@ -214,6 +218,14 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
int normalLinesCount = 0;
int rtlLinesCount = 0;
if (Math.abs(ColorUtils.calculateLuminance(Theme.getColor(Theme.key_chat_messageTextOut)) - ColorUtils.calculateLuminance(Theme.getColor(Theme.key_chat_messagePanelText))) > 0.2f) {
crossfade = true;
changeColor = true;
fromColor = Theme.getColor(Theme.key_chat_messagePanelText);
toColor = Theme.getColor(Theme.key_chat_messageTextOut);
}
if (messageTextLayout.getLineCount() == layout.getLineCount()) {
n = messageTextLayout.getLineCount();
for (int i = 0; i < n; i++) {
@ -263,8 +275,6 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
layout = new StaticLayout(normalText, textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);
rtlLayout = new StaticLayout(rtlText, textPaint, width, Layout.Alignment.ALIGN_NORMAL, 1.0f, 0, false);
}
}
toXOffsetRtl = layout.getWidth() - messageView.getMessageObject().textLayoutBlocks.get(0).textLayout.getWidth();
@ -309,7 +319,6 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
drawableFromTop -= AndroidUtilities.dp(46);
}
gradientMatrix = new Matrix();
gradientPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
gradientPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
@ -422,12 +431,11 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
boolean messageViewOverscrolled = messageView.getBottom() - AndroidUtilities.dp(4) > listView.getMeasuredHeight();
boolean clipBottomWithAlpha = messageViewOverscrolled && (messageViewY + messageView.getMeasuredHeight() - AndroidUtilities.dp(8) > clipBottom) && container.getMeasuredHeight() > 0;
if (clipBottomWithAlpha) {
canvas.saveLayerAlpha(0, Math.max(0, messageViewY), container.getMeasuredWidth(), container.getMeasuredHeight(), 255, Canvas.ALL_SAVE_FLAG);
}
canvas.save();
canvas.clipRect(0, listView.getTop() + chatActivity.getChatListViewPadding() - container.getY() - AndroidUtilities.dp(3), container.getMeasuredWidth(), container.getMeasuredHeight());
canvas.clipRect(0, listView.getY() + chatActivity.getChatListViewPadding() - container.getY() - AndroidUtilities.dp(3), container.getMeasuredWidth(), container.getMeasuredHeight());
canvas.save();
float drawableX = messageViewX + messageView.getBackgroundDrawableLeft() + (fromX - (toX - toXOffset)) * (1f - progressX);
float drawableToTop = messageViewY + messageView.getBackgroundDrawableTop();
@ -572,14 +580,19 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
canvas.save();
canvas.translate(fromX * (1f - progressX) + (toX - toXOffset) * progressX, fromY * (1f - progress) + (toY + textLayoutBlock.textYOffset) * progress);
canvas.scale(scale, scale * scale2, 0, 0);
// canvas.translate(0, textLayoutBlock.textYOffset / 2);
if (drawBitmaps) {
if (crossfade) {
bitmapPaint.setAlpha((int) (255 * (1f - alphaProgress)));
}
canvas.drawBitmap(textLayoutBitmap, 0, 0, bitmapPaint);
} else {
if (crossfade) {
if (crossfade && changeColor) {
int oldColor = Theme.chat_msgTextPaint.getColor();
Theme.chat_msgTextPaint.setColor(ColorUtils.setAlphaComponent(fromColor, (int) (Color.alpha(fromColor) * (1f - alphaProgress))));
layout.draw(canvas);
Theme.chat_msgTextPaint.setColor(oldColor);
} else if (crossfade) {
int oldAlpha = Theme.chat_msgTextPaint.getAlpha();
Theme.chat_msgTextPaint.setAlpha((int) (oldAlpha * (1f - alphaProgress)));
layout.draw(canvas);
@ -587,7 +600,6 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
} else {
layout.draw(canvas);
}
}
canvas.restore();
@ -601,7 +613,12 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
}
canvas.drawBitmap(textLayoutBitmapRtl, 0, 0, bitmapPaint);
} else {
if (crossfade) {
if (crossfade && changeColor) {
int oldColor = Theme.chat_msgTextPaint.getColor();
Theme.chat_msgTextPaint.setColor(ColorUtils.setAlphaComponent(fromColor, (int) (Color.alpha(fromColor) * (1f - alphaProgress))));
rtlLayout.draw(canvas);
Theme.chat_msgTextPaint.setColor(oldColor);
} else if (crossfade) {
int oldAlpha = Theme.chat_msgTextPaint.getAlpha();
Theme.chat_msgTextPaint.setAlpha((int) (oldAlpha * (1f - alphaProgress)));
rtlLayout.draw(canvas);
@ -609,7 +626,6 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
} else {
rtlLayout.draw(canvas);
}
}
canvas.restore();
}
@ -629,14 +645,12 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
canvas.restore();
}
canvas.restore();
if (clipBottomWithAlpha) {
gradientMatrix.setTranslate(0, clipBottom);
gradientShader.setLocalMatrix(gradientMatrix);
canvas.drawRect(0, clipBottom, container.getMeasuredWidth(), container.getMeasuredHeight(), gradientPaint);
canvas.restore();
}
@ -647,8 +661,6 @@ public class TextMessageEnterTransition implements MessageEnterTransitionContain
if (enterView.getSendButton().getVisibility() == View.VISIBLE && sendProgress < 1f) {
canvas.save();
canvas.translate(enterView.getX() + enterView.getSendButton().getX() + ((View) enterView.getSendButton().getParent()).getX() + ((View) enterView.getSendButton().getParent().getParent()).getX() - container.getX() + AndroidUtilities.dp(52) * sendProgress, enterView.getY() + enterView.getSendButton().getY() + ((View) enterView.getSendButton().getParent()).getY() + ((View) enterView.getSendButton().getParent().getParent()).getY() - container.getY());
// canvas.saveLayerAlpha(0, 0, enterView.getSendButton().getWidth(), enterView.getSendButton().getHeight(), (int) (enterView.getSendButton().getAlpha() * 255), Canvas.ALL_SAVE_FLAG);
//canvas.scale(enterView.getSendButton().getScaleX(), enterView.getSendButton().getScaleY(), enterView.getSendButton().getWidth() / 2f, enterView.getSendButton().getHeight() / 2f);
enterView.getSendButton().draw(canvas);
canvas.restore();
canvas.restore();

View file

@ -76,6 +76,7 @@ import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.HintView;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.voip.AcceptDeclineView;
import org.telegram.ui.Components.voip.PrivateVideoPreviewDialog;
import org.telegram.ui.Components.voip.VoIPButtonsLayout;
import org.telegram.ui.Components.voip.VoIPFloatingLayout;
import org.telegram.ui.Components.voip.VoIPHelper;
@ -142,8 +143,10 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
Paint overlayBottomPaint = new Paint();
boolean isOutgoing;
boolean callingUserIsVideo = false;
boolean currentUserIsVideo = false;
boolean callingUserIsVideo;
boolean currentUserIsVideo;
private PrivateVideoPreviewDialog previewDialog;
private int currentState;
private int previousState;
@ -306,6 +309,10 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
if (isFinished || switchingToPip) {
return;
}
if (previewDialog != null) {
previewDialog.dismiss(false, false);
return;
}
if (callingUserIsVideo && currentUserIsVideo && cameraForceExpanded) {
cameraForceExpanded = false;
currentUserCameraFloatingLayout.setRelativePosition(callingUserMiniFloatingLayout);
@ -380,6 +387,9 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
currentUserCameraFloatingLayout.setInsets(lastInsets);
callingUserMiniFloatingLayout.setInsets(lastInsets);
fragmentView.requestLayout();
if (previewDialog != null) {
previewDialog.setBottomPadding(lastInsets.getSystemWindowInsetBottom());
}
}
public VoIPFragment(int account) {
@ -576,6 +586,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
callingUserPhotoView.setImage(ImageLocation.getForUserOrChat(callingUser, ImageLocation.TYPE_BIG), null, gradientDrawable, callingUser);
currentUserCameraFloatingLayout = new VoIPFloatingLayout(context);
currentUserCameraFloatingLayout.setDelegate((progress, value) -> currentUserTextureView.setScreenshareMiniProgress(progress, value));
currentUserCameraFloatingLayout.setRelativePosition(1f, 1f);
currentUserTextureView = new VoIPTextureView(context, true, false);
currentUserTextureView.renderer.setIsCamera(true);
@ -753,7 +764,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().acceptIncomingCall();
if (currentUserIsVideo) {
VoIPService.getSharedInstance().requestVideoCall();
VoIPService.getSharedInstance().requestVideoCall(false);
}
}
}
@ -1093,6 +1104,9 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
callingUserTextureView.setTranslationX(tx);
callingUserTextureView.setTranslationY(ty);
callingUserTextureView.setRoundCorners(v * AndroidUtilities.dp(4) * 1 / callingUserScale);
if (!currentUserCameraFloatingLayout.measuredAsFloatingMode) {
currentUserTextureView.setScreenshareMiniProgress(v, false);
}
callingUserPhotoView.setScaleX(callingUserScale);
callingUserPhotoView.setScaleY(callingUserScale);
@ -1163,7 +1177,6 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
}
}
private void updateViewState() {
if (isFinished || switchingToPip) {
return;
@ -1175,20 +1188,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
boolean showReconnecting = false;
boolean showCallingAvatarMini = false;
int statusLayoutOffset = 0;
VoIPService service = VoIPService.getSharedInstance();
if (service != null) {
callingUserIsVideo = service.getRemoteVideoState() == Instance.VIDEO_STATE_ACTIVE;
currentUserIsVideo = service.getVideoState(false) == Instance.VIDEO_STATE_ACTIVE || service.getVideoState(false) == Instance.VIDEO_STATE_PAUSED;
if (currentUserIsVideo && !isVideoCall) {
isVideoCall = true;
}
}
if (animated) {
currentUserCameraFloatingLayout.saveRelatedPosition();
callingUserMiniFloatingLayout.saveRelatedPosition();
}
switch (currentState) {
case VoIPService.STATE_WAITING_INCOMING:
@ -1310,6 +1310,22 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
}
break;
}
if (previewDialog != null) {
return;
}
if (service != null) {
callingUserIsVideo = service.getRemoteVideoState() == Instance.VIDEO_STATE_ACTIVE;
currentUserIsVideo = service.getVideoState(false) == Instance.VIDEO_STATE_ACTIVE || service.getVideoState(false) == Instance.VIDEO_STATE_PAUSED;
if (currentUserIsVideo && !isVideoCall) {
isVideoCall = true;
}
}
if (animated) {
currentUserCameraFloatingLayout.saveRelatedPosition();
callingUserMiniFloatingLayout.saveRelatedPosition();
}
if (callingUserIsVideo) {
if (!switchingToPip) {
@ -1410,8 +1426,9 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
if (currentUserIsVideo) {
service.sharedUIParams.tapToVideoTooltipWasShowed = true;
}
currentUserTextureView.setIsScreencast(service.isScreencast());
currentUserTextureView.renderer.setMirror(service.isFrontFaceCamera());
service.setSinks(currentUserIsVideo ? currentUserTextureView.renderer : null, showCallingUserVideoMini ? callingUserMiniTextureRenderer : callingUserTextureView.renderer);
service.setSinks(currentUserIsVideo && !service.isScreencast() ? currentUserTextureView.renderer : null, showCallingUserVideoMini ? callingUserMiniTextureRenderer : callingUserTextureView.renderer);
if (animated) {
notificationsLayout.beforeLayoutChanges();
@ -1610,10 +1627,10 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
if (animated) {
if (currentUserCameraFloatingLayout.getTag() != null && (int) currentUserCameraFloatingLayout.getTag() == STATE_GONE) {
if (currentUserCameraFloatingLayout.getVisibility() == View.GONE) {
currentUserCameraFloatingLayout.setVisibility(View.VISIBLE);
currentUserCameraFloatingLayout.setAlpha(0f);
currentUserCameraFloatingLayout.setScaleX(0.7f);
currentUserCameraFloatingLayout.setScaleY(0.7f);
currentUserCameraFloatingLayout.setVisibility(View.VISIBLE);
}
if (cameraShowingAnimator != null) {
cameraShowingAnimator.removeAllListeners();
@ -1621,9 +1638,9 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
}
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(
ObjectAnimator.ofFloat(currentUserCameraFloatingLayout, View.ALPHA, currentUserCameraFloatingLayout.getAlpha(), 1f),
ObjectAnimator.ofFloat(currentUserCameraFloatingLayout, View.SCALE_X, currentUserCameraFloatingLayout.getScaleX(), 1f),
ObjectAnimator.ofFloat(currentUserCameraFloatingLayout, View.SCALE_Y, currentUserCameraFloatingLayout.getScaleY(), 1f)
ObjectAnimator.ofFloat(currentUserCameraFloatingLayout, View.ALPHA, 0.0f, 1f),
ObjectAnimator.ofFloat(currentUserCameraFloatingLayout, View.SCALE_X, 0.7f, 1f),
ObjectAnimator.ofFloat(currentUserCameraFloatingLayout, View.SCALE_Y, 0.7f, 1f)
);
cameraShowingAnimator = animatorSet;
cameraShowingAnimator.setDuration(150).start();
@ -1785,7 +1802,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
if (currentState == VoIPService.STATE_WAITING_INCOMING || currentState == VoIPService.STATE_BUSY) {
if (service.privateCall != null && service.privateCall.video && currentState == VoIPService.STATE_WAITING_INCOMING) {
if (currentUserIsVideo || callingUserIsVideo) {
if (!service.isScreencast() && (currentUserIsVideo || callingUserIsVideo)) {
setFrontalCameraAction(bottomButtons[0], service, animated);
if (uiVisible) {
speakerPhoneIcon.animate().alpha(1f).start();
@ -1806,7 +1823,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
if (instance == null) {
return;
}
if (currentUserIsVideo || callingUserIsVideo) {
if (!service.isScreencast() && (currentUserIsVideo || callingUserIsVideo)) {
setFrontalCameraAction(bottomButtons[0], service, animated);
if (uiVisible) {
speakerPhoneIcon.setTag(1);
@ -1874,7 +1891,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
}
if (isVideoAvailable) {
if (currentUserIsVideo) {
bottomButton.setData(R.drawable.calls_video, Color.WHITE, ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * 0.12f)), LocaleController.getString("VoipStopVideo", R.string.VoipStopVideo), false, animated);
bottomButton.setData(service.isScreencast() ? R.drawable.calls_sharescreen : R.drawable.calls_video, Color.WHITE, ColorUtils.setAlphaComponent(Color.WHITE, (int) (255 * 0.12f)), LocaleController.getString("VoipStopVideo", R.string.VoipStopVideo), false, animated);
} else {
bottomButton.setData(R.drawable.calls_video, Color.BLACK, Color.WHITE, LocaleController.getString("VoipStartVideo", R.string.VoipStartVideo), true, animated);
}
@ -1883,7 +1900,7 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && activity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{Manifest.permission.CAMERA}, 102);
} else {
if (service.privateCall != null && !service.privateCall.video && !callingUserIsVideo && !service.sharedUIParams.cameraAlertWasShowed) {
if (Build.VERSION.SDK_INT < 21 && service.privateCall != null && !service.privateCall.video && !callingUserIsVideo && !service.sharedUIParams.cameraAlertWasShowed) {
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setMessage(LocaleController.getString("VoipSwitchToVideoCall", R.string.VoipSwitchToVideoCall));
builder.setPositiveButton(LocaleController.getString("VoipSwitch", R.string.VoipSwitch), (dialogInterface, i) -> {
@ -1974,6 +1991,13 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
}
}
public void onScreenCastStart() {
if (previewDialog == null) {
return;
}
previewDialog.dismiss(true, true);
}
private void toggleCameraInput() {
VoIPService service = VoIPService.getSharedInstance();
if (service != null) {
@ -1987,16 +2011,54 @@ public class VoIPFragment implements VoIPService.StateListener, NotificationCent
fragmentView.announceForAccessibility(text);
}
if (!currentUserIsVideo) {
currentUserIsVideo = true;
if (!service.isSpeakerphoneOn()) {
VoIPService.getSharedInstance().toggleSpeakerphoneOrShowRouteSheet(activity, false);
if (Build.VERSION.SDK_INT >= 21) {
if (previewDialog == null) {
service.createCaptureDevice(false);
if (!service.isFrontFaceCamera()) {
service.switchCamera();
}
windowView.setLockOnScreen(true);
previewDialog = new PrivateVideoPreviewDialog(fragmentView.getContext(), false, true) {
@Override
public void onDismiss(boolean screencast, boolean apply) {
previewDialog = null;
VoIPService service = VoIPService.getSharedInstance();
windowView.setLockOnScreen(false);
if (apply) {
currentUserIsVideo = true;
if (service != null && !screencast) {
service.requestVideoCall(false);
service.setVideoState(false, Instance.VIDEO_STATE_ACTIVE);
}
} else {
if (service != null) {
service.setVideoState(false, Instance.VIDEO_STATE_INACTIVE);
}
}
previousState = currentState;
updateViewState();
}
};
if (lastInsets != null) {
previewDialog.setBottomPadding(lastInsets.getSystemWindowInsetBottom());
}
fragmentView.addView(previewDialog);
}
return;
} else {
currentUserIsVideo = true;
if (!service.isSpeakerphoneOn()) {
VoIPService.getSharedInstance().toggleSpeakerphoneOrShowRouteSheet(activity, false);
}
service.requestVideoCall(false);
service.setVideoState(false, Instance.VIDEO_STATE_ACTIVE);
}
service.requestVideoCall();
service.setVideoState(false, Instance.VIDEO_STATE_ACTIVE);
} else {
currentUserTextureView.saveCameraLastBitmap();
service.setVideoState(false, Instance.VIDEO_STATE_INACTIVE);
if (Build.VERSION.SDK_INT >= 21) {
service.clearCamera();
}
}
previousState = currentState;
updateViewState();