use of org.telegram.ui.Cells.ChatMessageCell in project Telegram-FOSS by Telegram-FOSS-Team.
the class ChatListItemAnimator method animateAddImpl.
@Override
public void animateAddImpl(RecyclerView.ViewHolder holder) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("animate add impl");
}
final View view = holder.itemView;
mAddAnimations.add(holder);
if (holder == greetingsSticker) {
view.setAlpha(1f);
}
AnimatorSet animatorSet = new AnimatorSet();
if (view instanceof ChatMessageCell) {
ChatMessageCell cell = (ChatMessageCell) view;
if (cell.getAnimationOffsetX() != 0) {
animatorSet.playTogether(ObjectAnimator.ofFloat(cell, cell.ANIMATION_OFFSET_X, cell.getAnimationOffsetX(), 0f));
}
float pivotX = cell.getBackgroundDrawableLeft() + (cell.getBackgroundDrawableRight() - cell.getBackgroundDrawableLeft()) / 2f;
cell.setPivotX(pivotX);
view.animate().translationY(0).setDuration(getAddDuration()).start();
} else {
view.animate().translationX(0).translationY(0).setDuration(getAddDuration()).start();
}
boolean useScale = true;
long currentDelay = (long) ((1f - Math.max(0, Math.min(1f, view.getBottom() / (float) recyclerListView.getMeasuredHeight()))) * 100);
if (view instanceof ChatMessageCell) {
if (holder == greetingsSticker) {
useScale = false;
if (chatGreetingsView != null) {
chatGreetingsView.stickerToSendView.setAlpha(0f);
}
recyclerListView.setClipChildren(false);
ChatMessageCell messageCell = (ChatMessageCell) view;
View parentForGreetingsView = (View) chatGreetingsView.getParent();
float fromX = chatGreetingsView.stickerToSendView.getX() + chatGreetingsView.getX() + parentForGreetingsView.getX();
float fromY = chatGreetingsView.stickerToSendView.getY() + chatGreetingsView.getY() + parentForGreetingsView.getY();
float toX = messageCell.getPhotoImage().getImageX() + recyclerListView.getX() + messageCell.getX();
float toY = messageCell.getPhotoImage().getImageY() + recyclerListView.getY() + messageCell.getY();
float fromW = chatGreetingsView.stickerToSendView.getWidth();
float fromH = chatGreetingsView.stickerToSendView.getHeight();
float toW = messageCell.getPhotoImage().getImageWidth();
float toH = messageCell.getPhotoImage().getImageHeight();
float deltaX = fromX - toX;
float deltaY = fromY - toY;
toX = messageCell.getPhotoImage().getImageX();
toY = messageCell.getPhotoImage().getImageY();
messageCell.getTransitionParams().imageChangeBoundsTransition = true;
messageCell.getTransitionParams().animateDrawingTimeAlpha = true;
messageCell.getPhotoImage().setImageCoords(toX + deltaX, toX + deltaY, fromW, fromH);
ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1f);
float finalToX = toX;
float finalToY = toY;
valueAnimator.addUpdateListener(animation -> {
float v = (float) animation.getAnimatedValue();
messageCell.getTransitionParams().animateChangeProgress = v;
if (messageCell.getTransitionParams().animateChangeProgress > 1) {
messageCell.getTransitionParams().animateChangeProgress = 1f;
}
messageCell.getPhotoImage().setImageCoords(finalToX + deltaX * (1f - v), finalToY + deltaY * (1f - v), fromW * (1f - v) + toW * v, fromH * (1f - v) + toH * v);
messageCell.invalidate();
});
valueAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
messageCell.getTransitionParams().resetAnimation();
messageCell.getPhotoImage().setImageCoords(finalToX, finalToY, toW, toH);
if (chatGreetingsView != null) {
chatGreetingsView.stickerToSendView.setAlpha(1f);
}
messageCell.invalidate();
}
});
animatorSet.play(valueAnimator);
} else {
MessageObject.GroupedMessages groupedMessages = ((ChatMessageCell) view).getCurrentMessagesGroup();
if (groupedMessages != null) {
Long groupDelay = groupIdToEnterDelay.get(groupedMessages.groupId);
if (groupDelay == null) {
groupIdToEnterDelay.put(groupedMessages.groupId, currentDelay);
} else {
currentDelay = groupDelay;
}
}
if (groupedMessages != null && groupedMessages.transitionParams.backgroundChangeBounds) {
animatorSet.setStartDelay(140);
}
}
}
view.setAlpha(0f);
animatorSet.playTogether(ObjectAnimator.ofFloat(view, View.ALPHA, view.getAlpha(), 1f));
if (useScale) {
view.setScaleX(0.9f);
view.setScaleY(0.9f);
animatorSet.playTogether(ObjectAnimator.ofFloat(view, View.SCALE_Y, view.getScaleY(), 1f));
animatorSet.playTogether(ObjectAnimator.ofFloat(view, View.SCALE_X, view.getScaleX(), 1f));
} else {
view.setScaleX(1f);
view.setScaleY(1f);
}
if (holder == greetingsSticker) {
animatorSet.setDuration(350);
animatorSet.setInterpolator(new OvershootInterpolator());
} else {
animatorSet.setStartDelay(currentDelay);
animatorSet.setDuration(DEFAULT_DURATION);
}
animatorSet.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchAddStarting(holder);
}
@Override
public void onAnimationCancel(Animator animator) {
view.setAlpha(1);
}
@Override
public void onAnimationEnd(Animator animator) {
animator.removeAllListeners();
view.setAlpha(1f);
view.setScaleX(1f);
view.setScaleY(1f);
view.setTranslationY(0f);
view.setTranslationY(0f);
if (mAddAnimations.remove(holder)) {
dispatchAddFinished(holder);
dispatchFinishedWhenDone();
}
}
});
animators.put(holder, animatorSet);
animatorSet.start();
}
use of org.telegram.ui.Cells.ChatMessageCell in project Telegram-FOSS by Telegram-FOSS-Team.
the class ChatListItemAnimator method animateRemove.
@Override
public boolean animateRemove(RecyclerView.ViewHolder holder, ItemHolderInfo info) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("animate remove");
}
boolean rez = super.animateRemove(holder, info);
if (rez) {
if (info != null) {
int fromY = info.top;
int toY = holder.itemView.getTop();
int fromX = info.left;
int toX = holder.itemView.getLeft();
int deltaX = toX - fromX;
int deltaY = toY - fromY;
if (deltaY != 0) {
holder.itemView.setTranslationY(-deltaY);
}
if (holder.itemView instanceof ChatMessageCell) {
ChatMessageCell chatMessageCell = (ChatMessageCell) holder.itemView;
if (deltaX != 0) {
chatMessageCell.setAnimationOffsetX(-deltaX);
}
if (info instanceof ItemHolderInfoExtended) {
ItemHolderInfoExtended infoExtended = ((ItemHolderInfoExtended) info);
chatMessageCell.setImageCoords(infoExtended.imageX, infoExtended.imageY, infoExtended.imageWidth, infoExtended.imageHeight);
}
} else {
if (deltaX != 0) {
holder.itemView.setTranslationX(-deltaX);
}
}
}
}
return rez;
}
use of org.telegram.ui.Cells.ChatMessageCell in project Telegram-FOSS by Telegram-FOSS-Team.
the class ChatListItemAnimator method animateChangeImpl.
void animateChangeImpl(final ChangeInfo changeInfo) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("animate change impl");
}
final RecyclerView.ViewHolder holder = changeInfo.oldHolder;
final View view = holder == null ? null : holder.itemView;
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;
final View newView = newHolder != null ? newHolder.itemView : null;
if (view != null) {
final ViewPropertyAnimator oldViewAnim = view.animate().setDuration(getChangeDuration());
mChangeAnimations.add(changeInfo.oldHolder);
oldViewAnim.translationX(changeInfo.toX - changeInfo.fromX);
oldViewAnim.translationY(changeInfo.toY - changeInfo.fromY);
oldViewAnim.alpha(0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchChangeStarting(changeInfo.oldHolder, true);
}
@Override
public void onAnimationEnd(Animator animator) {
oldViewAnim.setListener(null);
view.setAlpha(1);
view.setScaleX(1f);
view.setScaleX(1f);
if (view instanceof ChatMessageCell) {
((ChatMessageCell) view).setAnimationOffsetX(0);
} else {
view.setTranslationX(0);
}
view.setTranslationY(0);
if (mChangeAnimations.remove(changeInfo.oldHolder)) {
dispatchChangeFinished(changeInfo.oldHolder, true);
dispatchFinishedWhenDone();
}
}
}).start();
}
if (newView != null) {
final ViewPropertyAnimator newViewAnimation = newView.animate();
mChangeAnimations.add(changeInfo.newHolder);
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration()).alpha(1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchChangeStarting(changeInfo.newHolder, false);
}
@Override
public void onAnimationEnd(Animator animator) {
newViewAnimation.setListener(null);
newView.setAlpha(1);
newView.setScaleX(1f);
newView.setScaleX(1f);
if (newView instanceof ChatMessageCell) {
((ChatMessageCell) newView).setAnimationOffsetX(0);
} else {
newView.setTranslationX(0);
}
newView.setTranslationY(0);
if (mChangeAnimations.remove(changeInfo.newHolder)) {
dispatchChangeFinished(changeInfo.newHolder, false);
dispatchFinishedWhenDone();
}
}
}).start();
}
}
use of org.telegram.ui.Cells.ChatMessageCell in project Telegram-FOSS by Telegram-FOSS-Team.
the class ChatListItemAnimator method animateMove.
@Override
public boolean animateMove(RecyclerView.ViewHolder holder, ItemHolderInfo info, int fromX, int fromY, int toX, int toY) {
if (BuildVars.LOGS_ENABLED) {
FileLog.d("animate move");
}
final View view = holder.itemView;
ChatMessageCell chatMessageCell = null;
if (holder.itemView instanceof ChatMessageCell) {
chatMessageCell = ((ChatMessageCell) holder.itemView);
fromX += (int) chatMessageCell.getAnimationOffsetX();
if (chatMessageCell.getTransitionParams().lastTopOffset != chatMessageCell.getTopMediaOffset()) {
fromY += chatMessageCell.getTransitionParams().lastTopOffset - chatMessageCell.getTopMediaOffset();
}
} else {
fromX += (int) holder.itemView.getTranslationX();
}
fromY += (int) holder.itemView.getTranslationY();
float imageX = 0;
float imageY = 0;
float imageW = 0;
float imageH = 0;
int[] roundRadius = new int[4];
if (chatMessageCell != null) {
imageX = chatMessageCell.getPhotoImage().getImageX();
imageY = chatMessageCell.getPhotoImage().getImageY();
imageW = chatMessageCell.getPhotoImage().getImageWidth();
imageH = chatMessageCell.getPhotoImage().getImageHeight();
for (int i = 0; i < 4; i++) {
roundRadius[i] = chatMessageCell.getPhotoImage().getRoundRadius()[i];
}
}
resetAnimation(holder);
int deltaX = toX - fromX;
int deltaY = toY - fromY;
if (deltaY != 0) {
view.setTranslationY(-deltaY);
}
MoveInfoExtended moveInfo = new MoveInfoExtended(holder, fromX, fromY, toX, toY);
if (chatMessageCell != null) {
ChatMessageCell.TransitionParams params = chatMessageCell.getTransitionParams();
if (!params.supportChangeAnimation()) {
if (deltaX == 0 && deltaY == 0) {
dispatchMoveFinished(holder);
return false;
}
if (deltaX != 0) {
view.setTranslationX(-deltaX);
}
mPendingMoves.add(moveInfo);
checkIsRunning();
return true;
}
MessageObject.GroupedMessages group = chatMessageCell.getCurrentMessagesGroup();
if (deltaX != 0) {
chatMessageCell.setAnimationOffsetX(-deltaX);
}
if (info instanceof ItemHolderInfoExtended) {
ImageReceiver newImage = chatMessageCell.getPhotoImage();
ItemHolderInfoExtended infoExtended = ((ItemHolderInfoExtended) info);
moveInfo.animateImage = params.wasDraw && infoExtended.imageHeight != 0 && infoExtended.imageWidth != 0;
if (moveInfo.animateImage) {
recyclerListView.setClipChildren(false);
recyclerListView.invalidate();
params.imageChangeBoundsTransition = true;
if (chatMessageCell.getMessageObject().isRoundVideo()) {
params.animateToImageX = imageX;
params.animateToImageY = imageY;
params.animateToImageW = imageW;
params.animateToImageH = imageH;
params.animateToRadius = roundRadius;
} else {
params.animateToImageX = newImage.getImageX();
params.animateToImageY = newImage.getImageY();
params.animateToImageW = newImage.getImageWidth();
params.animateToImageH = newImage.getImageHeight();
params.animateToRadius = newImage.getRoundRadius();
}
params.animateRadius = false;
for (int i = 0; i < 4; i++) {
if (params.imageRoundRadius[i] != params.animateToRadius[i]) {
params.animateRadius = true;
break;
}
}
if (params.animateToImageX == infoExtended.imageX && params.animateToImageY == infoExtended.imageY && params.animateToImageH == infoExtended.imageHeight && params.animateToImageW == infoExtended.imageWidth && !params.animateRadius) {
params.imageChangeBoundsTransition = false;
moveInfo.animateImage = false;
} else {
moveInfo.imageX = infoExtended.imageX;
moveInfo.imageY = infoExtended.imageY;
moveInfo.imageWidth = infoExtended.imageWidth;
moveInfo.imageHeight = infoExtended.imageHeight;
if (group != null && group.hasCaption != group.transitionParams.drawCaptionLayout) {
group.transitionParams.captionEnterProgress = group.transitionParams.drawCaptionLayout ? 1f : 0;
}
if (params.animateRadius) {
if (params.animateToRadius == newImage.getRoundRadius()) {
params.animateToRadius = new int[4];
for (int i = 0; i < 4; i++) {
params.animateToRadius[i] = newImage.getRoundRadius()[i];
}
}
newImage.setRoundRadius(params.imageRoundRadius);
}
chatMessageCell.setImageCoords(moveInfo.imageX, moveInfo.imageY, moveInfo.imageWidth, moveInfo.imageHeight);
}
}
if (group == null && params.wasDraw) {
boolean isOut = chatMessageCell.getMessageObject().isOutOwner();
boolean widthChanged = (isOut && params.lastDrawingBackgroundRect.left != chatMessageCell.getBackgroundDrawableLeft()) || (!isOut && params.lastDrawingBackgroundRect.right != chatMessageCell.getBackgroundDrawableRight());
if (widthChanged || params.lastDrawingBackgroundRect.top != chatMessageCell.getBackgroundDrawableTop() || params.lastDrawingBackgroundRect.bottom != chatMessageCell.getBackgroundDrawableBottom()) {
moveInfo.deltaBottom = chatMessageCell.getBackgroundDrawableBottom() - params.lastDrawingBackgroundRect.bottom;
moveInfo.deltaTop = chatMessageCell.getBackgroundDrawableTop() - params.lastDrawingBackgroundRect.top;
if (isOut) {
moveInfo.deltaLeft = chatMessageCell.getBackgroundDrawableLeft() - params.lastDrawingBackgroundRect.left;
} else {
moveInfo.deltaRight = chatMessageCell.getBackgroundDrawableRight() - params.lastDrawingBackgroundRect.right;
}
moveInfo.animateBackgroundOnly = true;
params.animateBackgroundBoundsInner = true;
params.animateBackgroundWidth = widthChanged;
params.deltaLeft = -moveInfo.deltaLeft;
params.deltaRight = -moveInfo.deltaRight;
params.deltaTop = -moveInfo.deltaTop;
params.deltaBottom = -moveInfo.deltaBottom;
recyclerListView.setClipChildren(false);
recyclerListView.invalidate();
}
}
}
if (group != null) {
if (willChangedGroups.contains(group)) {
willChangedGroups.remove(group);
RecyclerListView recyclerListView = (RecyclerListView) holder.itemView.getParent();
int animateToLeft = 0;
int animateToRight = 0;
int animateToTop = 0;
int animateToBottom = 0;
boolean allVisibleItemsDeleted = true;
MessageObject.GroupedMessages.TransitionParams groupTransitionParams = group.transitionParams;
ChatMessageCell lastDrawingCell = null;
for (int i = 0; i < recyclerListView.getChildCount(); i++) {
View child = recyclerListView.getChildAt(i);
if (child instanceof ChatMessageCell) {
ChatMessageCell cell = (ChatMessageCell) child;
if (cell.getCurrentMessagesGroup() == group && !cell.getMessageObject().deleted) {
int left = cell.getLeft() + cell.getBackgroundDrawableLeft();
int right = cell.getLeft() + cell.getBackgroundDrawableRight();
int top = cell.getTop() + cell.getBackgroundDrawableTop();
int bottom = cell.getTop() + cell.getBackgroundDrawableBottom();
if (animateToLeft == 0 || left < animateToLeft) {
animateToLeft = left;
}
if (animateToRight == 0 || right > animateToRight) {
animateToRight = right;
}
if (cell.getTransitionParams().wasDraw || groupTransitionParams.isNewGroup) {
lastDrawingCell = cell;
allVisibleItemsDeleted = false;
if (animateToTop == 0 || top < animateToTop) {
animateToTop = top;
}
if (animateToBottom == 0 || bottom > animateToBottom) {
animateToBottom = bottom;
}
}
}
}
}
groupTransitionParams.isNewGroup = false;
if (animateToTop == 0 && animateToBottom == 0 && animateToLeft == 0 && animateToRight == 0) {
moveInfo.animateChangeGroupBackground = false;
groupTransitionParams.backgroundChangeBounds = false;
} else {
moveInfo.groupOffsetTop = -animateToTop + groupTransitionParams.top;
moveInfo.groupOffsetBottom = -animateToBottom + groupTransitionParams.bottom;
moveInfo.groupOffsetLeft = -animateToLeft + groupTransitionParams.left;
moveInfo.groupOffsetRight = -animateToRight + groupTransitionParams.right;
moveInfo.animateChangeGroupBackground = true;
groupTransitionParams.backgroundChangeBounds = true;
groupTransitionParams.offsetTop = moveInfo.groupOffsetTop;
groupTransitionParams.offsetBottom = moveInfo.groupOffsetBottom;
groupTransitionParams.offsetLeft = moveInfo.groupOffsetLeft;
groupTransitionParams.offsetRight = moveInfo.groupOffsetRight;
groupTransitionParams.captionEnterProgress = groupTransitionParams.drawCaptionLayout ? 1f : 0f;
recyclerListView.setClipChildren(false);
recyclerListView.invalidate();
}
groupTransitionParams.drawBackgroundForDeletedItems = allVisibleItemsDeleted;
}
}
MessageObject.GroupedMessages removedGroup = willRemovedGroup.get(chatMessageCell.getMessageObject().getId());
if (removedGroup != null) {
MessageObject.GroupedMessages.TransitionParams groupTransitionParams = removedGroup.transitionParams;
willRemovedGroup.remove(chatMessageCell.getMessageObject().getId());
if (params.wasDraw) {
// invoke when group transform to single message
int animateToLeft = chatMessageCell.getLeft() + chatMessageCell.getBackgroundDrawableLeft();
int animateToRight = chatMessageCell.getLeft() + chatMessageCell.getBackgroundDrawableRight();
int animateToTop = chatMessageCell.getTop() + chatMessageCell.getBackgroundDrawableTop();
int animateToBottom = chatMessageCell.getTop() + chatMessageCell.getBackgroundDrawableBottom();
params.animateBackgroundBoundsInner = moveInfo.animateRemoveGroup = true;
moveInfo.deltaLeft = animateToLeft - groupTransitionParams.left;
moveInfo.deltaRight = animateToRight - groupTransitionParams.right;
moveInfo.deltaTop = animateToTop - groupTransitionParams.top;
moveInfo.deltaBottom = animateToBottom - groupTransitionParams.bottom;
moveInfo.animateBackgroundOnly = false;
params.deltaLeft = (int) (-moveInfo.deltaLeft - chatMessageCell.getAnimationOffsetX());
params.deltaRight = (int) (-moveInfo.deltaRight - chatMessageCell.getAnimationOffsetX());
params.deltaTop = (int) (-moveInfo.deltaTop - chatMessageCell.getTranslationY());
params.deltaBottom = (int) (-moveInfo.deltaBottom - chatMessageCell.getTranslationY());
params.transformGroupToSingleMessage = true;
recyclerListView.setClipChildren(false);
recyclerListView.invalidate();
} else {
groupTransitionParams.drawBackgroundForDeletedItems = true;
}
}
boolean drawPinnedBottom = chatMessageCell.isDrawPinnedBottom();
if (params.drawPinnedBottomBackground != drawPinnedBottom) {
moveInfo.animatePinnedBottom = true;
params.changePinnedBottomProgress = 0;
}
moveInfo.animateChangeInternal = chatMessageCell.getTransitionParams().animateChange();
if (moveInfo.animateChangeInternal) {
chatMessageCell.getTransitionParams().animateChange = true;
chatMessageCell.getTransitionParams().animateChangeProgress = 0f;
}
if (deltaX == 0 && deltaY == 0 && !moveInfo.animateImage && !moveInfo.animateRemoveGroup && !moveInfo.animateChangeGroupBackground && !moveInfo.animatePinnedBottom && !moveInfo.animateBackgroundOnly && !moveInfo.animateChangeInternal) {
dispatchMoveFinished(holder);
return false;
}
} else if (holder.itemView instanceof BotHelpCell) {
BotHelpCell botInfo = (BotHelpCell) holder.itemView;
botInfo.setAnimating(true);
} else {
if (deltaX == 0 && deltaY == 0) {
dispatchMoveFinished(holder);
return false;
}
if (deltaX != 0) {
view.setTranslationX(-deltaX);
}
}
mPendingMoves.add(moveInfo);
checkIsRunning();
return true;
}
use of org.telegram.ui.Cells.ChatMessageCell in project Telegram-FOSS by Telegram-FOSS-Team.
the class ChatListItemAnimator method runMessageEnterTransition.
private void runMessageEnterTransition() {
boolean removalsPending = !mPendingRemovals.isEmpty();
boolean movesPending = !mPendingMoves.isEmpty();
boolean changesPending = !mPendingChanges.isEmpty();
boolean additionsPending = !mPendingAdditions.isEmpty();
if (!removalsPending && !movesPending && !additionsPending && !changesPending) {
return;
}
int addedItemsHeight = 0;
for (int i = 0; i < mPendingAdditions.size(); i++) {
View view = mPendingAdditions.get(i).itemView;
if (view instanceof ChatMessageCell) {
ChatMessageCell cell = ((ChatMessageCell) view);
if (cell.getCurrentPosition() != null && (cell.getCurrentPosition().flags & MessageObject.POSITION_FLAG_LEFT) == 0) {
continue;
}
}
addedItemsHeight += mPendingAdditions.get(i).itemView.getHeight();
}
for (RecyclerView.ViewHolder holder : mPendingRemovals) {
animateRemoveImpl(holder);
}
mPendingRemovals.clear();
if (movesPending) {
final ArrayList<MoveInfo> moves = new ArrayList<>();
moves.addAll(mPendingMoves);
mPendingMoves.clear();
for (MoveInfo moveInfo : moves) {
animateMoveImpl(moveInfo.holder, moveInfo);
}
moves.clear();
}
if (additionsPending) {
final ArrayList<RecyclerView.ViewHolder> additions = new ArrayList<>();
additions.addAll(mPendingAdditions);
mPendingAdditions.clear();
for (RecyclerView.ViewHolder holder : additions) {
animateAddImpl(holder, addedItemsHeight);
}
additions.clear();
}
}
Aggregations