NekoX/TMessagesProj/src/main/java/org/telegram/ui/GroupCallActivity.java

8676 lines
447 KiB
Java

package org.telegram.ui;
import static android.content.Context.AUDIO_SERVICE;
import android.Manifest;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
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.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.media.AudioManager;
import android.media.projection.MediaProjectionManager;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.text.Editable;
import android.text.InputType;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.util.Property;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.OvershootInterpolator;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.collection.LongSparseArray;
import androidx.core.graphics.ColorUtils;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.ListUpdateCallback;
import androidx.recyclerview.widget.RecyclerView;
import androidx.viewpager.widget.ViewPager;
import org.telegram.messenger.AccountInstance;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ChatObject;
import org.telegram.messenger.DialogObject;
import org.telegram.messenger.FileLoader;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.ImageLoader;
import org.telegram.messenger.ImageLocation;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessageObject;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.SharedConfig;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
import org.telegram.messenger.support.LongSparseIntArray;
import org.telegram.messenger.voip.Instance;
import org.telegram.messenger.voip.VoIPService;
import org.telegram.tgnet.ConnectionsManager;
import org.telegram.tgnet.TLObject;
import org.telegram.tgnet.TLRPC;
import org.telegram.ui.ActionBar.ActionBar;
import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
import org.telegram.ui.ActionBar.ActionBarPopupWindow;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.BottomSheet;
import org.telegram.ui.ActionBar.SimpleTextView;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ActionBar.ThemeDescription;
import org.telegram.ui.Cells.AccountSelectCell;
import org.telegram.ui.Cells.CheckBoxCell;
import org.telegram.ui.Cells.GroupCallInvitedCell;
import org.telegram.ui.Cells.GroupCallTextCell;
import org.telegram.ui.Cells.GroupCallUserCell;
import org.telegram.ui.Components.AlertsCreator;
import org.telegram.ui.Components.AnimationProperties;
import org.telegram.ui.Components.AudioPlayerAlert;
import org.telegram.ui.Components.AvatarDrawable;
import org.telegram.ui.Components.BackupImageView;
import org.telegram.ui.Components.BlobDrawable;
import org.telegram.ui.Components.CheckBoxSquare;
import org.telegram.ui.Components.CubicBezierInterpolator;
import org.telegram.ui.Components.EditTextBoldCursor;
import org.telegram.ui.Components.FillLastGridLayoutManager;
import org.telegram.ui.Components.GroupCallFullscreenAdapter;
import org.telegram.ui.Components.GroupCallPip;
import org.telegram.ui.Components.GroupCallRecordAlert;
import org.telegram.ui.Components.GroupVoipInviteAlert;
import org.telegram.ui.Components.HintView;
import org.telegram.ui.Components.ImageUpdater;
import org.telegram.ui.Components.JoinCallAlert;
import org.telegram.ui.Components.LayoutHelper;
import org.telegram.ui.Components.NumberPicker;
import org.telegram.ui.Components.ProfileGalleryView;
import org.telegram.ui.Components.RLottieDrawable;
import org.telegram.ui.Components.RLottieImageView;
import org.telegram.ui.Components.RadialProgressView;
import org.telegram.ui.Components.RecordStatusDrawable;
import org.telegram.ui.Components.RecyclerListView;
import org.telegram.ui.Components.ShareAlert;
import org.telegram.ui.Components.TypefaceSpan;
import org.telegram.ui.Components.UndoView;
import org.telegram.ui.Components.WaveDrawable;
import org.telegram.ui.Components.voip.CellFlickerDrawable;
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.PrivateVideoPreviewDialog;
import org.telegram.ui.Components.voip.RTMPStreamPipOverlay;
import org.telegram.ui.Components.voip.VoIPToggleButton;
import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
import tw.nekomimi.nekogram.NekoConfig;
public class GroupCallActivity extends BottomSheet implements NotificationCenter.NotificationCenterDelegate, VoIPService.StateListener {
public final static int TABLET_LIST_SIZE = 320;
public static final long TRANSITION_DURATION = 350;
private static final int eveyone_can_speak_item = 1;
private static final int admin_can_speak_item = 2;
private static final int share_invite_link_item = 3;
private static final int leave_item = 4;
private static final int start_record_item = 5;
private static final int edit_item = 6;
private static final int permission_item = 7;
private static final int user_item = 8;
private static final int screen_capture_item = 9;
private static final int sound_item = 10;
private static final int noise_item = 11;
private static final int user_item_gap = 0;
private static final int MUTE_BUTTON_STATE_UNMUTE = 0;
private static final int MUTE_BUTTON_STATE_MUTE = 1;
private static final int MUTE_BUTTON_STATE_MUTED_BY_ADMIN = 2;
private static final int MUTE_BUTTON_STATE_CONNECTING = 3;
private static final int MUTE_BUTTON_STATE_RAISED_HAND = 4;
private static final int MUTE_BUTTON_STATE_START_NOW = 5;
private static final int MUTE_BUTTON_STATE_SET_REMINDER = 6;
private static final int MUTE_BUTTON_STATE_CANCEL_REMINDER = 7;
public static int currentScreenOrientation;
public static GroupCallActivity groupCallInstance;
public static boolean groupCallUiVisible;
private final ProfileGalleryView avatarsViewPager;
private final GridLayoutManager.SpanSizeLookup spanSizeLookup;
private AccountInstance accountInstance;
private View actionBarBackground;
private ActionBar actionBar;
private ListAdapter listAdapter;
private RecyclerListView listView;
private LinearLayout scheduleTimerContainer;
private TextView scheduleInfoTextView;
private TextView scheduleButtonTextView;
private SimpleTextView scheduleStartInTextView;
private SimpleTextView scheduleTimeTextView;
private SimpleTextView scheduleStartAtTextView;
private GroupCallItemAnimator itemAnimator;
private FillLastGridLayoutManager layoutManager;
private VoIPToggleButton flipButton;
private VoIPToggleButton cameraButton;
private VoIPToggleButton soundButton;
private float soundButtonScale;
private float cameraButtonScale;
private VoIPToggleButton leaveButton;
private RLottieImageView muteButton;
private TextView[] muteLabel = new TextView[2];
private FrameLayout buttonsContainer;
private RadialProgressView radialProgressView;
private Drawable shadowDrawable;
private View actionBarShadow;
private AnimatorSet actionBarAnimation;
private LaunchActivity parentActivity;
private UndoView[] undoView = new UndoView[2];
private AccountSelectCell accountSelectCell;
private View accountGap;
private boolean changingPermissions;
private HintView recordHintView;
private HintView reminderHintView;
private int buttonsVisibility;
private ImageView expandButton;
private ImageView minimizeButton;
public final ArrayList<ChatObject.VideoParticipant> visibleVideoParticipants = new ArrayList<>();
float progressToHideUi;
private ShareAlert shareAlert;
private boolean delayedGroupCallUpdated;
private long creatingServiceTime;
private boolean callInitied;
private RectF rect = new RectF();
private boolean enterEventSent;
private boolean anyEnterEventSent;
private float scrollOffsetY;
PrivateVideoPreviewDialog previewDialog;
private TLRPC.Peer selfPeer;
private TLObject userSwitchObject;
private Paint listViewBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private ArrayList<TLRPC.TL_groupCallParticipant> oldParticipants = new ArrayList<>();
private ArrayList<ChatObject.VideoParticipant> oldVideoParticipants = new ArrayList<>();
private ArrayList<Long> oldInvited = new ArrayList<>();
private int oldCount;
private RLottieDrawable bigMicDrawable;
private RLottieDrawable handDrawables;
private boolean playingHandAnimation;
private final BlobDrawable tinyWaveDrawable;
private final BlobDrawable bigWaveDrawable;
private float amplitude;
private float animateToAmplitude;
private float animateAmplitudeDiff;
private RadialGradient radialGradient;
private final Matrix radialMatrix;
private final Paint radialPaint;
private float switchToButtonProgress;
private float switchToButtonInt2;
private float scheduleButtonsScale;
private ValueAnimator scheduleAnimator;
private ValueAnimator muteButtonAnimator;
private ValueAnimator expandAnimator;
private ValueAnimator expandSizeAnimator;
private TLRPC.InputPeer schedulePeer;
public TLRPC.Chat currentChat;
public ChatObject.Call call;
private boolean scheduleHasFewPeers;
private String scheduledHash;
private RecordCallDrawable recordCallDrawable;
private AudioPlayerAlert.ClippingTextViewSwitcher titleTextView;
private ActionBarMenuItem otherItem;
private ActionBarMenuItem pipItem;
private ActionBarMenuItem screenShareItem;
private ActionBarMenuSubItem inviteItem;
private ActionBarMenuSubItem editTitleItem;
private ActionBarMenuSubItem soundItem;
private ActionBarMenuSubItem noiseItem;
private ActionBarMenuSubItem permissionItem;
private ActionBarMenuSubItem recordItem;
private ActionBarMenuSubItem screenItem;
private ActionBarMenuSubItem everyoneItem;
private ActionBarMenuSubItem adminItem;
private ActionBarMenuSubItem leaveItem;
private final LinearLayout menuItemsContainer;
private View soundItemDivider;
private Runnable updateCallRecordRunnable;
private GroupVoipInviteAlert groupVoipInviteAlert;
private int muteButtonState = MUTE_BUTTON_STATE_UNMUTE;
private boolean animatingToFullscreenExpand = false;
private boolean startingGroupCall;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
private Paint paintTmp = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.DITHER_FLAG | Paint.FILTER_BITMAP_FLAG);
private Paint leaveBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private WeavingState[] states = new WeavingState[8];
private float switchProgress = 1.0f;
private WeavingState prevState;
private WeavingState currentState;
private long lastUpdateTime;
private int shaderBitmapSize = 200;
private float showWavesProgress;
private float showLightingProgress;
private boolean scheduled;
private boolean pressed;
private int currentCallState;
private float colorProgress;
private int backgroundColor;
private boolean invalidateColors = true;
private final int[] colorsTmp = new int[3];
// private boolean isVideoCall = true;
private final ArrayList<GroupCallMiniTextureView> attachedRenderers = new ArrayList<>();
private final ArrayList<GroupCallMiniTextureView> attachedRenderersTmp = new ArrayList<>();
private GroupCallRenderersContainer renderersContainer;
private View blurredView;
PinchToZoomHelper pinchToZoomHelper;
private float progressToAvatarPreview;
private View scrimPopupLayout;
private boolean avatarsPreviewShowed;
private boolean useBlur;
ImageUpdater currentAvatarUpdater;
AvatarUpdaterDelegate avatarUpdaterDelegate;
private Boolean wasNotInLayoutFullscreen;
private Boolean wasExpandBigSize = true;
private int scheduleStartAt;
private boolean contentFullyOverlayed;
// private float progressToFullscreenMode;
ValueAnimator fullscreenModeAnimator;
RecyclerListView fullscreenUsersListView;
RecyclerListView tabletVideoGridView;
GroupCallTabletGridAdapter tabletGridAdapter;
GroupCallFullscreenAdapter fullscreenAdapter;
ViewTreeObserver.OnPreDrawListener requestFullscreenListener;
public CellFlickerDrawable cellFlickerDrawable = new CellFlickerDrawable();
public static boolean isLandscapeMode;
public static boolean isTabletMode;
public final ArrayList<GroupCallStatusIcon> statusIconPool = new ArrayList<>();
private boolean drawSpeakingSubtitle;
private HashMap<View, Float> buttonsAnimationParamsX = new HashMap<>();
private HashMap<View, Float> buttonsAnimationParamsY = new HashMap<>();
boolean animateButtonsOnNextLayout;
private Runnable onUserLeaveHintListener = this::onUserLeaveHint;
private Runnable updateSchedeulRunnable = new Runnable() {
@Override
public void run() {
if (scheduleTimeTextView == null || isDismissed()) {
return;
}
int time;
if (call != null) {
time = call.call.schedule_date;
} else {
time = scheduleStartAt;
}
if (time == 0) {
return;
}
int diff = time - accountInstance.getConnectionsManager().getCurrentTime();
if (diff >= 24 * 60 * 60) {
scheduleTimeTextView.setText(LocaleController.formatPluralString("Days", Math.round(diff / (24 * 60 * 60.0f))));
} else {
scheduleTimeTextView.setText(AndroidUtilities.formatFullDuration(Math.abs(diff)));
if (diff < 0 && scheduleStartInTextView.getTag() == null) {
scheduleStartInTextView.setTag(1);
scheduleStartInTextView.setText(LocaleController.getString("VoipChatLateBy", R.string.VoipChatLateBy));
}
}
scheduleStartAtTextView.setText(LocaleController.formatStartsTime(time, 3));
AndroidUtilities.runOnUIThread(updateSchedeulRunnable, 1000);
}
};
private Runnable unmuteRunnable = () -> {
if (VoIPService.getSharedInstance() == null) {
return;
}
VoIPService.getSharedInstance().setMicMute(false, true, false);
};
private Runnable pressRunnable = () -> {
if (call == null || !scheduled || VoIPService.getSharedInstance() == null) {
return;
}
if (!NekoConfig.disableVibration.Bool()) {
muteButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
updateMuteButton(MUTE_BUTTON_STATE_MUTE, true);
AndroidUtilities.runOnUIThread(unmuteRunnable, 80);
scheduled = false;
pressed = true;
};
LongSparseIntArray visiblePeerIds = new LongSparseIntArray();
public static final Property<GroupCallActivity, Float> COLOR_PROGRESS = new AnimationProperties.FloatProperty<GroupCallActivity>("colorProgress") {
@Override
public void setValue(GroupCallActivity object, float value) {
object.setColorProgress(value);
}
@Override
public Float get(GroupCallActivity object) {
return object.getColorProgress();
}
};
private final FrameLayout avatarPreviewContainer;
private final AvatarPreviewPagerIndicator avatarPagerIndicator;
private ViewGroup currentOptionsLayout;
public boolean drawingForBlur;
private final RLottieDrawable flipIcon;
private int flipIconCurrentEndFrame;
private boolean hasVideo;
private final View buttonsBackgroundGradientView;
private final View buttonsBackgroundGradientView2;
private GradientDrawable buttonsBackgroundGradient;
private int[] gradientColors = new int[2];
private final DefaultItemAnimator fullscreenListItemAnimator;
private boolean previewTextureTransitionEnabled;
private boolean listViewVideoVisibility = true;
public static boolean paused;
private static class SmallRecordCallDrawable extends Drawable {
private Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
private long lastUpdateTime;
private float alpha = 1.0f;
private int state;
private View parentView;
public SmallRecordCallDrawable(View parent) {
super();
parentView = parent;
}
@Override
public int getIntrinsicWidth() {
return AndroidUtilities.dp(24);
}
@Override
public int getIntrinsicHeight() {
return AndroidUtilities.dp(24);
}
@Override
public void draw(Canvas canvas) {
int cx = getBounds().centerX();
int cy = getBounds().centerY();
if (parentView instanceof SimpleTextView) {
cy += AndroidUtilities.dp(1);
cx -= AndroidUtilities.dp(3);
} else {
cy += AndroidUtilities.dp(2);
}
paint2.setColor(0xffEE7D79);
paint2.setAlpha((int) (255 * alpha));
canvas.drawCircle(cx, cy, AndroidUtilities.dp(4), paint2);
long newTime = SystemClock.elapsedRealtime();
long dt = newTime - lastUpdateTime;
if (dt > 17) {
dt = 17;
}
lastUpdateTime = newTime;
if (state == 0) {
alpha += dt / 2000.0f;
if (alpha >= 1.0f) {
alpha = 1.0f;
state = 1;
}
} else if (state == 1) {
alpha -= dt / 2000.0f;
if (alpha < 0.5f) {
alpha = 0.5f;
state = 0;
}
}
parentView.invalidate();
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
}
private static class RecordCallDrawable extends Drawable {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
private long lastUpdateTime;
private float alpha = 1.0f;
private int state;
private boolean recording;
private View parentView;
public RecordCallDrawable() {
super();
paint.setColor(0xffffffff);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(AndroidUtilities.dp(1.5f));
}
public void setParentView(View view) {
parentView = view;
}
@Override
public int getIntrinsicWidth() {
return AndroidUtilities.dp(24);
}
@Override
public int getIntrinsicHeight() {
return AndroidUtilities.dp(24);
}
public boolean isRecording() {
return recording;
}
public void setRecording(boolean value) {
recording = value;
alpha = 1.0f;
invalidateSelf();
}
@Override
public void draw(Canvas canvas) {
int cx = getBounds().centerX();
int cy = getBounds().centerY();
canvas.drawCircle(cx, cy, AndroidUtilities.dp(10), paint);
paint2.setColor(recording ? 0xffEE7D79 : 0xffffffff);
paint2.setAlpha((int) (255 * alpha));
canvas.drawCircle(cx, cy, AndroidUtilities.dp(5), paint2);
if (recording) {
long newTime = SystemClock.elapsedRealtime();
long dt = newTime - lastUpdateTime;
if (dt > 17) {
dt = 17;
}
lastUpdateTime = newTime;
if (state == 0) {
alpha += dt / 2000.0f;
if (alpha >= 1.0f) {
alpha = 1.0f;
state = 1;
}
} else if (state == 1) {
alpha -= dt / 2000.0f;
if (alpha < 0.5f) {
alpha = 0.5f;
state = 0;
}
}
parentView.invalidate();
}
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(ColorFilter colorFilter) {
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
}
private class VolumeSlider extends FrameLayout {
private RLottieImageView imageView;
private TextView textView;
private TLRPC.TL_groupCallParticipant currentParticipant;
private RLottieDrawable speakerDrawable;
private boolean captured;
private float sx, sy;
private int thumbX;
private double currentProgress;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint paint2 = new Paint(Paint.ANTI_ALIAS_FLAG);
private Path path = new Path();
private float[] radii = new float[8];
private RectF rect = new RectF();
private int currentColor;
private int oldColor;
private float colorChangeProgress;
private long lastUpdateTime;
private float[] volumeAlphas = new float[3];
private boolean dragging;
public VolumeSlider(Context context, TLRPC.TL_groupCallParticipant participant) {
super(context);
setWillNotDraw(false);
currentParticipant = participant;
currentProgress = ChatObject.getParticipantVolume(participant) / 20000.0f;
colorChangeProgress = 1.0f;
setPadding(AndroidUtilities.dp(12), 0, AndroidUtilities.dp(12), 0);
speakerDrawable = new RLottieDrawable(R.raw.speaker, "" + R.raw.speaker, AndroidUtilities.dp(24), AndroidUtilities.dp(24), true, null);
imageView = new RLottieImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER);
imageView.setAnimation(speakerDrawable);
imageView.setTag(currentProgress == 0 ? 1 : null);
addView(imageView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 40, Gravity.CENTER_VERTICAL | (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT), 0, 0, 0, 0));
speakerDrawable.setCustomEndFrame(currentProgress == 0 ? 17 : 34);
speakerDrawable.setCurrentFrame(speakerDrawable.getCustomEndFrame() - 1, false, true);
textView = new TextView(context);
textView.setLines(1);
textView.setSingleLine(true);
textView.setGravity(Gravity.LEFT);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setTextColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
double vol = ChatObject.getParticipantVolume(currentParticipant) / 100.0;
textView.setText(String.format(Locale.US, "%d%%", (int) (vol > 0 ? Math.max(vol, 1) : 0)));
textView.setPadding(LocaleController.isRTL ? 0 : AndroidUtilities.dp(43), 0, LocaleController.isRTL ? AndroidUtilities.dp(43) : 0, 0);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL));
paint2.setStyle(Paint.Style.STROKE);
paint2.setStrokeWidth(AndroidUtilities.dp(1.5f));
paint2.setStrokeCap(Paint.Cap.ROUND);
paint2.setColor(0xffffffff);
int percent = (int) (ChatObject.getParticipantVolume(currentParticipant) / 100.0);
for (int a = 0; a < volumeAlphas.length; a++) {
int p;
if (a == 0) {
p = 0;
} else if (a == 1) {
p = 50;
} else {
p = 150;
}
if (percent > p) {
volumeAlphas[a] = 1.0f;
} else {
volumeAlphas[a] = 0.0f;
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(48), View.MeasureSpec.EXACTLY));
thumbX = (int) (MeasureSpec.getSize(widthMeasureSpec) * currentProgress);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
return onTouch(ev);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
return onTouch(event);
}
boolean onTouch(MotionEvent ev) {
if (ev.getAction() == MotionEvent.ACTION_DOWN) {
sx = ev.getX();
sy = ev.getY();
return true;
} else if (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_CANCEL) {
captured = false;
if (ev.getAction() == MotionEvent.ACTION_UP) {
final ViewConfiguration vc = ViewConfiguration.get(getContext());
if (Math.abs(ev.getY() - sy) < vc.getScaledTouchSlop()) {
thumbX = (int) ev.getX();
if (thumbX < 0) {
thumbX = 0;
} else if (thumbX > getMeasuredWidth()) {
thumbX = getMeasuredWidth();
}
dragging = true;
}
}
if (dragging) {
if (ev.getAction() == MotionEvent.ACTION_UP) {
onSeekBarDrag(thumbX / (double) getMeasuredWidth(), true);
}
dragging = false;
invalidate();
return true;
}
} else if (ev.getAction() == MotionEvent.ACTION_MOVE) {
if (!captured) {
final ViewConfiguration vc = ViewConfiguration.get(getContext());
if (Math.abs(ev.getY() - sy) > vc.getScaledTouchSlop()) {
return false;
}
if (Math.abs(ev.getX() - sx) > vc.getScaledTouchSlop()) {
captured = true;
getParent().requestDisallowInterceptTouchEvent(true);
if (ev.getY() >= 0 && ev.getY() <= getMeasuredHeight()) {
thumbX = (int) ev.getX();
if (thumbX < 0) {
thumbX = 0;
} else if (thumbX > getMeasuredWidth()) {
thumbX = getMeasuredWidth();
}
dragging = true;
invalidate();
return true;
}
}
} else {
if (dragging) {
thumbX = (int) ev.getX();
if (thumbX < 0) {
thumbX = 0;
} else if (thumbX > getMeasuredWidth()) {
thumbX = getMeasuredWidth();
}
onSeekBarDrag(thumbX / (double) getMeasuredWidth(), false);
invalidate();
return true;
}
}
}
return false;
}
private void onSeekBarDrag(double progress, boolean finalMove) {
if (VoIPService.getSharedInstance() == null) {
return;
}
currentProgress = progress;
currentParticipant.volume = (int) (progress * 20000);
currentParticipant.volume_by_admin = false;
currentParticipant.flags |= 128;
double vol = ChatObject.getParticipantVolume(currentParticipant) / 100.0;
textView.setText(String.format(Locale.US, "%d%%", (int) (vol > 0 ? Math.max(vol, 1) : 0)));
VoIPService.getSharedInstance().setParticipantVolume(currentParticipant, currentParticipant.volume);
if (finalMove) {
long id = MessageObject.getPeerId(currentParticipant.peer);
TLObject object;
if (id > 0) {
object = accountInstance.getMessagesController().getUser(id);
} else {
object = accountInstance.getMessagesController().getChat(-id);
}
if (currentParticipant.volume == 0) {
if (scrimPopupWindow != null) {
scrimPopupWindow.dismiss();
scrimPopupWindow = null;
}
dismissAvatarPreview(true);
processSelectedOption(currentParticipant, id, ChatObject.canManageCalls(currentChat) ? 0 : 5);
} else {
VoIPService.getSharedInstance().editCallMember(object, null, null, currentParticipant.volume, null, null);
}
}
Integer newTag = currentProgress == 0 ? 1 : null;
if (imageView.getTag() == null && newTag != null || imageView.getTag() != null && newTag == null) {
speakerDrawable.setCustomEndFrame(currentProgress == 0 ? 17 : 34);
speakerDrawable.setCurrentFrame(currentProgress == 0 ? 0 : 17);
speakerDrawable.start();
imageView.setTag(newTag);
}
}
@Override
protected void onDraw(Canvas canvas) {
int prevColor = currentColor;
if (currentProgress < 0.25f) {
currentColor = 0xffCC5757;
} else if (currentProgress > 0.25f && currentProgress < 0.5f) {
currentColor = 0xffC9A53B;
} else if (currentProgress >= 0.5f && currentProgress <= 0.75f) {
currentColor = 0xff57BC6B;
} else {
currentColor = 0xff4DA6DF;
}
int color;
if (prevColor == 0) {
color = currentColor;
colorChangeProgress = 1f;
} else {
color = AndroidUtilities.getOffsetColor(oldColor, prevColor, colorChangeProgress, 1.0f);
if (prevColor != currentColor) {
colorChangeProgress = 0.0f;
oldColor = color;
}
}
paint.setColor(color);
long newTime = SystemClock.elapsedRealtime();
long dt = newTime - lastUpdateTime;
if (dt > 17) {
dt = 17;
}
lastUpdateTime = newTime;
if (colorChangeProgress < 1.0f) {
colorChangeProgress += dt / 200.0f;
if (colorChangeProgress > 1.0f) {
colorChangeProgress = 1.0f;
} else {
invalidate();
}
}
path.reset();
radii[0] = radii[1] = radii[6] = radii[7] = AndroidUtilities.dp(6);
float rad = thumbX < AndroidUtilities.dp(12) ? Math.max(0, (thumbX - AndroidUtilities.dp(6)) / (float) AndroidUtilities.dp(6)) : 1.0f;
radii[2] = radii[3] = radii[4] = radii[5] = AndroidUtilities.dp(6) * rad;
rect.set(0, 0, thumbX, getMeasuredHeight());
path.addRoundRect(rect, radii, Path.Direction.CW);
path.close();
canvas.drawPath(path, paint);
int percent = (int) (ChatObject.getParticipantVolume(currentParticipant) / 100.0);
int cx = imageView.getLeft() + imageView.getMeasuredWidth() / 2 + AndroidUtilities.dp(5);
int cy = imageView.getTop() + imageView.getMeasuredHeight() / 2;
for (int a = 0; a < volumeAlphas.length; a++) {
int p;
if (a == 0) {
p = 0;
rad = AndroidUtilities.dp(6);
} else if (a == 1) {
p = 50;
rad = AndroidUtilities.dp(10);
} else {
p = 150;
rad = AndroidUtilities.dp(14);
}
float offset = (AndroidUtilities.dp(2) * (1.0f - volumeAlphas[a]));
paint2.setAlpha((int) (255 * volumeAlphas[a]));
rect.set(cx - rad + offset, cy - rad + offset, cx + rad - offset, cy + rad - offset);
canvas.drawArc(rect, -50, 100, false, paint2);
if (percent > p) {
if (volumeAlphas[a] < 1.0f) {
volumeAlphas[a] += dt / 180.0f;
if (volumeAlphas[a] > 1.0f) {
volumeAlphas[a] = 1.0f;
}
invalidate();
}
} else {
if (volumeAlphas[a] > 0.0f) {
volumeAlphas[a] -= dt / 180.0f;
if (volumeAlphas[a] < 0.0f) {
volumeAlphas[a] = 0.0f;
}
invalidate();
}
}
}
}
}
public static class WeavingState {
private float targetX = -1f;
private float targetY = -1f;
private float startX;
private float startY;
private float duration;
private float time;
public Shader shader;
private Matrix matrix = new Matrix();
public int currentState;
public WeavingState(int state) {
currentState = state;
}
public void update(int top, int left, int size, long dt, float amplitude) {
if (shader == null) {
return;
}
if (duration == 0 || time >= duration) {
duration = Utilities.random.nextInt(200) + 1500;
time = 0;
if (targetX == -1f) {
setTarget();
}
startX = targetX;
startY = targetY;
setTarget();
}
time += dt * (0.5f + BlobDrawable.GRADIENT_SPEED_MIN) + dt * (BlobDrawable.GRADIENT_SPEED_MAX * 2) * amplitude;
if (time > duration) {
time = duration;
}
float interpolation = CubicBezierInterpolator.EASE_OUT.getInterpolation(time / duration);
float x = left + size * (startX + (targetX - startX) * interpolation) - 200;
float y = top + size * (startY + (targetY - startY) * interpolation) - 200;
float s;
if (isGradientState(currentState)) {
s = 1f;
} else {
s = currentState == MUTE_BUTTON_STATE_MUTE ? 4 : 2.5f;
}
float scale = AndroidUtilities.dp(122) / 400.0f * s;
matrix.reset();
matrix.postTranslate(x, y);
matrix.postScale(scale, scale, x + 200, y + 200);
shader.setLocalMatrix(matrix);
}
private void setTarget() {
if (isGradientState(currentState)) {
targetX = 0.85f + 0.20f * Utilities.random.nextInt(100) / 100f;
targetY = 1f;
} else if (currentState == MUTE_BUTTON_STATE_MUTE) {
targetX = 0.2f + 0.3f * Utilities.random.nextInt(100) / 100f;
targetY = 0.7f + 0.3f * Utilities.random.nextInt(100) / 100f;
} else {
targetX = 0.8f + 0.2f * (Utilities.random.nextInt(100) / 100f);
targetY = Utilities.random.nextInt(100) / 100f;
}
}
}
public static boolean isGradientState(int state) {
return VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().groupCall != null && VoIPService.getSharedInstance().groupCall.call.rtmp_stream || state == MUTE_BUTTON_STATE_MUTED_BY_ADMIN || state == MUTE_BUTTON_STATE_RAISED_HAND || state == MUTE_BUTTON_STATE_START_NOW || state == MUTE_BUTTON_STATE_SET_REMINDER || state == MUTE_BUTTON_STATE_CANCEL_REMINDER;
}
@SuppressWarnings("FieldCanBeLocal")
private static class LabeledButton extends FrameLayout {
private ImageView imageView;
private TextView textView;
public LabeledButton(Context context, String text, int resId, int color) {
super(context);
imageView = new ImageView(context);
if (Build.VERSION.SDK_INT >= 21) {
imageView.setBackground(Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(50), color, 0x1fffffff));
} else {
imageView.setBackground(Theme.createSimpleSelectorCircleDrawable(AndroidUtilities.dp(50), color, color));
}
imageView.setImageResource(resId);
imageView.setScaleType(ImageView.ScaleType.CENTER);
addView(imageView, LayoutHelper.createFrame(50, 50, Gravity.CENTER_HORIZONTAL | Gravity.TOP));
textView = new TextView(context);
textView.setTextColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 12);
textView.setGravity(Gravity.CENTER_HORIZONTAL);
textView.setText(text);
addView(textView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.TOP, 0, 50 + 5, 0, 0));
}
public void setColor(int color) {
Theme.setSelectorDrawableColor(imageView.getBackground(), color, false);
if (Build.VERSION.SDK_INT < 21) {
Theme.setSelectorDrawableColor(imageView.getBackground(), color, true);
}
imageView.invalidate();
}
}
private void prepareBlurBitmap() {
if (blurredView == null) {
return;
}
int w = (int) ((containerView.getMeasuredWidth() - backgroundPaddingLeft * 2) / 6.0f);
int h = (int) ((containerView.getMeasuredHeight() - AndroidUtilities.statusBarHeight) / 6.0f);
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.scale(1.0f / 6.0f, 1.0f / 6.0f);
canvas.save();
canvas.translate(0, -AndroidUtilities.statusBarHeight);
parentActivity.getActionBarLayout().draw(canvas);
canvas.drawColor(ColorUtils.setAlphaComponent(Color.BLACK, (int) (255 * 0.3f)));
canvas.restore();
canvas.save();
canvas.translate(containerView.getX(), -AndroidUtilities.statusBarHeight);
drawingForBlur = true;
containerView.draw(canvas);
drawingForBlur = false;
Utilities.stackBlurBitmap(bitmap, Math.max(7, Math.max(w, h) / 180));
blurredView.setBackground(new BitmapDrawable(bitmap));
blurredView.setAlpha(0.0f);
blurredView.setVisibility(View.VISIBLE);
}
@Override
protected boolean canDismissWithSwipe() {
return false;
}
@Override
protected boolean onCustomOpenAnimation() {
groupCallUiVisible = true;
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.groupCallVisibilityChanged);
GroupCallPip.updateVisibility(getContext());
return super.onCustomOpenAnimation();
}
@Override
public void dismiss() {
parentActivity.removeOnUserLeaveHintListener(onUserLeaveHintListener);
parentActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
groupCallUiVisible = false;
if (groupVoipInviteAlert != null) {
groupVoipInviteAlert.dismiss();
}
delayedGroupCallUpdated = true;
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.groupCallVisibilityChanged);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.needShowAlert);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.groupCallUpdated);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.chatInfoDidLoad);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.didLoadChatAdmins);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.applyGroupCallVisibleParticipants);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.userInfoDidLoad);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.mainUserInfoChanged);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.updateInterfaces);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.groupCallScreencastStateChanged);
accountInstance.getNotificationCenter().removeObserver(this, NotificationCenter.groupCallSpeakingUsersUpdated);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.webRtcMicAmplitudeEvent);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didEndCall);
super.dismiss();
}
private boolean isStillConnecting() {
return currentCallState == VoIPService.STATE_WAIT_INIT || currentCallState == VoIPService.STATE_WAIT_INIT_ACK || currentCallState == VoIPService.STATE_CREATING || currentCallState == VoIPService.STATE_RECONNECTING;
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.groupCallUpdated) {
Long callId = (Long) args[1];
if (call != null && call.call.id == callId) {
if (call.call instanceof TLRPC.TL_groupCallDiscarded) {
dismiss();
} else {
if (creatingServiceTime == 0 && (muteButtonState == MUTE_BUTTON_STATE_CANCEL_REMINDER || muteButtonState == MUTE_BUTTON_STATE_START_NOW || muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) && !call.isScheduled()) {
try {
Intent intent = new Intent(parentActivity, VoIPService.class);
intent.putExtra("chat_id", currentChat.id);
intent.putExtra("createGroupCall", false);
intent.putExtra("hasFewPeers", scheduleHasFewPeers);
intent.putExtra("peerChannelId", schedulePeer.channel_id);
intent.putExtra("peerChatId", schedulePeer.chat_id);
intent.putExtra("peerUserId", schedulePeer.user_id);
intent.putExtra("hash", scheduledHash);
intent.putExtra("peerAccessHash", schedulePeer.access_hash);
intent.putExtra("is_outgoing", true);
intent.putExtra("start_incall_activity", false);
intent.putExtra("account", accountInstance.getCurrentAccount());
intent.putExtra("scheduleDate", scheduleStartAt);
parentActivity.startService(intent);
} catch (Throwable e) {
FileLog.e(e);
}
creatingServiceTime = SystemClock.elapsedRealtime();
AndroidUtilities.runOnUIThread(() -> {
if (!isStillConnecting()) {
return;
}
updateState(true, false);
}, 3000);
}
if (!callInitied && VoIPService.getSharedInstance() != null) {
call.addSelfDummyParticipant(false);
initCreatedGroupCall();
VoIPService.getSharedInstance().playConnectedSound();
}
updateItems();
for (int a = 0, N = listView.getChildCount(); a < N; a++) {
View child = listView.getChildAt(a);
if (child instanceof GroupCallUserCell) {
((GroupCallUserCell) child).applyParticipantChanges(true);
}
}
if (scrimView != null) {
delayedGroupCallUpdated = true;
} else {
applyCallParticipantUpdates(true);
}
updateSubtitle();
boolean selfUpdate = (Boolean) args[2];
boolean raisedHand = muteButtonState == MUTE_BUTTON_STATE_RAISED_HAND;
updateState(true, selfUpdate);
updateTitle(true);
if (raisedHand && (muteButtonState == MUTE_BUTTON_STATE_MUTE || muteButtonState == MUTE_BUTTON_STATE_UNMUTE)) {
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_CAN_NOW_SPEAK, null);
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().playAllowTalkSound();
}
}
if (args.length >= 4) {
long justJoinedId = (Long) args[3];
if (justJoinedId != 0 && !isRtmpStream()) {
boolean hasInDialogs = false;
try {
ArrayList<TLRPC.Dialog> dialogs = accountInstance.getMessagesController().getAllDialogs();
if (dialogs != null) {
for (TLRPC.Dialog dialog : dialogs) {
if (dialog.id == justJoinedId) {
hasInDialogs = true;
break;
}
}
}
} catch (Exception ignore) {}
if (DialogObject.isUserDialog(justJoinedId)) {
TLRPC.User user = accountInstance.getMessagesController().getUser(justJoinedId);
if (user != null && (call.call.participants_count < 250 || UserObject.isContact(user) || user.verified || hasInDialogs)) {
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_USER_JOINED, user, currentChat, null, null);
}
} else {
TLRPC.Chat chat = accountInstance.getMessagesController().getChat(-justJoinedId);
if (chat != null && (call.call.participants_count < 250 || !ChatObject.isNotInChat(chat) || chat.verified || hasInDialogs)) {
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_USER_JOINED, chat, currentChat, null, null);
}
}
}
}
}
}
} else if (id == NotificationCenter.groupCallSpeakingUsersUpdated) {
if (renderersContainer.inFullscreenMode && call != null) {
boolean autoPinEnabled = renderersContainer.autoPinEnabled();
if (call != null && renderersContainer.inFullscreenMode && renderersContainer.fullscreenParticipant != null && call.participants.get(MessageObject.getPeerId(renderersContainer.fullscreenParticipant.participant.peer)) == null) {
autoPinEnabled = true;
}
if (autoPinEnabled) {
ChatObject.VideoParticipant currentSpeaker = null;
for (int i = 0; i < visibleVideoParticipants.size(); i++) {
ChatObject.VideoParticipant participant = visibleVideoParticipants.get(i);
boolean newSpeaking = call.currentSpeakingPeers.get(MessageObject.getPeerId(participant.participant.peer), null) != null;
if (newSpeaking && !participant.participant.muted_by_you && renderersContainer.fullscreenPeerId != MessageObject.getPeerId(participant.participant.peer)) {
currentSpeaker = participant;
}
}
if (currentSpeaker != null) {
fullscreenFor(currentSpeaker);
}
}
}
renderersContainer.setVisibleParticipant(true);
updateSubtitle();
} else if (id == NotificationCenter.webRtcMicAmplitudeEvent) {
float amplitude = (float) args[0];
setMicAmplitude(amplitude);
} else if (id == NotificationCenter.needShowAlert) {
int num = (Integer) args[0];
if (num == 6) {
String text = (String) args[1];
String error;
if ("GROUPCALL_PARTICIPANTS_TOO_MUCH".equals(text)) {
if (ChatObject.isChannelOrGiga(currentChat)) {
error = LocaleController.getString("VoipChannelTooMuch", R.string.VoipChannelTooMuch);
} else {
error = LocaleController.getString("VoipGroupTooMuch", R.string.VoipGroupTooMuch);
}
} else if ("ANONYMOUS_CALLS_DISABLED".equals(text) || "GROUPCALL_ANONYMOUS_FORBIDDEN".equals(text)) {
if (ChatObject.isChannelOrGiga(currentChat)) {
error = LocaleController.getString("VoipChannelJoinAnonymousAdmin", R.string.VoipChannelJoinAnonymousAdmin);
} else {
error = LocaleController.getString("VoipGroupJoinAnonymousAdmin", R.string.VoipGroupJoinAnonymousAdmin);
}
} else {
error = LocaleController.getString("ErrorOccurred", R.string.ErrorOccurred) + "\n" + text;
}
AlertDialog.Builder builder = AlertsCreator.createSimpleAlert(getContext(), LocaleController.getString("VoipGroupVoiceChat", R.string.VoipGroupVoiceChat), error);
builder.setOnDismissListener(dialog -> dismiss());
try {
builder.show();
} catch (Exception e) {
FileLog.e(e);
}
}
} else if (id == NotificationCenter.didEndCall) {
if (VoIPService.getSharedInstance() == null) {
dismiss();
}
} else if (id == NotificationCenter.chatInfoDidLoad) {
TLRPC.ChatFull chatFull = (TLRPC.ChatFull) args[0];
if (chatFull.id == currentChat.id) {
updateItems();
updateState(isShowing(), false);
}
long selfId = MessageObject.getPeerId(selfPeer);
if (call != null && chatFull.id == -selfId) {
TLRPC.TL_groupCallParticipant participant = call.participants.get(selfId);
if (participant != null) {
participant.about = chatFull.about;
applyCallParticipantUpdates(true);
AndroidUtilities.updateVisibleRows(listView);
if (currentOptionsLayout != null) {
for (int i = 0; i < currentOptionsLayout.getChildCount(); i++) {
View child = currentOptionsLayout.getChildAt(i);
if (child instanceof ActionBarMenuSubItem && child.getTag() != null && (Integer) child.getTag() == 10) {
((ActionBarMenuSubItem) child).setTextAndIcon(
TextUtils.isEmpty(participant.about) ? LocaleController.getString("VoipAddDescription", R.string.VoipAddDescription) : LocaleController.getString("VoipEditDescription", R.string.VoipEditDescription),
TextUtils.isEmpty(participant.about) ? R.drawable.msg_addbio : R.drawable.msg_info
);
}
}
}
}
}
} else if (id == NotificationCenter.didLoadChatAdmins) {
long chatId = (Long) args[0];
if (chatId == currentChat.id) {
updateItems();
updateState(isShowing(), false);
}
} else if (id == NotificationCenter.applyGroupCallVisibleParticipants) {
int count = listView.getChildCount();
long time = (Long) args[0];
for (int a = 0; a < count; a++) {
View child = listView.getChildAt(a);
RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child);
if (holder != null && holder.itemView instanceof GroupCallUserCell) {
GroupCallUserCell cell = (GroupCallUserCell) holder.itemView;
cell.getParticipant().lastVisibleDate = time;
}
}
} else if (id == NotificationCenter.userInfoDidLoad) {
Long uid = (Long) args[0];
long selfId = MessageObject.getPeerId(selfPeer);
if (call != null && selfId == uid) {
TLRPC.TL_groupCallParticipant participant = call.participants.get(selfId);
if (participant != null) {
TLRPC.UserFull userInfo = (TLRPC.UserFull) args[1];
participant.about = userInfo.about;
applyCallParticipantUpdates(true);
AndroidUtilities.updateVisibleRows(listView);
if (currentOptionsLayout != null) {
for (int i = 0; i < currentOptionsLayout.getChildCount(); i++) {
View child = currentOptionsLayout.getChildAt(i);
if (child instanceof ActionBarMenuSubItem && child.getTag() != null && (Integer) child.getTag() == 10) {
((ActionBarMenuSubItem) child).setTextAndIcon(
TextUtils.isEmpty(participant.about) ? LocaleController.getString("VoipAddBio", R.string.VoipAddBio) : LocaleController.getString("VoipEditBio", R.string.VoipEditBio),
TextUtils.isEmpty(participant.about) ? R.drawable.msg_addbio : R.drawable.msg_info
);
}
}
}
}
}
} else if (id == NotificationCenter.mainUserInfoChanged) {
applyCallParticipantUpdates(true);
AndroidUtilities.updateVisibleRows(listView);
} else if (id == NotificationCenter.updateInterfaces) {
int mask = (int) args[0];
if ((mask & MessagesController.UPDATE_MASK_CHAT_NAME) != 0) {
applyCallParticipantUpdates(true);
AndroidUtilities.updateVisibleRows(listView);
}
} else if (id == NotificationCenter.groupCallScreencastStateChanged) {
if (previewDialog != null) {
previewDialog.dismiss(true, true);
}
updateItems();
}
}
private void setMicAmplitude(float amplitude) {
if (VoIPService.getSharedInstance() == null || VoIPService.getSharedInstance().isMicMute()) {
amplitude = 0f;
}
setAmplitude(amplitude * 4000.0f);
if (call != null && listView != null) {
TLRPC.TL_groupCallParticipant participant = call.participants.get(MessageObject.getPeerId(selfPeer));
if (participant != null) {
if (!renderersContainer.inFullscreenMode) {
ArrayList<TLRPC.TL_groupCallParticipant> array = delayedGroupCallUpdated ? oldParticipants : call.visibleParticipants;
int idx = array.indexOf(participant);
if (idx >= 0) {
RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(idx + listAdapter.usersStartRow);
if (holder != null && holder.itemView instanceof GroupCallUserCell) {
GroupCallUserCell cell = (GroupCallUserCell) holder.itemView;
cell.setAmplitude(amplitude * 15.0f);
if (holder.itemView == scrimView) {
if (!contentFullyOverlayed) {
containerView.invalidate();
}
}
}
}
} else {
for (int i = 0; i < fullscreenUsersListView.getChildCount(); i++) {
GroupCallFullscreenAdapter.GroupCallUserCell cell = (GroupCallFullscreenAdapter.GroupCallUserCell) fullscreenUsersListView.getChildAt(i);
if (MessageObject.getPeerId(cell.getParticipant().peer) == MessageObject.getPeerId(participant.peer)) {
cell.setAmplitude(amplitude * 15.0f);
}
}
}
renderersContainer.setAmplitude(participant, amplitude * 15.0f);
}
}
}
private void applyCallParticipantUpdates(boolean animated) {
if (renderersContainer == null || listView == null || call == null || delayedGroupCallUpdated) {
return;
}
if (renderersContainer.inFullscreenMode) {
renderersContainer.setVisibleParticipant(true);
}
long self = MessageObject.getPeerId(call.selfPeer);
long dummyPeer = MessageObject.getPeerId(selfPeer);
if (self != dummyPeer && call.participants.get(self) != null) {
selfPeer = call.selfPeer;
}
int count = listView.getChildCount();
View minChild = null;
int minPosition = 0;
int minTop = Integer.MAX_VALUE;
for (int a = 0; a < count; a++) {
View child = listView.getChildAt(a);
RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child);
if (holder != null && holder.getAdapterPosition() != RecyclerView.NO_POSITION && holder.getLayoutPosition() != RecyclerView.NO_POSITION) {
if (minChild == null || child.getTop() < minTop) {
minChild = child;
minPosition = holder.getLayoutPosition();
minTop = child.getTop();
}
}
}
updateVideoParticipantList();
if (listView.getItemAnimator() != null && !animated) {
listView.setItemAnimator(null);
} else if (listView.getItemAnimator() == null && animated) {
listView.setItemAnimator(itemAnimator);
}
try {
UpdateCallback updateCallback = new UpdateCallback(listAdapter);
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) {
FileLog.e(e);
listAdapter.notifyDataSetChanged();
}
call.saveActiveDates();
if (minChild != null) {
layoutManager.scrollToPositionWithOffset(minPosition, minChild.getTop() - listView.getPaddingTop());
}
oldParticipants.clear();
oldParticipants.addAll(call.visibleParticipants);
oldVideoParticipants.clear();
oldVideoParticipants.addAll(visibleVideoParticipants);
oldInvited.clear();
oldInvited.addAll(call.invitedUsers);
oldCount = listAdapter.getItemCount();
for (int a = 0; a < count; a++) {
View child = listView.getChildAt(a);
if (child instanceof GroupCallUserCell || child instanceof GroupCallInvitedCell) {
RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child);
if (holder != null) {
if (child instanceof GroupCallUserCell) {
((GroupCallUserCell) child).setDrawDivider(holder.getAdapterPosition() != listAdapter.getItemCount() - 2);
} else {
((GroupCallInvitedCell) child).setDrawDivider(holder.getAdapterPosition() != listAdapter.getItemCount() - 2);
}
}
}
}
boolean autoPinEnabled = renderersContainer.autoPinEnabled();
if (renderersContainer.inFullscreenMode && renderersContainer.fullscreenParticipant != null && !ChatObject.Call.videoIsActive(renderersContainer.fullscreenParticipant.participant, renderersContainer.fullscreenParticipant.presentation, call)) {
boolean foundAnotherVideoParticipant = false;
if (!visibleVideoParticipants.isEmpty()) {
foundAnotherVideoParticipant = true;
if (autoPinEnabled) {
fullscreenFor(visibleVideoParticipants.get(0));
}
}
if (!foundAnotherVideoParticipant) {
fullscreenFor(null);
}
}
fullscreenAdapter.update(true, fullscreenUsersListView);
if (fullscreenUsersListView.getVisibility() == View.VISIBLE) {
AndroidUtilities.updateVisibleRows(fullscreenUsersListView);
}
if (isTabletMode) {
tabletGridAdapter.update(true, tabletVideoGridView);
}
if (listView.getVisibility() == View.VISIBLE) {
AndroidUtilities.updateVisibleRows(listView);
}
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
attachedRenderersTmp.get(i).updateAttachState(true);
}
if (call != null && renderersContainer.inFullscreenMode && renderersContainer.fullscreenParticipant != null && call.participants.get(MessageObject.getPeerId(renderersContainer.fullscreenParticipant.participant.peer)) == null) {
autoPinEnabled = true;
}
boolean hasVideoLocal = !call.visibleVideoParticipants.isEmpty();
if (hasVideoLocal != hasVideo) {
hasVideo = hasVideoLocal;
if (isTabletMode) {
containerView.requestLayout();
}
}
}
private void updateVideoParticipantList() {
visibleVideoParticipants.clear();
if (isTabletMode) {
if (renderersContainer.inFullscreenMode) {
visibleVideoParticipants.addAll(call.visibleVideoParticipants);
if (renderersContainer.fullscreenParticipant != null) {
visibleVideoParticipants.remove(renderersContainer.fullscreenParticipant);
}
}
} else {
visibleVideoParticipants.addAll(call.visibleVideoParticipants);
}
}
private void updateRecordCallText() {
if (call == null) {
return;
}
int time = accountInstance.getConnectionsManager().getCurrentTime() - call.call.record_start_date;
if (call.recording) {
recordItem.setSubtext(AndroidUtilities.formatDuration(time, false));
} else {
recordItem.setSubtext(null);
}
}
private void updateItems() {
if (call == null || call.isScheduled()) {
pipItem.setVisibility(View.INVISIBLE);
screenShareItem.setVisibility(View.GONE);
if (call == null) {
otherItem.setVisibility(View.GONE);
return;
}
}
if (changingPermissions) {
return;
}
TLRPC.Chat newChat = accountInstance.getMessagesController().getChat(currentChat.id);
if (newChat != null) {
currentChat = newChat;
}
if (ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_INVITE) || (!ChatObject.isChannel(currentChat) || currentChat.megagroup) && (!TextUtils.isEmpty(currentChat.username) || ChatObject.canUserDoAdminAction(currentChat, ChatObject.ACTION_INVITE)) || ChatObject.isChannel(currentChat) && !currentChat.megagroup && !TextUtils.isEmpty(currentChat.username)) {
inviteItem.setVisibility(View.VISIBLE);
} else {
inviteItem.setVisibility(View.GONE);
}
TLRPC.TL_groupCallParticipant participant = call.participants.get(MessageObject.getPeerId(selfPeer));
if (call == null || call.isScheduled() || participant != null && !participant.can_self_unmute && participant.muted) {
noiseItem.setVisibility(View.GONE);
} else {
noiseItem.setVisibility(View.VISIBLE);
}
noiseItem.setIcon(SharedConfig.noiseSupression ? R.drawable.msg_noise_on : R.drawable.msg_noise_off);
noiseItem.setSubtext(SharedConfig.noiseSupression ? LocaleController.getString("VoipNoiseCancellationEnabled", R.string.VoipNoiseCancellationEnabled) : LocaleController.getString("VoipNoiseCancellationDisabled", R.string.VoipNoiseCancellationDisabled));
if (ChatObject.canManageCalls(currentChat)) {
leaveItem.setVisibility(View.VISIBLE);
editTitleItem.setVisibility(View.VISIBLE);
if (isRtmpStream()) {
recordItem.setVisibility(View.VISIBLE);
screenItem.setVisibility(View.GONE);
} else {
if (call.isScheduled()) {
recordItem.setVisibility(View.GONE);
screenItem.setVisibility(View.GONE);
} else {
recordItem.setVisibility(View.VISIBLE);
}
}
if (!call.canRecordVideo() || call.isScheduled() || Build.VERSION.SDK_INT < 21 || isRtmpStream()) {
screenItem.setVisibility(View.GONE);
} else {
screenItem.setVisibility(View.VISIBLE);
}
screenShareItem.setVisibility(View.GONE);
recordCallDrawable.setRecording(call.recording);
if (call.recording) {
if (updateCallRecordRunnable == null) {
AndroidUtilities.runOnUIThread(updateCallRecordRunnable = () -> {
updateRecordCallText();
AndroidUtilities.runOnUIThread(updateCallRecordRunnable, 1000);
}, 1000);
}
recordItem.setText(LocaleController.getString("VoipGroupStopRecordCall", R.string.VoipGroupStopRecordCall));
} else {
if (updateCallRecordRunnable != null) {
AndroidUtilities.cancelRunOnUIThread(updateCallRecordRunnable);
updateCallRecordRunnable = null;
}
recordItem.setText(LocaleController.getString("VoipGroupRecordCall", R.string.VoipGroupRecordCall));
}
if (VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().getVideoState(true) == Instance.VIDEO_STATE_ACTIVE) {
screenItem.setTextAndIcon(LocaleController.getString("VoipChatStopScreenCapture", R.string.VoipChatStopScreenCapture), R.drawable.msg_screencast_off);
} else {
screenItem.setTextAndIcon(LocaleController.getString("VoipChatStartScreenCapture", R.string.VoipChatStartScreenCapture), R.drawable.msg_screencast);
}
updateRecordCallText();
} else {
boolean mutedByAdmin = participant != null && !participant.can_self_unmute && participant.muted && !ChatObject.canManageCalls(currentChat);
boolean sharingScreen = VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().getVideoState(true) == Instance.VIDEO_STATE_ACTIVE;
if (Build.VERSION.SDK_INT >= 21 && !mutedByAdmin && (call.canRecordVideo() || sharingScreen) && !call.isScheduled() && !isRtmpStream()) {
if (sharingScreen) {
screenShareItem.setVisibility(View.GONE);
screenItem.setVisibility(View.VISIBLE);
screenItem.setTextAndIcon(LocaleController.getString("VoipChatStopScreenCapture", R.string.VoipChatStopScreenCapture), R.drawable.msg_screencast_off);
screenItem.setContentDescription(LocaleController.getString("VoipChatStopScreenCapture", R.string.VoipChatStopScreenCapture));
} else {
screenItem.setTextAndIcon(LocaleController.getString("VoipChatStartScreenCapture", R.string.VoipChatStartScreenCapture), R.drawable.msg_screencast);
screenItem.setContentDescription(LocaleController.getString("VoipChatStartScreenCapture", R.string.VoipChatStartScreenCapture));
screenShareItem.setVisibility(View.GONE);
screenItem.setVisibility(View.VISIBLE);
}
} else {
screenShareItem.setVisibility(View.GONE);
screenItem.setVisibility(View.GONE);
}
leaveItem.setVisibility(View.GONE);
editTitleItem.setVisibility(View.GONE);
recordItem.setVisibility(View.GONE);
}
if (ChatObject.canManageCalls(currentChat) && call.call.can_change_join_muted) {
permissionItem.setVisibility(View.VISIBLE);
} else {
permissionItem.setVisibility(View.GONE);
}
soundItem.setVisibility(isRtmpStream() ? View.GONE : View.VISIBLE);
if (editTitleItem.getVisibility() == View.VISIBLE || permissionItem.getVisibility() == View.VISIBLE || inviteItem.getVisibility() == View.VISIBLE ||
screenItem.getVisibility() == View.VISIBLE || recordItem.getVisibility() == View.VISIBLE || leaveItem.getVisibility() == View.VISIBLE) {
soundItemDivider.setVisibility(View.VISIBLE);
} else {
soundItemDivider.setVisibility(View.GONE);
}
int margin = 48;
if ((VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().hasFewPeers || scheduleHasFewPeers) && !isRtmpStream()) {
accountSelectCell.setVisibility(View.VISIBLE);
accountGap.setVisibility(View.VISIBLE);
long peerId = MessageObject.getPeerId(selfPeer);
TLObject object;
if (DialogObject.isUserDialog(peerId)) {
object = accountInstance.getMessagesController().getUser(peerId);
} else {
object = accountInstance.getMessagesController().getChat(-peerId);
}
accountSelectCell.setObject(object);
margin += 48;
} else {
margin += 48;
accountSelectCell.setVisibility(View.GONE);
accountGap.setVisibility(View.GONE);
}
if (currentChat != null && !ChatObject.isChannelOrGiga(currentChat) && isRtmpStream() && inviteItem.getVisibility() == View.GONE) {
otherItem.setVisibility(View.GONE);
} else {
otherItem.setVisibility(View.VISIBLE);
}
FrameLayout.LayoutParams layoutParams = ((FrameLayout.LayoutParams) titleTextView.getLayoutParams());
if (layoutParams.rightMargin != AndroidUtilities.dp(margin)) {
layoutParams.rightMargin = AndroidUtilities.dp(margin);
titleTextView.requestLayout();
}
((FrameLayout.LayoutParams) menuItemsContainer.getLayoutParams()).rightMargin = 0;
actionBar.setTitleRightMargin(AndroidUtilities.dp(48) * 2);
}
protected void makeFocusable(BottomSheet bottomSheet, AlertDialog alertDialog, EditTextBoldCursor editText, boolean showKeyboard) {
if (!enterEventSent) {
BaseFragment fragment = parentActivity.getActionBarLayout().fragmentsStack.get(parentActivity.getActionBarLayout().fragmentsStack.size() - 1);
if (fragment instanceof ChatActivity) {
boolean keyboardVisible = ((ChatActivity) fragment).needEnterText();
enterEventSent = true;
anyEnterEventSent = true;
AndroidUtilities.runOnUIThread(() -> {
if (bottomSheet != null && !bottomSheet.isDismissed()) {
bottomSheet.setFocusable(true);
editText.requestFocus();
if (showKeyboard) {
AndroidUtilities.runOnUIThread(() -> AndroidUtilities.showKeyboard(editText));
}
} else if (alertDialog != null && alertDialog.isShowing()) {
alertDialog.setFocusable(true);
editText.requestFocus();
if (showKeyboard) {
AndroidUtilities.runOnUIThread(() -> AndroidUtilities.showKeyboard(editText));
}
}
}, keyboardVisible ? 200 : 0);
} else {
enterEventSent = true;
anyEnterEventSent = true;
if (bottomSheet != null) {
bottomSheet.setFocusable(true);
} else if (alertDialog != null) {
alertDialog.setFocusable(true);
}
if (showKeyboard) {
AndroidUtilities.runOnUIThread(() -> {
editText.requestFocus();
AndroidUtilities.showKeyboard(editText);
}, 100);
}
}
}
}
public static void create(LaunchActivity activity, AccountInstance account, TLRPC.Chat scheduleChat, TLRPC.InputPeer schedulePeer, boolean hasFewPeers, String scheduledHash) {
if (groupCallInstance != null || schedulePeer == null && VoIPService.getSharedInstance() == null) {
return;
}
if (schedulePeer != null) {
ChatObject.Call call = account.getMessagesController().getGroupCall(scheduleChat.id, false);
groupCallInstance = new GroupCallActivity(activity, account, call, scheduleChat, schedulePeer, hasFewPeers, scheduledHash);
} else {
ChatObject.Call call = VoIPService.getSharedInstance().groupCall;
if (call == null) {
return;
}
TLRPC.Chat chat = account.getMessagesController().getChat(call.chatId);
if (chat == null) {
return;
}
call.addSelfDummyParticipant(true);
groupCallInstance = new GroupCallActivity(activity, account, call, chat, null, hasFewPeers, scheduledHash);
}
groupCallInstance.parentActivity = activity;
groupCallInstance.show();
}
private GroupCallActivity(Context context, AccountInstance account, ChatObject.Call groupCall, TLRPC.Chat chat, TLRPC.InputPeer schedulePeer, boolean scheduleHasFewPeers, String scheduledHash) {
super(context, false);
this.accountInstance = account;
this.call = groupCall;
this.schedulePeer = schedulePeer;
this.currentChat = chat;
this.scheduledHash = scheduledHash;
this.currentAccount = account.getCurrentAccount();
this.scheduleHasFewPeers = scheduleHasFewPeers;
fullWidth = true;
isTabletMode = false;
isLandscapeMode = false;
paused = false;
setDelegate(new BottomSheetDelegateInterface() {
@Override
public void onOpenAnimationStart() {
}
@Override
public void onOpenAnimationEnd() {
if (muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
showReminderHint();
}
}
@Override
public boolean canDismiss() {
return true;
}
});
drawDoubleNavigationBar = true;
drawNavigationBar = true;
if (Build.VERSION.SDK_INT >= 30) {
getWindow().setNavigationBarColor(0xff000000);
}
scrollNavBar = true;
navBarColorKey = null;
scrimPaint = new Paint() {
@Override
public void setAlpha(int a) {
super.setAlpha(a);
if (containerView != null) {
containerView.invalidate();
}
}
};
setOnDismissListener(dialog -> {
BaseFragment fragment = parentActivity.getActionBarLayout().fragmentsStack.get(parentActivity.getActionBarLayout().fragmentsStack.size() - 1);
if (anyEnterEventSent) {
if (fragment instanceof ChatActivity) {
((ChatActivity) fragment).onEditTextDialogClose(true, true);
}
}
});
setDimBehindAlpha(75);
listAdapter = new ListAdapter(context);
RecordStatusDrawable recordStatusDrawable = new RecordStatusDrawable(true);
recordStatusDrawable.setColor(Theme.getColor(Theme.key_voipgroup_speakingText));
recordStatusDrawable.start();
actionBar = new ActionBar(context) {
@Override
public void setAlpha(float alpha) {
if (getAlpha() != alpha) {
super.setAlpha(alpha);
containerView.invalidate();
}
}
@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
if (getAdditionalSubtitleTextView().getVisibility() == View.VISIBLE) {
canvas.save();
canvas.translate(getSubtitleTextView().getLeft(), getSubtitleTextView().getY() - AndroidUtilities.dp(1));
recordStatusDrawable.setAlpha((int) (255 * getAdditionalSubtitleTextView().getAlpha()));
recordStatusDrawable.draw(canvas);
canvas.restore();
invalidate();
}
}
};
actionBar.setSubtitle("");
actionBar.getSubtitleTextView().setVisibility(View.VISIBLE);
actionBar.createAdditionalSubtitleTextView();
actionBar.getAdditionalSubtitleTextView().setPadding(AndroidUtilities.dp(24), 0, 0, 0);
AndroidUtilities.updateViewVisibilityAnimated(actionBar.getAdditionalSubtitleTextView(), drawSpeakingSubtitle, 1f, false);
actionBar.getAdditionalSubtitleTextView().setTextColor(Theme.getColor(Theme.key_voipgroup_speakingText));
actionBar.setSubtitleColor(Theme.getColor(Theme.key_voipgroup_lastSeenTextUnscrolled));
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
actionBar.setOccupyStatusBar(false);
actionBar.setAllowOverlayTitle(false);
actionBar.setItemsColor(Theme.getColor(Theme.key_voipgroup_actionBarItems), false);
actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_actionBarActionModeDefaultSelector), false);
actionBar.setTitleColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
actionBar.setSubtitleColor(Theme.getColor(Theme.key_voipgroup_lastSeenTextUnscrolled));
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
onBackPressed();
} else if (id == eveyone_can_speak_item) {
call.call.join_muted = false;
toggleAdminSpeak();
} else if (id == admin_can_speak_item) {
call.call.join_muted = true;
toggleAdminSpeak();
} else if (id == share_invite_link_item) {
getLink(false);
} else if (id == leave_item) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
if (ChatObject.isChannelOrGiga(currentChat)) {
builder.setTitle(LocaleController.getString("VoipChannelEndAlertTitle", R.string.VoipChannelEndAlertTitle));
builder.setMessage(LocaleController.getString("VoipChannelEndAlertText", R.string.VoipChannelEndAlertText));
} else {
builder.setTitle(LocaleController.getString("VoipGroupEndAlertTitle", R.string.VoipGroupEndAlertTitle));
builder.setMessage(LocaleController.getString("VoipGroupEndAlertText", R.string.VoipGroupEndAlertText));
}
builder.setDialogButtonColorKey(Theme.key_voipgroup_listeningText);
builder.setPositiveButton(LocaleController.getString("VoipGroupEnd", R.string.VoipGroupEnd), (dialogInterface, i) -> {
if (call.isScheduled()) {
TLRPC.ChatFull chatFull = accountInstance.getMessagesController().getChatFull(currentChat.id);
if (chatFull != null) {
chatFull.flags &= ~2097152;
chatFull.call = null;
accountInstance.getNotificationCenter().postNotificationName(NotificationCenter.groupCallUpdated, currentChat.id, call.call.id, false);
}
TLRPC.TL_phone_discardGroupCall req = new TLRPC.TL_phone_discardGroupCall();
req.call = call.getInputGroupCall();
accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> {
if (response instanceof TLRPC.TL_updates) {
TLRPC.TL_updates updates = (TLRPC.TL_updates) response;
accountInstance.getMessagesController().processUpdates(updates, false);
}
});
} else if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().hangUp(1);
}
dismiss();
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didStartedCall);
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
AlertDialog dialog = builder.create();
dialog.setBackgroundColor(Theme.getColor(Theme.key_voipgroup_dialogBackground));
dialog.show();
TextView button = (TextView) dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setTextColor(Theme.getColor(Theme.key_voipgroup_leaveCallMenu));
}
dialog.setTextColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
} else if (id == screen_capture_item) {
screenShareItem.callOnClick();
} else if (id == start_record_item) {
if (call.recording) {
boolean video = call.call.record_video_active;
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setDialogButtonColorKey(Theme.key_voipgroup_listeningText);
builder.setTitle(LocaleController.getString("VoipGroupStopRecordingTitle", R.string.VoipGroupStopRecordingTitle));
if (ChatObject.isChannelOrGiga(currentChat)) {
builder.setMessage(LocaleController.getString("VoipChannelStopRecordingText", R.string.VoipChannelStopRecordingText));
} else {
builder.setMessage(LocaleController.getString("VoipGroupStopRecordingText", R.string.VoipGroupStopRecordingText));
}
builder.setPositiveButton(LocaleController.getString("Stop", R.string.Stop), (dialogInterface, i) -> {
call.toggleRecord(null, 0);
getUndoView().showWithAction(0, video ? UndoView.ACTION_VOIP_VIDEO_RECORDING_FINISHED : UndoView.ACTION_VOIP_RECORDING_FINISHED, null);
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
AlertDialog dialog = builder.create();
dialog.setBackgroundColor(Theme.getColor(Theme.key_voipgroup_dialogBackground));
dialog.show();
dialog.setTextColor(Theme.getColor(Theme.key_voipgroup_nameText));
} else {
GroupCallRecordAlert alert = new GroupCallRecordAlert(getContext(), currentChat, hasVideo) {
@Override
public void onStartRecord(@ChatObject.Call.RecordType int type) {
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setDialogButtonColorKey(Theme.key_voipgroup_listeningText);
enterEventSent = false;
builder.setTitle(LocaleController.getString("VoipGroupStartRecordingTitle", R.string.VoipGroupStartRecordingTitle));
if (type == 0) {
builder.setMessage(LocaleController.getString(call.call.rtmp_stream ? R.string.VoipGroupStartRecordingRtmpText : R.string.VoipGroupStartRecordingText));
} else {
if (ChatObject.isChannelOrGiga(currentChat)) {
builder.setMessage(LocaleController.getString(call.call.rtmp_stream ? R.string.VoipGroupStartRecordingRtmpVideoText : R.string.VoipChannelStartRecordingVideoText));
} else {
builder.setMessage(LocaleController.getString(call.call.rtmp_stream ? R.string.VoipGroupStartRecordingRtmpVideoText : R.string.VoipGroupStartRecordingVideoText));
}
}
builder.setCheckFocusable(false);
EditTextBoldCursor editText = new EditTextBoldCursor(getContext());
editText.setBackgroundDrawable(Theme.createEditTextDrawable(getContext(), Theme.getColor(Theme.key_voipgroup_windowBackgroundWhiteInputField), Theme.getColor(Theme.key_voipgroup_windowBackgroundWhiteInputFieldActivated)));
LinearLayout linearLayout = new LinearLayout(getContext());
linearLayout.setOrientation(LinearLayout.VERTICAL);
builder.setView(linearLayout);
editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
editText.setTextColor(Theme.getColor(Theme.key_voipgroup_nameText));
editText.setMaxLines(1);
editText.setLines(1);
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
editText.setGravity(Gravity.LEFT | Gravity.TOP);
editText.setSingleLine(true);
editText.setHint(LocaleController.getString("VoipGroupSaveFileHint", R.string.VoipGroupSaveFileHint));
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setHintTextColor(Theme.getColor(Theme.key_voipgroup_lastSeenText));
editText.setCursorColor(Theme.getColor(Theme.key_voipgroup_nameText));
editText.setCursorSize(AndroidUtilities.dp(20));
editText.setCursorWidth(1.5f);
editText.setPadding(0, AndroidUtilities.dp(4), 0, 0);
linearLayout.addView(editText, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, Gravity.TOP | Gravity.LEFT, 24, 0, 24, 12));
editText.setOnEditorActionListener((textView, i2, keyEvent) -> {
AndroidUtilities.hideKeyboard(textView);
builder.create().getButton(AlertDialog.BUTTON_POSITIVE).callOnClick();
return false;
});
final AlertDialog alertDialog = builder.create();
alertDialog.setBackgroundColor(Theme.getColor(Theme.key_voipgroup_inviteMembersBackground));
alertDialog.setOnShowListener(dialog -> makeFocusable(null, alertDialog, editText, true));
alertDialog.setOnDismissListener(dialog -> AndroidUtilities.hideKeyboard(editText));
builder.setPositiveButton(LocaleController.getString("Start", R.string.Start), (dialogInterface, i) -> {
call.toggleRecord(editText.getText().toString(), type);
AndroidUtilities.hideKeyboard(editText);
getUndoView().showWithAction(0, type == ChatObject.Call.RECORD_TYPE_AUDIO ? UndoView.ACTION_VOIP_RECORDING_STARTED : UndoView.ACTION_VOIP_VIDEO_RECORDING_STARTED, null);
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().playStartRecordSound();
}
});
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), (dialog, which) -> AndroidUtilities.hideKeyboard(editText));
AlertDialog dialog = builder.create();
dialog.setBackgroundColor(Theme.getColor(Theme.key_voipgroup_dialogBackground));
dialog.show();
dialog.setTextColor(Theme.getColor(Theme.key_voipgroup_nameText));
if (editText != null) {
editText.requestFocus();
}
}
};
if (isRtmpStream()) {
alert.onStartRecord(ChatObject.Call.RECORD_TYPE_VIDEO_LANDSCAPE);
} else {
alert.show();
}
}
} else if (id == permission_item) {
changingPermissions = true;
everyoneItem.setVisibility(View.VISIBLE);
adminItem.setVisibility(View.VISIBLE);
accountGap.setVisibility(View.GONE);
inviteItem.setVisibility(View.GONE);
leaveItem.setVisibility(View.GONE);
permissionItem.setVisibility(View.GONE);
editTitleItem.setVisibility(View.GONE);
recordItem.setVisibility(View.GONE);
screenItem.setVisibility(View.GONE);
accountSelectCell.setVisibility(View.GONE);
soundItem.setVisibility(View.GONE);
noiseItem.setVisibility(View.GONE);
otherItem.forceUpdatePopupPosition();
} else if (id == edit_item) {
enterEventSent = false;
final EditTextBoldCursor editText = new EditTextBoldCursor(getContext());
editText.setBackgroundDrawable(Theme.createEditTextDrawable(getContext(), true));
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setDialogButtonColorKey(Theme.key_voipgroup_listeningText);
if (ChatObject.isChannelOrGiga(currentChat)) {
builder.setTitle(LocaleController.getString("VoipChannelTitle", R.string.VoipChannelTitle));
} else {
builder.setTitle(LocaleController.getString("VoipGroupTitle", R.string.VoipGroupTitle));
}
builder.setCheckFocusable(false);
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), (dialog, which) -> AndroidUtilities.hideKeyboard(editText));
LinearLayout linearLayout = new LinearLayout(getContext());
linearLayout.setOrientation(LinearLayout.VERTICAL);
builder.setView(linearLayout);
editText.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
editText.setTextColor(Theme.getColor(Theme.key_voipgroup_nameText));
editText.setMaxLines(1);
editText.setLines(1);
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_CAP_SENTENCES);
editText.setGravity(Gravity.LEFT | Gravity.TOP);
editText.setSingleLine(true);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setHint(currentChat.title);
editText.setHintTextColor(Theme.getColor(Theme.key_voipgroup_lastSeenText));
editText.setCursorColor(Theme.getColor(Theme.key_voipgroup_nameText));
editText.setCursorSize(AndroidUtilities.dp(20));
editText.setCursorWidth(1.5f);
editText.setPadding(0, AndroidUtilities.dp(4), 0, 0);
linearLayout.addView(editText, LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, 36, Gravity.TOP | Gravity.LEFT, 24, 6, 24, 0));
editText.setOnEditorActionListener((textView, i, keyEvent) -> {
AndroidUtilities.hideKeyboard(textView);
builder.create().getButton(AlertDialog.BUTTON_POSITIVE).callOnClick();
return false;
});
editText.addTextChangedListener(new TextWatcher() {
boolean ignoreTextChange;
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (ignoreTextChange) {
return;
}
if (s.length() > 40) {
ignoreTextChange = true;
s.delete(40, s.length());
AndroidUtilities.shakeView(editText, 2, 0);
editText.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
ignoreTextChange = false;
}
}
});
if (!TextUtils.isEmpty(call.call.title)) {
editText.setText(call.call.title);
editText.setSelection(editText.length());
}
builder.setPositiveButton(LocaleController.getString("Save", R.string.Save), (dialog, which) -> {
AndroidUtilities.hideKeyboard(editText);
call.setTitle(editText.getText().toString());
builder.getDismissRunnable().run();
});
final AlertDialog alertDialog = builder.create();
alertDialog.setBackgroundColor(Theme.getColor(Theme.key_voipgroup_inviteMembersBackground));
alertDialog.setOnShowListener(dialog -> makeFocusable(null, alertDialog, editText, true));
alertDialog.setOnDismissListener(dialog -> AndroidUtilities.hideKeyboard(editText));
alertDialog.show();
alertDialog.setTextColor(Theme.getColor(Theme.key_voipgroup_nameText));
editText.requestFocus();
} else if (id == user_item) {
JoinCallAlert.open(getContext(), -currentChat.id, accountInstance, null, JoinCallAlert.TYPE_DISPLAY, selfPeer, (peer1, hasFewPeers, schedule) -> {
if (call == null) {
return;
}
TLObject object;
if (peer1 instanceof TLRPC.TL_inputPeerUser) {
object = accountInstance.getMessagesController().getUser(peer1.user_id);
} else if (peer1 instanceof TLRPC.TL_inputPeerChat) {
object = accountInstance.getMessagesController().getChat(peer1.chat_id);
} else {
object = accountInstance.getMessagesController().getChat(peer1.channel_id);
}
if (call.isScheduled()) {
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_USER_CHANGED, object, currentChat, null, null);
if (peer1 instanceof TLRPC.TL_inputPeerChannel) {
selfPeer = new TLRPC.TL_peerChannel();
selfPeer.channel_id = peer1.channel_id;
} else if (peer1 instanceof TLRPC.TL_inputPeerUser) {
selfPeer = new TLRPC.TL_peerUser();
selfPeer.user_id = peer1.user_id;
} else if (peer1 instanceof TLRPC.TL_inputPeerChat) {
selfPeer = new TLRPC.TL_peerChat();
selfPeer.chat_id = peer1.chat_id;
}
GroupCallActivity.this.schedulePeer = peer1;
TLRPC.ChatFull chatFull = accountInstance.getMessagesController().getChatFull(currentChat.id);
if (chatFull != null) {
chatFull.groupcall_default_join_as = selfPeer;
if (chatFull instanceof TLRPC.TL_chatFull) {
chatFull.flags |= 32768;
} else {
chatFull.flags |= 67108864;
}
}
TLRPC.TL_phone_saveDefaultGroupCallJoinAs req = new TLRPC.TL_phone_saveDefaultGroupCallJoinAs();
req.peer = MessagesController.getInputPeer(currentChat);
req.join_as = peer1;
accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> {
});
updateItems();
} else {
if (VoIPService.getSharedInstance() == null || !hasFewPeers) {
return;
}
TLRPC.TL_groupCallParticipant participant = call.participants.get(MessageObject.getPeerId(selfPeer));
VoIPService.getSharedInstance().setGroupCallPeer(peer1);
userSwitchObject = object;
}
});
} else if (id == noise_item) {
SharedConfig.toggleNoiseSupression();
VoIPService service = VoIPService.getSharedInstance();
if (service == null) {
return;
}
service.setNoiseSupressionEnabled(SharedConfig.noiseSupression);
} else if (id == sound_item) {
VoIPService service = VoIPService.getSharedInstance();
if (service == null) {
return;
}
ArrayList<CharSequence> names = new ArrayList<>();
ArrayList<Integer> icons = new ArrayList<>();
ArrayList<Integer> options = new ArrayList<>();
names.add(LocaleController.getString("VoipAudioRoutingSpeaker", R.string.VoipAudioRoutingSpeaker));
icons.add(R.drawable.msg_voice_speaker);
options.add(0);
if (service.hasEarpiece()) {
names.add(service.isHeadsetPlugged() ? LocaleController.getString("VoipAudioRoutingHeadset", R.string.VoipAudioRoutingHeadset) : LocaleController.getString("VoipAudioRoutingPhone", R.string.VoipAudioRoutingPhone));
icons.add(service.isHeadsetPlugged() ? R.drawable.msg_voice_headphones : R.drawable.msg_voice_phone);
options.add(1);
}
if (service.isBluetoothHeadsetConnected()) {
names.add(service.currentBluetoothDeviceName != null ? service.currentBluetoothDeviceName : LocaleController.getString("VoipAudioRoutingBluetooth", R.string.VoipAudioRoutingBluetooth));
icons.add(R.drawable.msg_voice_bluetooth);
options.add(2);
}
int n = names.size();
CharSequence[] itemsArray = new CharSequence[n];
int[] iconsArray = new int[n];
for (int i = 0; i < n; i++) {
itemsArray[i] = names.get(i);
iconsArray[i] = icons.get(i);
}
BottomSheet.Builder builder = new BottomSheet.Builder(context)
.setTitle(LocaleController.getString("VoipSelectAudioOutput", R.string.VoipSelectAudioOutput), true)
.setItems(itemsArray, iconsArray, (dialog, which) -> {
if (VoIPService.getSharedInstance() == null) {
return;
}
service.setAudioOutput(options.get(which));
});
BottomSheet bottomSheet = builder.create();
bottomSheet.setBackgroundColor(Theme.getColor(Theme.key_voipgroup_listViewBackgroundUnscrolled));
bottomSheet.fixNavigationBar(Theme.getColor(Theme.key_voipgroup_listViewBackgroundUnscrolled));
int selectedPosition;
if (service.getCurrentAudioRoute() == VoIPService.AUDIO_ROUTE_SPEAKER) {
selectedPosition = 0;
} else if (service.getCurrentAudioRoute() == VoIPService.AUDIO_ROUTE_EARPIECE) {
selectedPosition = 1;
} else {
selectedPosition = 2;
}
builder.show();
bottomSheet.setTitleColor(Theme.getColor(Theme.key_voipgroup_nameText));
for (int i = 0; i < bottomSheet.getItemViews().size(); i++) {
BottomSheetCell cell = bottomSheet.getItemViews().get(i);
int color;
if (i == selectedPosition) {
color = Theme.getColor(Theme.key_voipgroup_listeningText);
cell.isSelected = true;
} else {
color = Theme.getColor(Theme.key_voipgroup_nameText);
}
cell.setTextColor(color);
cell.setIconColor(color);
cell.setBackground(Theme.createSelectorDrawable(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_actionBarItems), (int) (255 * 0.05f)), 2));
}
}
}
});
TLRPC.InputPeer peer;
if (schedulePeer != null) {
peer = schedulePeer;
} else {
peer = VoIPService.getSharedInstance().getGroupCallPeer();
}
if (peer == null) {
selfPeer = new TLRPC.TL_peerUser();
selfPeer.user_id = accountInstance.getUserConfig().getClientUserId();
} else if (peer instanceof TLRPC.TL_inputPeerChannel) {
selfPeer = new TLRPC.TL_peerChannel();
selfPeer.channel_id = peer.channel_id;
} else if (peer instanceof TLRPC.TL_inputPeerUser) {
selfPeer = new TLRPC.TL_peerUser();
selfPeer.user_id = peer.user_id;
} else if (peer instanceof TLRPC.TL_inputPeerChat) {
selfPeer = new TLRPC.TL_peerChat();
selfPeer.chat_id = peer.chat_id;
}
VoIPService.audioLevelsCallback = (uids, levels, voice) -> {
for (int a = 0; a < uids.length; a++) {
TLRPC.TL_groupCallParticipant participant = call.participantsBySources.get(uids[a]);
if (participant != null) {
if (!renderersContainer.inFullscreenMode) {
ArrayList<TLRPC.TL_groupCallParticipant> array = delayedGroupCallUpdated ? oldParticipants : call.visibleParticipants;
int idx = array.indexOf(participant);
if (idx >= 0) {
RecyclerView.ViewHolder holder = listView.findViewHolderForAdapterPosition(idx + listAdapter.usersStartRow);
if (holder != null && holder.itemView instanceof GroupCallUserCell) {
GroupCallUserCell cell = (GroupCallUserCell) holder.itemView;
cell.setAmplitude(levels[a] * 15.0f);
if (holder.itemView == scrimView) {
if (!contentFullyOverlayed) {
containerView.invalidate();
}
}
}
}
} else {
for (int i = 0; i < fullscreenUsersListView.getChildCount(); i++) {
GroupCallFullscreenAdapter.GroupCallUserCell cell = (GroupCallFullscreenAdapter.GroupCallUserCell) fullscreenUsersListView.getChildAt(i);
if (MessageObject.getPeerId(cell.getParticipant().peer) == MessageObject.getPeerId(participant.peer)) {
cell.setAmplitude(levels[a] * 15.0f);
}
}
}
renderersContainer.setAmplitude(participant, levels[a] * 15.0f);
}
}
};
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.groupCallUpdated);
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.needShowAlert);
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.chatInfoDidLoad);
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.didLoadChatAdmins);
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.applyGroupCallVisibleParticipants);
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.userInfoDidLoad);
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.mainUserInfoChanged);
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.updateInterfaces);
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.groupCallScreencastStateChanged);
accountInstance.getNotificationCenter().addObserver(this, NotificationCenter.groupCallSpeakingUsersUpdated);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.webRtcMicAmplitudeEvent);
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.didEndCall);
shadowDrawable = context.getResources().getDrawable(R.drawable.sheet_shadow_round).mutate();
bigMicDrawable = new RLottieDrawable(R.raw.voip_filled, "" + R.raw.voip_filled, AndroidUtilities.dp(72), AndroidUtilities.dp(72), true, null);
handDrawables = new RLottieDrawable(R.raw.hand_2, "" + R.raw.hand_2, AndroidUtilities.dp(72), AndroidUtilities.dp(72), true, null);
containerView = new FrameLayout(context) {
private boolean ignoreLayout = false;
private RectF rect = new RectF();
private int lastSize;
private boolean updateRenderers;
boolean localHasVideo;
boolean wasLayout;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int totalHeight = MeasureSpec.getSize(heightMeasureSpec);
ignoreLayout = true;
boolean landscape = MeasureSpec.getSize(widthMeasureSpec) > totalHeight && !AndroidUtilities.isTablet();
renderersContainer.listWidth = MeasureSpec.getSize(widthMeasureSpec);
boolean tablet = AndroidUtilities.isTablet() && MeasureSpec.getSize(widthMeasureSpec) > totalHeight && !isRtmpStream();
if (isLandscapeMode != landscape) {
isLandscapeMode = landscape;
int measuredWidth = muteButton.getMeasuredWidth();
if (measuredWidth == 0) {
measuredWidth = muteButton.getLayoutParams().width;
}
float muteButtonScale = AndroidUtilities.dp(52) / (float) (measuredWidth - AndroidUtilities.dp(8));
float multiplier = isLandscapeMode ? muteButtonScale : renderersContainer.inFullscreenMode ? muteButtonScale : 1f;
boolean isExpanded = renderersContainer.inFullscreenMode && (AndroidUtilities.isTablet() || isLandscapeMode == isRtmpLandscapeMode());
View expandView = isExpanded ? minimizeButton : expandButton;
View expandOtherView = isExpanded ? expandButton : minimizeButton;
expandView.setAlpha(1f);
expandView.setScaleX(multiplier);
expandView.setScaleY(multiplier);
expandOtherView.setAlpha(0f);
muteLabel[0].setAlpha(1f);
muteLabel[1].setAlpha(1f);
if (!renderersContainer.inFullscreenMode && (!isLandscapeMode || AndroidUtilities.isTablet())) {
muteLabel[0].setScaleX(1f);
muteLabel[1].setScaleY(1f);
} else {
muteLabel[0].setScaleX(0.687f);
muteLabel[1].setScaleY(0.687f);
}
invalidateLayoutFullscreen();
layoutManager.setSpanCount(isLandscapeMode ? 6 : 2);
listView.invalidateItemDecorations();
fullscreenUsersListView.invalidateItemDecorations();
updateRenderers = true;
if (scheduleInfoTextView != null) {
scheduleInfoTextView.setVisibility(!isLandscapeMode ? View.VISIBLE : View.GONE);
}
boolean needFullscreen = isRtmpLandscapeMode() == landscape;
if (needFullscreen && isRtmpStream() && !renderersContainer.inFullscreenMode && !call.visibleVideoParticipants.isEmpty()) {
fullscreenFor(call.visibleVideoParticipants.get(0));
renderersContainer.delayHideUi();
}
}
if (isTabletMode != tablet) {
isTabletMode = tablet;
tabletVideoGridView.setVisibility(tablet ? View.VISIBLE : View.GONE);
listView.invalidateItemDecorations();
fullscreenUsersListView.invalidateItemDecorations();
updateRenderers = true;
}
if (updateRenderers) {
applyCallParticipantUpdates(true);
listAdapter.notifyDataSetChanged();
fullscreenAdapter.update(false, tabletVideoGridView);
if (isTabletMode) {
tabletGridAdapter.update(false, tabletVideoGridView);
}
tabletVideoGridView.setVisibility(isTabletMode ? View.VISIBLE : View.GONE);
tabletGridAdapter.setVisibility(tabletVideoGridView, isTabletMode && !renderersContainer.inFullscreenMode, true);
listViewVideoVisibility = !isTabletMode || renderersContainer.inFullscreenMode;
boolean fullscreenListVisibility = !isTabletMode && renderersContainer.inFullscreenMode;
fullscreenAdapter.setVisibility(fullscreenUsersListView, fullscreenListVisibility);
fullscreenUsersListView.setVisibility(fullscreenListVisibility ? View.VISIBLE : View.GONE);
listView.setVisibility((isTabletMode || !renderersContainer.inFullscreenMode) ? View.VISIBLE : View.GONE);
layoutManager.setSpanCount(isLandscapeMode ? 6 : 2);
updateState(false, false);
listView.invalidateItemDecorations();
fullscreenUsersListView.invalidateItemDecorations();
AndroidUtilities.updateVisibleRows(listView);
updateRenderers = false;
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
renderersContainer.setIsTablet(isTabletMode);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
attachedRenderersTmp.get(i).updateAttachState(true);
}
}
if (Build.VERSION.SDK_INT >= 21) {
setPadding(backgroundPaddingLeft, getStatusBarHeight(), backgroundPaddingLeft, 0);
}
int availableHeight = totalHeight - getPaddingTop() - AndroidUtilities.dp(14 + 231);
int listViewPaddingBottom;
LayoutParams layoutParams = (LayoutParams) renderersContainer.getLayoutParams();
if (isTabletMode) {
layoutParams.topMargin = ActionBar.getCurrentActionBarHeight();
} else {
layoutParams.topMargin = 0;
}
for (int a = 0; a < 2; a++) {
layoutParams = (LayoutParams) undoView[a].getLayoutParams();
if (isTabletMode) {
layoutParams.rightMargin = AndroidUtilities.dp(TABLET_LIST_SIZE + 8);
} else {
layoutParams.rightMargin = AndroidUtilities.dp(8);
}
}
if (tabletVideoGridView != null) {
layoutParams = (LayoutParams) tabletVideoGridView.getLayoutParams();
layoutParams.topMargin = ActionBar.getCurrentActionBarHeight();
}
int buttonsGradientSize = AndroidUtilities.dp(150);
//listView layoutParams
layoutParams = (LayoutParams) listView.getLayoutParams();
if (isTabletMode) {
layoutParams.gravity = hasVideo ? Gravity.RIGHT : Gravity.CENTER_HORIZONTAL;
layoutParams.width = AndroidUtilities.dp(TABLET_LIST_SIZE);
layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(4);
layoutParams.bottomMargin = buttonsGradientSize;
layoutParams.topMargin = ActionBar.getCurrentActionBarHeight();
listViewPaddingBottom = AndroidUtilities.dp(60);
} else if (isLandscapeMode) {
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.topMargin = ActionBar.getCurrentActionBarHeight();
layoutParams.bottomMargin = AndroidUtilities.dp(14);
layoutParams.rightMargin = AndroidUtilities.dp(90);
layoutParams.leftMargin = AndroidUtilities.dp(14);
listViewPaddingBottom = 0;
} else {
layoutParams.gravity = Gravity.TOP | Gravity.LEFT;
layoutParams.width = LayoutHelper.MATCH_PARENT;
listViewPaddingBottom = AndroidUtilities.dp(60);
layoutParams.bottomMargin = buttonsGradientSize;
layoutParams.topMargin = ActionBar.getCurrentActionBarHeight() + AndroidUtilities.dp(14);
layoutParams.rightMargin = layoutParams.leftMargin = AndroidUtilities.dp(14);
}
//
if (isLandscapeMode && !isTabletMode) {
buttonsBackgroundGradientView.setVisibility(View.GONE);
buttonsBackgroundGradientView2.setVisibility(View.GONE);
} else {
buttonsBackgroundGradientView.setVisibility(View.VISIBLE);
layoutParams = (LayoutParams) buttonsBackgroundGradientView.getLayoutParams();
layoutParams.bottomMargin = buttonsGradientSize;
if (isTabletMode) {
layoutParams.gravity = hasVideo ? Gravity.RIGHT | Gravity.BOTTOM : Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
layoutParams.width = AndroidUtilities.dp(TABLET_LIST_SIZE + 8);
} else {
layoutParams.width = LayoutHelper.MATCH_PARENT;
}
buttonsBackgroundGradientView2.setVisibility(View.VISIBLE);
layoutParams = (LayoutParams) buttonsBackgroundGradientView2.getLayoutParams();
layoutParams.height = buttonsGradientSize;
if (isTabletMode) {
layoutParams.gravity = hasVideo ? Gravity.RIGHT | Gravity.BOTTOM : Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
layoutParams.width = AndroidUtilities.dp(TABLET_LIST_SIZE + 8);
} else {
layoutParams.width = LayoutHelper.MATCH_PARENT;
}
}
if (isLandscapeMode) {
fullscreenUsersListView.setPadding(0, AndroidUtilities.dp(9), 0, AndroidUtilities.dp(9));
} else {
fullscreenUsersListView.setPadding(AndroidUtilities.dp(9), 0, AndroidUtilities.dp(9), 0);
}
// buttonsContainer
layoutParams = (LayoutParams) buttonsContainer.getLayoutParams();
if (isTabletMode) {
layoutParams.width = AndroidUtilities.dp(TABLET_LIST_SIZE);
layoutParams.height = AndroidUtilities.dp(200);
layoutParams.gravity = hasVideo ? Gravity.RIGHT | Gravity.BOTTOM : Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
layoutParams.rightMargin = 0;
} else if (isLandscapeMode) {
layoutParams.width = AndroidUtilities.dp(90);
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.RIGHT | Gravity.TOP;
} else {
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.height = AndroidUtilities.dp(200);
layoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
layoutParams.rightMargin = 0;
}
if (isLandscapeMode && !isTabletMode) {
layoutParams = (LayoutParams) actionBar.getLayoutParams();
layoutParams.rightMargin = AndroidUtilities.dp(90);
layoutParams = (LayoutParams) menuItemsContainer.getLayoutParams();
layoutParams.rightMargin = AndroidUtilities.dp(90);
layoutParams = (LayoutParams) actionBarBackground.getLayoutParams();
layoutParams.rightMargin = AndroidUtilities.dp(90);
layoutParams = (LayoutParams) actionBarShadow.getLayoutParams();
layoutParams.rightMargin = AndroidUtilities.dp(90);
} else {
layoutParams = (LayoutParams) actionBar.getLayoutParams();
layoutParams.rightMargin = 0;
layoutParams = (LayoutParams) menuItemsContainer.getLayoutParams();
layoutParams.rightMargin = 0;
layoutParams = (LayoutParams) actionBarBackground.getLayoutParams();
layoutParams.rightMargin = 0;
layoutParams = (LayoutParams) actionBarShadow.getLayoutParams();
layoutParams.rightMargin = 0;
}
layoutParams = (LayoutParams) fullscreenUsersListView.getLayoutParams();
if (isLandscapeMode) {
if (((LinearLayoutManager) fullscreenUsersListView.getLayoutManager()).getOrientation() != RecyclerView.VERTICAL) {
((LinearLayoutManager) fullscreenUsersListView.getLayoutManager()).setOrientation(RecyclerView.VERTICAL);
}
layoutParams.height = LayoutHelper.MATCH_PARENT;
layoutParams.width = AndroidUtilities.dp(80);
layoutParams.gravity = Gravity.TOP | Gravity.RIGHT;
layoutParams.rightMargin = AndroidUtilities.dp(100);
layoutParams.bottomMargin = 0;
} else {
if (((LinearLayoutManager) fullscreenUsersListView.getLayoutManager()).getOrientation() != RecyclerView.HORIZONTAL) {
((LinearLayoutManager) fullscreenUsersListView.getLayoutManager()).setOrientation(RecyclerView.HORIZONTAL);
}
layoutParams.height = AndroidUtilities.dp(80);
layoutParams.width = LayoutHelper.MATCH_PARENT;
layoutParams.gravity = Gravity.BOTTOM;
layoutParams.rightMargin = 0;
layoutParams.bottomMargin = AndroidUtilities.dp(100);
}
layoutParams = (LayoutParams) actionBarShadow.getLayoutParams();
layoutParams.topMargin = ActionBar.getCurrentActionBarHeight();
int contentSize = Math.max(AndroidUtilities.dp(64 + 50 + 58 * 2.5f), availableHeight / 5 * 3);
int padding = isTabletMode ? 0 : Math.max(0, availableHeight - contentSize + AndroidUtilities.dp(8));
if (listView.getPaddingTop() != padding || listView.getPaddingBottom() != listViewPaddingBottom) {
listView.setPadding(0, padding, 0, listViewPaddingBottom);
}
if (scheduleStartAtTextView != null) {
int y = padding + (availableHeight - padding + AndroidUtilities.dp(60)) / 2;
FrameLayout.LayoutParams layoutParams1 = (FrameLayout.LayoutParams) scheduleStartInTextView.getLayoutParams();
layoutParams1.topMargin = y - AndroidUtilities.dp(30);
FrameLayout.LayoutParams layoutParams2 = (FrameLayout.LayoutParams) scheduleStartAtTextView.getLayoutParams();
layoutParams2.topMargin = y + AndroidUtilities.dp(80);
FrameLayout.LayoutParams layoutParams3 = (FrameLayout.LayoutParams) scheduleTimeTextView.getLayoutParams();
if (layoutParams1.topMargin < ActionBar.getCurrentActionBarHeight() || layoutParams2.topMargin + AndroidUtilities.dp(20) > totalHeight - AndroidUtilities.dp(231)) {
scheduleStartInTextView.setVisibility(INVISIBLE);
scheduleStartAtTextView.setVisibility(INVISIBLE);
layoutParams3.topMargin = y - AndroidUtilities.dp(20);
} else {
scheduleStartInTextView.setVisibility(VISIBLE);
scheduleStartAtTextView.setVisibility(VISIBLE);
layoutParams3.topMargin = y;
}
}
for (int i = 0; i < attachedRenderers.size(); i++) {
attachedRenderers.get(i).setFullscreenMode(renderersContainer.inFullscreenMode, true);
}
ignoreLayout = false;
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(totalHeight, MeasureSpec.EXACTLY));
int currentSize = getMeasuredHeight() + (getMeasuredWidth() << 16);
if (currentSize != lastSize) {
lastSize = currentSize;
dismissAvatarPreview(false);
}
cellFlickerDrawable.setParentWidth(getMeasuredWidth());
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
boolean needAnimate = false;
float fromX = 0;
if (isTabletMode && localHasVideo != hasVideo && wasLayout) {
needAnimate = true;
fromX = listView.getX();
}
localHasVideo = hasVideo;
renderersContainer.inLayout = true;
super.onLayout(changed, l, t, r, b);
renderersContainer.inLayout = false;
updateLayout(false);
wasLayout = true;
if (needAnimate && listView.getLeft() != fromX) {
float dx = fromX - listView.getLeft();
listView.setTranslationX(dx);
buttonsContainer.setTranslationX(dx);
buttonsBackgroundGradientView.setTranslationX(dx);
buttonsBackgroundGradientView2.setTranslationX(dx);
listView.animate().translationX(0).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
buttonsBackgroundGradientView.animate().translationX(0).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
buttonsBackgroundGradientView2.animate().translationX(0).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
buttonsContainer.animate().translationX(0).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
}
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
if (scrimView != null && ev.getAction() == MotionEvent.ACTION_DOWN) {
float x = ev.getX();
float y = ev.getY();
boolean dismissScrim = true;
rect.set(scrimPopupLayout.getX(), scrimPopupLayout.getY(), scrimPopupLayout.getX() + scrimPopupLayout.getMeasuredWidth(), scrimPopupLayout.getY() + scrimPopupLayout.getMeasuredHeight());
if (rect.contains(x, y)) {
dismissScrim = false;
}
rect.set(avatarPreviewContainer.getX(), avatarPreviewContainer.getY(), avatarPreviewContainer.getX() + avatarPreviewContainer.getMeasuredWidth(), avatarPreviewContainer.getY() + avatarPreviewContainer.getMeasuredWidth() + scrimView.getMeasuredHeight());
if (rect.contains(x, y)) {
dismissScrim = false;
}
if (dismissScrim) {
dismissAvatarPreview(true);
return true;
}
}
if (ev.getAction() == MotionEvent.ACTION_DOWN && scrollOffsetY != 0 && ev.getY() < scrollOffsetY - AndroidUtilities.dp(37) && actionBar.getAlpha() == 0.0f && !avatarsPreviewShowed && previewDialog == null && !renderersContainer.inFullscreenMode) {
dismiss();
return true;
}
return super.onInterceptTouchEvent(ev);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
return !isDismissed() && super.onTouchEvent(e);
}
@Override
public void requestLayout() {
if (ignoreLayout) {
return;
}
super.requestLayout();
}
@Override
protected void onDraw(Canvas canvas) {
int offset = AndroidUtilities.dp(74);
float top = scrollOffsetY - offset;
int height = getMeasuredHeight() + AndroidUtilities.dp(15) + backgroundPaddingTop;
float rad = 1.0f;
if (top + backgroundPaddingTop < ActionBar.getCurrentActionBarHeight()) {
int willMoveUpTo = offset - backgroundPaddingTop - AndroidUtilities.dp(14);
float moveProgress = Math.min(1.0f, (ActionBar.getCurrentActionBarHeight() - top - backgroundPaddingTop) / willMoveUpTo);
int diff = (int) ((ActionBar.getCurrentActionBarHeight() - willMoveUpTo) * moveProgress);
top -= diff;
height += diff;
rad = 1.0f - moveProgress;
}
top += getPaddingTop();
if (renderersContainer.progressToFullscreenMode != 1f) {
shadowDrawable.setBounds(0, (int) top, getMeasuredWidth(), height);
shadowDrawable.draw(canvas);
if (rad != 1.0f) {
Theme.dialogs_onlineCirclePaint.setColor(backgroundColor);
rect.set(backgroundPaddingLeft, backgroundPaddingTop + top, getMeasuredWidth() - backgroundPaddingLeft, backgroundPaddingTop + top + AndroidUtilities.dp(24));
canvas.drawRoundRect(rect, AndroidUtilities.dp(12) * rad, AndroidUtilities.dp(12) * rad, Theme.dialogs_onlineCirclePaint);
}
int finalColor = Color.argb((int) (255 * actionBar.getAlpha()), (int) (Color.red(backgroundColor) * 0.8f), (int) (Color.green(backgroundColor) * 0.8f), (int) (Color.blue(backgroundColor) * 0.8f));
Theme.dialogs_onlineCirclePaint.setColor(finalColor);
float bottom = getStatusBarHeight();
canvas.drawRect(backgroundPaddingLeft, 0, getMeasuredWidth() - backgroundPaddingLeft, bottom, Theme.dialogs_onlineCirclePaint);
if (previewDialog != null) {
Theme.dialogs_onlineCirclePaint.setColor(previewDialog.getBackgroundColor());
canvas.drawRect(backgroundPaddingLeft, 0, getMeasuredWidth() - backgroundPaddingLeft, getStatusBarHeight(), Theme.dialogs_onlineCirclePaint);
}
}
if (renderersContainer.progressToFullscreenMode != 0) {
Theme.dialogs_onlineCirclePaint.setColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_actionBar), (int) (255 * renderersContainer.progressToFullscreenMode)));
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), Theme.dialogs_onlineCirclePaint);
}
}
HashMap<Object, View> listCells = new HashMap<>();
@Override
protected void dispatchDraw(Canvas canvas) {
if (isTabletMode) {
buttonsContainer.setTranslationY(0);
fullscreenUsersListView.setTranslationY(0);
buttonsContainer.setTranslationX(0);
fullscreenUsersListView.setTranslationY(0);
} else if (isLandscapeMode) {
buttonsContainer.setTranslationY(0);
fullscreenUsersListView.setTranslationY(0);
buttonsContainer.setTranslationX(progressToHideUi * AndroidUtilities.dp(94));
fullscreenUsersListView.setTranslationX(progressToHideUi * AndroidUtilities.dp(94));
} else {
buttonsContainer.setTranslationX(0);
fullscreenUsersListView.setTranslationX(0);
buttonsContainer.setTranslationY(progressToHideUi * AndroidUtilities.dp(94));
fullscreenUsersListView.setTranslationY(progressToHideUi * AndroidUtilities.dp(94));
}
for (int i = 0; i < listView.getChildCount(); i++) {
View view = listView.getChildAt(i);
if (view instanceof GroupCallUserCell) {
GroupCallUserCell cell = (GroupCallUserCell) view;
cell.setDrawAvatar(true);
}
if (!(view instanceof GroupCallGridCell)) {
if (view.getMeasuredWidth() != listView.getMeasuredWidth()) {
view.setTranslationX((listView.getMeasuredWidth() - view.getMeasuredWidth()) >> 1);
} else {
view.setTranslationX(0);
}
}
}
if (renderersContainer.isAnimating()) {
if (fullscreenUsersListView.getVisibility() == View.VISIBLE) {
listCells.clear();
for (int i = 0; i < listView.getChildCount(); i++) {
View view = listView.getChildAt(i);
if (view instanceof GroupCallGridCell && listView.getChildAdapterPosition(view) >= 0) {
GroupCallGridCell cell = (GroupCallGridCell) view;
if (cell.getRenderer() != renderersContainer.fullscreenTextureView) {
listCells.put(cell.getParticipant(), view);
}
} else if (view instanceof GroupCallUserCell && listView.getChildAdapterPosition(view) >= 0) {
GroupCallUserCell cell = (GroupCallUserCell) view;
listCells.put(cell.getParticipant(), cell);
}
}
for (int i = 0; i < fullscreenUsersListView.getChildCount(); i++) {
GroupCallFullscreenAdapter.GroupCallUserCell cellTo = (GroupCallFullscreenAdapter.GroupCallUserCell) fullscreenUsersListView.getChildAt(i);
View cellFrom = listCells.get(cellTo.getVideoParticipant());
if (cellFrom == null) {
cellFrom = listCells.get(cellTo.getParticipant());
}
float progressToFullscreenMode = renderersContainer.progressToFullscreenMode;
if (!fullscreenListItemAnimator.isRunning()) {
cellTo.setAlpha(1f);
}
if (cellFrom != null) {
float toX, toY, fromX, fromY;
if (cellFrom instanceof GroupCallGridCell) {
GroupCallGridCell gridCell = (GroupCallGridCell) cellFrom;
fromX = gridCell.getLeft() + listView.getX() - renderersContainer.getLeft();
fromY = gridCell.getTop() + listView.getY() - renderersContainer.getTop();
toX = cellTo.getLeft() + fullscreenUsersListView.getX();
toY = cellTo.getTop() + fullscreenUsersListView.getY();
} else {
GroupCallUserCell userCell = (GroupCallUserCell) cellFrom;
fromX = userCell.getLeft() + listView.getX() - renderersContainer.getLeft() + userCell.getAvatarImageView().getLeft() + (userCell.getAvatarImageView().getMeasuredWidth() >> 1);
fromY = userCell.getTop() + listView.getY() - renderersContainer.getTop() + userCell.getAvatarImageView().getTop() + (userCell.getAvatarImageView().getMeasuredHeight() >> 1);
toX = cellTo.getLeft() + fullscreenUsersListView.getX() + (cellTo.getMeasuredWidth() >> 1);
toY = cellTo.getTop() + fullscreenUsersListView.getY() + (cellTo.getMeasuredHeight() >> 1);
userCell.setDrawAvatar(false);
}
cellTo.setTranslationX((fromX - toX) * (1f - progressToFullscreenMode));
cellTo.setTranslationY((fromY - toY) * (1f - progressToFullscreenMode));
cellTo.setScaleX(1f);
cellTo.setScaleY(1f);
cellTo.setProgressToFullscreen(progressToFullscreenMode);
} else {
cellTo.setScaleX(1f);
cellTo.setScaleY(1f);
cellTo.setTranslationX(0);
cellTo.setTranslationY(0);
cellTo.setProgressToFullscreen(1f);
if (cellTo.getRenderer() == null) {
cellTo.setAlpha(progressToFullscreenMode);
}
}
}
}
} else {
for (int i = 0; i < fullscreenUsersListView.getChildCount(); i++) {
GroupCallFullscreenAdapter.GroupCallUserCell cellTo = (GroupCallFullscreenAdapter.GroupCallUserCell) fullscreenUsersListView.getChildAt(i);
cellTo.setProgressToFullscreen(1f);
}
}
for (int i = 0; i < attachedRenderers.size(); i++) {
GroupCallMiniTextureView child = attachedRenderers.get(i);
child.updatePosition(listView, tabletVideoGridView, fullscreenUsersListView, renderersContainer);
}
if (!isTabletMode) {
buttonsBackgroundGradientView.setAlpha(1f - renderersContainer.progressToFullscreenMode);
buttonsBackgroundGradientView2.setAlpha(1f - renderersContainer.progressToFullscreenMode);
} else {
buttonsBackgroundGradientView.setAlpha(1f);
buttonsBackgroundGradientView2.setAlpha(1f);
}
if (renderersContainer.swipedBack) {
listView.setAlpha(1f - renderersContainer.progressToFullscreenMode);
} else {
listView.setAlpha(1f);
}
super.dispatchDraw(canvas);
if (drawingForBlur) {
return;
}
if (avatarsPreviewShowed) {
if (scrimView != null) {
if (!useBlur) {
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), scrimPaint);
}
float listTop = listView.getY();
float[] radii = new float[8];
Path roundPath = new Path();
int count = listView.getChildCount();
float viewClipBottom = listView.getY() + listView.getMeasuredHeight();
GroupCallUserCell scrimViewLocal = null;
if (hasScrimAnchorView) {
for (int num = 0; num < count; num++) {
View child = listView.getChildAt(num);
if (child == scrimView) {
scrimViewLocal = scrimView;
break;
}
}
} else {
scrimViewLocal = scrimView;
}
if (scrimViewLocal != null && listTop < viewClipBottom) {
canvas.save();
if (scrimFullscreenView == null) {
canvas.clipRect(0, listTop * (1f - progressToAvatarPreview), getMeasuredWidth(), viewClipBottom * (1f - progressToAvatarPreview) + getMeasuredHeight() * progressToAvatarPreview);
}
float childY, childX;
if (!hasScrimAnchorView) {
childY = avatarPreviewContainer.getTop() + avatarPreviewContainer.getMeasuredWidth();
childX = avatarPreviewContainer.getLeft();
} else {
childY = (listView.getY() + scrimViewLocal.getY()) * (1f - progressToAvatarPreview) + (avatarPreviewContainer.getTop() + avatarPreviewContainer.getMeasuredWidth()) * progressToAvatarPreview;
childX = (listView.getLeft() + scrimViewLocal.getX()) * (1f - progressToAvatarPreview) + avatarPreviewContainer.getLeft() * progressToAvatarPreview;
}
canvas.translate(childX, childY);
if (!hasScrimAnchorView) {
canvas.saveLayerAlpha(0 ,0, scrimViewLocal.getMeasuredWidth(), scrimViewLocal.getClipHeight(), (int) (255 * progressToAvatarPreview), Canvas.ALL_SAVE_FLAG);
} else {
canvas.save();
}
float progress = progressToAvatarPreview;
float pr = 1.0f - CubicBezierInterpolator.EASE_OUT.getInterpolation(1.0f - progress);
int h = (int) (scrimViewLocal.getMeasuredHeight() + (scrimViewLocal.getClipHeight() - scrimViewLocal.getMeasuredHeight()) * pr);
rect.set(0, 0, scrimViewLocal.getMeasuredWidth(), h);
scrimViewLocal.setProgressToAvatarPreview(hasScrimAnchorView ? progressToAvatarPreview : 1f);
for (int i = 0; i < 4; i++) {
radii[i] = AndroidUtilities.dp(13) * (1f - progressToAvatarPreview);
radii[4 + i] = AndroidUtilities.dp(13);
}
roundPath.reset();
roundPath.addRoundRect(rect, radii, Path.Direction.CW);
roundPath.close();
canvas.drawPath(roundPath, listViewBackgroundPaint);
scrimViewLocal.draw(canvas);
canvas.restore();
canvas.restore();
if (scrimPopupLayout != null) {
float y = childY + h;
float x = getMeasuredWidth() - scrimPopupLayout.getMeasuredWidth() - AndroidUtilities.dp(14);
if (progressToAvatarPreview != 1f) {
canvas.saveLayerAlpha(x, y, x + scrimPopupLayout.getMeasuredWidth(), y + scrimPopupLayout.getMeasuredHeight(), (int) (255 * progressToAvatarPreview), Canvas.ALL_SAVE_FLAG);
} else {
canvas.save();
}
scrimPopupLayout.setTranslationX(x - scrimPopupLayout.getLeft());
scrimPopupLayout.setTranslationY(y - scrimPopupLayout.getTop());
float scale = 0.8f + 0.2f * progressToAvatarPreview;
canvas.scale(scale, scale, x + scrimPopupLayout.getMeasuredWidth() / 2f, y);
canvas.translate(x, y);
scrimPopupLayout.draw(canvas);
canvas.restore();
}
}
if (!pinchToZoomHelper.isInOverlayMode()) {
canvas.save();
if (hasScrimAnchorView && scrimFullscreenView == null) {
canvas.clipRect(0, listTop * (1f - progressToAvatarPreview), getMeasuredWidth(), viewClipBottom * (1f - progressToAvatarPreview) + getMeasuredHeight() * progressToAvatarPreview);
}
canvas.scale(avatarPreviewContainer.getScaleX(), avatarPreviewContainer.getScaleY(), avatarPreviewContainer.getX(), avatarPreviewContainer.getY());
canvas.translate(avatarPreviewContainer.getX(), avatarPreviewContainer.getY());
avatarPreviewContainer.draw(canvas);
canvas.restore();
}
}
if (progressToAvatarPreview != 1f && scrimFullscreenView == null) {
canvas.saveLayerAlpha((int) buttonsBackgroundGradientView2.getX(), (int) buttonsBackgroundGradientView.getY(), (int) (buttonsBackgroundGradientView2.getX() + buttonsBackgroundGradientView2.getMeasuredWidth()), getMeasuredHeight(), (int) (255 * (1f - progressToAvatarPreview)), Canvas.ALL_SAVE_FLAG);
canvas.save();
canvas.translate(buttonsBackgroundGradientView2.getX(), buttonsBackgroundGradientView2.getY());
buttonsBackgroundGradientView2.draw(canvas);
canvas.restore();
canvas.save();
canvas.translate(buttonsBackgroundGradientView.getX(), buttonsBackgroundGradientView.getY());
buttonsBackgroundGradientView.draw(canvas);
canvas.restore();
canvas.save();
canvas.translate(buttonsContainer.getX(), buttonsContainer.getY());
buttonsContainer.draw(canvas);
canvas.restore();
for (int i = 0; i < 2; i++) {
if (undoView[i].getVisibility() == View.VISIBLE) {
canvas.save();
canvas.translate(undoView[1].getX(), undoView[1].getY());
undoView[1].draw(canvas);
canvas.restore();
}
}
canvas.restore();
}
} else {
if (scrimView != null) {
canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), scrimPaint);
float listTop = listView.getY();
float listBottom = listView.getY() + listView.getMeasuredHeight();
if (hasScrimAnchorView) {
int count = listView.getChildCount();
for (int num = 0; num < count; num++) {
View child = listView.getChildAt(num);
if (child != scrimView) {
continue;
}
float viewClipLeft = Math.max(listView.getLeft(), listView.getLeft() + child.getX());
float viewClipTop = Math.max(listTop, listView.getY() + child.getY());
float viewClipRight = Math.min(listView.getRight(), listView.getLeft() + child.getX() + child.getMeasuredWidth());
float viewClipBottom = Math.min(listView.getY() + listView.getMeasuredHeight(), listView.getY() + child.getY() + scrimView.getClipHeight());
if (viewClipTop < viewClipBottom) {
if (child.getAlpha() != 1f) {
canvas.saveLayerAlpha(viewClipLeft, viewClipTop, viewClipRight, viewClipBottom, (int) (255 * child.getAlpha()), Canvas.ALL_SAVE_FLAG);
} else {
canvas.save();
}
canvas.clipRect(viewClipLeft, viewClipTop, viewClipRight, getMeasuredHeight());
canvas.translate(listView.getLeft() + child.getX(), listView.getY() + child.getY());
float progress = scrimPaint.getAlpha() / 100.0f;
float pr = 1.0f - CubicBezierInterpolator.EASE_OUT.getInterpolation(1.0f - progress);
int h = (int) (scrimView.getMeasuredHeight() + (scrimView.getClipHeight() - scrimView.getMeasuredHeight()) * pr);
rect.set(0, 0, child.getMeasuredWidth(), h);
scrimView.setAboutVisibleProgress(listViewBackgroundPaint.getColor(), progress);
canvas.drawRoundRect(rect, AndroidUtilities.dp(13), AndroidUtilities.dp(13), listViewBackgroundPaint);
child.draw(canvas);
canvas.restore();
}
}
} else if (scrimFullscreenView != null) {
canvas.save();
float x = scrimFullscreenView.getX() + fullscreenUsersListView.getX() + renderersContainer.getX();
float y = scrimFullscreenView.getY() + fullscreenUsersListView.getY() + renderersContainer.getY();
canvas.translate(x, y);
if (scrimFullscreenView.getRenderer() != null && scrimFullscreenView.getRenderer().isAttached() && !scrimFullscreenView.getRenderer().showingInFullscreen) {
scrimFullscreenView.getRenderer().draw(canvas);
} else {
scrimFullscreenView.draw(canvas);
}
scrimFullscreenView.drawOverlays(canvas);
canvas.restore();
} else if (scrimRenderer != null && scrimRenderer.isAttached()) {
canvas.save();
float x = scrimRenderer.getX() + renderersContainer.getX();
float y = scrimRenderer.getY() + renderersContainer.getY();
canvas.translate(x, y);
scrimRenderer.draw(canvas);
canvas.restore();
}
}
}
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (!isTabletMode && renderersContainer.progressToFullscreenMode == 1f && (child == actionBar || child == actionBarShadow || child == actionBarBackground || child == titleTextView || child == menuItemsContainer)) {
return true;
}
if (drawingForBlur && child == renderersContainer) {
canvas.save();
canvas.translate(renderersContainer.getX() + fullscreenUsersListView.getX(), renderersContainer.getY() + fullscreenUsersListView.getY());
fullscreenUsersListView.draw(canvas);
canvas.restore();
return true;
}
if (child == avatarPreviewContainer || child == scrimPopupLayout || child == scrimView) {
return true;
}
if (contentFullyOverlayed && useBlur) {
if (child == listView || child == buttonsContainer) {
return true;
}
}
if (scrimFullscreenView == null && !drawingForBlur && avatarsPreviewShowed && (child == buttonsBackgroundGradientView2 || child == buttonsBackgroundGradientView || child == buttonsContainer || child == undoView[0] || child == undoView[1])) {
return true;
}
return super.drawChild(canvas, child, drawingTime);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (scrimView != null && keyCode == KeyEvent.KEYCODE_BACK) {
dismissAvatarPreview(true);
return true;
}
return super.onKeyDown(keyCode, event);
}
};
containerView.setFocusable(true);
containerView.setFocusableInTouchMode(true);
containerView.setWillNotDraw(false);
containerView.setPadding(backgroundPaddingLeft, 0, backgroundPaddingLeft, 0);
containerView.setKeepScreenOn(true);
containerView.setClipChildren(false);
if (schedulePeer != null) {
scheduleStartInTextView = new SimpleTextView(context);
scheduleStartInTextView.setGravity(Gravity.CENTER);
scheduleStartInTextView.setTextColor(0xffffffff);
scheduleStartInTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
scheduleStartInTextView.setTextSize(18);
scheduleStartInTextView.setText(LocaleController.getString("VoipChatStartsIn", R.string.VoipChatStartsIn));
containerView.addView(scheduleStartInTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 21, 0, 21, 231 + 80)); //-80
scheduleTimeTextView = new SimpleTextView(context) {
private LinearGradient linearGradient;
private int lastTextWidth;
private Matrix matrix = new Matrix();
private float targetX = -1f;
private float startX;
private float duration;
private float time;
private float gradientWidth;
private long lastUpdateTime;
private void setTarget() {
targetX = 0.20f * (Utilities.random.nextInt(100) - 50) / 50.0f;
}
@Override
protected boolean createLayout(int width) {
boolean result = super.createLayout(width);
int w = getTextWidth();
if (w != lastTextWidth) {
gradientWidth = w * 1.3f;
linearGradient = new LinearGradient(0, getTextHeight(), w * 2.0f, 0, new int[]{Theme.getColor(Theme.key_voipgroup_mutedByAdminGradient), Theme.getColor(Theme.key_voipgroup_mutedByAdminGradient3), Theme.getColor(Theme.key_voipgroup_mutedByAdminGradient2), Theme.getColor(Theme.key_voipgroup_mutedByAdminGradient2)}, new float[]{0.0f, 0.38f, 0.76f, 1.0f}, Shader.TileMode.CLAMP);
getPaint().setShader(linearGradient);
lastTextWidth = w;
}
return result;
}
@Override
protected void onDraw(Canvas canvas) {
float moveProgress = 0.0f;
if (linearGradient != null) {
if (call != null && call.isScheduled()) {
long diff = ((long) call.call.schedule_date) * 1000 - accountInstance.getConnectionsManager().getCurrentTimeMillis();
if (diff < 0) {
moveProgress = 1.0f;
} else if (diff < 5000) {
moveProgress = 1.0f - diff / 5000.0f;
}
}
matrix.reset();
matrix.postTranslate(-lastTextWidth * 0.7f * moveProgress, 0);
long newTime = SystemClock.elapsedRealtime();
long dt = newTime - lastUpdateTime;
if (dt > 20) {
dt = 17;
}
lastUpdateTime = newTime;
if (duration == 0 || time >= duration) {
duration = Utilities.random.nextInt(200) + 1500;
time = 0;
if (targetX == -1f) {
setTarget();
}
startX = targetX;
setTarget();
}
time += dt * (0.5f + BlobDrawable.GRADIENT_SPEED_MIN) + dt * (BlobDrawable.GRADIENT_SPEED_MAX * 2) * amplitude;
if (time > duration) {
time = duration;
}
float interpolation = CubicBezierInterpolator.EASE_OUT.getInterpolation(time / duration);
float x = gradientWidth * (startX + (targetX - startX) * interpolation) - gradientWidth / 2;
matrix.postTranslate(x, 0);
linearGradient.setLocalMatrix(matrix);
invalidate();
}
super.onDraw(canvas);
}
};
scheduleTimeTextView.setGravity(Gravity.CENTER);
scheduleTimeTextView.setTextColor(0xffffffff);
scheduleTimeTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
scheduleTimeTextView.setTextSize(60);
containerView.addView(scheduleTimeTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 21, 0, 21, 231));
scheduleStartAtTextView = new SimpleTextView(context);
scheduleStartAtTextView.setGravity(Gravity.CENTER);
scheduleStartAtTextView.setTextColor(0xffffffff);
scheduleStartAtTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
scheduleStartAtTextView.setTextSize(18);
containerView.addView(scheduleStartAtTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 21, 0, 21, 231 - 30)); //+ 30
}
listView = new RecyclerListView(context) {
private final LongSparseIntArray visiblePeerTmp = new LongSparseIntArray();
@Override
public boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (child == scrimView) {
return false;
}
return super.drawChild(canvas, child, drawingTime);
}
@Override
protected void dispatchDraw(Canvas canvas) {
float inMaxBottom = 0;
float inMinTop = Float.MAX_VALUE;
boolean animateBackground = itemAnimator.outMinTop != Float.MAX_VALUE;
visiblePeerTmp.clear();
for (int i = 0; i < visiblePeerIds.size(); i++){
visiblePeerTmp.put(visiblePeerIds.keyAt(i), 1);
}
visiblePeerIds.clear();
boolean visiblePeersChanged = false;
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 || holder.getItemViewType() == 6) {
continue;
}
if (holder.getItemViewType() == 1 && holder.itemView instanceof GroupCallUserCell) {
GroupCallUserCell userCell = (GroupCallUserCell) holder.itemView;
visiblePeerIds.append(userCell.getPeerId(), 1);
if (visiblePeerTmp.get(userCell.getPeerId(), 0) == 0) {
visiblePeersChanged = true;
} else {
visiblePeerTmp.delete(userCell.getPeerId());
}
}
if (animateBackground) {
if (!itemAnimator.removingHolders.contains(holder)) {
inMinTop = Math.min(inMinTop, Math.max(0, child.getTop()));
inMaxBottom = Math.max(inMaxBottom, child.getBottom());
}
} else {
inMaxBottom = Math.max(inMaxBottom, child.getY() + child.getMeasuredHeight());
inMinTop = Math.min(inMinTop, Math.max(0, child.getY()));
}
}
if (visiblePeerTmp.size() > 0) {
visiblePeersChanged = true;
}
if (visiblePeersChanged) {
updateSubtitle();
}
float minTop, maxBottom;
if (animateBackground) {
minTop = itemAnimator.outMinTop * (1f - itemAnimator.animationProgress) + inMinTop * (itemAnimator.animationProgress);
maxBottom = itemAnimator.outMaxBottom * (1f - itemAnimator.animationProgress) + inMaxBottom * (itemAnimator.animationProgress);
} else {
minTop = inMinTop;
maxBottom = inMaxBottom;
}
if (inMinTop != Float.MAX_VALUE) {
int itemsWidth = AndroidUtilities.isTablet() ? Math.min(AndroidUtilities.dp(420), getMeasuredWidth()) : getMeasuredWidth();
int padding = (getMeasuredWidth() - itemsWidth) >> 1;
rect.set(padding, minTop, getMeasuredWidth() - padding, Math.min(getMeasuredHeight() - getTranslationY(), maxBottom));
canvas.drawRoundRect(rect, AndroidUtilities.dp(13), AndroidUtilities.dp(13), listViewBackgroundPaint);
}
canvas.save();
canvas.clipRect(0, 0, getMeasuredWidth(), getMeasuredHeight());
super.dispatchDraw(canvas);
canvas.restore();
}
@Override
public void setVisibility(int visibility) {
if (getVisibility() != visibility) {
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
if (child instanceof GroupCallGridCell) {
attachRenderer((GroupCallGridCell) child, visibility == View.VISIBLE);
}
}
}
super.setVisibility(visibility);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
itemAnimator.updateBackgroundBeforeAnimation();
}
};
listView.setClipToPadding(false);
listView.setClipChildren(false);
itemAnimator = new GroupCallItemAnimator();
itemAnimator.setTranslationInterpolator(CubicBezierInterpolator.DEFAULT);
itemAnimator.setRemoveDuration(TRANSITION_DURATION);
itemAnimator.setAddDuration(TRANSITION_DURATION);
itemAnimator.setMoveDuration(TRANSITION_DURATION);
itemAnimator.setDelayAnimations(false);
listView.setItemAnimator(itemAnimator);
listView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
if (listView.getChildCount() <= 0 || call == null) {
return;
}
if (!call.loadingMembers && !call.membersLoadEndReached && layoutManager.findLastVisibleItemPosition() > listAdapter.getItemCount() - 5) {
call.loadMembers(false);
}
updateLayout(true);
containerView.invalidate();
}
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
int offset = AndroidUtilities.dp(74);
float top = scrollOffsetY - offset;
if (top + backgroundPaddingTop < ActionBar.getCurrentActionBarHeight() && listView.canScrollVertically(1)) {
View child = listView.getChildAt(0);
RecyclerListView.Holder holder = (RecyclerListView.Holder) listView.findViewHolderForAdapterPosition(0);
if (holder != null && holder.itemView.getTop() > 0) {
listView.smoothScrollBy(0, holder.itemView.getTop());
}
}
} else {
if (recordHintView != null) {
recordHintView.hide();
}
if (reminderHintView != null) {
reminderHintView.hide();
}
}
}
});
listView.setVerticalScrollBarEnabled(false);
listView.setLayoutManager(layoutManager = new FillLastGridLayoutManager(getContext(), isLandscapeMode ? 6 : 2, LinearLayoutManager.VERTICAL, false, 0, listView));
layoutManager.setSpanSizeLookup(spanSizeLookup = new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
int spanSize = isLandscapeMode ? 6 : 2;
if (!isTabletMode && position >= listAdapter.usersVideoGridStartRow && position < listAdapter.usersVideoGridEndRow) {
int spanCount = 1;
int size = listAdapter.usersVideoGridEndRow - listAdapter.usersVideoGridStartRow;
if (position == listAdapter.usersVideoGridEndRow - 1) {
if (isLandscapeMode) {
spanCount = 2;
} else if (size % 2 == 0) {
spanCount = 1;
} else {
spanCount = 2;
}
}
if (isLandscapeMode) {
if (size == 1) {
return 6;
} else if (size == 2) {
return 3;
} else {
return 2;
}
} else {
return spanCount;
}
}
return spanSize;
}
});
listView.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view);
if (position >= 0) {
outRect.setEmpty();
if (position >= listAdapter.usersVideoGridStartRow && position < listAdapter.usersVideoGridEndRow) {
int userPosition = position - listAdapter.usersVideoGridStartRow;
int cellCount = isLandscapeMode ? 6 : 2;
int index = userPosition % cellCount;
if (index == 0) {
outRect.right = AndroidUtilities.dp(2);
} else if (index == cellCount - 1) {
outRect.left = AndroidUtilities.dp(2);
} else {
// outRect.right = AndroidUtilities.dp(0.5f);
outRect.left = AndroidUtilities.dp(1f);
}
}
}
}
});
layoutManager.setBind(false);
containerView.addView(listView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 14, 14, 14, 231));
listView.setAdapter(listAdapter);
listView.setTopBottomSelectorRadius(13);
listView.setSelectorDrawableColor(Theme.getColor(Theme.key_voipgroup_listSelector));
listView.setOnItemClickListener((view, position, x, y) -> {
if (view instanceof GroupCallGridCell) {
fullscreenFor(((GroupCallGridCell) view).getParticipant());
} else if (view instanceof GroupCallUserCell) {
GroupCallUserCell cell = (GroupCallUserCell) view;
showMenuForCell(cell);
} else if (view instanceof GroupCallInvitedCell) {
GroupCallInvitedCell cell = (GroupCallInvitedCell) view;
if (cell.getUser() == null) {
return;
}
parentActivity.switchToAccount(currentAccount, true);
Bundle args = new Bundle();
args.putLong("user_id", cell.getUser().id);
if (cell.hasAvatarSet()) {
args.putBoolean("expandPhoto", true);
}
parentActivity.presentFragment(new ProfileActivity(args));
dismiss();
} else if (position == listAdapter.addMemberRow) {
if (ChatObject.isChannel(currentChat) && !currentChat.megagroup && !TextUtils.isEmpty(currentChat.username)) {
getLink(false);
return;
}
TLRPC.ChatFull chatFull = accountInstance.getMessagesController().getChatFull(currentChat.id);
if (chatFull == null) {
return;
}
enterEventSent = false;
groupVoipInviteAlert = new GroupVoipInviteAlert(getContext(), accountInstance.getCurrentAccount(), currentChat, chatFull, call.participants, call.invitedUsersMap);
groupVoipInviteAlert.setOnDismissListener(dialog -> groupVoipInviteAlert = null);
groupVoipInviteAlert.setDelegate(new GroupVoipInviteAlert.GroupVoipInviteAlertDelegate() {
@Override
public void copyInviteLink() {
getLink(true);
}
@Override
public void inviteUser(long id) {
inviteUserToCall(id, true);
}
@Override
public void needOpenSearch(MotionEvent ev, EditTextBoldCursor editText) {
if (!enterEventSent) {
if (ev.getX() > editText.getLeft() && ev.getX() < editText.getRight()
&& ev.getY() > editText.getTop() && ev.getY() < editText.getBottom()) {
makeFocusable(groupVoipInviteAlert, null, editText, true);
} else {
makeFocusable(groupVoipInviteAlert, null, editText, false);
}
}
}
});
groupVoipInviteAlert.show();
}
});
listView.setOnItemLongClickListener((view, position) -> {
if (isRtmpStream()) {
return false;
}
if (view instanceof GroupCallGridCell) {
return showMenuForCell(view);
}
if (view instanceof GroupCallUserCell) {
updateItems();
GroupCallUserCell cell = (GroupCallUserCell) view;
return cell.clickMuteButton();
}
return false;
});
tabletVideoGridView = new RecyclerListView(context);
containerView.addView(tabletVideoGridView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.LEFT, 14, 14, TABLET_LIST_SIZE + 4, 14));
tabletVideoGridView.setAdapter(tabletGridAdapter = new GroupCallTabletGridAdapter(groupCall, currentAccount, this));
GridLayoutManager gridLayoutManager = new GridLayoutManager(context, 6, LinearLayoutManager.VERTICAL, false);
tabletVideoGridView.setLayoutManager(gridLayoutManager);
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return tabletGridAdapter.getSpanCount(position);
}
});
tabletVideoGridView.setOnItemClickListener((view, position) -> {
GroupCallGridCell cell = (GroupCallGridCell) view;
if (cell.getParticipant() != null) {
fullscreenFor(cell.getParticipant());
}
});
DefaultItemAnimator tabletGridItemAnimator = new DefaultItemAnimator();
tabletGridItemAnimator.setDelayAnimations(false);
tabletGridItemAnimator.setTranslationInterpolator(CubicBezierInterpolator.DEFAULT);
tabletGridItemAnimator.setRemoveDuration(TRANSITION_DURATION);
tabletGridItemAnimator.setAddDuration(TRANSITION_DURATION);
tabletGridItemAnimator.setMoveDuration(TRANSITION_DURATION);
tabletGridItemAnimator = new DefaultItemAnimator() {
@Override
protected void onMoveAnimationUpdate(RecyclerView.ViewHolder holder) {
listView.invalidate();
renderersContainer.invalidate();
containerView.invalidate();
updateLayout(true);
}
};
tabletVideoGridView.setItemAnimator(tabletGridItemAnimator);
tabletVideoGridView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
containerView.invalidate();
}
});
tabletGridAdapter.setVisibility(tabletVideoGridView, false, false);
tabletVideoGridView.setVisibility(View.GONE);
buttonsContainer = new FrameLayout(context) {
AnimatorSet currentButtonsAnimation;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (!isLandscapeMode) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(AndroidUtilities.dp(460), MeasureSpec.getSize(widthMeasureSpec)), MeasureSpec.EXACTLY);
}
for (int i = 0; i < 2; i++) {
if (isLandscapeMode && !isTabletMode) {
muteLabel[i].getLayoutParams().width = (int) (MeasureSpec.getSize(widthMeasureSpec) / 0.68f);
} else {
muteLabel[i].getLayoutParams().width = LayoutHelper.WRAP_CONTENT;
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
int cw = AndroidUtilities.dp(122);
int w = (getMeasuredWidth() - cw) / 2;
int h = getMeasuredHeight();
int buttonsCount = 5;
if (cameraButton.getVisibility() != View.VISIBLE) {
buttonsCount--;
}
if (soundButton.getVisibility() != View.VISIBLE) {
buttonsCount--;
}
if (flipButton.getVisibility() != View.VISIBLE) {
buttonsCount--;
}
if (isLandscapeMode && !isTabletMode) {
int part = getMeasuredHeight() / buttonsCount;
int y, x;
if (soundButton.getVisibility() == View.VISIBLE) {
y = part / 2 - cameraButton.getMeasuredHeight() / 2;
x = (getMeasuredWidth() - cameraButton.getMeasuredWidth()) >> 1;
cameraButton.layout(x, y, x + cameraButton.getMeasuredWidth(), y + cameraButton.getMeasuredHeight());
int partOffset = buttonsCount == 4 ? part : 0;
y = part / 2 + partOffset - soundButton.getMeasuredHeight() / 2;
x = (getMeasuredWidth() - soundButton.getMeasuredWidth()) >> 1;
soundButton.layout(x, y, x + soundButton.getMeasuredWidth(), y + soundButton.getMeasuredHeight());
} else {
y = part / 2 - flipButton.getMeasuredHeight() / 2;
x = (getMeasuredWidth() - flipButton.getMeasuredWidth()) >> 1;
flipButton.layout(x, y, x + flipButton.getMeasuredWidth(), y + flipButton.getMeasuredHeight());
int partOffset = buttonsCount == 4 ? part : 0;
y = part / 2 + partOffset - cameraButton.getMeasuredHeight() / 2;
x = (getMeasuredWidth() - cameraButton.getMeasuredWidth()) >> 1;
cameraButton.layout(x, y, x + cameraButton.getMeasuredWidth(), y + cameraButton.getMeasuredHeight());
}
int partOffset = buttonsCount == 4 ? part * 3 : part * 2;
y = part / 2 + partOffset - leaveButton.getMeasuredHeight() / 2;
x = (getMeasuredWidth() - leaveButton.getMeasuredWidth()) >> 1;
leaveButton.layout(x, y, x + leaveButton.getMeasuredWidth(), y + leaveButton.getMeasuredHeight());
partOffset = buttonsCount == 4 ? part * 2 : part;
y = part / 2 + partOffset - muteButton.getMeasuredWidth() / 2 - AndroidUtilities.dp(4);
x = (getMeasuredWidth() - muteButton.getMeasuredWidth()) >> 1;
if (buttonsCount == 3) {
y -= AndroidUtilities.dp(6);
}
muteButton.layout(x, y, x + muteButton.getMeasuredWidth(), y + muteButton.getMeasuredHeight());
minimizeButton.layout(x, y, x + minimizeButton.getMeasuredWidth(), y + minimizeButton.getMeasuredHeight());
expandButton.layout(x, y, x + expandButton.getMeasuredWidth(), y + expandButton.getMeasuredHeight());
float muteButtonScale = AndroidUtilities.dp(52) / (float) (muteButton.getMeasuredWidth() - AndroidUtilities.dp(8));
muteButton.animate().cancel();
muteButton.setScaleX(muteButtonScale);
muteButton.setScaleY(muteButtonScale);
for (int a = 0; a < 2; a++) {
x = (getMeasuredWidth() - muteLabel[a].getMeasuredWidth()) >> 1;
partOffset = buttonsCount == 4 ? part * 2 : part;
y = part / 2 + partOffset - muteButton.getMeasuredWidth() / 2 - AndroidUtilities.dp(4);
if (buttonsCount == 3) {
y -= AndroidUtilities.dp(6);
}
y += muteButton.getMeasuredWidth() * 0.687f + AndroidUtilities.dp(4);
if (y + muteLabel[a].getMeasuredHeight() > partOffset + part) {
y -= AndroidUtilities.dp(4);
}
muteLabel[a].layout(x, y, x + muteLabel[a].getMeasuredWidth(), y + muteLabel[a].getMeasuredHeight());
muteLabel[a].setScaleX(0.687f);
muteLabel[a].setScaleY(0.687f);
}
} else if (renderersContainer.inFullscreenMode && !isTabletMode) {
int part = getMeasuredWidth() / buttonsCount;
int x, y;
if (soundButton.getVisibility() == View.VISIBLE) {
x = part / 2 - cameraButton.getMeasuredWidth() / 2;
y = getMeasuredHeight() - cameraButton.getMeasuredHeight();
cameraButton.layout(x, y, x + cameraButton.getMeasuredWidth(), y + cameraButton.getMeasuredHeight());
int partOffset = buttonsCount == 4 ? part : 0;
x = part / 2 + partOffset - leaveButton.getMeasuredWidth() / 2;
y = getMeasuredHeight() - soundButton.getMeasuredHeight();
soundButton.layout(x, y, x + soundButton.getMeasuredWidth(), y + soundButton.getMeasuredHeight());
} else {
int partOffset = buttonsCount == 4 ? part : 0;
x = part / 2 + partOffset - cameraButton.getMeasuredWidth() / 2;
y = getMeasuredHeight() - cameraButton.getMeasuredHeight();
cameraButton.layout(x, y, x + cameraButton.getMeasuredWidth(), y + cameraButton.getMeasuredHeight());
x = part / 2 - flipButton.getMeasuredWidth() / 2;
y = getMeasuredHeight() - flipButton.getMeasuredHeight();
flipButton.layout(x, y, x + flipButton.getMeasuredWidth(), y + flipButton.getMeasuredHeight());
}
int partOffset = buttonsCount == 4 ? part * 3 : part * 2;
x = part / 2 + partOffset - leaveButton.getMeasuredWidth() / 2;
y = getMeasuredHeight() - leaveButton.getMeasuredHeight();
leaveButton.layout(x, y, x + leaveButton.getMeasuredWidth(), y + leaveButton.getMeasuredHeight());
partOffset = buttonsCount == 4 ? part * 2 : part;
x = part / 2 + partOffset - muteButton.getMeasuredWidth() / 2;
y = getMeasuredHeight() - leaveButton.getMeasuredHeight() - (muteButton.getMeasuredWidth() - AndroidUtilities.dp(52)) / 2;
muteButton.layout(x, y, x + muteButton.getMeasuredWidth(), y + muteButton.getMeasuredHeight());
minimizeButton.layout(x, y, x + minimizeButton.getMeasuredWidth(), y + minimizeButton.getMeasuredHeight());
expandButton.layout(x, y, x + expandButton.getMeasuredWidth(), y + expandButton.getMeasuredHeight());
float muteButtonScale = AndroidUtilities.dp(52) / (float) (muteButton.getMeasuredWidth() - AndroidUtilities.dp(8));
muteButton.animate().scaleX(muteButtonScale).scaleY(muteButtonScale).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
for (int a = 0; a < 2; a++) {
partOffset = buttonsCount == 4 ? part * 2 : part;
x = partOffset + (part - muteLabel[a].getMeasuredWidth()) / 2;
y = h - AndroidUtilities.dp(27);
muteLabel[a].layout(x, y, x + muteLabel[a].getMeasuredWidth(), y + muteLabel[a].getMeasuredHeight());
muteLabel[a].animate().scaleX(0.687f).scaleY(0.687f).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
} else {
int x, y;
int buttonsYOffset = AndroidUtilities.dp(0);
if (soundButton.getVisibility() == View.VISIBLE) {
if (cameraButton.getVisibility() == View.VISIBLE) {
x = (w - cameraButton.getMeasuredWidth()) / 2;
y = (h - cameraButton.getMeasuredHeight()) / 2;// - AndroidUtilities.dp(32);
cameraButton.layout(x, y, x + cameraButton.getMeasuredWidth(), y + cameraButton.getMeasuredHeight());
x = (w - soundButton.getMeasuredWidth()) / 2;
y = (h - leaveButton.getMeasuredHeight()) / 2;// + AndroidUtilities.dp(32);
soundButton.layout(x, y, x + soundButton.getMeasuredWidth(), y + soundButton.getMeasuredHeight());
} else {
x = (w - soundButton.getMeasuredWidth()) / 2;
y = (h - soundButton.getMeasuredHeight()) / 2;
soundButton.layout(x, y, x + soundButton.getMeasuredWidth(), y + soundButton.getMeasuredHeight());
}
} else {
int offset = flipButton.getVisibility() == View.VISIBLE ? AndroidUtilities.dp(28) : 0;
x = (w - flipButton.getMeasuredWidth()) / 2;
y = (h - flipButton.getMeasuredHeight()) / 2 + buttonsYOffset - offset;
flipButton.layout(x, y, x + flipButton.getMeasuredWidth(), y + flipButton.getMeasuredHeight());
x = (w - cameraButton.getMeasuredWidth()) / 2;
y = (h - cameraButton.getMeasuredHeight()) / 2 + buttonsYOffset + offset;
cameraButton.layout(x, y, x + cameraButton.getMeasuredWidth(), y + cameraButton.getMeasuredHeight());
}
y = (h - leaveButton.getMeasuredHeight()) / 2 + buttonsYOffset;
x = getMeasuredWidth() - w + (w - leaveButton.getMeasuredWidth()) / 2;
leaveButton.layout(x, y, x + leaveButton.getMeasuredWidth(), y + leaveButton.getMeasuredHeight());
x = (getMeasuredWidth() - muteButton.getMeasuredWidth()) / 2;
y = (h - muteButton.getMeasuredHeight()) / 2 - AndroidUtilities.dp(9);
muteButton.layout(x, y, x + muteButton.getMeasuredWidth(), y + muteButton.getMeasuredHeight());
minimizeButton.layout(x, y, x + minimizeButton.getMeasuredWidth(), y + minimizeButton.getMeasuredHeight());
expandButton.layout(x, y, x + expandButton.getMeasuredWidth(), y + expandButton.getMeasuredHeight());
muteButton.animate().setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).scaleX(1f).scaleY(1f).start();
for (int a = 0; a < 2; a++) {
x = (getMeasuredWidth() - muteLabel[a].getMeasuredWidth()) / 2;
y = h - AndroidUtilities.dp(12) - muteLabel[a].getMeasuredHeight();
muteLabel[a].layout(x, y, x + muteLabel[a].getMeasuredWidth(), y + muteLabel[a].getMeasuredHeight());
muteLabel[a].animate().scaleX(1f).scaleY(1f).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
}
if (animateButtonsOnNextLayout) {
AnimatorSet animatorSet = new AnimatorSet();
boolean hasAnimation = false;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
Float fromX = buttonsAnimationParamsX.get(child);
Float fromY = buttonsAnimationParamsY.get(child);
if (fromX != null && fromY != null) {
hasAnimation = true;
animatorSet.playTogether(ObjectAnimator.ofFloat(child, TRANSLATION_X, fromX - child.getLeft(), 0));
animatorSet.playTogether(ObjectAnimator.ofFloat(child, TRANSLATION_Y, fromY - child.getTop(), 0));
}
}
if (hasAnimation) {
if (currentButtonsAnimation != null) {
currentButtonsAnimation.removeAllListeners();
currentButtonsAnimation.cancel();
}
currentButtonsAnimation = animatorSet;
animatorSet.setDuration(TRANSITION_DURATION);
animatorSet.setInterpolator(CubicBezierInterpolator.DEFAULT);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
currentButtonsAnimation = null;
for (int i = 0; i < getChildCount(); i++) {
View child = getChildAt(i);
child.setTranslationX(0);
child.setTranslationY(0);
}
}
});
animatorSet.start();
}
buttonsAnimationParamsX.clear();
buttonsAnimationParamsY.clear();
}
animateButtonsOnNextLayout = false;
}
final OvershootInterpolator overshootInterpolator = new OvershootInterpolator(1.5f);
int currentLightColor;
@SuppressLint("DrawAllocation")
@Override
protected void dispatchDraw(Canvas canvas) {
if (contentFullyOverlayed && useBlur) {
return;
}
int offset = (getMeasuredWidth() - getMeasuredHeight()) / 2;
long newTime = SystemClock.elapsedRealtime();
long dt = newTime - lastUpdateTime;
lastUpdateTime = newTime;
if (dt > 20) {
dt = 17;
}
if (currentState != null) {
currentState.update(0, offset, getMeasuredHeight(), dt, amplitude);
}
tinyWaveDrawable.minRadius = AndroidUtilities.dp(62);
tinyWaveDrawable.maxRadius = AndroidUtilities.dp(62) + AndroidUtilities.dp(20) * BlobDrawable.FORM_SMALL_MAX;
bigWaveDrawable.minRadius = AndroidUtilities.dp(65);
bigWaveDrawable.maxRadius = AndroidUtilities.dp(65) + AndroidUtilities.dp(20) * BlobDrawable.FORM_BIG_MAX;
if (animateToAmplitude != amplitude) {
amplitude += animateAmplitudeDiff * dt;
if (animateAmplitudeDiff > 0) {
if (amplitude > animateToAmplitude) {
amplitude = animateToAmplitude;
}
} else {
if (amplitude < animateToAmplitude) {
amplitude = animateToAmplitude;
}
}
}
boolean canSwitchProgress = true;
if (prevState != null && prevState.currentState == MUTE_BUTTON_STATE_CONNECTING) {
radialProgressView.toCircle(true, true);
if (!radialProgressView.isCircle()) {
canSwitchProgress = false;
}
} else if (prevState != null && currentState != null && currentState.currentState == MUTE_BUTTON_STATE_CONNECTING) {
radialProgressView.toCircle(true, false);
}
if (canSwitchProgress) {
if (switchProgress != 1f) {
if (prevState != null && prevState.currentState == MUTE_BUTTON_STATE_CONNECTING) {
switchProgress += dt / 100f;
} else {
switchProgress += dt / 180f;
}
if (switchProgress >= 1.0f) {
switchProgress = 1f;
prevState = null;
if (currentState != null && currentState.currentState == MUTE_BUTTON_STATE_CONNECTING) {
radialProgressView.toCircle(false, true);
}
}
invalidateColors = true;
}
if (invalidateColors && currentState != null) {
invalidateColors = false;
int lightingColor;
int soundButtonColor;
int soundButtonColorChecked;
if (prevState != null) {
fillColors(prevState.currentState, colorsTmp);
int oldLight = colorsTmp[0];
int oldSound = colorsTmp[1];
int oldSound2 = colorsTmp[2];
fillColors(currentState.currentState, colorsTmp);
lightingColor = ColorUtils.blendARGB(oldLight, colorsTmp[0], switchProgress);
soundButtonColorChecked = ColorUtils.blendARGB(oldSound, colorsTmp[1], switchProgress);
soundButtonColor = ColorUtils.blendARGB(oldSound2, colorsTmp[2], switchProgress);
} else {
fillColors(currentState.currentState, colorsTmp);
lightingColor = colorsTmp[0];
soundButtonColorChecked = colorsTmp[1];
soundButtonColor = colorsTmp[2];
}
if (currentLightColor != lightingColor) {
radialGradient = new RadialGradient(0, 0, AndroidUtilities.dp(100), new int[]{ColorUtils.setAlphaComponent(lightingColor, 60), ColorUtils.setAlphaComponent(lightingColor, 0)}, null, Shader.TileMode.CLAMP);
radialPaint.setShader(radialGradient);
currentLightColor = lightingColor;
}
soundButton.setBackgroundColor(soundButtonColor, soundButtonColorChecked);
cameraButton.setBackgroundColor(soundButtonColor, soundButtonColorChecked);
flipButton.setBackgroundColor(soundButtonColor, soundButtonColorChecked);
}
boolean showWaves = false;
boolean showLighting = false;
if (currentState != null) {
showWaves = currentState.currentState == MUTE_BUTTON_STATE_MUTE || currentState.currentState == MUTE_BUTTON_STATE_UNMUTE || isGradientState(currentState.currentState);
showLighting = currentState.currentState != MUTE_BUTTON_STATE_CONNECTING;
}
if (prevState != null && currentState != null && currentState.currentState == MUTE_BUTTON_STATE_CONNECTING) {
showWavesProgress -= dt / 180f;
if (showWavesProgress < 0f) {
showWavesProgress = 0f;
}
} else {
if (showWaves && showWavesProgress != 1f) {
showWavesProgress += dt / 350f;
if (showWavesProgress > 1f) {
showWavesProgress = 1f;
}
} else if (!showWaves && showWavesProgress != 0) {
showWavesProgress -= dt / 350f;
if (showWavesProgress < 0f) {
showWavesProgress = 0f;
}
}
}
if (showLighting && showLightingProgress != 1f) {
showLightingProgress += dt / 350f;
if (showLightingProgress > 1f) {
showLightingProgress = 1f;
}
} else if (!showLighting && showLightingProgress != 0) {
showLightingProgress -= dt / 350f;
if (showLightingProgress < 0f) {
showLightingProgress = 0f;
}
}
}
float showWavesProgressInterpolated = overshootInterpolator.getInterpolation(GroupCallActivity.this.showWavesProgress);
showWavesProgressInterpolated = 0.4f + 0.6f * showWavesProgressInterpolated;
bigWaveDrawable.update(amplitude, 1f);
tinyWaveDrawable.update(amplitude, 1f);
if (prevState != null && currentState != null && (currentState.currentState == MUTE_BUTTON_STATE_CONNECTING || prevState.currentState == MUTE_BUTTON_STATE_CONNECTING)) {
float progress;
if (currentState.currentState == MUTE_BUTTON_STATE_CONNECTING) {
progress = switchProgress;
paint.setShader(prevState.shader);
} else {
progress = 1f - switchProgress;
paint.setShader(currentState.shader);
}
paintTmp.setColor(AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_listViewBackgroundUnscrolled), Theme.getColor(Theme.key_voipgroup_disabledButton), colorProgress, 1.0f));
int cx = (int) (muteButton.getX() + muteButton.getMeasuredWidth() / 2);
int cy = (int) (muteButton.getY() + muteButton.getMeasuredHeight() / 2);
radialMatrix.setTranslate(cx, cy);
radialGradient.setLocalMatrix(radialMatrix);
paint.setAlpha(76);
if (call != null) {
float radius = AndroidUtilities.dp(52) / 2f;
canvas.drawCircle(leaveButton.getX() + leaveButton.getMeasuredWidth() / 2f, leaveButton.getY() + radius, radius, leaveBackgroundPaint);
}
canvas.save();
canvas.scale(BlobDrawable.GLOBAL_SCALE * muteButton.getScaleX(), BlobDrawable.GLOBAL_SCALE * muteButton.getScaleY(), cx, cy);
canvas.save();
float scale = BlobDrawable.SCALE_BIG_MIN + BlobDrawable.SCALE_BIG * amplitude * 0.5f;
canvas.scale(scale * showLightingProgress, scale * showLightingProgress, cx, cy);
float scaleLight = 0.7f + BlobDrawable.LIGHT_GRADIENT_SIZE;
canvas.save();
canvas.scale(scaleLight, scaleLight, cx, cy);
canvas.drawCircle(cx, cy, AndroidUtilities.dp(160), radialPaint);
canvas.restore();
canvas.restore();
if (call != null) {
canvas.save();
scale = BlobDrawable.SCALE_BIG_MIN + BlobDrawable.SCALE_BIG * amplitude * scheduleButtonsScale;
canvas.scale(scale * showWavesProgressInterpolated, scale * showWavesProgressInterpolated, cx, cy);
bigWaveDrawable.draw(cx, cy, canvas, paint);
canvas.restore();
canvas.save();
scale = BlobDrawable.SCALE_SMALL_MIN + BlobDrawable.SCALE_SMALL * amplitude * scheduleButtonsScale;
canvas.scale(scale * showWavesProgressInterpolated, scale * showWavesProgressInterpolated, cx, cy);
tinyWaveDrawable.draw(cx, cy, canvas, paint);
canvas.restore();
}
paint.setAlpha(255);
if (canSwitchProgress) {
canvas.drawCircle(cx, cy, AndroidUtilities.dp(57), paint);
paint.setColor(Theme.getColor(Theme.key_voipgroup_connectingProgress));
if (progress != 0) {
paint.setAlpha((int) (255 * progress));
paint.setShader(null);
canvas.drawCircle(cx, cy, AndroidUtilities.dp(57), paint);
}
}
canvas.drawCircle(cx, cy, AndroidUtilities.dp(55) * progress, paintTmp);
if (!canSwitchProgress) {
radialProgressView.draw(canvas, cx, cy);
}
canvas.restore();
} else {
for (int i = 0; i < 2; i++) {
float alpha;
float buttonRadius = AndroidUtilities.dp(57);
if (i == 0 && prevState != null) {
paint.setShader(prevState.shader);
alpha = 1f - switchProgress;
if (prevState.currentState == MUTE_BUTTON_STATE_CONNECTING) {
buttonRadius -= alpha * AndroidUtilities.dp(2);
}
} else if (i == 1 && currentState != null) {
paint.setShader(currentState.shader);
alpha = switchProgress;
if (currentState.currentState == MUTE_BUTTON_STATE_CONNECTING) {
buttonRadius -= alpha * AndroidUtilities.dp(2);
}
} else {
continue;
}
if (paint.getShader() == null) {
paint.setColor(AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_listViewBackgroundUnscrolled), Theme.getColor(Theme.key_voipgroup_disabledButton), colorProgress, 1.0f));
}
int cx = (int) (muteButton.getX() + muteButton.getMeasuredWidth() / 2);
int cy = (int) (muteButton.getY() + muteButton.getMeasuredHeight() / 2);
radialMatrix.setTranslate(cx, cy);
radialGradient.setLocalMatrix(radialMatrix);
paint.setAlpha((int) (76 * alpha * switchToButtonProgress));
if (switchToButtonProgress > 0) {
if (i == 1) {
int a = leaveBackgroundPaint.getAlpha();
leaveBackgroundPaint.setAlpha((int) (a * switchToButtonProgress));
float radius = AndroidUtilities.dp(52) / 2f;
canvas.drawCircle(leaveButton.getX() + leaveButton.getMeasuredWidth() / 2, leaveButton.getY() + radius, radius, leaveBackgroundPaint);
leaveBackgroundPaint.setAlpha(a);
}
}
canvas.save();
canvas.scale(BlobDrawable.GLOBAL_SCALE * muteButton.getScaleX(), BlobDrawable.GLOBAL_SCALE * muteButton.getScaleX(), cx, cy);
canvas.save();
float translation;
if (isLandscapeMode) {
translation = 0;
} else {
translation = AndroidUtilities.dp(65) * (1.0f - switchToButtonInt2);
}
// cy += translation;
float scale = BlobDrawable.SCALE_BIG_MIN + BlobDrawable.SCALE_BIG * amplitude * 0.5f;
canvas.scale(scale * showLightingProgress, scale * showLightingProgress, cx, cy);
if (i == 1) {
float scaleLight = 0.7f + BlobDrawable.LIGHT_GRADIENT_SIZE * scheduleButtonsScale;
canvas.save();
canvas.scale(scaleLight, scaleLight, cx, cy);
int a = radialPaint.getAlpha();
radialPaint.setAlpha((int) (a * switchToButtonProgress * (1f - progressToHideUi)));
canvas.drawCircle(cx, cy, AndroidUtilities.dp(160), radialPaint);
radialPaint.setAlpha(a);
canvas.restore();
}
canvas.restore();
if (switchToButtonProgress > 0) {
canvas.save();
scale = BlobDrawable.SCALE_BIG_MIN + BlobDrawable.SCALE_BIG * amplitude * showWavesProgressInterpolated * scheduleButtonsScale;
canvas.scale(scale, scale, cx, cy);
bigWaveDrawable.draw(cx, cy, canvas, paint);
canvas.restore();
canvas.save();
scale = BlobDrawable.SCALE_SMALL_MIN + BlobDrawable.SCALE_SMALL * amplitude * showWavesProgressInterpolated * scheduleButtonsScale;
canvas.scale(scale, scale, cx, cy);
tinyWaveDrawable.draw(cx, cy, canvas, paint);
canvas.restore();
}
if (isLandscapeMode) {
if (i == 0) {
paint.setAlpha((int) (255 * switchToButtonInt2));
} else {
paint.setAlpha((int) (255 * alpha * switchToButtonInt2));
}
} else {
if (i == 0) {
paint.setAlpha(255);
} else {
paint.setAlpha((int) (255 * alpha));
}
}
if (currentButtonsAnimation == null) {
muteButton.setTranslationY(translation);
}
float switchButtonProgrss = isLandscapeMode ? 1f : switchToButtonInt2;
float startX = getMeasuredWidth() / 2 - AndroidUtilities.dp(21);
float startY = AndroidUtilities.dp(24);
float w = (startX + (buttonRadius - startX) * switchButtonProgrss) * scheduleButtonsScale;
float h = (startY + (buttonRadius - startY) * switchButtonProgrss) * scheduleButtonsScale;
rect.set(cx - w, cy - h, cx + w, cy + h);
float rad = AndroidUtilities.dp(4) + (buttonRadius - AndroidUtilities.dp(4)) * switchButtonProgrss;
canvas.drawRoundRect(rect, rad, rad, paint);
if (i == 1 && currentState.currentState == MUTE_BUTTON_STATE_CONNECTING) {
radialProgressView.draw(canvas, cx, cy);
}
canvas.restore();
if (isLandscapeMode && switchToButtonInt2 == 0) {
paint.setAlpha(255);
float x = scheduleButtonTextView.getX() - getX();
float y = scheduleButtonTextView.getY() - getY();
rect.set(x, y, x + scheduleButtonTextView.getMeasuredWidth(), y + scheduleButtonTextView.getMeasuredHeight());
canvas.drawRoundRect(rect, AndroidUtilities.dp(4), AndroidUtilities.dp(4), paint);
}
}
}
super.dispatchDraw(canvas);
if (!renderersContainer.isAnimating()) {
invalidate();
}
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (child == muteButton && child.getScaleX() != 1f) {
canvas.save();
float s = 1f / muteButton.getScaleX();
s = 1f + (s - 1f) * 0.2f;
canvas.scale(s, s, child.getX() + child.getMeasuredWidth() / 2f, child.getY() + child.getMeasuredHeight() / 2f);
boolean b = super.drawChild(canvas, child, drawingTime);
canvas.restore();
return b;
} else {
return super.drawChild(canvas, child, drawingTime);
}
}
};
int color = Theme.getColor(Theme.key_voipgroup_unmuteButton2);
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
radialMatrix = new Matrix();
radialGradient = new RadialGradient(0, 0, AndroidUtilities.dp(160), new int[]{Color.argb(50, r, g, b), Color.argb(0, r, g, b)}, null, Shader.TileMode.CLAMP);
radialPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
radialPaint.setShader(radialGradient);
tinyWaveDrawable = new BlobDrawable(9);
bigWaveDrawable = new BlobDrawable(12);
tinyWaveDrawable.minRadius = AndroidUtilities.dp(62);
tinyWaveDrawable.maxRadius = AndroidUtilities.dp(72);
tinyWaveDrawable.generateBlob();
bigWaveDrawable.minRadius = AndroidUtilities.dp(65);
bigWaveDrawable.maxRadius = AndroidUtilities.dp(75);
bigWaveDrawable.generateBlob();
tinyWaveDrawable.paint.setColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_unmuteButton), (int) (255 * WaveDrawable.CIRCLE_ALPHA_2)));
bigWaveDrawable.paint.setColor(ColorUtils.setAlphaComponent(Theme.getColor(Theme.key_voipgroup_unmuteButton), (int) (255 * WaveDrawable.CIRCLE_ALPHA_1)));
soundButton = new VoIPToggleButton(context);
soundButton.setCheckable(true);
soundButton.setTextSize(12);
buttonsContainer.addView(soundButton, LayoutHelper.createFrame(68, 80));
soundButton.setOnClickListener(v -> {
if (call == null || call.isScheduled() || isRtmpStream()) {
getLink(false);
return;
}
if (VoIPService.getSharedInstance() == null) {
return;
}
VoIPService.getSharedInstance().toggleSpeakerphoneOrShowRouteSheet(getContext(), false);
});
cameraButton = new VoIPToggleButton(context);
cameraButton.setCheckable(true);
cameraButton.setTextSize(12);
cameraButton.showText(false, false);
cameraButton.setCrossOffset(-AndroidUtilities.dpf2(3.5f));
cameraButton.setVisibility(View.GONE);
buttonsContainer.addView(cameraButton, LayoutHelper.createFrame(68, 80));
flipButton = new VoIPToggleButton(context);
flipButton.setCheckable(true);
flipButton.setTextSize(12);
flipButton.showText(false, false);
RLottieImageView flipIconView = new RLottieImageView(context);
flipButton.addView(flipIconView, LayoutHelper.createFrame(32, 32, 0, 18, 10, 18, 0));
flipIcon = new RLottieDrawable(R.raw.camera_flip, "" + R.raw.camera_flip, AndroidUtilities.dp(24), AndroidUtilities.dp(24), true, null);
flipIconView.setAnimation(flipIcon);
flipButton.setOnClickListener(view -> {
renderersContainer.delayHideUi();
VoIPService service = VoIPService.getSharedInstance();
if (service != null && service.getVideoState(false) == Instance.VIDEO_STATE_ACTIVE) {
service.switchCamera();
if (flipIconCurrentEndFrame == 18) {
flipIcon.setCustomEndFrame(flipIconCurrentEndFrame = 39);
flipIcon.start();
} else {
flipIcon.setCurrentFrame(0, false);
flipIcon.setCustomEndFrame(flipIconCurrentEndFrame = 18);
flipIcon.start();
}
for (int i = 0; i < attachedRenderers.size(); i++) {
GroupCallMiniTextureView renderer = attachedRenderers.get(i);
if (renderer.participant.participant.self && !renderer.participant.presentation) {
renderer.startFlipAnimation();
}
}
}
});
flipButton.setVisibility(View.GONE);
buttonsContainer.addView(flipButton, LayoutHelper.createFrame(68, 80));
leaveButton = new VoIPToggleButton(context);
leaveButton.setDrawBackground(false);
leaveButton.setTextSize(12);
leaveButton.setData((call != null && isRtmpStream()) ? R.drawable.msg_voiceclose : R.drawable.calls_decline, 0xffffffff, Theme.getColor(Theme.key_voipgroup_leaveButton), 0.3f, false, LocaleController.getString("VoipGroupLeave", R.string.VoipGroupLeave), false, false);
buttonsContainer.addView(leaveButton, LayoutHelper.createFrame(68, 80));
leaveButton.setOnClickListener(v -> {
renderersContainer.delayHideUi();
if (call == null || call.isScheduled()) {
dismiss();
return;
}
updateItems();
onLeaveClick(context, this::dismiss, false);
});
muteButton = new RLottieImageView(context) {
@Override
public boolean onTouchEvent(MotionEvent event) {
if (isRtmpStream()) {
return super.onTouchEvent(event);
}
//pinnedVideoView.delayHideUi();
if (event.getAction() == MotionEvent.ACTION_DOWN && muteButtonState == MUTE_BUTTON_STATE_UNMUTE && call != null) {
AndroidUtilities.runOnUIThread(pressRunnable, 300);
scheduled = true;
} else if (event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL) {
if (scheduled) {
AndroidUtilities.cancelRunOnUIThread(pressRunnable);
scheduled = false;
} else if (pressed) {
AndroidUtilities.cancelRunOnUIThread(unmuteRunnable);
updateMuteButton(MUTE_BUTTON_STATE_UNMUTE, true);
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().setMicMute(true, true, false);
if (!NekoConfig.disableVibration.Bool()) {
muteButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
}
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
attachedRenderersTmp.get(i).updateAttachState(true);
}
pressed = false;
MotionEvent cancel = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
super.onTouchEvent(cancel);
cancel.recycle();
return true;
}
}
return super.onTouchEvent(event);
}
@Override
public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
super.onInitializeAccessibilityNodeInfo(info);
info.setClassName(Button.class.getName());
info.setEnabled(muteButtonState == MUTE_BUTTON_STATE_UNMUTE || muteButtonState == MUTE_BUTTON_STATE_MUTE);
if (muteButtonState == MUTE_BUTTON_STATE_MUTE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
info.addAction(new AccessibilityNodeInfo.AccessibilityAction(AccessibilityNodeInfo.ACTION_CLICK, LocaleController.getString("VoipMute", R.string.VoipMute)));
}
}
};
muteButton.setAnimation(bigMicDrawable);
muteButton.setScaleType(ImageView.ScaleType.CENTER);
buttonsContainer.addView(muteButton, LayoutHelper.createFrame(122, 122, Gravity.CENTER_HORIZONTAL | Gravity.TOP));
muteButton.setOnClickListener(new View.OnClickListener() {
Runnable finishRunnable = new Runnable() {
@Override
public void run() {
muteButton.setAnimation(bigMicDrawable);
playingHandAnimation = false;
}
};
@SuppressLint("SourceLockedOrientationActivity")
@Override
public void onClick(View v) {
if (call == null || muteButtonState == MUTE_BUTTON_STATE_CONNECTING) {
return;
}
if (isRtmpStream() && !call.isScheduled()) {
boolean fullscreen = renderersContainer != null && renderersContainer.inFullscreenMode && (AndroidUtilities.isTablet() || isLandscapeMode == isRtmpLandscapeMode());
if (fullscreen) {
fullscreenFor(null);
if (isLandscapeMode) {
AndroidUtilities.runOnUIThread(() -> {
wasNotInLayoutFullscreen = null;
wasExpandBigSize = null;
updateMuteButton(muteButtonState, true);
}, 200);
}
parentActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
} else if (!visibleVideoParticipants.isEmpty()) {
ChatObject.VideoParticipant participant = visibleVideoParticipants.get(0);
if (AndroidUtilities.isTablet()) {
fullscreenFor(participant);
} else {
if (isLandscapeMode == isRtmpLandscapeMode()) {
fullscreenFor(participant);
}
if (isRtmpLandscapeMode()) {
parentActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
} else {
parentActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
}
return;
}
if (muteButtonState == MUTE_BUTTON_STATE_START_NOW) {
if (startingGroupCall) {
return;
}
v.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
startingGroupCall = true;
TLRPC.TL_phone_startScheduledGroupCall req = new TLRPC.TL_phone_startScheduledGroupCall();
req.call = call.getInputGroupCall();
accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) {
accountInstance.getMessagesController().processUpdates((TLRPC.Updates) response, false);
}
});
} else if (muteButtonState == MUTE_BUTTON_STATE_CANCEL_REMINDER || muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
if (muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
if (reminderHintView != null) {
reminderHintView.hide();
}
}
TLRPC.TL_phone_toggleGroupCallStartSubscription req = new TLRPC.TL_phone_toggleGroupCallStartSubscription();
req.call = call.getInputGroupCall();
call.call.schedule_start_subscribed = !call.call.schedule_start_subscribed;
req.subscribed = call.call.schedule_start_subscribed;
accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) {
accountInstance.getMessagesController().processUpdates((TLRPC.Updates) response, false);
}
});
updateMuteButton(call.call.schedule_start_subscribed ? MUTE_BUTTON_STATE_CANCEL_REMINDER : MUTE_BUTTON_STATE_SET_REMINDER, true);
} else {
if (VoIPService.getSharedInstance() == null || isStillConnecting()) {
return;
}
if (muteButtonState == MUTE_BUTTON_STATE_MUTED_BY_ADMIN || muteButtonState == MUTE_BUTTON_STATE_RAISED_HAND) {
if (playingHandAnimation) {
return;
}
playingHandAnimation = true;
AndroidUtilities.shakeView(muteLabel[0], 2, 0);
v.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
int num = Utilities.random.nextInt(100);
int endFrame;
int startFrame;
if (num < 32) {
startFrame = 0;
endFrame = 120;
} else if (num < 64) {
startFrame = 120;
endFrame = 240;
} else if (num < 97) {
startFrame = 240;
endFrame = 420;
} else if (num == 98) {
startFrame = 420;
endFrame = 540;
} else {
startFrame = 540;
endFrame = 720;
}
handDrawables.setCustomEndFrame(endFrame);
handDrawables.setOnFinishCallback(finishRunnable, endFrame - 1);
muteButton.setAnimation(handDrawables);
handDrawables.setCurrentFrame(startFrame);
muteButton.playAnimation();
if (muteButtonState == MUTE_BUTTON_STATE_MUTED_BY_ADMIN) {
TLRPC.TL_groupCallParticipant participant = call.participants.get(MessageObject.getPeerId(selfPeer));
TLObject object;
long peerId = MessageObject.getPeerId(participant.peer);
if (DialogObject.isUserDialog(peerId)) {
object = accountInstance.getMessagesController().getUser(peerId);
} else {
object = accountInstance.getMessagesController().getChat(-peerId);
}
VoIPService.getSharedInstance().editCallMember(object, null, null, null, true, null);
updateMuteButton(MUTE_BUTTON_STATE_RAISED_HAND, true);
}
} else if (muteButtonState == MUTE_BUTTON_STATE_UNMUTE) {
updateMuteButton(MUTE_BUTTON_STATE_MUTE, true);
VoIPService.getSharedInstance().setMicMute(false, false, true);
if (!NekoConfig.disableVibration.Bool()) {
muteButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
} else {
updateMuteButton(MUTE_BUTTON_STATE_UNMUTE, true);
VoIPService.getSharedInstance().setMicMute(true, false, true);
if (!NekoConfig.disableVibration.Bool()) {
muteButton.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
}
}
}
}
});
int padding = AndroidUtilities.dp(38);
expandButton = new ImageView(context);
expandButton.setScaleX(0.1f);
expandButton.setScaleY(0.1f);
expandButton.setAlpha(0f);
expandButton.setImageResource(R.drawable.voice_expand);
expandButton.setPadding(padding, padding, padding, padding);
buttonsContainer.addView(expandButton, LayoutHelper.createFrame(122, 122, Gravity.CENTER_HORIZONTAL | Gravity.TOP));
minimizeButton = new ImageView(context);
minimizeButton.setScaleX(0.1f);
minimizeButton.setScaleY(0.1f);
minimizeButton.setAlpha(0f);
minimizeButton.setImageResource(R.drawable.voice_minimize);
minimizeButton.setPadding(padding, padding, padding, padding);
buttonsContainer.addView(minimizeButton, LayoutHelper.createFrame(122, 122, Gravity.CENTER_HORIZONTAL | Gravity.TOP));
if (call != null && isRtmpStream() && !call.isScheduled()) {
expandButton.setAlpha(1f);
expandButton.setScaleX(1f);
expandButton.setScaleY(1f);
muteButton.setAlpha(0f);
}
radialProgressView = new RadialProgressView(context);
radialProgressView.setSize(AndroidUtilities.dp(110));
radialProgressView.setStrokeWidth(4);
radialProgressView.setProgressColor(Theme.getColor(Theme.key_voipgroup_connectingProgress));
for (int a = 0; a < 2; a++) {
muteLabel[a] = new TextView(context);
muteLabel[a].setTextColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
muteLabel[a].setTextSize(TypedValue.COMPLEX_UNIT_DIP, 18);
muteLabel[a].setGravity(Gravity.CENTER_HORIZONTAL);
buttonsContainer.addView(muteLabel[a], LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 0, 0, 26));
}
// buttonsContainer.addView(muteLabelContainer, LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT);
actionBar.setAlpha(0.0f);
actionBar.getBackButton().setScaleX(0.9f);
actionBar.getBackButton().setScaleY(0.9f);
actionBar.getBackButton().setTranslationX(-AndroidUtilities.dp(14));
actionBar.getTitleTextView().setTranslationY(AndroidUtilities.dp(23));
actionBar.getSubtitleTextView().setTranslationY(AndroidUtilities.dp(20));
actionBar.getAdditionalSubtitleTextView().setTranslationY(AndroidUtilities.dp(20));
otherItem = new ActionBarMenuItem(context, null, 0, Theme.getColor(Theme.key_voipgroup_actionBarItems));
otherItem.setLongClickEnabled(false);
otherItem.setIcon(R.drawable.ic_ab_other);
otherItem.setContentDescription(LocaleController.getString("AccDescrMoreOptions", R.string.AccDescrMoreOptions));
otherItem.setSubMenuOpenSide(2);
otherItem.setDelegate(id -> actionBar.getActionBarMenuOnItemClick().onItemClick(id));
otherItem.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_voipgroup_actionBarItemsSelector), 6));
otherItem.setOnClickListener(v -> {
if (call == null || renderersContainer.inFullscreenMode) {
return;
}
if (call.call.join_muted) {
everyoneItem.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
everyoneItem.setChecked(false);
adminItem.setColors(Theme.getColor(Theme.key_voipgroup_checkMenu), Theme.getColor(Theme.key_voipgroup_checkMenu));
adminItem.setChecked(true);
} else {
everyoneItem.setColors(Theme.getColor(Theme.key_voipgroup_checkMenu), Theme.getColor(Theme.key_voipgroup_checkMenu));
everyoneItem.setChecked(true);
adminItem.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
adminItem.setChecked(false);
}
changingPermissions = false;
otherItem.hideSubItem(eveyone_can_speak_item);
otherItem.hideSubItem(admin_can_speak_item);
if (VoIPService.getSharedInstance() != null && (VoIPService.getSharedInstance().hasEarpiece() || VoIPService.getSharedInstance().isBluetoothHeadsetConnected())) {
int rout = VoIPService.getSharedInstance().getCurrentAudioRoute();
if (rout == VoIPService.AUDIO_ROUTE_BLUETOOTH) {
soundItem.setIcon(R.drawable.msg_voice_bluetooth);
soundItem.setSubtext(VoIPService.getSharedInstance().currentBluetoothDeviceName != null ? VoIPService.getSharedInstance().currentBluetoothDeviceName : LocaleController.getString("VoipAudioRoutingBluetooth", R.string.VoipAudioRoutingBluetooth));
} else if (rout == VoIPService.AUDIO_ROUTE_EARPIECE) {
soundItem.setIcon(VoIPService.getSharedInstance().isHeadsetPlugged() ? R.drawable.msg_voice_headphones : R.drawable.msg_voice_phone);
soundItem.setSubtext(VoIPService.getSharedInstance().isHeadsetPlugged() ? LocaleController.getString("VoipAudioRoutingHeadset", R.string.VoipAudioRoutingHeadset) : LocaleController.getString("VoipAudioRoutingPhone", R.string.VoipAudioRoutingPhone));
} else if (rout == VoIPService.AUDIO_ROUTE_SPEAKER) {
AudioManager am = (AudioManager) context.getSystemService(AUDIO_SERVICE);
if (am.isSpeakerphoneOn()) {
soundItem.setIcon(R.drawable.msg_voice_speaker);
soundItem.setSubtext(LocaleController.getString("VoipAudioRoutingSpeaker", R.string.VoipAudioRoutingSpeaker));
} else {
soundItem.setIcon(R.drawable.msg_voice_phone);
soundItem.setSubtext(LocaleController.getString("VoipAudioRoutingPhone", R.string.VoipAudioRoutingPhone));
}
}
}
updateItems();
otherItem.toggleSubMenu();
});
otherItem.setPopupItemsColor(Theme.getColor(Theme.key_voipgroup_actionBarItems), false);
otherItem.setPopupItemsColor(Theme.getColor(Theme.key_voipgroup_actionBarItems), true);
pipItem = new ActionBarMenuItem(context, null, 0, Theme.getColor(Theme.key_voipgroup_actionBarItems));
pipItem.setLongClickEnabled(false);
pipItem.setIcon((call != null && isRtmpStream()) ? R.drawable.ic_goinline : R.drawable.msg_voice_pip);
pipItem.setContentDescription(LocaleController.getString("AccDescrPipMode", R.string.AccDescrPipMode));
pipItem.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_voipgroup_actionBarItemsSelector), 6));
pipItem.setOnClickListener(v -> {
if (isRtmpStream()) {
if (AndroidUtilities.checkInlinePermissions(parentActivity)) {
RTMPStreamPipOverlay.show();
dismiss();
} else {
AlertsCreator.createDrawOverlayPermissionDialog(parentActivity, null).show();
}
return;
}
if (AndroidUtilities.checkInlinePermissions(parentActivity)) {
GroupCallPip.clearForce();
dismiss();
} else {
AlertsCreator.createDrawOverlayGroupCallPermissionDialog(getContext()).show();
}
});
screenShareItem = new ActionBarMenuItem(context, null, 0, Theme.getColor(Theme.key_voipgroup_actionBarItems));
screenShareItem.setLongClickEnabled(false);
screenShareItem.setIcon(R.drawable.msg_screencast);
screenShareItem.setContentDescription(LocaleController.getString("AccDescrPipMode", R.string.AccDescrPipMode));
screenShareItem.setBackgroundDrawable(Theme.createSelectorDrawable(Theme.getColor(Theme.key_voipgroup_actionBarItemsSelector), 6));
screenShareItem.setOnClickListener(v -> {
VoIPService voIPService = VoIPService.getSharedInstance();
if (voIPService == null) {
return;
}
if (voIPService.getVideoState(true) == Instance.VIDEO_STATE_ACTIVE) {
voIPService.stopScreenCapture();
} else {
startScreenCapture();
}
});
titleTextView = new AudioPlayerAlert.ClippingTextViewSwitcher(context) {
@Override
protected TextView createTextView() {
TextView textView = new TextView(context);
textView.setTextColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setGravity(Gravity.LEFT | Gravity.TOP);
textView.setSingleLine(true);
textView.setEllipsize(TextUtils.TruncateAt.END);
textView.setOnClickListener(v -> {
if (call != null && call.recording) {
showRecordHint(textView);
}
});
return textView;
}
};
actionBarBackground = new View(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), ActionBar.getCurrentActionBarHeight());
}
};
actionBarBackground.setAlpha(0.0f);
containerView.addView(actionBarBackground, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
containerView.addView(titleTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.LEFT, 23, 0, 48, 0));
containerView.addView(actionBar, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 0, 0, 0, 0));
menuItemsContainer = new LinearLayout(context);
menuItemsContainer.setOrientation(LinearLayout.HORIZONTAL);
menuItemsContainer.addView(screenShareItem, LayoutHelper.createLinear(48, 48));
menuItemsContainer.addView(pipItem, LayoutHelper.createLinear(48, 48));
menuItemsContainer.addView(otherItem, LayoutHelper.createLinear(48, 48));
containerView.addView(menuItemsContainer, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, 48, Gravity.TOP | Gravity.RIGHT));
actionBarShadow = new View(context);
actionBarShadow.setAlpha(0.0f);
actionBarShadow.setBackgroundColor(Theme.getColor(Theme.key_dialogShadowLine));
containerView.addView(actionBarShadow, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 1));
for (int a = 0; a < 2; a++) {
undoView[a] = new UndoView(context) {
@Override
public void showWithAction(long did, int action, Object infoObject, Object infoObject2, Runnable actionRunnable, Runnable cancelRunnable) {
if (previewDialog != null) {
return;
}
super.showWithAction(did, action, infoObject, infoObject2, actionRunnable, cancelRunnable);
}
};
undoView[a].setAdditionalTranslationY(AndroidUtilities.dp(10));
if (Build.VERSION.SDK_INT >= 21) {
undoView[a].setTranslationZ(AndroidUtilities.dp(5));
}
containerView.addView(undoView[a], LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.LEFT, 8, 0, 8, 8));
}
accountSelectCell = new AccountSelectCell(context, true);
accountSelectCell.setTag(R.id.width_tag, 240);
otherItem.addSubItem(user_item, accountSelectCell, LayoutHelper.WRAP_CONTENT, AndroidUtilities.dp(48));
otherItem.setShowSubmenuByMove(false);
accountSelectCell.setBackground(Theme.createRadSelectorDrawable(Theme.getColor(Theme.key_voipgroup_listSelector), 6, 6));
accountGap = otherItem.addGap(user_item_gap);
everyoneItem = otherItem.addSubItem(eveyone_can_speak_item, 0, LocaleController.getString("VoipGroupAllCanSpeak", R.string.VoipGroupAllCanSpeak), true);
everyoneItem.updateSelectorBackground(true, false);
adminItem = otherItem.addSubItem(admin_can_speak_item, 0, LocaleController.getString("VoipGroupOnlyAdminsCanSpeak", R.string.VoipGroupOnlyAdminsCanSpeak), true);
adminItem.updateSelectorBackground(false, true);
everyoneItem.setCheckColor(Theme.key_voipgroup_checkMenu);
everyoneItem.setColors(Theme.getColor(Theme.key_voipgroup_checkMenu), Theme.getColor(Theme.key_voipgroup_checkMenu));
adminItem.setCheckColor(Theme.key_voipgroup_checkMenu);
adminItem.setColors(Theme.getColor(Theme.key_voipgroup_checkMenu), Theme.getColor(Theme.key_voipgroup_checkMenu));
Paint soundDrawablePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
soundDrawablePaint.setColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
soundDrawablePaint.setStyle(Paint.Style.STROKE);
soundDrawablePaint.setStrokeWidth(AndroidUtilities.dp(1.5f));
soundDrawablePaint.setStrokeCap(Paint.Cap.ROUND);
soundItem = otherItem.addSubItem(sound_item, R.drawable.msg_voice_speaker, null, LocaleController.getString("VoipGroupAudio", R.string.VoipGroupAudio), true, false);
soundItem.setItemHeight(56);
noiseItem = otherItem.addSubItem(noise_item, R.drawable.msg_noise_on, null, LocaleController.getString("VoipNoiseCancellation", R.string.VoipNoiseCancellation), true, false);
noiseItem.setItemHeight(56);
soundItemDivider = otherItem.addDivider(ColorUtils.blendARGB(Theme.getColor(Theme.key_voipgroup_actionBar), Color.BLACK, 0.3f));
((ViewGroup.MarginLayoutParams) soundItemDivider.getLayoutParams()).topMargin = 0;
((ViewGroup.MarginLayoutParams) soundItemDivider.getLayoutParams()).bottomMargin = 0;
editTitleItem = otherItem.addSubItem(edit_item, R.drawable.msg_edit, recordCallDrawable, ChatObject.isChannelOrGiga(currentChat) ? LocaleController.getString("VoipChannelEditTitle", R.string.VoipChannelEditTitle) : LocaleController.getString("VoipGroupEditTitle", R.string.VoipGroupEditTitle), true, false);
permissionItem = otherItem.addSubItem(permission_item, R.drawable.msg_permissions, recordCallDrawable, LocaleController.getString("VoipGroupEditPermissions", R.string.VoipGroupEditPermissions), false, false);
inviteItem = otherItem.addSubItem(share_invite_link_item, R.drawable.msg_link, LocaleController.getString("VoipGroupShareInviteLink", R.string.VoipGroupShareInviteLink));
recordCallDrawable = new RecordCallDrawable();
screenItem = otherItem.addSubItem(screen_capture_item, R.drawable.msg_screencast, LocaleController.getString("VoipChatStartScreenCapture", R.string.VoipChatStartScreenCapture));
recordItem = otherItem.addSubItem(start_record_item, 0, recordCallDrawable, LocaleController.getString("VoipGroupRecordCall", R.string.VoipGroupRecordCall), true, false);
recordCallDrawable.setParentView(recordItem.getImageView());
leaveItem = otherItem.addSubItem(leave_item, R.drawable.msg_endcall, ChatObject.isChannelOrGiga(currentChat) ? LocaleController.getString("VoipChannelEndChat", R.string.VoipChannelEndChat) : LocaleController.getString("VoipGroupEndChat", R.string.VoipGroupEndChat));
otherItem.setPopupItemsSelectorColor(Theme.getColor(Theme.key_voipgroup_listSelector));
otherItem.getPopupLayout().setFitItems(true);
soundItem.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
noiseItem.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
leaveItem.setColors(Theme.getColor(Theme.key_voipgroup_leaveCallMenu), Theme.getColor(Theme.key_voipgroup_leaveCallMenu));
inviteItem.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
editTitleItem.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
permissionItem.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
recordItem.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
screenItem.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
if (call != null) {
initCreatedGroupCall();
}
leaveBackgroundPaint.setColor(Theme.getColor(Theme.key_voipgroup_leaveButton));
updateTitle(false);
actionBar.getTitleTextView().setOnClickListener(v -> {
if (call != null && call.recording) {
showRecordHint(actionBar.getTitleTextView());
}
});
fullscreenUsersListView = new RecyclerListView(context) {
@Override
public boolean drawChild(Canvas canvas, View child, long drawingTime) {
GroupCallFullscreenAdapter.GroupCallUserCell cell = (GroupCallFullscreenAdapter.GroupCallUserCell) child;
if (!renderersContainer.isAnimating() && !fullscreenListItemAnimator.isRunning()) {
cell.setAlpha(1f);
cell.setTranslationX(0);
cell.setTranslationY(0);
}
if (cell.isRemoving(fullscreenUsersListView) && cell.getRenderer() != null) {
return true;
} else if (cell.getTranslationY() != 0 && cell.getRenderer() != null && cell.getRenderer().primaryView != null) {
float listTop = listView.getTop() - getTop();
float listBottom = listTop + listView.getMeasuredHeight();
float progress = renderersContainer.progressToFullscreenMode;
canvas.save();
canvas.clipRect(0, listTop * (1f - progress), getMeasuredWidth(), listBottom * (1f - progress) + getMeasuredHeight() * progress);
boolean r = super.drawChild(canvas, child, drawingTime);
canvas.restore();
return r;
} else {
return super.drawChild(canvas, child, drawingTime);
}
}
};
fullscreenListItemAnimator = new DefaultItemAnimator() {
@Override
protected void onMoveAnimationUpdate(RecyclerView.ViewHolder holder) {
listView.invalidate();
renderersContainer.invalidate();
containerView.invalidate();
updateLayout(true);
}
};
fullscreenUsersListView.setClipToPadding(false);
fullscreenListItemAnimator.setDelayAnimations(false);
fullscreenListItemAnimator.setTranslationInterpolator(CubicBezierInterpolator.DEFAULT);
fullscreenListItemAnimator.setRemoveDuration(TRANSITION_DURATION);
fullscreenListItemAnimator.setAddDuration(TRANSITION_DURATION);
fullscreenListItemAnimator.setMoveDuration(TRANSITION_DURATION);
fullscreenUsersListView.setItemAnimator(fullscreenListItemAnimator);
fullscreenUsersListView.setOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
containerView.invalidate();
renderersContainer.invalidate();
}
});
fullscreenUsersListView.setClipChildren(false);
LinearLayoutManager layoutManager = new LinearLayoutManager(context);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
fullscreenUsersListView.setLayoutManager(layoutManager);
fullscreenUsersListView.setAdapter(fullscreenAdapter = new GroupCallFullscreenAdapter(groupCall, currentAccount, this));
fullscreenAdapter.setVisibility(fullscreenUsersListView, false);
fullscreenUsersListView.setOnItemClickListener((view, position) -> {
// pinnedVideoView.delayHideUi();
GroupCallFullscreenAdapter.GroupCallUserCell userCell = (GroupCallFullscreenAdapter.GroupCallUserCell) view;
if (userCell.getVideoParticipant() == null) {
fullscreenFor(new ChatObject.VideoParticipant(userCell.getParticipant(), false, false));
} else {
fullscreenFor(userCell.getVideoParticipant());
}
});
fullscreenUsersListView.setOnItemLongClickListener((view, position) -> {
if (showMenuForCell(view)) {
listView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
}
return false;
});
fullscreenUsersListView.setVisibility(View.GONE);
fullscreenUsersListView.addItemDecoration(new RecyclerView.ItemDecoration() {
@Override
public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
int p = parent.getChildAdapterPosition(view);
if (!isLandscapeMode) {
outRect.set(AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4), 0);
} else {
outRect.set(0, AndroidUtilities.dp(4), 0, AndroidUtilities.dp(4));
}
}
});
renderersContainer = new GroupCallRenderersContainer(context, listView, fullscreenUsersListView, attachedRenderers, call, this) {
@Override
protected void update() {
super.update();
float finalColorProgress2 = Math.max(colorProgress, renderersContainer == null ? 0 : renderersContainer.progressToFullscreenMode);
navBarColor = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_actionBarUnscrolled), Theme.getColor(Theme.key_voipgroup_actionBar), finalColorProgress2, 1.0f);
containerView.invalidate();
setColorProgress(colorProgress);
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if (child == scrimRenderer) {
return true;
}
return super.drawChild(canvas, child, drawingTime);
}
@Override
protected void onFullScreenModeChanged(boolean startAnimation) {
delayedGroupCallUpdated = startAnimation;
if (isTabletMode) {
if (!startAnimation && renderersContainer.inFullscreenMode) {
tabletGridAdapter.setVisibility(tabletVideoGridView, false, true);
}
} else {
if (startAnimation) {
GroupCallActivity.this.undoView[0].hide(false, 1);
renderersContainer.undoView[0].hide(false, 2);
if (!renderersContainer.inFullscreenMode) {
listView.setVisibility(View.VISIBLE);
actionBar.setVisibility(View.VISIBLE);
}
updateState(true, false);
buttonsContainer.requestLayout();
if (fullscreenUsersListView.getVisibility() != View.VISIBLE) {
fullscreenUsersListView.setVisibility(View.VISIBLE);
fullscreenAdapter.setVisibility(fullscreenUsersListView, true);
fullscreenAdapter.update(false, fullscreenUsersListView);
} else {
fullscreenAdapter.setVisibility(fullscreenUsersListView, true);
applyCallParticipantUpdates(true);
}
} else {
if (!renderersContainer.inFullscreenMode) {
fullscreenUsersListView.setVisibility(View.GONE);
fullscreenAdapter.setVisibility(fullscreenUsersListView, false);
} else {
actionBar.setVisibility(View.GONE);
listView.setVisibility(View.GONE);
}
if (fullscreenUsersListView.getVisibility() == View.VISIBLE) {
for (int i = 0; i < fullscreenUsersListView.getChildCount(); i++) {
View child = fullscreenUsersListView.getChildAt(i);
child.setAlpha(1f);
child.setScaleX(1f);
child.setScaleY(1f);
child.setTranslationX(0);
child.setTranslationY(0);
((GroupCallFullscreenAdapter.GroupCallUserCell) child).setProgressToFullscreen(renderersContainer.progressToFullscreenMode);
}
}
}
buttonsBackgroundGradientView2.setVisibility(startAnimation ? View.VISIBLE : View.GONE);
if (!delayedGroupCallUpdated) {
applyCallParticipantUpdates(true);
}
}
}
ValueAnimator uiVisibilityAnimator;
public void onUiVisibilityChanged() {
if (renderersContainer == null) {
return;
}
boolean uiVisible = renderersContainer.isUiVisible();
if (uiVisibilityAnimator != null) {
uiVisibilityAnimator.removeAllListeners();
uiVisibilityAnimator.cancel();
}
uiVisibilityAnimator = ValueAnimator.ofFloat(progressToHideUi, uiVisible ? 0 : 1f);
uiVisibilityAnimator.addUpdateListener(valueAnimator -> {
progressToHideUi = (float) valueAnimator.getAnimatedValue();
renderersContainer.setProgressToHideUi(progressToHideUi);
fullscreenUsersListView.invalidate();
containerView.invalidate();
buttonsContainer.invalidate();
});
uiVisibilityAnimator.setDuration(TRANSITION_DURATION);
uiVisibilityAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
uiVisibilityAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
invalidateLayoutFullscreen();
}
@Override
public void onAnimationEnd(Animator animation) {
uiVisibilityAnimator = null;
progressToHideUi = uiVisible ? 0 : 1f;
renderersContainer.setProgressToHideUi(progressToHideUi);
fullscreenUsersListView.invalidate();
containerView.invalidate();
buttonsContainer.invalidate();
}
});
uiVisibilityAnimator.start();
}
@Override
protected boolean canHideUI() {
return super.canHideUI() && previewDialog == null;
}
@Override
protected void onBackPressed() {
GroupCallActivity.this.onBackPressed();
}
};
renderersContainer.setClipChildren(false);
fullscreenAdapter.setRenderersPool(attachedRenderers, renderersContainer);
if (tabletVideoGridView != null) {
tabletGridAdapter.setRenderersPool(attachedRenderers, renderersContainer);
}
avatarPagerIndicator = new AvatarPreviewPagerIndicator(context);
avatarsViewPager = new ProfileGalleryView(context, actionBar, listView, avatarPagerIndicator) {
@Override
public void invalidate() {
super.invalidate();
containerView.invalidate();
}
};
avatarsViewPager.setImagesLayerNum(8192);
avatarsViewPager.setInvalidateWithParent(true);
avatarPagerIndicator.setProfileGalleryView(avatarsViewPager);
avatarPreviewContainer = new FrameLayout(context) {
Rect rect = new Rect();
RectF rectF = new RectF();
Path path = new Path();
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int size = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
super.onMeasure(MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(size + getPaddingBottom(), MeasureSpec.EXACTLY));
}
@Override
protected void dispatchDraw(Canvas canvas) {
if (progressToAvatarPreview != 1) {
if (scrimView != null && hasScrimAnchorView) {
canvas.save();
float s = getMeasuredHeight() / (float) scrimView.getAvatarImageView().getMeasuredHeight();
float fromRadius = scrimView.getAvatarImageView().getMeasuredHeight() / 2f * s;
int topRad = (int) ((fromRadius * (1f - progressToAvatarPreview) + (AndroidUtilities.dp(13) * progressToAvatarPreview)));
int bottomRad = (int) (fromRadius * (1f - progressToAvatarPreview));
scrimView.getAvatarWavesDrawable().draw(canvas, scrimView.getAvatarImageView().getMeasuredHeight() / 2, scrimView.getAvatarImageView().getMeasuredHeight() / 2, this);
scrimView.getAvatarImageView().getImageReceiver().setImageCoords(0, 0, getMeasuredWidth(), getMeasuredHeight());
scrimView.getAvatarImageView().setRoundRadius(topRad, topRad, bottomRad, bottomRad);
scrimView.getAvatarImageView().getImageReceiver().draw(canvas);
scrimView.getAvatarImageView().setRoundRadius(scrimView.getAvatarImageView().getMeasuredHeight() / 2);
canvas.restore();
} else if (scrimFullscreenView != null && scrimRenderer == null && previewTextureTransitionEnabled) {
canvas.save();
float s = getMeasuredHeight() / (float) scrimFullscreenView.getAvatarImageView().getMeasuredHeight();
float fromRadius = scrimFullscreenView.getAvatarImageView().getMeasuredHeight() / 2f * s;
int topRad = (int) ((fromRadius * (1f - progressToAvatarPreview) + (AndroidUtilities.dp(13) * progressToAvatarPreview)));
int bottomRad = (int) (fromRadius * (1f - progressToAvatarPreview));
// scrimFullscreenView.getAvatarWavesDrawable().draw(canvas, scrimFullscreenView.getAvatarImageView().getMeasuredHeight() / 2, scrimFullscreenView.getAvatarImageView().getMeasuredHeight() / 2, this);
scrimFullscreenView.getAvatarImageView().getImageReceiver().setImageCoords(0, 0, getMeasuredWidth(), getMeasuredHeight());
scrimFullscreenView.getAvatarImageView().setRoundRadius(topRad, topRad, bottomRad, bottomRad);
scrimFullscreenView.getAvatarImageView().getImageReceiver().draw(canvas);
scrimFullscreenView.getAvatarImageView().setRoundRadius(scrimFullscreenView.getAvatarImageView().getMeasuredHeight() / 2);
canvas.restore();
}
}
avatarsViewPager.setAlpha(progressToAvatarPreview);
path.reset();
rectF.set(0, 0, getMeasuredHeight(), getMeasuredWidth());
path.addRoundRect(rectF, new float[]{AndroidUtilities.dp(13), AndroidUtilities.dp(13), AndroidUtilities.dp(13), AndroidUtilities.dp(13), 0, 0, 0, 0}, Path.Direction.CCW);
canvas.save();
canvas.clipPath(path);
View textureView = avatarsViewPager.findVideoActiveView();
if (textureView != null && scrimRenderer != null && scrimRenderer.isAttached() && !drawingForBlur) {
canvas.save();
rect.setEmpty();
avatarsViewPager.getChildVisibleRect(textureView, rect, null);
int left = rect.left;
if (left < -avatarsViewPager.getMeasuredWidth()) {
left += avatarsViewPager.getMeasuredWidth() * 2;
} else if (left > avatarsViewPager.getMeasuredWidth()) {
left -= avatarsViewPager.getMeasuredWidth() * 2;
}
canvas.translate(left, 0);
scrimRenderer.draw(canvas);
canvas.restore();
}
super.dispatchDraw(canvas);
canvas.restore();
}
@Override
public void invalidate() {
super.invalidate();
containerView.invalidate();
}
};
avatarPreviewContainer.setVisibility(View.GONE);
avatarsViewPager.setVisibility(View.VISIBLE);
avatarsViewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
int realPosition = avatarsViewPager.getRealPosition(position);
avatarPagerIndicator.saveCurrentPageProgress();
avatarPagerIndicator.invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
blurredView = new View(context) {
@Override
public void setAlpha(float alpha) {
if (getAlpha() != alpha) {
super.setAlpha(alpha);
checkContentOverlayed();
}
}
};
containerView.addView(renderersContainer);
renderersContainer.addView(fullscreenUsersListView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 80, Gravity.BOTTOM, 0, 0, 0, 100));
buttonsContainer.setWillNotDraw(false);
buttonsBackgroundGradientView = new View(context);
gradientColors[0] = backgroundColor;
gradientColors[1] = Color.TRANSPARENT;
buttonsBackgroundGradientView.setBackground(buttonsBackgroundGradient = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, gradientColors));
containerView.addView(buttonsBackgroundGradientView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 60, Gravity.LEFT | Gravity.BOTTOM));
buttonsBackgroundGradientView2 = new View(context);
buttonsBackgroundGradientView2.setBackgroundColor(gradientColors[0]);
containerView.addView(buttonsBackgroundGradientView2, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 0, Gravity.LEFT | Gravity.BOTTOM));
containerView.addView(buttonsContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 200, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM));
containerView.addView(blurredView);
avatarPreviewContainer.addView(avatarsViewPager, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
avatarPreviewContainer.addView(avatarPagerIndicator, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 0, 0, 0, 0));
containerView.addView(avatarPreviewContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, 0, 14, 14, 14, 14));
applyCallParticipantUpdates(false);
listAdapter.notifyDataSetChanged();
if (isTabletMode) {
tabletGridAdapter.update(false, tabletVideoGridView);
}
oldCount = listAdapter.getItemCount();
if (schedulePeer != null) {
scheduleInfoTextView = new TextView(context);
scheduleInfoTextView.setGravity(Gravity.CENTER);
scheduleInfoTextView.setTextColor(0xff7B8389);
scheduleInfoTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
if (ChatObject.isChannel(currentChat) && !currentChat.megagroup) {
scheduleInfoTextView.setTag(1);
}
containerView.addView(scheduleInfoTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 21, 0, 21, 100));
final NumberPicker dayPicker = new NumberPicker(context);
dayPicker.setTextColor(0xffffffff);
dayPicker.setSelectorColor(0xff6D89ED);
dayPicker.setTextOffset(AndroidUtilities.dp(10));
dayPicker.setItemCount(5);
final NumberPicker hourPicker = new NumberPicker(context) {
@Override
protected CharSequence getContentDescription(int value) {
return LocaleController.formatPluralString("Hours", value);
}
};
hourPicker.setItemCount(5);
hourPicker.setTextColor(0xffffffff);
hourPicker.setSelectorColor(0xff6D89ED);
hourPicker.setTextOffset(-AndroidUtilities.dp(10));
final NumberPicker minutePicker = new NumberPicker(context) {
@Override
protected CharSequence getContentDescription(int value) {
return LocaleController.formatPluralString("Minutes", value);
}
};
minutePicker.setItemCount(5);
minutePicker.setTextColor(0xffffffff);
minutePicker.setSelectorColor(0xff6D89ED);
minutePicker.setTextOffset(-AndroidUtilities.dp(34));
scheduleButtonTextView = new TextView(context);
scheduleButtonTextView.setLines(1);
scheduleButtonTextView.setSingleLine(true);
scheduleButtonTextView.setEllipsize(TextUtils.TruncateAt.END);
scheduleButtonTextView.setGravity(Gravity.CENTER);
scheduleButtonTextView.setBackground(Theme.createSimpleSelectorRoundRectDrawable(AndroidUtilities.dp(4), 0, 0x3f000000));
scheduleButtonTextView.setTextColor(0xffffffff);
scheduleButtonTextView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
scheduleButtonTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
containerView.addView(scheduleButtonTextView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 21, 0, 21, 20.5f));
scheduleButtonTextView.setOnClickListener(v -> {
scheduleAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
scheduleAnimator.setDuration(600);
scheduleAnimator.addUpdateListener(a -> {
switchToButtonProgress = (float) a.getAnimatedValue();
updateScheduleUI(true);
buttonsContainer.invalidate();
listView.invalidate();
});
scheduleAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
scheduleAnimator = null;
}
});
scheduleAnimator.start();
if (ChatObject.isChannelOrGiga(currentChat)) {
titleTextView.setText(LocaleController.getString("VoipChannelVoiceChat", R.string.VoipChannelVoiceChat), true);
} else {
titleTextView.setText(LocaleController.getString("VoipGroupVoiceChat", R.string.VoipGroupVoiceChat), true);
}
Calendar calendar = Calendar.getInstance();
boolean setSeconds = AlertsCreator.checkScheduleDate(null, null, 7 * 24 * 60 * 60, 3, dayPicker, hourPicker, minutePicker);
calendar.setTimeInMillis(System.currentTimeMillis() + (long) dayPicker.getValue() * 24 * 3600 * 1000);
calendar.set(Calendar.HOUR_OF_DAY, hourPicker.getValue());
calendar.set(Calendar.MINUTE, minutePicker.getValue());
if (setSeconds) {
calendar.set(Calendar.SECOND, 0);
}
scheduleStartAt = (int) (calendar.getTimeInMillis() / 1000);
updateScheduleUI(false);
TLRPC.TL_phone_createGroupCall req = new TLRPC.TL_phone_createGroupCall();
req.peer = MessagesController.getInputPeer(chat);
req.random_id = Utilities.random.nextInt();
req.schedule_date = scheduleStartAt;
req.flags |= 2;
account.getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) {
TLRPC.Updates updates = (TLRPC.Updates) response;
for (int a = 0; a < updates.updates.size(); a++) {
TLRPC.Update update = updates.updates.get(a);
if (update instanceof TLRPC.TL_updateGroupCall) {
TLRPC.TL_updateGroupCall updateGroupCall = (TLRPC.TL_updateGroupCall) update;
AndroidUtilities.runOnUIThread(() -> {
call = new ChatObject.Call();
call.call = new TLRPC.TL_groupCall();
call.call.participants_count = 0;
call.call.version = 1;
call.call.can_start_video = true;
call.call.can_change_join_muted = true;
call.chatId = chat.id;
call.call.schedule_date = scheduleStartAt;
call.call.flags |= 128;
call.currentAccount = accountInstance;
call.setSelfPeer(peer);
call.call.access_hash = updateGroupCall.call.access_hash;
call.call.id = updateGroupCall.call.id;
call.createNoVideoParticipant();
fullscreenAdapter.setGroupCall(call);
renderersContainer.setGroupCall(call);
tabletGridAdapter.setGroupCall(call);
accountInstance.getMessagesController().putGroupCall(call.chatId, call);
});
break;
}
}
accountInstance.getMessagesController().processUpdates(updates, false);
} else {
AndroidUtilities.runOnUIThread(() -> {
accountInstance.getNotificationCenter().postNotificationName(NotificationCenter.needShowAlert, 6, error.text);
dismiss();
});
}
}, ConnectionsManager.RequestFlagFailOnServerErrors);
});
scheduleTimerContainer = new LinearLayout(context) {
boolean ignoreLayout = false;
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
ignoreLayout = true;
int count = 5;
dayPicker.setItemCount(count);
hourPicker.setItemCount(count);
minutePicker.setItemCount(count);
dayPicker.getLayoutParams().height = AndroidUtilities.dp(54) * count;
hourPicker.getLayoutParams().height = AndroidUtilities.dp(54) * count;
minutePicker.getLayoutParams().height = AndroidUtilities.dp(54) * count;
ignoreLayout = false;
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public void requestLayout() {
if (ignoreLayout) {
return;
}
super.requestLayout();
}
};
scheduleTimerContainer.setWeightSum(1.0f);
scheduleTimerContainer.setOrientation(LinearLayout.HORIZONTAL);
containerView.addView(scheduleTimerContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 54 * 5, Gravity.TOP | Gravity.LEFT, 0, 50, 0, 0));
long currentTime = System.currentTimeMillis();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(currentTime);
int currentYear = calendar.get(Calendar.YEAR);
int currentDay = calendar.get(Calendar.DAY_OF_YEAR);
scheduleTimerContainer.addView(dayPicker, LayoutHelper.createLinear(0, 54 * 5, 0.5f));
dayPicker.setMinValue(0);
dayPicker.setMaxValue(365);
dayPicker.setWrapSelectorWheel(false);
dayPicker.setFormatter(value -> {
if (value == 0) {
return LocaleController.getString("MessageScheduleToday", R.string.MessageScheduleToday);
} else {
long date = currentTime + (long) value * 86400000L;
calendar.setTimeInMillis(date);
int year = calendar.get(Calendar.YEAR);
if (year == currentYear) {
return LocaleController.getInstance().formatterScheduleDay.format(date);
} else {
return LocaleController.getInstance().formatterScheduleYear.format(date);
}
}
});
final NumberPicker.OnValueChangeListener onValueChangeListener = (picker, oldVal, newVal) -> {
try {
container.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
} catch (Exception ignore) {
}
AlertsCreator.checkScheduleDate(scheduleButtonTextView, scheduleInfoTextView, 7 * 24 * 60 * 60, 2, dayPicker, hourPicker, minutePicker);
};
dayPicker.setOnValueChangedListener(onValueChangeListener);
hourPicker.setMinValue(0);
hourPicker.setMaxValue(23);
scheduleTimerContainer.addView(hourPicker, LayoutHelper.createLinear(0, 54 * 5, 0.2f));
hourPicker.setFormatter(value -> String.format("%02d", value));
hourPicker.setOnValueChangedListener(onValueChangeListener);
minutePicker.setMinValue(0);
minutePicker.setMaxValue(59);
minutePicker.setValue(0);
minutePicker.setFormatter(value -> String.format("%02d", value));
scheduleTimerContainer.addView(minutePicker, LayoutHelper.createLinear(0, 54 * 5, 0.3f));
minutePicker.setOnValueChangedListener(onValueChangeListener);
calendar.setTimeInMillis(currentTime + 3 * 60 * 60 * 1000);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
int nextDay = calendar.get(Calendar.DAY_OF_YEAR);
int minute = calendar.get(Calendar.MINUTE);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
dayPicker.setValue(currentDay != nextDay ? 1 : 0);
minutePicker.setValue(minute);
hourPicker.setValue(hour);
AlertsCreator.checkScheduleDate(scheduleButtonTextView, scheduleInfoTextView, 7 * 24 * 60 * 60, 2, dayPicker, hourPicker, minutePicker);
}
ViewGroup decorView;
if (Build.VERSION.SDK_INT >= 21) {
decorView = (ViewGroup) getWindow().getDecorView();
} else {
decorView = containerView;
}
pinchToZoomHelper = new PinchToZoomHelper(decorView, containerView) {
@Override
protected void invalidateViews() {
super.invalidateViews();
for (int i = 0; i < avatarsViewPager.getChildCount(); i++) {
avatarsViewPager.getChildAt(i).invalidate();
}
}
@Override
protected void drawOverlays(Canvas canvas, float alpha, float parentOffsetX, float parentOffsetY, float clipTop, float clipBottom) {
if (alpha > 0) {
float x = avatarPreviewContainer.getX() + containerView.getX();
float y = avatarPreviewContainer.getY() + containerView.getY();
AndroidUtilities.rectTmp.set(x, y, x + avatarsViewPager.getMeasuredWidth(), y + avatarsViewPager.getMeasuredHeight());
canvas.saveLayerAlpha(AndroidUtilities.rectTmp, (int) (255 * alpha), Canvas.ALL_SAVE_FLAG);
canvas.translate(x, y);
avatarPreviewContainer.draw(canvas);
canvas.restore();
}
}
};
pinchToZoomHelper.setCallback(new PinchToZoomHelper.Callback() {
@Override
public void onZoomStarted(MessageObject messageObject) {
listView.cancelClickRunnables(true);
pinchToZoomHelper.getPhotoImage().setRoundRadius(AndroidUtilities.dp(13), AndroidUtilities.dp(13), 0, 0);
containerView.invalidate();
}
@Override
public void onZoomFinished(MessageObject messageObject) {
containerView.invalidate();
}
});
avatarsViewPager.setPinchToZoomHelper(pinchToZoomHelper);
cameraButton.setOnClickListener((View) -> {
if (Build.VERSION.SDK_INT >= 23 && parentActivity != null && parentActivity.checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
parentActivity.requestPermissions(new String[]{Manifest.permission.CAMERA}, 104);
return;
}
if (VoIPService.getSharedInstance() == null) {
return;
}
if (VoIPService.getSharedInstance().getVideoState(false) != Instance.VIDEO_STATE_ACTIVE) {
undoView[0].hide(false, 1);
if (previewDialog == null) {
VoIPService voIPService = VoIPService.getSharedInstance();
if (voIPService != null) {
voIPService.createCaptureDevice(false);
}
previewDialog = new PrivateVideoPreviewDialog(context, true, VoIPService.getSharedInstance().getVideoState(true) != Instance.VIDEO_STATE_ACTIVE) {
@Override
public void onDismiss(boolean screencast, boolean apply) {
boolean showMicIcon = previewDialog.micEnabled;
previewDialog = null;
VoIPService service = VoIPService.getSharedInstance();
if (apply) {
if (service != null) {
service.setupCaptureDevice(screencast, showMicIcon);
}
if (screencast) {
if (service != null) {
service.setVideoState(false, Instance.VIDEO_STATE_INACTIVE);
}
}
updateState(true, false);
call.sortParticipants();
applyCallParticipantUpdates(true);
buttonsContainer.requestLayout();
} else {
if (service != null) {
service.setVideoState(false, Instance.VIDEO_STATE_INACTIVE);
}
}
}
};
container.addView(previewDialog);
if (voIPService != null && !voIPService.isFrontFaceCamera()) {
voIPService.switchCamera();
}
}
} else {
VoIPService.getSharedInstance().setVideoState(false, Instance.VIDEO_STATE_INACTIVE);
updateState(true, false);
updateSpeakerPhoneIcon(false);
call.sortParticipants();
applyCallParticipantUpdates(true);
buttonsContainer.requestLayout();
}
});
updateScheduleUI(false);
updateItems();
updateSpeakerPhoneIcon(false);
updateState(false, false);
setColorProgress(0.0f);
updateSubtitle();
}
public LaunchActivity getParentActivity() {
return parentActivity;
}
private void invalidateLayoutFullscreen() {
if (isRtmpStream()) {
boolean notFullscreen = renderersContainer.isUiVisible() || !renderersContainer.inFullscreenMode || isLandscapeMode != isRtmpLandscapeMode() && !AndroidUtilities.isTablet();
if (wasNotInLayoutFullscreen != null && notFullscreen == wasNotInLayoutFullscreen) {
return;
}
int systemUiVisibility = containerView.getSystemUiVisibility();
if (notFullscreen) {
systemUiVisibility &= ~View.SYSTEM_UI_FLAG_FULLSCREEN;
systemUiVisibility &= ~View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setHideSystemVerticalInsets(false);
} else {
setHideSystemVerticalInsets(true);
systemUiVisibility |= View.SYSTEM_UI_FLAG_FULLSCREEN;
systemUiVisibility |= View.SYSTEM_UI_FLAG_HIDE_NAVIGATION;
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
containerView.setSystemUiVisibility(systemUiVisibility);
wasNotInLayoutFullscreen = notFullscreen;
}
}
public LinearLayout getMenuItemsContainer() {
return menuItemsContainer;
}
public void fullscreenFor(ChatObject.VideoParticipant videoParticipant) {
if (videoParticipant == null) {
parentActivity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
VoIPService voIPService = VoIPService.getSharedInstance();
if (voIPService == null || renderersContainer.isAnimating()) {
return;
}
if (isTabletMode) {
if (requestFullscreenListener != null) {
listView.getViewTreeObserver().removeOnPreDrawListener(requestFullscreenListener);
requestFullscreenListener = null;
}
ArrayList<ChatObject.VideoParticipant> activeSinks = new ArrayList<>();
if (videoParticipant == null) {
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
final GroupCallMiniTextureView miniTextureView = attachedRenderersTmp.get(i);
if (miniTextureView.primaryView != null) {
miniTextureView.primaryView.setRenderer(null);
if (miniTextureView.secondaryView != null) {
miniTextureView.secondaryView.setRenderer(null);
}
if (miniTextureView.tabletGridView != null) {
miniTextureView.tabletGridView.setRenderer(null);
}
activeSinks.add(miniTextureView.participant);
miniTextureView.forceDetach(false);
miniTextureView.animate().alpha(0f).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (miniTextureView.getParent() != null) {
containerView.removeView(miniTextureView);
}
}
});
}
}
listViewVideoVisibility = false;
tabletGridAdapter.setVisibility(tabletVideoGridView, true, true);
} else {
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
final GroupCallMiniTextureView miniTextureView = attachedRenderersTmp.get(i);
if (miniTextureView.tabletGridView != null && (miniTextureView.participant == null || !miniTextureView.participant.equals(videoParticipant))) {
activeSinks.add(miniTextureView.participant);
miniTextureView.forceDetach(false);
if (miniTextureView.secondaryView != null) {
miniTextureView.secondaryView.setRenderer(null);
}
if (miniTextureView.primaryView != null) {
miniTextureView.primaryView.setRenderer(null);
}
miniTextureView.animate().alpha(0f).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (miniTextureView.getParent() != null) {
containerView.removeView(miniTextureView);
}
}
});
}
}
listViewVideoVisibility = true;
tabletGridAdapter.setVisibility(tabletVideoGridView, false, false);
if (!activeSinks.isEmpty()) {
AndroidUtilities.runOnUIThread(() -> {
for (int i = 0; i < attachedRenderers.size(); i++) {
if (attachedRenderers.get(i).participant != null) {
activeSinks.remove(attachedRenderers.get(i).participant);
}
}
for (int i = 0; i < activeSinks.size(); i++) {
ChatObject.VideoParticipant participant = activeSinks.get(i);
if (participant.participant.self) {
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().setLocalSink(null, participant.presentation);
}
} else {
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().removeRemoteSink(participant.participant, participant.presentation);
}
}
}
});
}
}
boolean updateScroll = !renderersContainer.inFullscreenMode;
listView.getViewTreeObserver().addOnPreDrawListener(requestFullscreenListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
listView.getViewTreeObserver().removeOnPreDrawListener(this);
requestFullscreenListener = null;
renderersContainer.requestFullscreen(videoParticipant);
if (delayedGroupCallUpdated) {
delayedGroupCallUpdated = false;
applyCallParticipantUpdates(true);
if (updateScroll && videoParticipant != null) {
listView.scrollToPosition(0);
}
delayedGroupCallUpdated = true;
} else {
applyCallParticipantUpdates(true);
}
return false;
}
});
} else {
if (requestFullscreenListener != null) {
listView.getViewTreeObserver().removeOnPreDrawListener(requestFullscreenListener);
requestFullscreenListener = null;
}
if (videoParticipant != null) {
if (fullscreenUsersListView.getVisibility() != View.VISIBLE) {
fullscreenUsersListView.setVisibility(View.VISIBLE);
fullscreenAdapter.update(false, fullscreenUsersListView);
delayedGroupCallUpdated = true;
if (!renderersContainer.inFullscreenMode) {
fullscreenAdapter.scrollTo(videoParticipant, fullscreenUsersListView);
}
listView.getViewTreeObserver().addOnPreDrawListener(requestFullscreenListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
listView.getViewTreeObserver().removeOnPreDrawListener(this);
requestFullscreenListener = null;
renderersContainer.requestFullscreen(videoParticipant);
AndroidUtilities.updateVisibleRows(fullscreenUsersListView);
return false;
}
});
} else {
renderersContainer.requestFullscreen(videoParticipant);
AndroidUtilities.updateVisibleRows(fullscreenUsersListView);
}
} else {
if (listView.getVisibility() != View.VISIBLE) {
listView.setVisibility(View.VISIBLE);
applyCallParticipantUpdates(false);
delayedGroupCallUpdated = true;
listView.getViewTreeObserver().addOnPreDrawListener(requestFullscreenListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
listView.getViewTreeObserver().removeOnPreDrawListener(this);
renderersContainer.requestFullscreen(null);
AndroidUtilities.updateVisibleRows(fullscreenUsersListView);
return false;
}
});
} else {
listView.getViewTreeObserver().addOnPreDrawListener(requestFullscreenListener = new ViewTreeObserver.OnPreDrawListener() {
@Override
public boolean onPreDraw() {
listView.getViewTreeObserver().removeOnPreDrawListener(this);
renderersContainer.requestFullscreen(null);
AndroidUtilities.updateVisibleRows(fullscreenUsersListView);
return false;
}
});
}
}
}
}
public void enableCamera() {
cameraButton.callOnClick();
}
private void checkContentOverlayed() {
boolean overlayed = !avatarPriviewTransitionInProgress && blurredView.getVisibility() == View.VISIBLE && blurredView.getAlpha() == 1f;
if (contentFullyOverlayed != overlayed) {
contentFullyOverlayed = overlayed;
buttonsContainer.invalidate();
containerView.invalidate();
listView.invalidate();
}
}
private void updateScheduleUI(boolean animation) {
if ((scheduleTimerContainer == null || call != null) && scheduleAnimator == null) {
scheduleButtonsScale = 1.0f;
switchToButtonInt2 = 1.0f;
switchToButtonProgress = 1.0f;
if (scheduleTimerContainer == null) {
return;
}
}
if (!animation) {
AndroidUtilities.cancelRunOnUIThread(updateSchedeulRunnable);
updateSchedeulRunnable.run();
if (call == null || call.isScheduled()) {
listView.setVisibility(View.INVISIBLE);
} else {
listView.setVisibility(View.VISIBLE);
}
if (ChatObject.isChannelOrGiga(currentChat)) {
leaveItem.setText(LocaleController.getString("VoipChannelCancelChat", R.string.VoipChannelCancelChat));
} else {
leaveItem.setText(LocaleController.getString("VoipGroupCancelChat", R.string.VoipGroupCancelChat));
}
}
float scheduleButtonsScale2;
float alpha;
if (switchToButtonProgress > 0.6f) {
scheduleButtonsScale = scheduleButtonsScale2 = 1.05f - CubicBezierInterpolator.DEFAULT.getInterpolation((switchToButtonProgress - 0.6f) / 0.4f) * 0.05f;
switchToButtonInt2 = 1.0f;
alpha = 1.0f;
} else {
scheduleButtonsScale = 1.0f + CubicBezierInterpolator.DEFAULT.getInterpolation(switchToButtonProgress / 0.6f) * 0.05f;
switchToButtonInt2 = CubicBezierInterpolator.DEFAULT.getInterpolation(switchToButtonProgress / 0.6f);
scheduleButtonsScale2 = 1.05f * CubicBezierInterpolator.DEFAULT.getInterpolation(switchToButtonProgress / 0.6f);
alpha = switchToButtonProgress / 0.6f;
}
float muteButtonScale = isLandscapeMode ? scheduleButtonsScale2 * AndroidUtilities.dp(52) / (float) (muteButton.getMeasuredWidth() - AndroidUtilities.dp(8)) : scheduleButtonsScale2;
float reversedAlpha = 1.0f - alpha;
leaveButton.setAlpha(alpha);
soundButton.setAlpha(alpha * (soundButton.isEnabled() ? 1.0f : 0.5f));
muteButton.setAlpha(alpha);
scheduleTimerContainer.setAlpha(reversedAlpha);
scheduleStartInTextView.setAlpha(alpha);
scheduleStartAtTextView.setAlpha(alpha);
scheduleTimeTextView.setAlpha(alpha);
muteLabel[0].setAlpha(alpha);
scheduleTimeTextView.setScaleX(scheduleButtonsScale2);
scheduleTimeTextView.setScaleY(scheduleButtonsScale2);
leaveButton.setScaleX(scheduleButtonsScale2);
leaveButton.setScaleY(scheduleButtonsScale2);
soundButton.setScaleX(scheduleButtonsScale2);
soundButton.setScaleY(scheduleButtonsScale2);
muteButton.setScaleX(muteButtonScale);
muteButton.setScaleY(muteButtonScale);
scheduleButtonTextView.setScaleX(reversedAlpha);
scheduleButtonTextView.setScaleY(reversedAlpha);
scheduleButtonTextView.setAlpha(reversedAlpha);
scheduleInfoTextView.setAlpha(reversedAlpha);
cameraButton.setAlpha(alpha);
cameraButton.setScaleY(scheduleButtonsScale2);
cameraButton.setScaleX(scheduleButtonsScale2);
flipButton.setAlpha(alpha);
flipButton.setScaleY(scheduleButtonsScale2);
flipButton.setScaleX(scheduleButtonsScale2);
otherItem.setAlpha(alpha);
int newVisibility = reversedAlpha == 0.0f ? View.INVISIBLE : View.VISIBLE;
if (newVisibility != scheduleTimerContainer.getVisibility()) {
scheduleTimerContainer.setVisibility(newVisibility);
scheduleButtonTextView.setVisibility(newVisibility);
}
}
private void initCreatedGroupCall() {
if (callInitied) {
return;
}
VoIPService service = VoIPService.getSharedInstance();
if (service == null) {
return;
}
callInitied = true;
oldParticipants.addAll(call.visibleParticipants);
oldVideoParticipants.addAll(visibleVideoParticipants);
oldInvited.addAll(call.invitedUsers);
currentCallState = service.getCallState();
if (call == null) {
call = service.groupCall;
fullscreenAdapter.setGroupCall(call);
renderersContainer.setGroupCall(call);
tabletGridAdapter.setGroupCall(call);
}
actionBar.setTitleRightMargin(AndroidUtilities.dp(48) * 2);
call.saveActiveDates();
VoIPService.getSharedInstance().registerStateListener(this);
if (scheduleTimeTextView != null && scheduleTimeTextView.getVisibility() == View.VISIBLE) {
leaveButton.setData(isRtmpStream() ? R.drawable.msg_voiceclose : R.drawable.calls_decline, 0xffffffff, Theme.getColor(Theme.key_voipgroup_leaveButton), 0.3f, false, LocaleController.getString("VoipGroupLeave", R.string.VoipGroupLeave), false, true);
updateSpeakerPhoneIcon(true);
leaveItem.setText(ChatObject.isChannelOrGiga(currentChat) ? LocaleController.getString("VoipChannelEndChat", R.string.VoipChannelEndChat) : LocaleController.getString("VoipGroupEndChat", R.string.VoipGroupEndChat));
listView.setVisibility(View.VISIBLE);
pipItem.setVisibility(View.VISIBLE);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(
ObjectAnimator.ofFloat(listView, View.ALPHA, 0.0f, 1.0f),
ObjectAnimator.ofFloat(listView, View.TRANSLATION_Y, AndroidUtilities.dp(200), 0.0f),
ObjectAnimator.ofFloat(scheduleTimeTextView, View.SCALE_X, 0.0f),
ObjectAnimator.ofFloat(scheduleTimeTextView, View.SCALE_Y, 0.0f),
ObjectAnimator.ofFloat(scheduleTimeTextView, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(scheduleStartInTextView, View.SCALE_X, 0.0f),
ObjectAnimator.ofFloat(scheduleStartInTextView, View.SCALE_Y, 0.0f),
ObjectAnimator.ofFloat(scheduleStartInTextView, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(scheduleStartAtTextView, View.SCALE_X, 0.0f),
ObjectAnimator.ofFloat(scheduleStartAtTextView, View.SCALE_Y, 0.0f),
ObjectAnimator.ofFloat(scheduleStartAtTextView, View.ALPHA, 0.0f),
ObjectAnimator.ofFloat(pipItem, View.SCALE_X, 0.0f, 1.0f),
ObjectAnimator.ofFloat(pipItem, View.SCALE_Y, 0.0f, 1.0f),
ObjectAnimator.ofFloat(pipItem, View.ALPHA, 0.0f, 1.0f));
animatorSet.setInterpolator(CubicBezierInterpolator.EASE_OUT);
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
scheduleTimeTextView.setVisibility(View.INVISIBLE);
scheduleStartAtTextView.setVisibility(View.INVISIBLE);
scheduleStartInTextView.setVisibility(View.INVISIBLE);
}
});
animatorSet.setDuration(300);
animatorSet.start();
}
}
private void updateSubtitle() {
if (actionBar == null || call == null) {
return;
}
SpannableStringBuilder spannableStringBuilder = null;
int speakingIndex = 0;
for (int i = 0; i < call.currentSpeakingPeers.size(); i++) {
long key = call.currentSpeakingPeers.keyAt(i);
TLRPC.TL_groupCallParticipant participant = call.currentSpeakingPeers.get(key);
if (participant.self || renderersContainer.isVisible(participant) || visiblePeerIds.get(key, 0) == 1) {
continue;
}
long peerId = MessageObject.getPeerId(participant.peer);
if (spannableStringBuilder == null) {
spannableStringBuilder = new SpannableStringBuilder();
}
if (speakingIndex < 2) {
TLRPC.User user = peerId > 0 ? MessagesController.getInstance(currentAccount).getUser(peerId) : null;
TLRPC.Chat chat = peerId <= 0 ? MessagesController.getInstance(currentAccount).getChat(peerId) : null;
if (user == null && chat == null) {
continue;
}
if (speakingIndex != 0) {
spannableStringBuilder.append(", ");
}
if (user != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
spannableStringBuilder.append(UserObject.getFirstName(user), new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0);
} else {
spannableStringBuilder.append(UserObject.getFirstName(user));
}
} else {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
spannableStringBuilder.append(chat.title, new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), 0);
} else {
spannableStringBuilder.append(chat.title);
}
}
}
speakingIndex++;
if (speakingIndex == 2) {
break;
}
}
boolean drawStatus;
if (speakingIndex > 0) {
String s = LocaleController.getPluralString("MembersAreSpeakingToast", speakingIndex);
int replaceIndex = s.indexOf("un1");
SpannableStringBuilder spannableStringBuilder1 = new SpannableStringBuilder(s);
spannableStringBuilder1.replace(replaceIndex, replaceIndex + 3, spannableStringBuilder);
actionBar.getAdditionalSubtitleTextView().setText(spannableStringBuilder1);
drawStatus = true;
} else {
drawStatus = false;
}
actionBar.getSubtitleTextView().setText(LocaleController.formatPluralString(isRtmpStream() ? "ViewersWatching" : "Participants", call.call.participants_count + (listAdapter.addSelfToCounter() ? 1 : 0)));
if (drawStatus != drawSpeakingSubtitle) {
drawSpeakingSubtitle = drawStatus;
actionBar.invalidate();
actionBar.getSubtitleTextView().setPivotX(0);
actionBar.getSubtitleTextView().setPivotY(actionBar.getMeasuredHeight() >> 1);
actionBar.getSubtitleTextView().animate().scaleX(drawSpeakingSubtitle ? 0.98f : 1f).scaleY(drawSpeakingSubtitle ? 0.9f : 1f).alpha(drawSpeakingSubtitle ? 0f : 1f).setDuration(150);
AndroidUtilities.updateViewVisibilityAnimated(actionBar.getAdditionalSubtitleTextView(), drawSpeakingSubtitle);
}
}
@Override
public void show() {
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.stopAllHeavyOperations, 2048);
super.show();
if (RTMPStreamPipOverlay.isVisible()) {
RTMPStreamPipOverlay.dismiss();
}
}
@Override
public void dismissInternal() {
if (renderersContainer != null) {
if (requestFullscreenListener != null) {
listView.getViewTreeObserver().removeOnPreDrawListener(requestFullscreenListener);
requestFullscreenListener = null;
}
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
attachedRenderersTmp.get(i).saveThumb();
renderersContainer.removeView(attachedRenderersTmp.get(i));
attachedRenderersTmp.get(i).release();
attachedRenderersTmp.get(i).forceDetach(true);
}
attachedRenderers.clear();
if (renderersContainer.getParent() != null) {
attachedRenderers.clear();
containerView.removeView(renderersContainer);
}
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.startAllHeavyOperations, 2048);
super.dismissInternal();
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().unregisterStateListener(this);
VoIPService.getSharedInstance().setSinks(null, null);
}
if (groupCallInstance == this) {
groupCallInstance = null;
}
groupCallUiVisible = false;
VoIPService.audioLevelsCallback = null;
GroupCallPip.updateVisibility(getContext());
if (call != null) {
call.clearVideFramesInfo();
}
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().clearRemoteSinks();
}
}
public final static float MAX_AMPLITUDE = 8_500f;
private void setAmplitude(double value) {
animateToAmplitude = (float) (Math.min(MAX_AMPLITUDE, value) / MAX_AMPLITUDE);
animateAmplitudeDiff = (animateToAmplitude - amplitude) / (100 + 500.0f * BlobDrawable.AMPLITUDE_SPEED);
}
@Override
public void onStateChanged(int state) {
currentCallState = state;
updateState(isShowing(), false);
}
public UndoView getUndoView() {
if (!isTabletMode && renderersContainer.inFullscreenMode) {
return renderersContainer.getUndoView();
}
if (undoView[0].getVisibility() == View.VISIBLE) {
UndoView old = undoView[0];
undoView[0] = undoView[1];
undoView[1] = old;
old.hide(true, 2);
containerView.removeView(undoView[0]);
containerView.addView(undoView[0]);
}
return undoView[0];
}
private float getColorProgress() {
return colorProgress;
}
private void updateTitle(boolean animated) {
if (call == null) {
if (ChatObject.isChannelOrGiga(currentChat)) {
titleTextView.setText(LocaleController.getString("VoipChannelScheduleVoiceChat", R.string.VoipChannelScheduleVoiceChat), animated);
} else {
titleTextView.setText(LocaleController.getString("VoipGroupScheduleVoiceChat", R.string.VoipGroupScheduleVoiceChat), animated);
}
return;
}
if (!TextUtils.isEmpty(call.call.title)) {
if (!call.call.title.equals(actionBar.getTitle())) {
if (animated) {
actionBar.setTitleAnimated(call.call.title, true, 180);
actionBar.getTitleTextView().setOnClickListener(v -> {
if (call != null && call.recording) {
showRecordHint(actionBar.getTitleTextView());
}
});
} else {
actionBar.setTitle(call.call.title);
}
titleTextView.setText(call.call.title, animated);
}
} else {
if (!currentChat.title.equals(actionBar.getTitle())) {
if (animated) {
actionBar.setTitleAnimated(currentChat.title, true, 180);
actionBar.getTitleTextView().setOnClickListener(v -> {
if (call != null && call.recording) {
showRecordHint(actionBar.getTitleTextView());
}
});
} else {
actionBar.setTitle(currentChat.title);
}
if (ChatObject.isChannelOrGiga(currentChat)) {
titleTextView.setText(LocaleController.getString("VoipChannelVoiceChat", R.string.VoipChannelVoiceChat), animated);
} else {
titleTextView.setText(LocaleController.getString("VoipGroupVoiceChat", R.string.VoipGroupVoiceChat), animated);
}
}
}
SimpleTextView textView = actionBar.getTitleTextView();
if (call.recording) {
if (textView.getRightDrawable() == null) {
textView.setRightDrawable(new SmallRecordCallDrawable(textView));
TextView tv = titleTextView.getTextView();
tv.setCompoundDrawablesWithIntrinsicBounds(null, null, new SmallRecordCallDrawable(tv), null);
tv = titleTextView.getNextTextView();
tv.setCompoundDrawablesWithIntrinsicBounds(null, null, new SmallRecordCallDrawable(tv), null);
}
} else {
if (textView.getRightDrawable() != null) {
textView.setRightDrawable(null);
titleTextView.getTextView().setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
titleTextView.getNextTextView().setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
}
}
}
private void setColorProgress(float progress) {
colorProgress = progress;
float finalColorProgress = colorProgress;
float finalColorProgress2 = Math.max(colorProgress, renderersContainer == null ? 0 : renderersContainer.progressToFullscreenMode);
backgroundColor = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_actionBarUnscrolled), Theme.getColor(Theme.key_voipgroup_actionBar), finalColorProgress, 1.0f);
actionBarBackground.setBackgroundColor(backgroundColor);
otherItem.redrawPopup(0xff232A33);
shadowDrawable.setColorFilter(new PorterDuffColorFilter(backgroundColor, PorterDuff.Mode.MULTIPLY));
navBarColor = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_actionBarUnscrolled), Theme.getColor(Theme.key_voipgroup_actionBar), finalColorProgress2, 1.0f);
int color = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_listViewBackgroundUnscrolled), Theme.getColor(Theme.key_voipgroup_listViewBackground), finalColorProgress, 1.0f);
listViewBackgroundPaint.setColor(color);
listView.setGlowColor(color);
if (muteButtonState == MUTE_BUTTON_STATE_CONNECTING || isGradientState(muteButtonState)) {
muteButton.invalidate();
}
if (buttonsBackgroundGradientView != null) {
gradientColors[0] = backgroundColor;
gradientColors[1] = Color.TRANSPARENT;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.Q) {
buttonsBackgroundGradient.setColors(gradientColors);
} else {
buttonsBackgroundGradientView.setBackground(buttonsBackgroundGradient = new GradientDrawable(GradientDrawable.Orientation.BOTTOM_TOP, gradientColors));
}
buttonsBackgroundGradientView2.setBackgroundColor(gradientColors[0]);
}
color = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_leaveButton), Theme.getColor(Theme.key_voipgroup_leaveButtonScrolled), finalColorProgress, 1.0f);
leaveButton.setBackgroundColor(color, color);
color = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_lastSeenTextUnscrolled), Theme.getColor(Theme.key_voipgroup_lastSeenText), finalColorProgress, 1.0f);
int color2 = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_mutedIconUnscrolled), Theme.getColor(Theme.key_voipgroup_mutedIcon), finalColorProgress, 1.0f);
for (int a = 0, N = listView.getChildCount(); a < N; a++) {
View child = listView.getChildAt(a);
if (child instanceof GroupCallTextCell) {
GroupCallTextCell cell = (GroupCallTextCell) child;
cell.setColors(color2, color);
} else if (child instanceof GroupCallUserCell) {
GroupCallUserCell cell = (GroupCallUserCell) child;
cell.setGrayIconColor(actionBar.getTag() != null ? Theme.key_voipgroup_mutedIcon : Theme.key_voipgroup_mutedIconUnscrolled, color2);
} else if (child instanceof GroupCallInvitedCell) {
GroupCallInvitedCell cell = (GroupCallInvitedCell) child;
cell.setGrayIconColor(actionBar.getTag() != null ? Theme.key_voipgroup_mutedIcon : Theme.key_voipgroup_mutedIconUnscrolled, color2);
}
}
containerView.invalidate();
listView.invalidate();
container.invalidate();
}
private String[] invites = new String[2];
private void getLink(boolean copy) {
TLRPC.Chat newChat = accountInstance.getMessagesController().getChat(currentChat.id);
if (newChat != null && TextUtils.isEmpty(newChat.username)) {
TLRPC.ChatFull chatFull = accountInstance.getMessagesController().getChatFull(currentChat.id);
String url;
if (!TextUtils.isEmpty(currentChat.username)) {
url = accountInstance.getMessagesController().linkPrefix + "/" + currentChat.username;
} else {
url = chatFull != null && chatFull.exported_invite != null ? chatFull.exported_invite.link : null;
}
if (TextUtils.isEmpty(url)) {
TLRPC.TL_messages_exportChatInvite req = new TLRPC.TL_messages_exportChatInvite();
req.peer = MessagesController.getInputPeer(currentChat);
accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_chatInviteExported) {
TLRPC.TL_chatInviteExported invite = (TLRPC.TL_chatInviteExported) response;
if (chatFull != null) {
chatFull.exported_invite = invite;
} else {
openShareAlert(true, null, invite.link, copy);
}
}
}));
} else {
openShareAlert(true, null, url, copy);
}
} else {
if (call == null) {
return;
}
for (int a = 0; a < 2; a++) {
int num = a;
TLRPC.TL_phone_exportGroupCallInvite req = new TLRPC.TL_phone_exportGroupCallInvite();
req.call = call.getInputGroupCall();
req.can_self_unmute = a == 1;
accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_phone_exportedGroupCallInvite) {
TLRPC.TL_phone_exportedGroupCallInvite invite = (TLRPC.TL_phone_exportedGroupCallInvite) response;
invites[num] = invite.link;
} else {
invites[num] = "";
}
for (int b = 0; b < 2; b++) {
if (invites[b] == null) {
return;
} else if (invites[b].length() == 0) {
invites[b] = null;
}
}
if (!copy && ChatObject.canManageCalls(currentChat) && !call.call.join_muted) {
invites[0] = null;
}
if (invites[0] == null && invites[1] == null && !TextUtils.isEmpty(currentChat.username)) {
openShareAlert(true, null, accountInstance.getMessagesController().linkPrefix + "/" + currentChat.username, copy);
} else {
openShareAlert(false, invites[0], invites[1], copy);
}
}));
}
}
}
private void openShareAlert(boolean withMessage, String urlMuted, String urlUnmuted, boolean copy) {
if (isRtmpStream()) {
urlUnmuted = null;
}
if (copy) {
AndroidUtilities.addToClipboard(urlMuted != null ? urlMuted : urlUnmuted);
if (AndroidUtilities.shouldShowClipboardToast()) {
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_LINK_COPIED, null, null, null, null);
}
} else {
boolean keyboardIsOpen = false;
if (parentActivity != null) {
BaseFragment fragment = parentActivity.getActionBarLayout().fragmentsStack.get(parentActivity.getActionBarLayout().fragmentsStack.size() - 1);
if (fragment instanceof ChatActivity) {
keyboardIsOpen = ((ChatActivity) fragment).needEnterText();
anyEnterEventSent = true;
enterEventSent = true;
}
}
if (urlMuted != null && urlUnmuted == null) {
urlUnmuted = urlMuted;
urlMuted = null;
}
String message;
if (urlMuted == null && withMessage) {
if (ChatObject.isChannelOrGiga(currentChat)) {
message = LocaleController.formatString("VoipChannelInviteText", R.string.VoipChannelInviteText, urlUnmuted);
} else {
message = LocaleController.formatString("VoipGroupInviteText", R.string.VoipGroupInviteText, urlUnmuted);
}
} else {
message = urlUnmuted;
}
shareAlert = new ShareAlert(getContext(), null, null, message, urlMuted, false, urlUnmuted, urlMuted, false, true) {
@Override
protected void onSend(LongSparseArray<TLRPC.Dialog> dids, int count) {
if (dids.size() == 1) {
getUndoView().showWithAction(dids.valueAt(0).id, UndoView.ACTION_VOIP_INVITE_LINK_SENT, count);
} else {
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_INVITE_LINK_SENT, count, dids.size(), null, null);
}
}
};
shareAlert.setDelegate(new ShareAlert.ShareAlertDelegate() {
@Override
public boolean didCopy() {
if (AndroidUtilities.shouldShowClipboardToast()) {
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_LINK_COPIED, null, null, null, null);
}
return true;
}
});
shareAlert.setOnDismissListener(dialog -> shareAlert = null);
AndroidUtilities.runOnUIThread(() -> {
if (shareAlert != null) {
shareAlert.show();
}
}, keyboardIsOpen ? 200 : 0);
}
}
private void inviteUserToCall(long id, boolean shouldAdd) {
if (call == null) {
return;
}
TLRPC.User user = accountInstance.getMessagesController().getUser(id);
if (user == null) {
return;
}
final AlertDialog[] progressDialog = new AlertDialog[]{new AlertDialog(getContext(), 3)};
TLRPC.TL_phone_inviteToGroupCall req = new TLRPC.TL_phone_inviteToGroupCall();
req.call = call.getInputGroupCall();
TLRPC.TL_inputUser inputUser = new TLRPC.TL_inputUser();
inputUser.user_id = user.id;
inputUser.access_hash = user.access_hash;
req.users.add(inputUser);
int requestId = accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) {
accountInstance.getMessagesController().processUpdates((TLRPC.Updates) response, false);
AndroidUtilities.runOnUIThread(() -> {
if (call != null && !delayedGroupCallUpdated) {
call.addInvitedUser(id);
applyCallParticipantUpdates(true);
if (groupVoipInviteAlert != null) {
groupVoipInviteAlert.dismiss();
}
try {
progressDialog[0].dismiss();
} catch (Throwable ignore) {
}
progressDialog[0] = null;
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_INVITED, user, currentChat, null, null);
}
});
} else {
AndroidUtilities.runOnUIThread(() -> {
try {
progressDialog[0].dismiss();
} catch (Throwable ignore) {
}
progressDialog[0] = null;
if (shouldAdd && "USER_NOT_PARTICIPANT".equals(error.text)) {
processSelectedOption(null, id, 3);
} else {
BaseFragment fragment = parentActivity.getActionBarLayout().fragmentsStack.get(parentActivity.getActionBarLayout().fragmentsStack.size() - 1);
AlertsCreator.processError(currentAccount, error, fragment, req);
}
});
}
});
if (requestId != 0) {
AndroidUtilities.runOnUIThread(() -> {
if (progressDialog[0] == null) {
return;
}
progressDialog[0].setOnCancelListener(dialog -> accountInstance.getConnectionsManager().cancelRequest(requestId, true));
progressDialog[0].show();
}, 500);
}
}
ObjectAnimator subtitleYAnimator;
ObjectAnimator additionalSubtitleYAnimator;
public void invalidateActionBarAlpha() {
actionBar.setAlpha((actionBar.getTag() != null ? 1f : 0f) * (1f - renderersContainer.progressToFullscreenMode));
}
private void updateLayout(boolean animated) {
float minY = Integer.MAX_VALUE;
int N = listView.getChildCount();
for (int a = 0; a < N; a++) {
View child = listView.getChildAt(a);
if (listView.getChildAdapterPosition(child) >= 0) {
minY = Math.min(minY, child.getTop());
}
}
if (minY < 0 || minY == Integer.MAX_VALUE) {
minY = N != 0 ? 0 : listView.getPaddingTop();
}
boolean show = minY <= ActionBar.getCurrentActionBarHeight() - AndroidUtilities.dp(14);
minY += ActionBar.getCurrentActionBarHeight() + AndroidUtilities.dp(14);
if (show && actionBar.getTag() == null || !show && actionBar.getTag() != null) {
actionBar.setTag(show ? 1 : null);
if (actionBarAnimation != null) {
actionBarAnimation.cancel();
actionBarAnimation = null;
}
setUseLightStatusBar(actionBar.getTag() == null);
actionBar.getBackButton().animate()
.scaleX(show ? 1.0f : 0.9f)
.scaleY(show ? 1.0f : 0.9f)
.translationX(show ? 0.0f : -AndroidUtilities.dp(14))
.setDuration(300)
.setInterpolator(CubicBezierInterpolator.DEFAULT)
.start();
actionBar.getTitleTextView().animate()
.translationY(show ? 0.0f : AndroidUtilities.dp(23))
.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();
if (additionalSubtitleYAnimator != null) {
additionalSubtitleYAnimator.cancel();
}
additionalSubtitleYAnimator = ObjectAnimator.ofFloat(actionBar.getAdditionalSubtitleTextView(), View.TRANSLATION_Y, show ? 0.0f : AndroidUtilities.dp(20));
additionalSubtitleYAnimator.setDuration(300);
additionalSubtitleYAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
additionalSubtitleYAnimator.start();
actionBarAnimation = new AnimatorSet();
actionBarAnimation.setDuration(140);
actionBarAnimation.playTogether(
ObjectAnimator.ofFloat(actionBar, View.ALPHA, show ? 1.0f : 0.0f),
ObjectAnimator.ofFloat(actionBarBackground, View.ALPHA, show ? 1.0f : 0.0f),
ObjectAnimator.ofFloat(actionBarShadow, View.ALPHA, show ? 1.0f : 0.0f));
actionBarAnimation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
actionBarAnimation = null;
}
});
actionBarAnimation.start();
renderersContainer.pipView.setClickable(!show || isLandscapeMode);
}
if (scrollOffsetY != minY) {
setScrollOffsetY(minY);
}
}
public void invalidateScrollOffsetY() {
setScrollOffsetY(scrollOffsetY);
}
private void setScrollOffsetY(float scrollOffsetY) {
this.scrollOffsetY = scrollOffsetY;
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) listView.getLayoutParams();
listView.setTopGlowOffset((int) ((scrollOffsetY) - layoutParams.topMargin));
int offset = AndroidUtilities.dp(74);
float t = scrollOffsetY - offset;
int diff;
if (t + backgroundPaddingTop < ActionBar.getCurrentActionBarHeight() * 2) {
int willMoveUpTo = offset - backgroundPaddingTop - AndroidUtilities.dp(14) + ActionBar.getCurrentActionBarHeight();
float moveProgress = Math.min(1.0f, (ActionBar.getCurrentActionBarHeight() * 2 - t - backgroundPaddingTop) / willMoveUpTo);
diff = (int) (AndroidUtilities.dp(AndroidUtilities.isTablet() ? 17 : 13) * moveProgress);
float newProgress = Math.min(1.0f, moveProgress);
if (Math.abs(newProgress - colorProgress) > 0.0001f) {
setColorProgress(Math.min(1.0f, moveProgress));
}
titleTextView.setScaleX(Math.max(0.9f, 1.0f - 0.1f * moveProgress * 1.2f));
titleTextView.setScaleY(Math.max(0.9f, 1.0f - 0.1f * moveProgress * 1.2f));
titleTextView.setAlpha(Math.max(0.0f, 1.0f - moveProgress * 1.2f) * (1f - renderersContainer.progressToFullscreenMode));
} else {
diff = 0;
titleTextView.setScaleX(1.0f);
titleTextView.setScaleY(1.0f);
titleTextView.setAlpha(1f - renderersContainer.progressToFullscreenMode);
if (colorProgress > 0.0001f) {
setColorProgress(0.0f);
}
}
menuItemsContainer.setTranslationY(Math.max(AndroidUtilities.dp(4), scrollOffsetY - AndroidUtilities.dp(53) - diff));
titleTextView.setTranslationY(Math.max(AndroidUtilities.dp(4), scrollOffsetY - AndroidUtilities.dp(44) - diff));
if (scheduleTimerContainer != null) {
scheduleTimerContainer.setTranslationY(Math.max(AndroidUtilities.dp(4), scrollOffsetY - AndroidUtilities.dp(44) - diff));
}
containerView.invalidate();
}
private void cancelMutePress() {
if (scheduled) {
scheduled = false;
AndroidUtilities.cancelRunOnUIThread(pressRunnable);
}
if (pressed) {
pressed = false;
MotionEvent cancel = MotionEvent.obtain(0, 0, MotionEvent.ACTION_CANCEL, 0, 0, 0);
muteButton.onTouchEvent(cancel);
cancel.recycle();
}
}
private void updateState(boolean animated, boolean selfUpdated) {
if (call == null || call.isScheduled()) {
int state;
if (ChatObject.canManageCalls(currentChat)) {
state = MUTE_BUTTON_STATE_START_NOW;
} else {
state = call.call.schedule_start_subscribed ? MUTE_BUTTON_STATE_CANCEL_REMINDER : MUTE_BUTTON_STATE_SET_REMINDER;
}
updateMuteButton(state, animated);
leaveButton.setData(isRtmpStream() ? R.drawable.msg_voiceclose : R.drawable.calls_decline, 0xffffffff, Theme.getColor(Theme.key_voipgroup_leaveButton), 0.3f, false, LocaleController.getString("Close", R.string.Close), false, false);
updateScheduleUI(false);
return;
}
VoIPService voIPService = VoIPService.getSharedInstance();
if (voIPService == null) {
return;
}
if (!voIPService.isSwitchingStream() && (creatingServiceTime == 0 || Math.abs(SystemClock.elapsedRealtime() - creatingServiceTime) > 3000) && (currentCallState == VoIPService.STATE_WAIT_INIT || currentCallState == VoIPService.STATE_WAIT_INIT_ACK || currentCallState == VoIPService.STATE_CREATING || currentCallState == VoIPService.STATE_RECONNECTING)) {
cancelMutePress();
updateMuteButton(MUTE_BUTTON_STATE_CONNECTING, animated);
} else {
if (userSwitchObject != null) {
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_USER_CHANGED, userSwitchObject, currentChat, null, null);
userSwitchObject = null;
}
TLRPC.TL_groupCallParticipant participant = call.participants.get(MessageObject.getPeerId(selfPeer));
if (!voIPService.micSwitching && participant != null && !participant.can_self_unmute && participant.muted && !ChatObject.canManageCalls(currentChat)) {
cancelMutePress();
if (participant.raise_hand_rating != 0) {
updateMuteButton(MUTE_BUTTON_STATE_RAISED_HAND, animated);
} else {
updateMuteButton(MUTE_BUTTON_STATE_MUTED_BY_ADMIN, animated);
}
voIPService.setMicMute(true, false, false);
} else {
boolean micMuted = voIPService.isMicMute();
if (!voIPService.micSwitching && selfUpdated && participant != null && participant.muted && !micMuted) {
cancelMutePress();
voIPService.setMicMute(true, false, false);
micMuted = true;
}
if (micMuted) {
updateMuteButton(MUTE_BUTTON_STATE_UNMUTE, animated);
} else {
updateMuteButton(MUTE_BUTTON_STATE_MUTE, animated);
}
}
}
boolean outgoingVideoIsActive = VoIPService.getSharedInstance() != null && VoIPService.getSharedInstance().getVideoState(false) == Instance.VIDEO_STATE_ACTIVE;
TLRPC.TL_groupCallParticipant participant = call.participants.get(MessageObject.getPeerId(selfPeer));
boolean mutedByAdmin = participant != null && !participant.can_self_unmute && participant.muted && !ChatObject.canManageCalls(currentChat);
boolean cameraButtonVisible;
boolean flipButtonVisible;
boolean soundButtonVisible;
if ((!mutedByAdmin && call.canRecordVideo() || outgoingVideoIsActive) && !isRtmpStream()) {
cameraButtonVisible = true;
soundButtonVisible = false;
} else {
cameraButtonVisible = false;
soundButtonVisible = true;
}
if (outgoingVideoIsActive) {
if (animated && flipButton.getVisibility() != View.VISIBLE) {
flipButton.setScaleX(0.3f);
flipButton.setScaleY(0.3f);
}
flipButtonVisible = true;
} else {
flipButtonVisible = false;
}
int newButtonsVisibility = (flipButtonVisible ? 1 : 0) + (soundButtonVisible ? 2 : 0) + (cameraButtonVisible ? 4 : 0) + (renderersContainer != null && renderersContainer.inFullscreenMode ? 8 : 0);
if (buttonsVisibility != 0 && buttonsVisibility != newButtonsVisibility && animated) {
for (int i = 0; i < buttonsContainer.getChildCount(); i++) {
View child = buttonsContainer.getChildAt(i);
if (child.getVisibility() == View.VISIBLE) {
buttonsAnimationParamsX.put(child, child.getX());
buttonsAnimationParamsY.put(child, child.getY());
}
}
animateButtonsOnNextLayout = true;
}
boolean soundButtonChanged = (buttonsVisibility | 2) != (newButtonsVisibility | 2);
buttonsVisibility = newButtonsVisibility;
if (cameraButtonVisible) {
cameraButton.setData(R.drawable.calls_video, Color.WHITE, 0, 1f, true, LocaleController.getString("VoipCamera", R.string.VoipCamera), !outgoingVideoIsActive, animated);
cameraButton.setChecked(true, false);
} else {
cameraButton.setVisibility(View.GONE);
}
if (flipButtonVisible) {
flipButton.setData(0, Color.WHITE, 0, 1f, true, LocaleController.getString("VoipFlip", R.string.VoipFlip), false, false);
flipButton.setChecked(true, false);
} else {
flipButton.setVisibility(View.GONE);
}
boolean soundButtonWasVisible = soundButton.getVisibility() == View.VISIBLE;
soundButton.setVisibility(soundButtonVisible ? View.VISIBLE : View.GONE);
if (soundButtonChanged && soundButtonVisible) {
updateSpeakerPhoneIcon(false);
}
if (soundButtonChanged) {
float s = soundButtonVisible ? 1f : 0.3f;
if (!animated) {
soundButton.animate().cancel();
soundButton.setScaleX(s);
soundButton.setScaleY(s);
} else {
if (soundButtonVisible && !soundButtonWasVisible) {
soundButton.setScaleX(0.3f);
soundButton.setScaleY(0.3f);
}
soundButton.animate().scaleX(s).scaleY(s).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
}
float cameraScale;
if (cameraButton.getVisibility() == View.VISIBLE) {
cameraScale = 1f;
cameraButton.showText(cameraScale == 1f, animated);
} else {
cameraScale = 0.3f;
}
if (this.cameraButtonScale != cameraScale) {
cameraButtonScale = cameraScale;
if (!animated) {
cameraButton.animate().cancel();
cameraButton.setScaleX(cameraScale);
cameraButton.setScaleY(cameraScale);
} else {
cameraButton.animate().scaleX(cameraScale).scaleY(cameraScale).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
}
float flipButtonScale;
if (isTabletMode) {
flipButtonScale = 0.8f;
} else {
flipButtonScale = isLandscapeMode || (renderersContainer != null && renderersContainer.inFullscreenMode) ? 1f : 0.8f;
}
if (!outgoingVideoIsActive) {
flipButtonScale = 0.3f;
}
if (!animated) {
flipButton.animate().cancel();
flipButton.setScaleX(flipButtonScale);
flipButton.setScaleY(flipButtonScale);
} else {
flipButton.animate().scaleX(flipButtonScale).scaleY(flipButtonScale).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
flipButton.showText(flipButtonScale == 1f, animated);
float soundButtonScale = outgoingVideoIsActive ? 0.3f : 1f;
if (this.soundButtonScale != soundButtonScale) {
this.soundButtonScale = soundButtonScale;
if (!animated) {
soundButton.animate().cancel();
soundButton.setScaleX(soundButtonScale);
soundButton.setScaleY(soundButtonScale);
} else {
soundButton.animate().scaleX(soundButtonScale).scaleY(soundButtonScale).setDuration(TRANSITION_DURATION).setInterpolator(CubicBezierInterpolator.DEFAULT).start();
}
}
}
@Override
public void onAudioSettingsChanged() {
updateSpeakerPhoneIcon(true);
if (VoIPService.getSharedInstance() == null || VoIPService.getSharedInstance().isMicMute()) {
setMicAmplitude(0f);
}
if (listView.getVisibility() == View.VISIBLE) {
AndroidUtilities.updateVisibleRows(listView);
}
if (fullscreenUsersListView.getVisibility() == View.VISIBLE) {
AndroidUtilities.updateVisibleRows(fullscreenUsersListView);
}
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
attachedRenderersTmp.get(i).updateAttachState(true);
}
}
private void updateSpeakerPhoneIcon(boolean animated) {
if (soundButton == null || soundButton.getVisibility() != View.VISIBLE) {
return;
}
VoIPService service = VoIPService.getSharedInstance();
if (service == null || isRtmpStream()) {
soundButton.setData(R.drawable.msg_voiceshare, Color.WHITE, 0, 0.3f, true, LocaleController.getString("VoipChatShare", R.string.VoipChatShare), false, animated);
soundButton.setEnabled(!TextUtils.isEmpty(currentChat.username) || ChatObject.hasAdminRights(currentChat) && ChatObject.canAddUsers(currentChat), false);
soundButton.setChecked(true, false);
return;
} else {
soundButton.setEnabled(true, animated);
}
boolean bluetooth = service.isBluetoothOn() || service.isBluetoothWillOn();
boolean checked = !bluetooth && service.isSpeakerphoneOn();
if (bluetooth) {
soundButton.setData(R.drawable.calls_bluetooth, Color.WHITE, 0, 0.1f, true, LocaleController.getString("VoipAudioRoutingBluetooth", R.string.VoipAudioRoutingBluetooth), false, animated);
} else if (checked) {
soundButton.setData(R.drawable.calls_speaker, Color.WHITE, 0, 0.3f, true, LocaleController.getString("VoipSpeaker", R.string.VoipSpeaker), false, animated);
} else {
if (service.isHeadsetPlugged()) {
soundButton.setData(R.drawable.calls_headphones, Color.WHITE, 0, 0.1f, true, LocaleController.getString("VoipAudioRoutingHeadset", R.string.VoipAudioRoutingHeadset), false, animated);
} else {
soundButton.setData(R.drawable.calls_speaker, Color.WHITE, 0, 0.1f, true, LocaleController.getString("VoipSpeaker", R.string.VoipSpeaker), false, animated);
}
}
soundButton.setChecked(checked, animated);
}
private void updateMuteButton(int state, boolean animated) {
boolean fullscreen = renderersContainer != null && renderersContainer.inFullscreenMode && (AndroidUtilities.isTablet() || isLandscapeMode == isRtmpLandscapeMode());
if (!isRtmpStream() && muteButtonState == state && animated) {
return;
}
if (muteButtonAnimator != null) {
muteButtonAnimator.cancel();
muteButtonAnimator = null;
}
if (expandAnimator != null) {
expandAnimator.cancel();
expandAnimator = null;
}
String newText;
String newSubtext;
boolean changed;
boolean mutedByAdmin = false;
if (state == MUTE_BUTTON_STATE_CANCEL_REMINDER) {
newText = LocaleController.getString("VoipGroupCancelReminder", R.string.VoipGroupCancelReminder);
newSubtext = "";
changed = bigMicDrawable.setCustomEndFrame(202);
} else if (state == MUTE_BUTTON_STATE_SET_REMINDER) {
newText = LocaleController.getString("VoipGroupSetReminder", R.string.VoipGroupSetReminder);
newSubtext = "";
changed = bigMicDrawable.setCustomEndFrame(344);
} else if (state == MUTE_BUTTON_STATE_START_NOW) {
newText = LocaleController.getString("VoipGroupStartNow", R.string.VoipGroupStartNow);
newSubtext = "";
changed = bigMicDrawable.setCustomEndFrame(377);
} else if (state == MUTE_BUTTON_STATE_UNMUTE) {
newText = LocaleController.getString("VoipGroupUnmute", R.string.VoipGroupUnmute);
newSubtext = LocaleController.getString("VoipHoldAndTalk", R.string.VoipHoldAndTalk);
if (muteButtonState == MUTE_BUTTON_STATE_CONNECTING) {
int endFrame = bigMicDrawable.getCustomEndFrame();
if (endFrame == 136 || endFrame == 173 || endFrame == 274 || endFrame == 311) {
changed = bigMicDrawable.setCustomEndFrame(99);
} else {
changed = false;
}
} else if (muteButtonState == MUTE_BUTTON_STATE_START_NOW) {
changed = bigMicDrawable.setCustomEndFrame(404);
} else if (muteButtonState == MUTE_BUTTON_STATE_CANCEL_REMINDER) {
changed = bigMicDrawable.setCustomEndFrame(376);
} else if (muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
changed = bigMicDrawable.setCustomEndFrame(237);
} else if (muteButtonState == MUTE_BUTTON_STATE_MUTED_BY_ADMIN) {
changed = bigMicDrawable.setCustomEndFrame(36);
} else {
changed = bigMicDrawable.setCustomEndFrame(99);
}
} else if (state == MUTE_BUTTON_STATE_MUTE) {
newText = LocaleController.getString("VoipTapToMute", R.string.VoipTapToMute);
newSubtext = "";
changed = bigMicDrawable.setCustomEndFrame(muteButtonState == MUTE_BUTTON_STATE_RAISED_HAND ? 99 : 69);
} else if (state == MUTE_BUTTON_STATE_RAISED_HAND) {
newText = LocaleController.getString("VoipMutedTapedForSpeak", R.string.VoipMutedTapedForSpeak);
newSubtext = LocaleController.getString("VoipMutedTapedForSpeakInfo", R.string.VoipMutedTapedForSpeakInfo);
changed = bigMicDrawable.setCustomEndFrame(136);
} else {
TLRPC.TL_groupCallParticipant participant = call.participants.get(MessageObject.getPeerId(selfPeer));
if (mutedByAdmin = participant != null && !participant.can_self_unmute && participant.muted && !ChatObject.canManageCalls(currentChat)) {
if (muteButtonState == MUTE_BUTTON_STATE_CANCEL_REMINDER) {
changed = bigMicDrawable.setCustomEndFrame(311);
} else if (muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
changed = bigMicDrawable.setCustomEndFrame(274);
} else if (muteButtonState == MUTE_BUTTON_STATE_MUTE) {
changed = bigMicDrawable.setCustomEndFrame(173);
} else {
changed = bigMicDrawable.setCustomEndFrame(136);
}
} else {
if (muteButtonState == MUTE_BUTTON_STATE_START_NOW) {
changed = bigMicDrawable.setCustomEndFrame(404);
} else if (muteButtonState == MUTE_BUTTON_STATE_CANCEL_REMINDER) {
changed = bigMicDrawable.setCustomEndFrame(376);
} else if (muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
changed = bigMicDrawable.setCustomEndFrame(237);
} else if (muteButtonState == MUTE_BUTTON_STATE_MUTED_BY_ADMIN || muteButtonState == MUTE_BUTTON_STATE_RAISED_HAND) {
changed = bigMicDrawable.setCustomEndFrame(36);
} else {
changed = bigMicDrawable.setCustomEndFrame(99);
}
}
if (state == MUTE_BUTTON_STATE_CONNECTING) {
newText = LocaleController.getString("Connecting", R.string.Connecting);
newSubtext = "";
} else {
newText = LocaleController.getString("VoipMutedByAdmin", R.string.VoipMutedByAdmin);
newSubtext = LocaleController.getString("VoipMutedTapForSpeak", R.string.VoipMutedTapForSpeak);
}
}
if (isRtmpStream() && state != MUTE_BUTTON_STATE_CONNECTING && !call.isScheduled()) {
newText = LocaleController.getString(fullscreen ? R.string.VoipGroupMinimizeStream : R.string.VoipGroupExpandStream);
newSubtext = "";
changed = animatingToFullscreenExpand != fullscreen;
animatingToFullscreenExpand = fullscreen;
}
final String contentDescription;
if (!TextUtils.isEmpty(newSubtext)) {
contentDescription = newText + " " + newSubtext;
} else {
contentDescription = newText;
}
muteButton.setContentDescription(contentDescription);
if (animated) {
if (changed) {
if (state == MUTE_BUTTON_STATE_START_NOW) {
bigMicDrawable.setCurrentFrame(376);
} else if (state == MUTE_BUTTON_STATE_CANCEL_REMINDER) {
bigMicDrawable.setCurrentFrame(173);
} else if (state == MUTE_BUTTON_STATE_SET_REMINDER) {
bigMicDrawable.setCurrentFrame(311);
} else if (state == MUTE_BUTTON_STATE_UNMUTE) {
if (muteButtonState == MUTE_BUTTON_STATE_START_NOW) {
bigMicDrawable.setCurrentFrame(376);
} else if (muteButtonState == MUTE_BUTTON_STATE_CANCEL_REMINDER) {
bigMicDrawable.setCurrentFrame(344);
} else if (muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
bigMicDrawable.setCurrentFrame(202);
} else if (muteButtonState == MUTE_BUTTON_STATE_MUTED_BY_ADMIN) {
bigMicDrawable.setCurrentFrame(0);
} else {
bigMicDrawable.setCurrentFrame(69);
}
} else if (state == MUTE_BUTTON_STATE_MUTE) {
bigMicDrawable.setCurrentFrame(muteButtonState == MUTE_BUTTON_STATE_RAISED_HAND ? 69 : 36);
} else if (state == MUTE_BUTTON_STATE_RAISED_HAND) {
bigMicDrawable.setCurrentFrame(99);
} else {
if (mutedByAdmin) {
if (muteButtonState == MUTE_BUTTON_STATE_CANCEL_REMINDER) {
bigMicDrawable.setCurrentFrame(274);
} else if (muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
bigMicDrawable.setCurrentFrame(237);
} else if (muteButtonState == MUTE_BUTTON_STATE_MUTE) {
bigMicDrawable.setCurrentFrame(136);
} else {
bigMicDrawable.setCurrentFrame(99);
}
} else {
if (muteButtonState == MUTE_BUTTON_STATE_START_NOW) {
bigMicDrawable.setCurrentFrame(376);
} else if (muteButtonState == MUTE_BUTTON_STATE_CANCEL_REMINDER) {
bigMicDrawable.setCurrentFrame(344);
} else if (muteButtonState == MUTE_BUTTON_STATE_SET_REMINDER) {
bigMicDrawable.setCurrentFrame(202);
} else if (muteButtonState == MUTE_BUTTON_STATE_MUTED_BY_ADMIN || muteButtonState == MUTE_BUTTON_STATE_RAISED_HAND) {
bigMicDrawable.setCurrentFrame(0);
} else {
bigMicDrawable.setCurrentFrame(69);
}
}
}
}
muteButton.playAnimation();
muteLabel[1].setVisibility(View.VISIBLE);
muteLabel[1].setAlpha(0.0f);
muteLabel[1].setTranslationY(-AndroidUtilities.dp(5));
muteLabel[1].setText(newText);
if (isRtmpStream() && !call.isScheduled()) {
muteButton.setAlpha(0f);
boolean isExpanded = renderersContainer.inFullscreenMode && (AndroidUtilities.isTablet() || isLandscapeMode == isRtmpLandscapeMode());
View hideView = isExpanded ? expandButton : minimizeButton;
View showView = isExpanded ? minimizeButton : expandButton;
float muteButtonScale = AndroidUtilities.dp(52) / (float) (muteButton.getMeasuredWidth() - AndroidUtilities.dp(8));
boolean bigSize = AndroidUtilities.isTablet() ? !renderersContainer.inFullscreenMode : !renderersContainer.inFullscreenMode && !isLandscapeMode;
boolean changedSize = wasExpandBigSize == null || bigSize != wasExpandBigSize;
wasExpandBigSize = bigSize;
if (expandSizeAnimator != null) {
expandSizeAnimator.cancel();
expandSizeAnimator = null;
}
if (changedSize) {
expandSizeAnimator = ValueAnimator.ofFloat(0, 1);
expandSizeAnimator.addUpdateListener(animation -> {
float multiplier = isLandscapeMode ? muteButtonScale : AndroidUtilities.lerp(1f, muteButtonScale, renderersContainer.progressToFullscreenMode);
showView.setScaleX(multiplier);
showView.setScaleY(multiplier);
});
expandSizeAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
expandSizeAnimator = null;
}
});
expandSizeAnimator.start();
} else {
float multiplier = isLandscapeMode ? muteButtonScale : AndroidUtilities.lerp(1f, muteButtonScale, renderersContainer.progressToFullscreenMode);
showView.setAlpha(1f);
showView.setScaleX(multiplier);
showView.setScaleY(multiplier);
hideView.setAlpha(0f);
}
if (changed) {
expandAnimator = ValueAnimator.ofFloat(0, 1);
expandAnimator.addUpdateListener(animation -> {
float val = (float) animation.getAnimatedValue();
float multiplier = isLandscapeMode ? muteButtonScale : AndroidUtilities.lerp(1f, muteButtonScale, renderersContainer.progressToFullscreenMode);
hideView.setAlpha(1f - val);
float scale = (0.1f + (1f - val) * 0.9f) * multiplier;
hideView.setScaleX(scale);
hideView.setScaleY(scale);
showView.setAlpha(val);
scale = (0.1f + val * 0.9f) * multiplier;
showView.setScaleX(scale);
showView.setScaleY(scale);
});
expandAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
expandAnimator = null;
}
});
expandAnimator.start();
} else {
float multiplier = isLandscapeMode ? muteButtonScale : AndroidUtilities.lerp(1f, muteButtonScale, renderersContainer.progressToFullscreenMode);
showView.setAlpha(1f);
showView.setScaleX(multiplier);
showView.setScaleY(multiplier);
hideView.setAlpha(0f);
}
} else {
muteButton.setAlpha(1f);
expandButton.setAlpha(0f);
minimizeButton.setAlpha(0f);
}
if (changed) {
muteButtonAnimator = ValueAnimator.ofFloat(0.0f, 1.0f);
muteButtonAnimator.addUpdateListener(animation -> {
float v = (float) animation.getAnimatedValue();
muteLabel[0].setAlpha(1.0f - v);
muteLabel[0].setTranslationY(AndroidUtilities.dp(5) * v);
muteLabel[1].setAlpha(v);
muteLabel[1].setTranslationY(AndroidUtilities.dp(-5 + 5 * v));
});
muteButtonAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (muteButtonAnimator != null) {
muteButtonAnimator = null;
TextView temp = muteLabel[0];
muteLabel[0] = muteLabel[1];
muteLabel[1] = temp;
temp.setVisibility(View.INVISIBLE);
for (int a = 0; a < 2; a++) {
muteLabel[a].setTranslationY(0);
}
}
}
});
muteButtonAnimator.setDuration(180);
muteButtonAnimator.start();
} else {
muteLabel[0].setAlpha(0f);
muteLabel[1].setAlpha(1f);
TextView temp = muteLabel[0];
muteLabel[0] = muteLabel[1];
muteLabel[1] = temp;
temp.setVisibility(View.INVISIBLE);
for (int a = 0; a < 2; a++) {
muteLabel[a].setTranslationY(0);
}
}
muteButtonState = state;
} else {
muteButtonState = state;
bigMicDrawable.setCurrentFrame(bigMicDrawable.getCustomEndFrame() - 1, false, true);
muteLabel[0].setText(newText);
if (isRtmpStream() && !call.isScheduled()) {
muteButton.setAlpha(0f);
boolean isExpanded = renderersContainer != null && renderersContainer.inFullscreenMode && (AndroidUtilities.isTablet() || isLandscapeMode == isRtmpLandscapeMode());
View hideView = isExpanded ? expandButton : minimizeButton;
View showView = isExpanded ? minimizeButton : expandButton;
showView.setAlpha(1f);
hideView.setAlpha(0f);
} else {
muteButton.setAlpha(1f);
expandButton.setAlpha(0f);
minimizeButton.setAlpha(0f);
}
}
updateMuteButtonState(animated);
}
private void fillColors(int state, int[] colorsToSet) {
if (state == MUTE_BUTTON_STATE_UNMUTE) {
colorsToSet[0] = Theme.getColor(Theme.key_voipgroup_unmuteButton2);
colorsToSet[1] = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_soundButtonActive), Theme.getColor(Theme.key_voipgroup_soundButtonActiveScrolled), colorProgress, 1.0f);
colorsToSet[2] = Theme.getColor(Theme.key_voipgroup_soundButton);
} else if (state == MUTE_BUTTON_STATE_MUTE) {
colorsToSet[0] = Theme.getColor(Theme.key_voipgroup_muteButton2);
colorsToSet[1] = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_soundButtonActive2), Theme.getColor(Theme.key_voipgroup_soundButtonActive2Scrolled), colorProgress, 1.0f);
colorsToSet[2] = Theme.getColor(Theme.key_voipgroup_soundButton2);
} else if (isGradientState(state)) {
colorsToSet[0] = Theme.getColor(Theme.key_voipgroup_mutedByAdminGradient3);
colorsToSet[1] = Theme.getColor(Theme.key_voipgroup_mutedByAdminMuteButton);
colorsToSet[2] = Theme.getColor(Theme.key_voipgroup_mutedByAdminMuteButtonDisabled);
} else {
colorsToSet[0] = Theme.getColor(Theme.key_voipgroup_disabledButton);
colorsToSet[1] = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_disabledButtonActive), Theme.getColor(Theme.key_voipgroup_disabledButtonActiveScrolled), colorProgress, 1.0f);
colorsToSet[2] = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_listViewBackgroundUnscrolled), Theme.getColor(Theme.key_voipgroup_disabledButton), colorProgress, 1.0f);
}
}
private void showRecordHint(View view) {
if (recordHintView == null) {
recordHintView = new HintView(getContext(), 8, true);
recordHintView.setAlpha(0.0f);
recordHintView.setVisibility(View.INVISIBLE);
recordHintView.setShowingDuration(3000);
containerView.addView(recordHintView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 19, 0, 19, 0));
if (ChatObject.isChannelOrGiga(currentChat)) {
recordHintView.setText(LocaleController.getString("VoipChannelRecording", R.string.VoipChannelRecording));
} else {
recordHintView.setText(LocaleController.getString("VoipGroupRecording", R.string.VoipGroupRecording));
}
recordHintView.setBackgroundColor(0xea272f38, 0xffffffff);
}
recordHintView.setExtraTranslationY(-AndroidUtilities.statusBarHeight);
recordHintView.showForView(view, true);
}
private void showReminderHint() {
SharedPreferences preferences = MessagesController.getGlobalMainSettings();
if (preferences.getBoolean("reminderhint", false)) {
return;
}
preferences.edit().putBoolean("reminderhint", true).commit();
if (reminderHintView == null) {
reminderHintView = new HintView(getContext(), 8);
reminderHintView.setAlpha(0.0f);
reminderHintView.setVisibility(View.INVISIBLE);
reminderHintView.setShowingDuration(4000);
containerView.addView(reminderHintView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP, 19, 0, 19, 0));
reminderHintView.setText(LocaleController.getString("VoipChatReminderHint", R.string.VoipChatReminderHint));
reminderHintView.setBackgroundColor(0xea272f38, 0xffffffff);
}
reminderHintView.setExtraTranslationY(-AndroidUtilities.statusBarHeight);
reminderHintView.showForView(muteButton, true);
}
private void updateMuteButtonState(boolean animated) {
muteButton.invalidate();
if (states[muteButtonState] == null) {
states[muteButtonState] = new WeavingState(muteButtonState);
if (muteButtonState == MUTE_BUTTON_STATE_CONNECTING) {
states[muteButtonState].shader = null;
} else {
if (isGradientState(muteButtonState)) {
states[muteButtonState].shader = new LinearGradient(0, 400, 400, 0, new int[]{Theme.getColor(Theme.key_voipgroup_mutedByAdminGradient), Theme.getColor(Theme.key_voipgroup_mutedByAdminGradient3), Theme.getColor(Theme.key_voipgroup_mutedByAdminGradient2)}, null, Shader.TileMode.CLAMP);
} else if (muteButtonState == MUTE_BUTTON_STATE_MUTE) {
states[muteButtonState].shader = new RadialGradient(200, 200, 200, new int[]{Theme.getColor(Theme.key_voipgroup_muteButton), Theme.getColor(Theme.key_voipgroup_muteButton3)}, null, Shader.TileMode.CLAMP);
} else {
states[muteButtonState].shader = new RadialGradient(200, 200, 200, new int[]{Theme.getColor(Theme.key_voipgroup_unmuteButton2), Theme.getColor(Theme.key_voipgroup_unmuteButton)}, null, Shader.TileMode.CLAMP);
}
}
}
if (states[muteButtonState] != currentState) {
prevState = currentState;
currentState = states[muteButtonState];
if (prevState == null || !animated) {
switchProgress = 1;
prevState = null;
} else {
switchProgress = 0;
}
}
if (!animated) {
boolean showWaves = false;
boolean showLighting = false;
if (currentState != null) {
showWaves = currentState.currentState == MUTE_BUTTON_STATE_MUTE || currentState.currentState == MUTE_BUTTON_STATE_UNMUTE;
showLighting = currentState.currentState != MUTE_BUTTON_STATE_CONNECTING;
}
showWavesProgress = showWaves ? 1f : 0f;
showLightingProgress = showLighting ? 1f : 0f;
}
buttonsContainer.invalidate();
}
private static void processOnLeave(ChatObject.Call call, boolean discard, long selfId, Runnable onLeave) {
if (VoIPService.getSharedInstance() != null) {
VoIPService.getSharedInstance().hangUp(discard ? 1 : 0);
}
if (call != null) {
TLRPC.TL_groupCallParticipant participant = call.participants.get(selfId);
if (participant != null) {
call.participants.delete(selfId);
call.sortedParticipants.remove(participant);
call.visibleParticipants.remove(participant);
for (int i = 0; i < call.visibleVideoParticipants.size(); i++) {
ChatObject.VideoParticipant videoParticipant = call.visibleVideoParticipants.get(i);
if (MessageObject.getPeerId(videoParticipant.participant.peer) == MessageObject.getPeerId(participant.peer)) {
call.visibleVideoParticipants.remove(i);
i--;
}
}
call.call.participants_count--;
}
for (int i = 0; i < call.sortedParticipants.size(); i++) {
TLRPC.TL_groupCallParticipant participant1 = call.sortedParticipants.get(i);
participant1.lastActiveDate = participant1.lastSpeakTime;
}
}
if (onLeave != null) {
onLeave.run();
}
NotificationCenter.getGlobalInstance().postNotificationName(NotificationCenter.didStartedCall);
}
public static void onLeaveClick(Context context, Runnable onLeave, boolean fromOverlayWindow) {
VoIPService service = VoIPService.getSharedInstance();
if (service == null) {
return;
}
TLRPC.Chat currentChat = service.getChat();
ChatObject.Call call = service.groupCall;
long selfId = service.getSelfId();
if (!ChatObject.canManageCalls(currentChat)) {
processOnLeave(call, false, selfId, onLeave);
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(context);
if (ChatObject.isChannelOrGiga(currentChat)) {
builder.setTitle(LocaleController.getString("VoipChannelLeaveAlertTitle", R.string.VoipChannelLeaveAlertTitle));
builder.setMessage(LocaleController.getString("VoipChannelLeaveAlertText", R.string.VoipChannelLeaveAlertText));
} else {
builder.setTitle(LocaleController.getString("VoipGroupLeaveAlertTitle", R.string.VoipGroupLeaveAlertTitle));
builder.setMessage(LocaleController.getString("VoipGroupLeaveAlertText", R.string.VoipGroupLeaveAlertText));
}
int currentAccount = service.getAccount();
CheckBoxCell[] cells = new CheckBoxCell[1];
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setOrientation(LinearLayout.VERTICAL);
cells[0] = new CheckBoxCell(context, 1);
cells[0].setBackgroundDrawable(Theme.getSelectorDrawable(false));
if (fromOverlayWindow) {
cells[0].setTextColor(Theme.getColor(Theme.key_dialogTextBlack));
} else {
cells[0].setTextColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
CheckBoxSquare checkBox = (CheckBoxSquare) cells[0].getCheckBoxView();
checkBox.setColors(Theme.key_voipgroup_mutedIcon, Theme.key_voipgroup_listeningText, Theme.key_voipgroup_nameText);
}
cells[0].setTag(0);
if (ChatObject.isChannelOrGiga(currentChat)) {
cells[0].setText(LocaleController.getString("VoipChannelLeaveAlertEndChat", R.string.VoipChannelLeaveAlertEndChat), "", false, false);
} else {
cells[0].setText(LocaleController.getString("VoipGroupLeaveAlertEndChat", R.string.VoipGroupLeaveAlertEndChat), "", false, false);
}
cells[0].setPadding(LocaleController.isRTL ? AndroidUtilities.dp(16) : AndroidUtilities.dp(8), 0, LocaleController.isRTL ? AndroidUtilities.dp(8) : AndroidUtilities.dp(16), 0);
linearLayout.addView(cells[0], LayoutHelper.createLinear(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT));
cells[0].setOnClickListener(v -> {
Integer num = (Integer) v.getTag();
cells[num].setChecked(!cells[num].isChecked(), true);
});
builder.setCustomViewOffset(12);
builder.setView(linearLayout);
builder.setDialogButtonColorKey(Theme.key_voipgroup_listeningText);
builder.setPositiveButton(LocaleController.getString("VoipGroupLeave", R.string.VoipGroupLeave), (dialogInterface, position) -> processOnLeave(call, cells[0].isChecked(), selfId, onLeave));
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
if (fromOverlayWindow) {
builder.setDimEnabled(false);
}
AlertDialog dialog = builder.create();
if (fromOverlayWindow) {
if (Build.VERSION.SDK_INT >= 26) {
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY);
} else {
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
}
dialog.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
}
if (!fromOverlayWindow) {
dialog.setBackgroundColor(Theme.getColor(Theme.key_voipgroup_dialogBackground));
}
dialog.show();
if (!fromOverlayWindow) {
TextView button = (TextView) dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setTextColor(Theme.getColor(Theme.key_voipgroup_leaveCallMenu));
}
dialog.setTextColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
}
}
private Paint scrimPaint;
private GroupCallUserCell scrimView;
private GroupCallGridCell scrimGridView;
private GroupCallMiniTextureView scrimRenderer;
private GroupCallFullscreenAdapter.GroupCallUserCell scrimFullscreenView;
private boolean hasScrimAnchorView;
private boolean avatarPriviewTransitionInProgress;
private boolean scrimViewAttached;
private int popupAnimationIndex = -1;
private AnimatorSet scrimAnimatorSet;
private ActionBarPopupWindow scrimPopupWindow;
private void processSelectedOption(TLRPC.TL_groupCallParticipant participant, long peerId, int option) {
VoIPService voIPService = VoIPService.getSharedInstance();
if (voIPService == null) {
return;
}
TLObject object;
if (peerId > 0) {
object = accountInstance.getMessagesController().getUser(peerId);
} else {
object = accountInstance.getMessagesController().getChat(-peerId);
}
if (option == 0 || option == 2 || option == 3) {
if (option == 0) {
if (VoIPService.getSharedInstance() == null) {
return;
}
VoIPService.getSharedInstance().editCallMember(object, true, null, null, null, null);
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_MUTED, object, null, null, null);
return;
}
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setDialogButtonColorKey(Theme.key_voipgroup_listeningText);
TextView messageTextView = new TextView(getContext());
messageTextView.setTextColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
messageTextView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 16);
messageTextView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP);
FrameLayout frameLayout = new FrameLayout(getContext());
builder.setView(frameLayout);
AvatarDrawable avatarDrawable = new AvatarDrawable();
avatarDrawable.setTextSize(AndroidUtilities.dp(12));
BackupImageView imageView = new BackupImageView(getContext());
imageView.setRoundRadius(AndroidUtilities.dp(20));
frameLayout.addView(imageView, LayoutHelper.createFrame(40, 40, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 22, 5, 22, 0));
avatarDrawable.setInfo(object);
String name;
if (object instanceof TLRPC.User) {
TLRPC.User user = (TLRPC.User) object;
imageView.setForUserOrChat(user, avatarDrawable);
name = UserObject.getFirstName(user);
} else {
TLRPC.Chat chat = (TLRPC.Chat) object;
imageView.setForUserOrChat(chat, avatarDrawable);
name = chat.title;
}
TextView textView = new TextView(getContext());
textView.setTextColor(Theme.getColor(Theme.key_voipgroup_actionBarItems));
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);
textView.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
textView.setLines(1);
textView.setMaxLines(1);
textView.setSingleLine(true);
textView.setGravity((LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.CENTER_VERTICAL);
textView.setEllipsize(TextUtils.TruncateAt.END);
if (option == 2) {
textView.setText(LocaleController.getString("VoipGroupRemoveMemberAlertTitle2", R.string.VoipGroupRemoveMemberAlertTitle2));
if (ChatObject.isChannelOrGiga(currentChat)) {
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("VoipChannelRemoveMemberAlertText2", R.string.VoipChannelRemoveMemberAlertText2, name, currentChat.title)));
} else {
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("VoipGroupRemoveMemberAlertText2", R.string.VoipGroupRemoveMemberAlertText2, name, currentChat.title)));
}
} else {
textView.setText(LocaleController.getString("VoipGroupAddMemberTitle", R.string.VoipGroupAddMemberTitle));
messageTextView.setText(AndroidUtilities.replaceTags(LocaleController.formatString("VoipGroupAddMemberText", R.string.VoipGroupAddMemberText, name, currentChat.title)));
}
frameLayout.addView(textView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, (LocaleController.isRTL ? 21 : 76), 11, (LocaleController.isRTL ? 76 : 21), 0));
frameLayout.addView(messageTextView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, (LocaleController.isRTL ? Gravity.RIGHT : Gravity.LEFT) | Gravity.TOP, 24, 57, 24, 9));
if (option == 2) {
builder.setPositiveButton(LocaleController.getString("VoipGroupUserRemove", R.string.VoipGroupUserRemove), (dialogInterface, i) -> {
if (object instanceof TLRPC.User) {
TLRPC.User user = (TLRPC.User) object;
accountInstance.getMessagesController().deleteParticipantFromChat(currentChat.id, user, null);
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_REMOVED, user, null, null, null);
} else {
TLRPC.Chat chat = (TLRPC.Chat) object;
accountInstance.getMessagesController().deleteParticipantFromChat(currentChat.id, null, chat, null, false, false);
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_REMOVED, chat, null, null, null);
}
});
} else if (object instanceof TLRPC.User) {
TLRPC.User user = (TLRPC.User) object;
builder.setPositiveButton(LocaleController.getString("VoipGroupAdd", R.string.VoipGroupAdd), (dialogInterface, i) -> {
BaseFragment fragment = parentActivity.getActionBarLayout().fragmentsStack.get(parentActivity.getActionBarLayout().fragmentsStack.size() - 1);
accountInstance.getMessagesController().addUserToChat(currentChat.id, user, 0, null, fragment, () -> inviteUserToCall(peerId, false));
});
}
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null);
AlertDialog dialog = builder.create();
dialog.setBackgroundColor(Theme.getColor(Theme.key_voipgroup_dialogBackground));
dialog.show();
if (option == 2) {
TextView button = (TextView) dialog.getButton(DialogInterface.BUTTON_POSITIVE);
if (button != null) {
button.setTextColor(Theme.getColor(Theme.key_voipgroup_leaveCallMenu));
}
}
} else if (option == 6) {
parentActivity.switchToAccount(currentAccount, true);
Bundle args = new Bundle();
if (peerId > 0) {
args.putLong("user_id", peerId);
} else {
args.putLong("chat_id", -peerId);
}
parentActivity.presentFragment(new ChatActivity(args));
dismiss();
} else if (option == 8) {
parentActivity.switchToAccount(currentAccount, true);
BaseFragment fragment = parentActivity.getActionBarLayout().fragmentsStack.get(parentActivity.getActionBarLayout().fragmentsStack.size() - 1);
if (fragment instanceof ChatActivity) {
if (((ChatActivity) fragment).getDialogId() == peerId) {
dismiss();
return;
}
}
Bundle args = new Bundle();
if (peerId > 0) {
args.putLong("user_id", peerId);
} else {
args.putLong("chat_id", -peerId);
}
parentActivity.presentFragment(new ChatActivity(args));
dismiss();
} else if (option == 7) {
voIPService.editCallMember(object, true, null, null, false, null);
updateMuteButton(MUTE_BUTTON_STATE_MUTED_BY_ADMIN, true);
} else if (option == 9) {
if (currentAvatarUpdater != null && currentAvatarUpdater.isUploadingImage()) {
return;
}
currentAvatarUpdater = new ImageUpdater(true);
currentAvatarUpdater.setOpenWithFrontfaceCamera(true);
currentAvatarUpdater.setForceDarkTheme(true);
currentAvatarUpdater.setSearchAvailable(true, true);
currentAvatarUpdater.setShowingFromDialog(true);
currentAvatarUpdater.parentFragment = parentActivity.getActionBarLayout().getLastFragment();
currentAvatarUpdater.setDelegate(avatarUpdaterDelegate = new AvatarUpdaterDelegate(peerId));
TLRPC.User user = accountInstance.getUserConfig().getCurrentUser();
currentAvatarUpdater.openMenu(user.photo != null && user.photo.photo_big != null && !(user.photo instanceof TLRPC.TL_userProfilePhotoEmpty), () -> accountInstance.getMessagesController().deleteUserPhoto(null), dialog -> {
});
} else if (option == 10) {
AlertsCreator.createChangeBioAlert(participant.about, peerId, getContext(), currentAccount);
} else if (option == 11) {
AlertsCreator.createChangeNameAlert(peerId, getContext(), currentAccount);
} else {
if (option == 5) {
voIPService.editCallMember(object, true, null, null, null, null);
getUndoView().showWithAction(0, UndoView.ACTION_VOIP_MUTED_FOR_YOU, object);
voIPService.setParticipantVolume(participant, 0);
} else {
if ((participant.flags & 128) != 0 && participant.volume == 0) {
participant.volume = 10000;
participant.volume_by_admin = false;
voIPService.editCallMember(object, false, null, participant.volume, null, null);
} else {
voIPService.editCallMember(object, false, null, null, null, null);
}
voIPService.setParticipantVolume(participant, ChatObject.getParticipantVolume(participant));
getUndoView().showWithAction(0, option == 1 ? UndoView.ACTION_VOIP_UNMUTED : UndoView.ACTION_VOIP_UNMUTED_FOR_YOU, object, null, null, null);
}
}
}
private boolean showMenuForCell(View rendererCell) {
if (itemAnimator.isRunning()) {
return false;
}
if (avatarPriviewTransitionInProgress || avatarsPreviewShowed) {
dismissAvatarPreview(true);
return false;
}
if (scrimPopupWindow != null) {
scrimPopupWindow.dismiss();
scrimPopupWindow = null;
return false;
}
clearScrimView();
GroupCallUserCell view;
if (rendererCell instanceof GroupCallGridCell) {
GroupCallGridCell groupCallGridCell = ((GroupCallGridCell) rendererCell);
if (groupCallGridCell.getParticipant() == call.videoNotAvailableParticipant) {
return false;
}
view = new GroupCallUserCell(groupCallGridCell.getContext());
long selfPeerId = MessageObject.getPeerId(selfPeer);
view.setData(accountInstance, groupCallGridCell.getParticipant().participant, call, selfPeerId, null, false);
hasScrimAnchorView = false;
scrimGridView = groupCallGridCell;
scrimRenderer = groupCallGridCell.getRenderer();
if (!isTabletMode && !isLandscapeMode) {
scrimViewAttached = true;
containerView.addView(view, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 14, 0, 14, 0));
} else {
scrimViewAttached = false;
}
} else if (rendererCell instanceof GroupCallFullscreenAdapter.GroupCallUserCell) {
GroupCallFullscreenAdapter.GroupCallUserCell groupCallFullscreenCell = ((GroupCallFullscreenAdapter.GroupCallUserCell) rendererCell);
if (groupCallFullscreenCell.getParticipant() == call.videoNotAvailableParticipant.participant) {
return false;
}
view = new GroupCallUserCell(groupCallFullscreenCell.getContext());
long selfPeerId = MessageObject.getPeerId(selfPeer);
view.setData(accountInstance, groupCallFullscreenCell.getParticipant(), call, selfPeerId, null, false);
hasScrimAnchorView = false;
scrimFullscreenView = groupCallFullscreenCell;
scrimRenderer = groupCallFullscreenCell.getRenderer();
if (scrimRenderer != null && scrimRenderer.showingInFullscreen) {
scrimRenderer = null;
}
containerView.addView(view, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, 0, 14, 0, 14, 0));
scrimViewAttached = true;
} else {
view = (GroupCallUserCell) rendererCell;
hasScrimAnchorView = true;
scrimViewAttached = true;
}
if (view == null) {
return false;
}
boolean showWithAvatarPreview = !isLandscapeMode && !isTabletMode && !AndroidUtilities.isInMultiwindow;
TLRPC.TL_groupCallParticipant participant = view.getParticipant();
Rect rect = new Rect();
ActionBarPopupWindow.ActionBarPopupWindowLayout popupLayout = new ActionBarPopupWindow.ActionBarPopupWindowLayout(getContext());
popupLayout.setBackgroundDrawable(null);
popupLayout.setPadding(0, 0, 0, 0);
popupLayout.setOnTouchListener(new View.OnTouchListener() {
private int[] pos = new int[2];
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
if (scrimPopupWindow != null && scrimPopupWindow.isShowing()) {
View contentView = scrimPopupWindow.getContentView();
contentView.getLocationInWindow(pos);
rect.set(pos[0], pos[1], pos[0] + contentView.getMeasuredWidth(), pos[1] + contentView.getMeasuredHeight());
if (!rect.contains((int) event.getX(), (int) event.getY())) {
scrimPopupWindow.dismiss();
}
}
} else if (event.getActionMasked() == MotionEvent.ACTION_OUTSIDE) {
if (scrimPopupWindow != null && scrimPopupWindow.isShowing()) {
scrimPopupWindow.dismiss();
}
}
return false;
}
});
popupLayout.setDispatchKeyEventListener(keyEvent -> {
if (keyEvent.getKeyCode() == KeyEvent.KEYCODE_BACK && keyEvent.getRepeatCount() == 0 && scrimPopupWindow != null && scrimPopupWindow.isShowing()) {
scrimPopupWindow.dismiss();
}
});
LinearLayout buttonsLayout = new LinearLayout(getContext());
LinearLayout volumeLayout = !participant.muted_by_you ? new LinearLayout(getContext()) : null;
currentOptionsLayout = buttonsLayout;
LinearLayout linearLayout = new LinearLayout(getContext()) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = MeasureSpec.getSize(widthMeasureSpec);
buttonsLayout.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
if (volumeLayout != null) {
volumeLayout.measure(MeasureSpec.makeMeasureSpec(buttonsLayout.getMeasuredWidth(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
setMeasuredDimension(buttonsLayout.getMeasuredWidth(), buttonsLayout.getMeasuredHeight() + volumeLayout.getMeasuredHeight());
} else {
setMeasuredDimension(buttonsLayout.getMeasuredWidth(), buttonsLayout.getMeasuredHeight());
}
}
};
linearLayout.setMinimumWidth(AndroidUtilities.dp(240));
linearLayout.setOrientation(LinearLayout.VERTICAL);
VolumeSlider volumeSlider = null;
int color = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_listViewBackgroundUnscrolled), Theme.getColor(Theme.key_voipgroup_listViewBackground), colorProgress, 1.0f);
if (volumeLayout != null && !view.isSelfUser() && !participant.muted_by_you && (!participant.muted || participant.can_self_unmute)) {
Drawable shadowDrawable = getContext().getResources().getDrawable(R.drawable.popup_fixed_alert).mutate();
shadowDrawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
volumeLayout.setBackgroundDrawable(shadowDrawable);
linearLayout.addView(volumeLayout, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0, 0, 0, 0));
volumeSlider = new VolumeSlider(getContext(), participant);
volumeLayout.addView(volumeSlider, LayoutHelper.MATCH_PARENT, 48);
}
buttonsLayout.setMinimumWidth(AndroidUtilities.dp(240));
buttonsLayout.setOrientation(LinearLayout.VERTICAL);
Drawable shadowDrawable = getContext().getResources().getDrawable(R.drawable.popup_fixed_alert).mutate();
shadowDrawable.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY));
buttonsLayout.setBackgroundDrawable(shadowDrawable);
linearLayout.addView(buttonsLayout, LayoutHelper.createLinear(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, 0, volumeSlider != null ? -8 : 0, 0, 0));
ScrollView scrollView;
if (Build.VERSION.SDK_INT >= 21) {
scrollView = new ScrollView(getContext(), null, 0, R.style.scrollbarShapeStyle) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(linearLayout.getMeasuredWidth(), getMeasuredHeight());
}
};
} else {
scrollView = new ScrollView(getContext());
}
scrollView.setClipToPadding(false);
popupLayout.addView(scrollView, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
long peerId = MessageObject.getPeerId(participant.peer);
ArrayList<String> items = new ArrayList<>(2);
ArrayList<Integer> icons = new ArrayList<>(2);
ArrayList<Integer> options = new ArrayList<>(2);
boolean isAdmin = false;
if (participant.peer instanceof TLRPC.TL_peerUser) {
if (ChatObject.isChannel(currentChat)) {
TLRPC.ChannelParticipant p = accountInstance.getMessagesController().getAdminInChannel(participant.peer.user_id, currentChat.id);
isAdmin = p != null && (p instanceof TLRPC.TL_channelParticipantCreator || p.admin_rights.manage_call);
} else {
TLRPC.ChatFull chatFull = accountInstance.getMessagesController().getChatFull(currentChat.id);
if (chatFull != null && chatFull.participants != null) {
for (int a = 0, N = chatFull.participants.participants.size(); a < N; a++) {
TLRPC.ChatParticipant chatParticipant = chatFull.participants.participants.get(a);
if (chatParticipant.user_id == participant.peer.user_id) {
isAdmin = chatParticipant instanceof TLRPC.TL_chatParticipantAdmin || chatParticipant instanceof TLRPC.TL_chatParticipantCreator;
break;
}
}
}
}
} else {
isAdmin = peerId == -currentChat.id;
}
if (view.isSelfUser()) {
if (view.isHandRaised()) {
items.add(LocaleController.getString("VoipGroupCancelRaiseHand", R.string.VoipGroupCancelRaiseHand));
icons.add(R.drawable.msg_handdown);
options.add(7);
}
items.add(view.hasAvatarSet() ? LocaleController.getString("VoipAddPhoto", R.string.VoipAddPhoto) : LocaleController.getString("VoipSetNewPhoto", R.string.VoipSetNewPhoto));
icons.add(R.drawable.msg_addphoto);
options.add(9);
if (peerId > 0) {
items.add(TextUtils.isEmpty(participant.about) ? LocaleController.getString("VoipAddBio", R.string.VoipAddBio) : LocaleController.getString("VoipEditBio", R.string.VoipEditBio));
} else {
items.add(TextUtils.isEmpty(participant.about) ? LocaleController.getString("VoipAddDescription", R.string.VoipAddDescription) : LocaleController.getString("VoipEditDescription", R.string.VoipEditDescription));
}
icons.add(TextUtils.isEmpty(participant.about) ? R.drawable.msg_addbio : R.drawable.msg_info);
options.add(10);
items.add(peerId > 0 ? LocaleController.getString("VoipEditName", R.string.VoipEditName) : LocaleController.getString("VoipEditTitle", R.string.VoipEditTitle));
icons.add(R.drawable.msg_edit);
options.add(11);
} else if (ChatObject.canManageCalls(currentChat)) {
if (!isAdmin || !participant.muted) {
if (!participant.muted || participant.can_self_unmute) {
items.add(LocaleController.getString("VoipGroupMute", R.string.VoipGroupMute));
icons.add(R.drawable.msg_voice_muted);
options.add(0);
} else {
items.add(LocaleController.getString("VoipGroupAllowToSpeak", R.string.VoipGroupAllowToSpeak));
if (participant.raise_hand_rating != 0) {
icons.add(R.drawable.msg_allowspeak);
} else {
icons.add(R.drawable.msg_voice_unmuted);
}
options.add(1);
}
}
if (participant.peer.channel_id != 0 && !ChatObject.isMegagroup(currentAccount, participant.peer.channel_id)) {
items.add(LocaleController.getString("VoipGroupOpenChannel", R.string.VoipGroupOpenChannel));
icons.add(R.drawable.msg_channel);
options.add(8);
} else {
items.add(LocaleController.getString("VoipGroupOpenProfile", R.string.VoipGroupOpenProfile));
icons.add(R.drawable.baseline_person_24);
options.add(6);
}
if (!isAdmin && ChatObject.canBlockUsers(currentChat)) {
items.add(LocaleController.getString("VoipGroupUserRemove", R.string.VoipGroupUserRemove));
icons.add(R.drawable.msg_block2);
options.add(2);
}
} else {
if (participant.muted_by_you) {
items.add(LocaleController.getString("VoipGroupUnmuteForMe", R.string.VoipGroupUnmuteForMe));
icons.add(R.drawable.msg_voice_unmuted);
options.add(4);
} else {
items.add(LocaleController.getString("VoipGroupMuteForMe", R.string.VoipGroupMuteForMe));
icons.add(R.drawable.msg_voice_muted);
options.add(5);
}
if (participant.peer.channel_id != 0 && !ChatObject.isMegagroup(currentAccount, participant.peer.channel_id)) {
items.add(LocaleController.getString("VoipGroupOpenChannel", R.string.VoipGroupOpenChannel));
icons.add(R.drawable.msg_msgbubble3);
options.add(8);
} else {
items.add(LocaleController.getString("VoipGroupOpenChat", R.string.VoipGroupOpenChat));
icons.add(R.drawable.baseline_person_24);
options.add(6);
}
}
for (int a = 0, N = items.size(); a < N; a++) {
ActionBarMenuSubItem cell = new ActionBarMenuSubItem(getContext(), a == 0, a == N - 1);
if (options.get(a) != 2) {
cell.setColors(Theme.getColor(Theme.key_voipgroup_actionBarItems), Theme.getColor(Theme.key_voipgroup_actionBarItems));
} else {
cell.setColors(Theme.getColor(Theme.key_voipgroup_leaveCallMenu), Theme.getColor(Theme.key_voipgroup_leaveCallMenu));
}
cell.setSelectorColor(Theme.getColor(Theme.key_voipgroup_listSelector));
cell.setTextAndIcon(items.get(a), icons.get(a));
buttonsLayout.addView(cell);
final int i = a;
cell.setTag(options.get(a));
cell.setOnClickListener(v1 -> {
if (i >= options.size()) {
return;
}
TLRPC.TL_groupCallParticipant participant1 = call.participants.get(MessageObject.getPeerId(participant.peer));
if (participant1 == null) {
participant1 = participant;
}
processSelectedOption(participant1, MessageObject.getPeerId(participant1.peer), options.get(i));
if (scrimPopupWindow != null) {
scrimPopupWindow.dismiss();
} else {
if (options.get(i) != 9 && options.get(i) != 10 && options.get(i) != 11) {
dismissAvatarPreview(true);
}
}
});
}
scrollView.addView(linearLayout, LayoutHelper.createScroll(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP));
listView.stopScroll();
layoutManager.setCanScrollVertically(false);
scrimView = view;
scrimView.setAboutVisible(true);
containerView.invalidate();
listView.invalidate();
if (scrimAnimatorSet != null) {
scrimAnimatorSet.cancel();
}
scrimPopupLayout = popupLayout;
final ImageLocation imageLocation;
final ImageLocation thumbLocation;
if (peerId > 0) {
TLRPC.User currentUser = accountInstance.getMessagesController().getUser(peerId);
imageLocation = ImageLocation.getForUserOrChat(currentUser, ImageLocation.TYPE_BIG);
thumbLocation = ImageLocation.getForUserOrChat(currentUser, ImageLocation.TYPE_SMALL);
} else {
TLRPC.Chat currentChat = accountInstance.getMessagesController().getChat(-peerId);
imageLocation = ImageLocation.getForUserOrChat(currentChat, ImageLocation.TYPE_BIG);
thumbLocation = ImageLocation.getForUserOrChat(currentChat, ImageLocation.TYPE_SMALL);
}
boolean hasAttachedRenderer = scrimRenderer != null && scrimRenderer.isAttached();
if (imageLocation == null && !hasAttachedRenderer) {
showWithAvatarPreview = false;
} else if (showWithAvatarPreview) {
avatarsViewPager.setParentAvatarImage(scrimView.getAvatarImageView());
avatarsViewPager.setHasActiveVideo(hasAttachedRenderer);
avatarsViewPager.setData(peerId, true);
avatarsViewPager.setCreateThumbFromParent(true);
avatarsViewPager.initIfEmpty(imageLocation, thumbLocation, true);
if (scrimRenderer != null) {
scrimRenderer.setShowingAsScrimView(true, true);
}
if (MessageObject.getPeerId(selfPeer) == peerId && currentAvatarUpdater != null && avatarUpdaterDelegate != null && avatarUpdaterDelegate.avatar != null) {
avatarsViewPager.addUploadingImage(avatarUpdaterDelegate.uploadingImageLocation, ImageLocation.getForLocal(avatarUpdaterDelegate.avatar));
}
}
if (showWithAvatarPreview) {
avatarsPreviewShowed = true;
popupLayout.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST));
containerView.addView(scrimPopupLayout, LayoutHelper.createFrame(LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT));
useBlur = true;//scrimFullscreenView == null;
if (useBlur) {
prepareBlurBitmap();
}
avatarPriviewTransitionInProgress = true;
avatarPreviewContainer.setVisibility(View.VISIBLE);
if (volumeSlider != null) {
volumeSlider.invalidate();
}
runAvatarPreviewTransition(true, view);
if (scrimFullscreenView != null) {
scrimFullscreenView.getAvatarImageView().setAlpha(0f);
}
} else {
avatarsPreviewShowed = false;
scrimPopupWindow = new ActionBarPopupWindow(popupLayout, LayoutHelper.WRAP_CONTENT, LayoutHelper.WRAP_CONTENT) {
@Override
public void dismiss() {
super.dismiss();
if (scrimPopupWindow != this) {
return;
}
scrimPopupWindow = null;
if (scrimAnimatorSet != null) {
scrimAnimatorSet.cancel();
scrimAnimatorSet = null;
}
layoutManager.setCanScrollVertically(true);
scrimAnimatorSet = new AnimatorSet();
ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofInt(scrimPaint, AnimationProperties.PAINT_ALPHA, 0));
scrimAnimatorSet.playTogether(animators);
scrimAnimatorSet.setDuration(220);
scrimAnimatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
clearScrimView();
containerView.invalidate();
listView.invalidate();
if (delayedGroupCallUpdated) {
delayedGroupCallUpdated = false;
applyCallParticipantUpdates(true);
}
}
});
scrimAnimatorSet.start();
}
};
scrimPopupWindow.setPauseNotifications(true);
scrimPopupWindow.setDismissAnimationDuration(220);
scrimPopupWindow.setOutsideTouchable(true);
scrimPopupWindow.setClippingEnabled(true);
scrimPopupWindow.setAnimationStyle(R.style.PopupContextAnimation);
scrimPopupWindow.setFocusable(true);
popupLayout.measure(View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(1000), View.MeasureSpec.AT_MOST));
scrimPopupWindow.setInputMethodMode(ActionBarPopupWindow.INPUT_METHOD_NOT_NEEDED);
scrimPopupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_UNSPECIFIED);
scrimPopupWindow.getContentView().setFocusableInTouchMode(true);
int popupX, popupY;
if (scrimFullscreenView != null) {
if (isLandscapeMode) {
popupX = (int) (scrimFullscreenView.getX() + fullscreenUsersListView.getX() + renderersContainer.getX()) - popupLayout.getMeasuredWidth() + AndroidUtilities.dp(32);
popupY = (int) (scrimFullscreenView.getY() + fullscreenUsersListView.getY() + renderersContainer.getY()) - AndroidUtilities.dp(6);
} else {
popupX = (int) (scrimFullscreenView.getX() + fullscreenUsersListView.getX() + renderersContainer.getX()) - AndroidUtilities.dp(14);
popupY = (int) (scrimFullscreenView.getY() + fullscreenUsersListView.getY() + renderersContainer.getY() - popupLayout.getMeasuredHeight());
}
} else {
popupX = (int) (listView.getX() + listView.getMeasuredWidth() + AndroidUtilities.dp(8) - popupLayout.getMeasuredWidth());
if (hasScrimAnchorView) {
popupY = (int) (listView.getY() + view.getY() + view.getClipHeight());
} else if (scrimGridView != null) {
popupY = (int) (listView.getY() + scrimGridView.getY() + scrimGridView.getMeasuredHeight());
} else {
popupY = (int) listView.getY();
}
}
scrimPopupWindow.showAtLocation(listView, Gravity.LEFT | Gravity.TOP, popupX, popupY);
scrimAnimatorSet = new AnimatorSet();
ArrayList<Animator> animators = new ArrayList<>();
animators.add(ObjectAnimator.ofInt(scrimPaint, AnimationProperties.PAINT_ALPHA, 0, 100));
scrimAnimatorSet.playTogether(animators);
scrimAnimatorSet.setDuration(150);
scrimAnimatorSet.start();
}
return true;
}
private void clearScrimView() {
if (scrimRenderer != null) {
scrimRenderer.textureView.setRoundCorners(AndroidUtilities.dp(8));
scrimRenderer.setShowingAsScrimView(false, false);
scrimRenderer.invalidate();
renderersContainer.invalidate();
}
if (scrimView != null && !hasScrimAnchorView) {
if (scrimView.getParent() != null) {
containerView.removeView(scrimView);
}
}
if (scrimView != null) {
scrimView.setProgressToAvatarPreview(0f);
scrimView.setAboutVisible(false);
scrimView.getAvatarImageView().setAlpha(1f);
}
if (scrimFullscreenView != null) {
scrimFullscreenView.getAvatarImageView().setAlpha(1f);
}
scrimView = null;
scrimGridView = null;
scrimFullscreenView = null;
scrimRenderer = null;
}
private void startScreenCapture() {
if (parentActivity == null || Build.VERSION.SDK_INT < 21) {
return;
}
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) parentActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
parentActivity.startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), LaunchActivity.SCREEN_CAPTURE_REQUEST_CODE);
}
private void runAvatarPreviewTransition(boolean enter, GroupCallUserCell view) {
float fromX, fromY, fromScale;
int fromRadius;
float left = AndroidUtilities.dp(14) + containerView.getPaddingLeft();
float top = AndroidUtilities.dp(14) + containerView.getPaddingTop();
if (hasScrimAnchorView) {
fromX = view.getAvatarImageView().getX() + view.getX() + listView.getX() - left;
fromY = view.getAvatarImageView().getY() + view.getY() + listView.getY() - top;
fromScale = view.getAvatarImageView().getMeasuredHeight() / (float) listView.getMeasuredWidth();
fromRadius = (int) ((view.getAvatarImageView().getMeasuredHeight() >> 1) / fromScale);
} else {
if (scrimRenderer == null) {
previewTextureTransitionEnabled = true;
} else {
previewTextureTransitionEnabled = enter || avatarsViewPager.getRealPosition(avatarsViewPager.getCurrentItem()) == 0;
}
if (scrimGridView != null && previewTextureTransitionEnabled) {
fromX = scrimGridView.getX() + listView.getX() - left;
fromY = scrimGridView.getY() + listView.getY() + AndroidUtilities.dp(2) - top;
fromScale = 1f;
fromRadius = 0;
} else if (scrimFullscreenView != null) {
if (scrimRenderer == null) {
fromX = scrimFullscreenView.getAvatarImageView().getX() + scrimFullscreenView.getX() + fullscreenUsersListView.getX() + renderersContainer.getX() - left;
fromY = scrimFullscreenView.getAvatarImageView().getY() + scrimFullscreenView.getY() + fullscreenUsersListView.getY() + renderersContainer.getY() - top;
fromScale = scrimFullscreenView.getAvatarImageView().getMeasuredHeight() / (float) listView.getMeasuredWidth();
fromRadius = (int) ((scrimFullscreenView.getAvatarImageView().getMeasuredHeight() >> 1) / fromScale);
} else if (previewTextureTransitionEnabled) {
fromX = scrimFullscreenView.getX() + fullscreenUsersListView.getX() + renderersContainer.getX() - left;
fromY = scrimFullscreenView.getY() + fullscreenUsersListView.getY() + renderersContainer.getY() - top;
fromScale = 1f;
fromRadius = 0;
} else {
fromX = 0;
fromY = 0;
fromScale = 0.96f;
fromRadius = 0;
}
} else {
fromX = 0;
fromY = 0;
fromScale = 0.96f;
fromRadius = 0;
}
if (!previewTextureTransitionEnabled && scrimRenderer != null) {
scrimRenderer.invalidate();
renderersContainer.invalidate();
scrimRenderer.setShowingAsScrimView(false, false);
scrimRenderer = null;
}
}
if (enter) {
avatarPreviewContainer.setScaleX(fromScale);
avatarPreviewContainer.setScaleY(fromScale);
avatarPreviewContainer.setTranslationX(fromX);
avatarPreviewContainer.setTranslationY(fromY);
avatarPagerIndicator.setAlpha(0);
}
avatarsViewPager.setRoundRadius(fromRadius, fromRadius);
if (useBlur) {
if (enter) {
blurredView.setAlpha(0f);
}
blurredView.animate().alpha(enter ? 1f : 0).setDuration(220).start();
}
avatarPagerIndicator.animate().alpha(enter ? 1f : 0).setDuration(220).start();
if (!enter && scrimRenderer != null) {
scrimRenderer.setShowingAsScrimView(false, true);
if (avatarsViewPager.getRealPosition(avatarsViewPager.getCurrentItem()) != 0) {
scrimRenderer.textureView.cancelAnimation();
scrimGridView = null;
}
}
ValueAnimator valueAnimator = ValueAnimator.ofFloat(enter ? 0 : 1f, enter ? 1f : 0);
valueAnimator.addUpdateListener((valueAnimator1) -> {
progressToAvatarPreview = (float) valueAnimator1.getAnimatedValue();
renderersContainer.progressToScrimView = progressToAvatarPreview;
float s = fromScale * (1f - progressToAvatarPreview) + 1f * progressToAvatarPreview;
avatarPreviewContainer.setScaleX(s);
avatarPreviewContainer.setScaleY(s);
avatarPreviewContainer.setTranslationX(fromX * (1f - progressToAvatarPreview));
avatarPreviewContainer.setTranslationY(fromY * (1f - progressToAvatarPreview));
if (!useBlur) {
scrimPaint.setAlpha((int) (100 * progressToAvatarPreview));
}
if (scrimRenderer != null) {
scrimRenderer.textureView.setRoundCorners(AndroidUtilities.dp(8) * (1f - progressToAvatarPreview));
}
avatarPreviewContainer.invalidate();
containerView.invalidate();
avatarsViewPager.setRoundRadius((int) (fromRadius * (1f - progressToAvatarPreview)), (int) (fromRadius * (1f - progressToAvatarPreview)));
});
popupAnimationIndex = accountInstance.getNotificationCenter().setAnimationInProgress(popupAnimationIndex, new int[]{NotificationCenter.dialogPhotosLoaded, NotificationCenter.fileLoaded, NotificationCenter.messagesDidLoad});
GroupCallMiniTextureView videoRenderer = scrimGridView == null ? null : scrimRenderer;
if (videoRenderer != null) {
videoRenderer.animateToScrimView = true;
}
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (videoRenderer != null) {
videoRenderer.animateToScrimView = false;
}
accountInstance.getNotificationCenter().onAnimationFinish(popupAnimationIndex);
avatarPriviewTransitionInProgress = false;
progressToAvatarPreview = enter ? 1f : 0f;
renderersContainer.progressToScrimView = progressToAvatarPreview;
if (!enter) {
scrimPaint.setAlpha(0);
clearScrimView();
if (scrimPopupLayout.getParent() != null) {
containerView.removeView(scrimPopupLayout);
}
scrimPopupLayout = null;
avatarPreviewContainer.setVisibility(View.GONE);
avatarsPreviewShowed = false;
layoutManager.setCanScrollVertically(true);
blurredView.setVisibility(View.GONE);
if (delayedGroupCallUpdated) {
delayedGroupCallUpdated = false;
applyCallParticipantUpdates(true);
}
if (scrimRenderer != null) {
scrimRenderer.textureView.setRoundCorners(0);
}
} else {
avatarPreviewContainer.setAlpha(1f);
avatarPreviewContainer.setScaleX(1f);
avatarPreviewContainer.setScaleY(1f);
avatarPreviewContainer.setTranslationX(0);
avatarPreviewContainer.setTranslationY(0);
}
checkContentOverlayed();
containerView.invalidate();
avatarsViewPager.invalidate();
listView.invalidate();
}
});
if (!hasScrimAnchorView && scrimRenderer != null) {
valueAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
valueAnimator.setDuration(220);
scrimRenderer.textureView.setAnimateNextDuration(220);
scrimRenderer.textureView.synchOrRunAnimation(valueAnimator);
} else {
valueAnimator.setInterpolator(CubicBezierInterpolator.DEFAULT);
valueAnimator.setDuration(220);
valueAnimator.start();
}
checkContentOverlayed();
}
private void dismissAvatarPreview(boolean animated) {
if (avatarPriviewTransitionInProgress || !avatarsPreviewShowed) {
return;
}
if (animated) {
avatarPriviewTransitionInProgress = true;
runAvatarPreviewTransition(false, scrimView);
} else {
clearScrimView();
containerView.removeView(scrimPopupLayout);
scrimPopupLayout = null;
avatarPreviewContainer.setVisibility(View.GONE);
containerView.invalidate();
avatarsPreviewShowed = false;
layoutManager.setCanScrollVertically(true);
listView.invalidate();
blurredView.setVisibility(View.GONE);
if (delayedGroupCallUpdated) {
delayedGroupCallUpdated = false;
applyCallParticipantUpdates(true);
}
checkContentOverlayed();
}
}
private class ListAdapter extends RecyclerListView.SelectionAdapter {
private final static int VIEW_TYPE_INVITE_MEMBERS = 0,
VIEW_TYPE_PARTICIPANT = 1,
VIEW_TYPE_CALL_INVITED = 2,
VIEW_TYPE_LAST_PADDING = 3,
VIEW_TYPE_GRID = 4,
VIEW_TYPE_VIDEO_GRID_DIVIDER = 5,
VIEW_TYPE_VIDEO_NOT_AVAILABLE = 6;
private Context mContext;
private int usersStartRow;
private int usersEndRow;
private int invitedStartRow;
private int invitedEndRow;
private int addMemberRow;
private int lastRow;
private int rowsCount;
private int usersVideoGridStartRow;
private int usersVideoGridEndRow;
private int videoGridDividerRow;
private int videoNotAvailableRow;
private boolean hasSelfUser;
public ListAdapter(Context context) {
mContext = context;
}
public boolean addSelfToCounter() {
if (isRtmpStream()) {
return false;
}
if (hasSelfUser || VoIPService.getSharedInstance() == null) {
return false;
}
return !VoIPService.getSharedInstance().isJoined();
}
@Override
public int getItemCount() {
return rowsCount;
}
private void updateRows() {
if (call == null || call.isScheduled() || delayedGroupCallUpdated) {
return;
}
rowsCount = 0;
hasSelfUser = call.participants.indexOfKey(MessageObject.getPeerId(selfPeer)) >= 0;
usersVideoGridStartRow = rowsCount;
rowsCount += visibleVideoParticipants.size();
usersVideoGridEndRow = rowsCount;
int videoCount = visibleVideoParticipants.size();
if (videoCount > 0) {
videoGridDividerRow = rowsCount++;
} else {
videoGridDividerRow = -1;
}
if (!visibleVideoParticipants.isEmpty() && ChatObject.canManageCalls(currentChat) && call.call.participants_count > accountInstance.getMessagesController().groupCallVideoMaxParticipants) {
videoNotAvailableRow = rowsCount++;
} else {
videoNotAvailableRow = -1;
}
usersStartRow = rowsCount;
if (!isRtmpStream()) {
rowsCount += call.visibleParticipants.size();
}
usersEndRow = rowsCount;
if (call.invitedUsers.isEmpty() || isRtmpStream()) {
invitedStartRow = -1;
invitedEndRow = -1;
} else {
invitedStartRow = rowsCount;
rowsCount += call.invitedUsers.size();
invitedEndRow = rowsCount;
}
if (!isRtmpStream() && ((!ChatObject.isChannel(currentChat) || currentChat.megagroup) && ChatObject.canWriteToChat(currentChat) ||
ChatObject.isChannel(currentChat) && !currentChat.megagroup && !TextUtils.isEmpty(currentChat.username))) {
addMemberRow = rowsCount++;
} else {
addMemberRow = -1;
}
lastRow = rowsCount++;
}
@Override
public void notifyDataSetChanged() {
updateRows();
super.notifyDataSetChanged();
}
@Override
public void notifyItemChanged(int position) {
updateRows();
super.notifyItemChanged(position);
}
@Override
public void notifyItemChanged(int position, @Nullable Object payload) {
updateRows();
super.notifyItemChanged(position, payload);
}
@Override
public void notifyItemRangeChanged(int positionStart, int itemCount) {
updateRows();
super.notifyItemRangeChanged(positionStart, itemCount);
}
@Override
public void notifyItemRangeChanged(int positionStart, int itemCount, @Nullable Object payload) {
updateRows();
super.notifyItemRangeChanged(positionStart, itemCount, payload);
}
@Override
public void notifyItemInserted(int position) {
updateRows();
super.notifyItemInserted(position);
}
@Override
public void notifyItemMoved(int fromPosition, int toPosition) {
updateRows();
super.notifyItemMoved(fromPosition, toPosition);
}
@Override
public void notifyItemRangeInserted(int positionStart, int itemCount) {
updateRows();
super.notifyItemRangeInserted(positionStart, itemCount);
}
@Override
public void notifyItemRemoved(int position) {
updateRows();
super.notifyItemRemoved(position);
}
@Override
public void notifyItemRangeRemoved(int positionStart, int itemCount) {
updateRows();
super.notifyItemRangeRemoved(positionStart, itemCount);
}
@Override
public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
int type = holder.getItemViewType();
if (type == VIEW_TYPE_PARTICIPANT) {
GroupCallUserCell cell = (GroupCallUserCell) holder.itemView;
String key = actionBar.getTag() != null ? Theme.key_voipgroup_mutedIcon : Theme.key_voipgroup_mutedIconUnscrolled;
cell.setGrayIconColor(key, Theme.getColor(key));
cell.setDrawDivider(holder.getAdapterPosition() != getItemCount() - 2);
} else if (type == VIEW_TYPE_CALL_INVITED) {
GroupCallInvitedCell cell = (GroupCallInvitedCell) holder.itemView;
String key = actionBar.getTag() != null ? Theme.key_voipgroup_mutedIcon : Theme.key_voipgroup_mutedIconUnscrolled;
cell.setGrayIconColor(key, Theme.getColor(key));
cell.setDrawDivider(holder.getAdapterPosition() != getItemCount() - 2);
}
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
switch (holder.getItemViewType()) {
case VIEW_TYPE_INVITE_MEMBERS:
GroupCallTextCell textCell = (GroupCallTextCell) holder.itemView;
int color = AndroidUtilities.getOffsetColor(Theme.getColor(Theme.key_voipgroup_lastSeenTextUnscrolled), Theme.getColor(Theme.key_voipgroup_lastSeenText), actionBar.getTag() != null ? 1.0f : 0.0f, 1.0f);
textCell.setColors(color, color);
if (ChatObject.isChannel(currentChat) && !currentChat.megagroup && !TextUtils.isEmpty(currentChat.username)) {
textCell.setTextAndIcon(LocaleController.getString("VoipGroupShareLink", R.string.VoipGroupShareLink), R.drawable.msg_link, false);
} else {
textCell.setTextAndIcon(LocaleController.getString("VoipGroupInviteMember", R.string.VoipGroupInviteMember), R.drawable.msg_contact_add, false);
}
break;
case VIEW_TYPE_PARTICIPANT: {
GroupCallUserCell userCell = (GroupCallUserCell) holder.itemView;
TLRPC.TL_groupCallParticipant participant;
int row = position - usersStartRow;
if (delayedGroupCallUpdated) {
if (row >= 0 && row < oldParticipants.size()) {
participant = oldParticipants.get(row);
} else {
participant = null;
}
} else {
if (row >= 0 && row < call.visibleParticipants.size()) {
participant = call.visibleParticipants.get(row);
} else {
participant = null;
}
}
if (participant != null) {
long peerId = MessageObject.getPeerId(participant.peer);
long selfPeerId = MessageObject.getPeerId(selfPeer);
TLRPC.FileLocation uploadingAvatar = (peerId == selfPeerId && avatarUpdaterDelegate != null) ? avatarUpdaterDelegate.avatar : null;
float uploadingProgress = (uploadingAvatar != null) ? avatarUpdaterDelegate.uploadingProgress : 1f;
boolean animated = userCell.getParticipant() != null && MessageObject.getPeerId(userCell.getParticipant().peer) == peerId;
userCell.setData(accountInstance, participant, call, selfPeerId, uploadingAvatar, animated);
userCell.setUploadProgress(uploadingProgress, animated);
}
break;
}
case VIEW_TYPE_CALL_INVITED: {
GroupCallInvitedCell invitedCell = (GroupCallInvitedCell) holder.itemView;
Long uid;
int row = position - invitedStartRow;
if (delayedGroupCallUpdated) {
if (row >= 0 && row < oldInvited.size()) {
uid = oldInvited.get(row);
} else {
uid = null;
}
} else {
if (row >= 0 && row < call.invitedUsers.size()) {
uid = call.invitedUsers.get(row);
} else {
uid = null;
}
}
if (uid != null) {
invitedCell.setData(currentAccount, uid);
}
break;
}
case VIEW_TYPE_GRID: {
GroupCallGridCell userCell = (GroupCallGridCell) holder.itemView;
ChatObject.VideoParticipant oldParticipant = userCell.getParticipant();
int row = position - usersVideoGridStartRow;
userCell.spanCount = spanSizeLookup.getSpanSize(position);
ChatObject.VideoParticipant participant;
if (delayedGroupCallUpdated) {
if (row >= 0 && row < oldVideoParticipants.size()) {
participant = oldVideoParticipants.get(row);
} else {
participant = null;
}
} else {
if (row >= 0 && row < visibleVideoParticipants.size()) {
participant = visibleVideoParticipants.get(row);
} else {
participant = null;
}
}
if (participant != null) {
long peerId = MessageObject.getPeerId(participant.participant.peer);
long selfPeerId = MessageObject.getPeerId(selfPeer);
TLRPC.FileLocation uploadingAvatar = (peerId == selfPeerId && avatarUpdaterDelegate != null) ? avatarUpdaterDelegate.avatar : null;
float uploadingProgress = (uploadingAvatar != null) ? avatarUpdaterDelegate.uploadingProgress : 1f;
boolean animated = userCell.getParticipant() != null && userCell.getParticipant().equals(participant);
userCell.setData(accountInstance, participant, call, selfPeerId);
}
if (oldParticipant != null && !oldParticipant.equals(participant) && userCell.attached && userCell.getRenderer() != null) {
attachRenderer(userCell, false);
attachRenderer(userCell, true);
}
break;
}
}
}
@Override
public boolean isEnabled(RecyclerView.ViewHolder holder) {
int type = holder.getItemViewType();
return !(type == VIEW_TYPE_LAST_PADDING || type == VIEW_TYPE_GRID || type == VIEW_TYPE_VIDEO_GRID_DIVIDER || type == VIEW_TYPE_VIDEO_NOT_AVAILABLE);
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case VIEW_TYPE_INVITE_MEMBERS:
view = new GroupCallTextCell(mContext) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (AndroidUtilities.isTablet()) {
int w = Math.min(AndroidUtilities.dp(420), MeasureSpec.getSize(widthMeasureSpec));
super.onMeasure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY), heightMeasureSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
};
break;
case VIEW_TYPE_PARTICIPANT:
view = new GroupCallUserCell(mContext) {
@Override
protected void onMuteClick(GroupCallUserCell cell) {
showMenuForCell(cell);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (AndroidUtilities.isTablet()) {
int w = Math.min(AndroidUtilities.dp(420), MeasureSpec.getSize(widthMeasureSpec));
super.onMeasure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY), heightMeasureSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
};
break;
case VIEW_TYPE_CALL_INVITED:
view = new GroupCallInvitedCell(mContext) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (AndroidUtilities.isTablet()) {
int w = Math.min(AndroidUtilities.dp(420), MeasureSpec.getSize(widthMeasureSpec));
super.onMeasure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY), heightMeasureSpec);
} else {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
};
break;
case VIEW_TYPE_GRID:
view = new GroupCallGridCell(mContext, false) {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
if (listView.getVisibility() == View.VISIBLE && listViewVideoVisibility) {
attachRenderer(this, true);
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
attachRenderer(this, false);
}
};
break;
case VIEW_TYPE_VIDEO_GRID_DIVIDER:
view = new View(mContext) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(AndroidUtilities.dp(isLandscapeMode ? 0 : 8), MeasureSpec.EXACTLY));
}
};
break;
case VIEW_TYPE_VIDEO_NOT_AVAILABLE:
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));
if (ChatObject.isChannelOrGiga(currentChat)) {
textView.setText(LocaleController.formatString("VoipChannelVideoNotAvailableAdmin", R.string.VoipChannelVideoNotAvailableAdmin, LocaleController.formatPluralString("Participants", accountInstance.getMessagesController().groupCallVideoMaxParticipants)));
} else {
textView.setText(LocaleController.formatString("VoipVideoNotAvailableAdmin", R.string.VoipVideoNotAvailableAdmin, LocaleController.formatPluralString("Members", accountInstance.getMessagesController().groupCallVideoMaxParticipants)));
}
view = textView;
break;
case VIEW_TYPE_LAST_PADDING:
default:
view = new View(mContext);
break;
}
RecyclerView.LayoutParams params = new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT);
view.setLayoutParams(params);
return new RecyclerListView.Holder(view);
}
@Override
public int getItemViewType(int position) {
if (position == lastRow) {
return VIEW_TYPE_LAST_PADDING;
} else if (position == addMemberRow) {
return VIEW_TYPE_INVITE_MEMBERS;
} else if (position == videoGridDividerRow) {
return VIEW_TYPE_VIDEO_GRID_DIVIDER;
} else if (position >= usersStartRow && position < usersEndRow) {
return VIEW_TYPE_PARTICIPANT;
} else if (position >= usersVideoGridStartRow && position < usersVideoGridEndRow) {
return VIEW_TYPE_GRID;
} else if (position == videoNotAvailableRow) {
return VIEW_TYPE_VIDEO_NOT_AVAILABLE;
}
return VIEW_TYPE_CALL_INVITED;
}
}
private void attachRenderer(GroupCallGridCell cell, boolean attach) {
if (isDismissed()) {
return;
}
if (attach && cell.getRenderer() == null) {
cell.setRenderer(GroupCallMiniTextureView.getOrCreate(attachedRenderers, renderersContainer, cell, null, null, cell.getParticipant(), call, this));
} else if (!attach) {
if (cell.getRenderer() != null) {
cell.getRenderer().setPrimaryView(null);
cell.setRenderer(null);
}
}
}
private int oldAddMemberRow;
private int oldUsersStartRow;
private int oldUsersEndRow;
private int oldInvitedStartRow;
private int oldInvitedEndRow;
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, int videoNotAvailableRow) {
oldAddMemberRow = addMemberRow;
oldUsersStartRow = usersStartRow;
oldUsersEndRow = usersEndRow;
oldInvitedStartRow = invitedStartRow;
oldInvitedEndRow = invitedEndRow;
oldUsersVideoStartRow = usersVideoStartRow;
oldUsersVideoEndRow = usersVideoEndRow;
oldVideoDividerRow = videoDividerRow;
oldVideoNotAvailableRow = videoNotAvailableRow;
}
private DiffUtil.Callback diffUtilsCallback = new DiffUtil.Callback() {
@Override
public int getOldListSize() {
return oldCount;
}
@Override
public int getNewListSize() {
return listAdapter.rowsCount;
}
@Override
public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
if (listAdapter.addMemberRow >= 0) {
if (oldItemPosition == oldAddMemberRow && newItemPosition == listAdapter.addMemberRow) {
return true;
} else if (oldItemPosition == oldAddMemberRow && newItemPosition != listAdapter.addMemberRow ||
oldItemPosition != oldAddMemberRow && newItemPosition == listAdapter.addMemberRow) {
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;
}
if (oldItemPosition == oldCount - 1 && newItemPosition == listAdapter.rowsCount - 1) {
return true;
} else if (oldItemPosition == oldCount - 1 || newItemPosition == listAdapter.rowsCount - 1) {
return false;
}
if ((newItemPosition >= listAdapter.usersVideoGridStartRow && newItemPosition < listAdapter.usersVideoGridEndRow) &&
(oldItemPosition >= oldUsersVideoStartRow && oldItemPosition < oldUsersVideoEndRow)) {
ChatObject.VideoParticipant oldItem = oldVideoParticipants.get(oldItemPosition - oldUsersVideoStartRow);
ChatObject.VideoParticipant newItem = visibleVideoParticipants.get(newItemPosition - listAdapter.usersVideoGridStartRow);
return oldItem.equals(newItem);
} else if ((newItemPosition >= listAdapter.usersStartRow && newItemPosition < listAdapter.usersEndRow) &&
(oldItemPosition >= oldUsersStartRow && oldItemPosition < oldUsersEndRow)) {
TLRPC.TL_groupCallParticipant oldItem = oldParticipants.get(oldItemPosition - oldUsersStartRow);
TLRPC.TL_groupCallParticipant newItem = call.visibleParticipants.get(newItemPosition - listAdapter.usersStartRow);
return MessageObject.getPeerId(oldItem.peer) == MessageObject.getPeerId(newItem.peer) && (oldItemPosition == newItemPosition || oldItem.lastActiveDate == oldItem.active_date);
} else if (newItemPosition >= listAdapter.invitedStartRow && newItemPosition < listAdapter.invitedEndRow &&
oldItemPosition >= oldInvitedStartRow && oldItemPosition < oldInvitedEndRow) {
Long oldItem = oldInvited.get(oldItemPosition - oldInvitedStartRow);
Long newItem = call.invitedUsers.get(newItemPosition - listAdapter.invitedStartRow);
return oldItem.equals(newItem);
}
return false;
}
@Override
public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {
return true;
}
};
private static class UpdateCallback implements ListUpdateCallback {
final RecyclerView.Adapter adapter;
private UpdateCallback(RecyclerView.Adapter adapter) {
this.adapter = adapter;
}
@Override
public void onInserted(int position, int count) {
adapter.notifyItemRangeInserted(position, count);
}
@Override
public void onRemoved(int position, int count) {
adapter.notifyItemRangeRemoved(position, count);
}
@Override
public void onMoved(int fromPosition, int toPosition) {
adapter.notifyItemMoved(fromPosition, toPosition);
}
@Override
public void onChanged(int position, int count, @Nullable Object payload) {
adapter.notifyItemRangeChanged(position, count, payload);
}
}
private void toggleAdminSpeak() {
TLRPC.TL_phone_toggleGroupCallSettings req = new TLRPC.TL_phone_toggleGroupCallSettings();
req.call = call.getInputGroupCall();
req.join_muted = call.call.join_muted;
req.flags |= 1;
accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> {
if (response != null) {
accountInstance.getMessagesController().processUpdates((TLRPC.Updates) response, false);
}
});
}
@Override
public ArrayList<ThemeDescription> getThemeDescriptions() {
return new ArrayList<>();
}
@Override
public void onBackPressed() {
if (previewDialog != null) {
previewDialog.dismiss(false, false);
return;
}
if (avatarsPreviewShowed) {
dismissAvatarPreview(true);
return;
}
if (renderersContainer.inFullscreenMode) {
fullscreenFor(null);
return;
}
super.onBackPressed();
}
private class AvatarUpdaterDelegate implements ImageUpdater.ImageUpdaterDelegate {
public float uploadingProgress;
private TLRPC.FileLocation avatarBig;
private TLRPC.FileLocation avatar;
private ImageLocation uploadingImageLocation;
private final long peerId;
private AvatarUpdaterDelegate(long peerId) {
this.peerId = peerId;
}
@Override
public void didUploadPhoto(TLRPC.InputFile photo, TLRPC.InputFile video, double videoStartTimestamp, String videoPath, TLRPC.PhotoSize bigSize, TLRPC.PhotoSize smallSize) {
AndroidUtilities.runOnUIThread(() -> {
if (photo != null || video != null) {
if (peerId > 0) {
TLRPC.TL_photos_uploadProfilePhoto req = new TLRPC.TL_photos_uploadProfilePhoto();
if (photo != null) {
req.file = photo;
req.flags |= 1;
}
if (video != null) {
req.video = video;
req.flags |= 2;
req.video_start_ts = videoStartTimestamp;
req.flags |= 4;
}
accountInstance.getConnectionsManager().sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (uploadingImageLocation != null) {
avatarsViewPager.removeUploadingImage(uploadingImageLocation);
uploadingImageLocation = null;
}
if (error == null) {
TLRPC.User user = accountInstance.getMessagesController().getUser(accountInstance.getUserConfig().getClientUserId());
if (user == null) {
user = accountInstance.getUserConfig().getCurrentUser();
if (user == null) {
return;
}
accountInstance.getMessagesController().putUser(user, false);
} else {
accountInstance.getUserConfig().setCurrentUser(user);
}
TLRPC.TL_photos_photo photos_photo = (TLRPC.TL_photos_photo) response;
ArrayList<TLRPC.PhotoSize> sizes = photos_photo.photo.sizes;
TLRPC.PhotoSize small = FileLoader.getClosestPhotoSizeWithSize(sizes, 150);
TLRPC.PhotoSize big = FileLoader.getClosestPhotoSizeWithSize(sizes, 800);
TLRPC.VideoSize videoSize = photos_photo.photo.video_sizes.isEmpty() ? null : photos_photo.photo.video_sizes.get(0);
user.photo = new TLRPC.TL_userProfilePhoto();
user.photo.photo_id = photos_photo.photo.id;
if (small != null) {
user.photo.photo_small = small.location;
}
if (big != null) {
user.photo.photo_big = big.location;
}
if (small != null && avatar != null) {
File destFile = FileLoader.getInstance(currentAccount).getPathToAttach(small, true);
File src = FileLoader.getInstance(currentAccount).getPathToAttach(avatar, true);
src.renameTo(destFile);
String oldKey = avatar.volume_id + "_" + avatar.local_id + "@50_50";
String newKey = small.location.volume_id + "_" + small.location.local_id + "@50_50";
ImageLoader.getInstance().replaceImageInCache(oldKey, newKey, ImageLocation.getForUser(user, ImageLocation.TYPE_SMALL), false);
}
if (big != null && avatarBig != null) {
File destFile = FileLoader.getInstance(currentAccount).getPathToAttach(big, true);
File src = FileLoader.getInstance(currentAccount).getPathToAttach(avatarBig, true);
src.renameTo(destFile);
}
if (videoSize != null && videoPath != null) {
File destFile = FileLoader.getInstance(currentAccount).getPathToAttach(videoSize, "mp4", true);
File src = new File(videoPath);
src.renameTo(destFile);
}
accountInstance.getMessagesStorage().clearUserPhotos(user.id);
ArrayList<TLRPC.User> users = new ArrayList<>();
users.add(user);
accountInstance.getMessagesStorage().putUsersAndChats(users, null, false, true);
final ImageLocation imageLocation;
final ImageLocation thumbLocation;
TLRPC.User currentUser = accountInstance.getMessagesController().getUser(peerId);
imageLocation = ImageLocation.getForUser(currentUser, ImageLocation.TYPE_BIG);
thumbLocation = ImageLocation.getForUser(currentUser, ImageLocation.TYPE_SMALL);
ImageLocation thumb = ImageLocation.getForLocal(avatarBig);
if (thumb == null) {
thumb = ImageLocation.getForLocal(avatar);
} else {
thumb = thumbLocation;
}
avatarsViewPager.setCreateThumbFromParent(false);
avatarsViewPager.initIfEmpty(imageLocation, thumb, true);
avatar = null;
avatarBig = null;
AndroidUtilities.updateVisibleRows(listView);
updateAvatarUploadingProgress(1f);
}
accountInstance.getNotificationCenter().postNotificationName(NotificationCenter.updateInterfaces, MessagesController.UPDATE_MASK_ALL);
accountInstance.getNotificationCenter().postNotificationName(NotificationCenter.mainUserInfoChanged);
accountInstance.getUserConfig().saveConfig(true);
}));
} else {
accountInstance.getMessagesController().changeChatAvatar(-peerId, null, photo, video, videoStartTimestamp, videoPath, smallSize.location, bigSize.location, () -> {
if (uploadingImageLocation != null) {
avatarsViewPager.removeUploadingImage(uploadingImageLocation);
uploadingImageLocation = null;
}
TLRPC.Chat currentChat = accountInstance.getMessagesController().getChat(-peerId);
ImageLocation imageLocation = ImageLocation.getForChat(currentChat, ImageLocation.TYPE_BIG);
ImageLocation thumbLocation = ImageLocation.getForChat(currentChat, ImageLocation.TYPE_SMALL);
ImageLocation thumb = ImageLocation.getForLocal(avatarBig);
if (thumb == null) {
thumb = ImageLocation.getForLocal(avatar);
} else {
thumb = thumbLocation;
}
avatarsViewPager.setCreateThumbFromParent(false);
avatarsViewPager.initIfEmpty(imageLocation, thumb, true);
avatar = null;
avatarBig = null;
AndroidUtilities.updateVisibleRows(listView);
updateAvatarUploadingProgress(1f);
});
}
} else {
avatar = smallSize.location;
avatarBig = bigSize.location;
uploadingImageLocation = ImageLocation.getForLocal(avatarBig);
avatarsViewPager.addUploadingImage(uploadingImageLocation, ImageLocation.getForLocal(avatar));
AndroidUtilities.updateVisibleRows(listView);
}
});
}
@Override
public void didStartUpload(boolean isVideo) {
}
@Override
public void onUploadProgressChanged(float progress) {
avatarsViewPager.setUploadProgress(uploadingImageLocation, progress);
updateAvatarUploadingProgress(progress);
}
public void updateAvatarUploadingProgress(float progress) {
uploadingProgress = progress;
if (listView == null) {
return;
}
for (int i = 0; i < listView.getChildCount(); i++) {
View child = listView.getChildAt(i);
if (child instanceof GroupCallUserCell) {
GroupCallUserCell cell = ((GroupCallUserCell) child);
if (cell.isSelfUser()) {
cell.setUploadProgress(progress, true);
}
}
}
}
}
public View getScrimView() {
return scrimView;
}
@Override
public void onCameraSwitch(boolean isFrontFace) {
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
attachedRenderersTmp.get(i).updateAttachState(true);
}
if (previewDialog != null) {
previewDialog.update();
}
}
private class GroupCallItemAnimator extends DefaultItemAnimator {
public float animationProgress;
public ValueAnimator animator;
HashSet<RecyclerView.ViewHolder> addingHolders = new HashSet<>();
HashSet<RecyclerView.ViewHolder> removingHolders = new HashSet<>();
float outMaxBottom;
float outMinTop;
@Override
public void endAnimations() {
super.endAnimations();
removingHolders.clear();
addingHolders.clear();
outMinTop = Float.MAX_VALUE;
listView.invalidate();
}
public void updateBackgroundBeforeAnimation() {
if (animator != null) {
return;
}
addingHolders.clear();
addingHolders.addAll(mPendingAdditions);
removingHolders.clear();
removingHolders.addAll(mPendingRemovals);
outMaxBottom = 0;
outMinTop = Float.MAX_VALUE;
if (!addingHolders.isEmpty() || !removingHolders.isEmpty()) {
for (int a = 0, N = listView.getChildCount(); a < N; a++) {
View child = listView.getChildAt(a);
RecyclerView.ViewHolder holder = listView.findContainingViewHolder(child);
if (holder == null || holder.getItemViewType() == 3 || holder.getItemViewType() == 4 || holder.getItemViewType() == 5) {
continue;
}
if (!addingHolders.contains(holder)) {
outMaxBottom = Math.max(outMaxBottom, child.getY() + child.getMeasuredHeight());
outMinTop = Math.min(outMinTop, Math.max(0, child.getY()));
}
}
animationProgress = 0f;
listView.invalidate();
}
}
@Override
public void runPendingAnimations() {
boolean removalsPending = !mPendingRemovals.isEmpty();
boolean movesPending = !mPendingMoves.isEmpty();
boolean additionsPending = !mPendingAdditions.isEmpty();
if (animator != null) {
animator.cancel();
animator = null;
}
if (removalsPending || movesPending || additionsPending) {
animationProgress = 0f;
animator = ValueAnimator.ofFloat(0, 1f);
animator.addUpdateListener(valueAnimator -> {
animationProgress = (float) valueAnimator.getAnimatedValue();
listView.invalidate();
renderersContainer.invalidate();
containerView.invalidate();
updateLayout(true);
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
animator = null;
listView.invalidate();
renderersContainer.invalidate();
containerView.invalidate();
updateLayout(true);
addingHolders.clear();
removingHolders.clear();
}
});
animator.setDuration(TRANSITION_DURATION);
animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
animator.start();
listView.invalidate();
renderersContainer.invalidate();
}
super.runPendingAnimations();
}
}
@Override
protected boolean canDismissWithTouchOutside() {
return !renderersContainer.inFullscreenMode;
}
private void onUserLeaveHint() {
if (isRtmpStream() && AndroidUtilities.checkInlinePermissions(parentActivity) && !RTMPStreamPipOverlay.isVisible()) {
dismiss();
AndroidUtilities.runOnUIThread(RTMPStreamPipOverlay::show, 100);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
parentActivity.addOnUserLeaveHintListener(onUserLeaveHintListener);
}
public void onResume() {
paused = false;
listAdapter.notifyDataSetChanged();
if (fullscreenUsersListView.getVisibility() == View.VISIBLE) {
fullscreenAdapter.update(false, fullscreenUsersListView);
}
if (isTabletMode) {
tabletGridAdapter.update(false, tabletVideoGridView);
}
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
attachedRenderersTmp.get(i).updateAttachState(true);
}
}
public void onPause() {
paused = true;
attachedRenderersTmp.clear();
attachedRenderersTmp.addAll(attachedRenderers);
for (int i = 0; i < attachedRenderersTmp.size(); i++) {
attachedRenderersTmp.get(i).updateAttachState(false);
}
}
public boolean isRtmpLandscapeMode() {
return isRtmpStream() && !call.visibleVideoParticipants.isEmpty() && (call.visibleVideoParticipants.get(0).aspectRatio == 0 || call.visibleVideoParticipants.get(0).aspectRatio >= 1);
}
public boolean isRtmpStream() {
return call != null && call.call.rtmp_stream;
}
}