NekoX/TMessagesProj/src/main/java/org/telegram/ui/Components/BotWebViewSheet.java

898 lines
42 KiB
Java

package org.telegram.ui.Components;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.ColorUtils;
import androidx.core.math.MathUtils;
import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
import org.json.JSONObject;
import org.telegram.messenger.AndroidUtilities;
import org.telegram.messenger.ContactsController;
import org.telegram.messenger.FileLog;
import org.telegram.messenger.LocaleController;
import org.telegram.messenger.MessagesController;
import org.telegram.messenger.NotificationCenter;
import org.telegram.messenger.R;
import org.telegram.messenger.UserObject;
import org.telegram.messenger.Utilities;
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.ActionBarMenu;
import org.telegram.ui.ActionBar.ActionBarMenuItem;
import org.telegram.ui.ActionBar.ActionBarMenuSubItem;
import org.telegram.ui.ActionBar.AlertDialog;
import org.telegram.ui.ActionBar.BaseFragment;
import org.telegram.ui.ActionBar.Theme;
import org.telegram.ui.ChatActivity;
import org.telegram.ui.LaunchActivity;
import org.telegram.ui.PaymentFormActivity;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Locale;
public class BotWebViewSheet extends Dialog implements NotificationCenter.NotificationCenterDelegate {
public final static int TYPE_WEB_VIEW_BUTTON = 0, TYPE_SIMPLE_WEB_VIEW_BUTTON = 1, TYPE_BOT_MENU_BUTTON = 2;
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
TYPE_WEB_VIEW_BUTTON,
TYPE_SIMPLE_WEB_VIEW_BUTTON,
TYPE_BOT_MENU_BUTTON
})
public @interface WebViewType {}
private final static int POLL_PERIOD = 60000;
private final static SimpleFloatPropertyCompat<BotWebViewSheet> ACTION_BAR_TRANSITION_PROGRESS_VALUE = new SimpleFloatPropertyCompat<BotWebViewSheet>("actionBarTransitionProgress", obj -> obj.actionBarTransitionProgress, (obj, value) -> {
obj.actionBarTransitionProgress = value;
obj.frameLayout.invalidate();
obj.actionBar.setAlpha(value);
obj.updateLightStatusBar();
}).setMultiplier(100f);
private float actionBarTransitionProgress = 0f;
private SpringAnimation springAnimation;
private Boolean wasLightStatusBar;
private SizeNotifierFrameLayout frameLayout;
private long lastSwipeTime;
private ChatAttachAlertBotWebViewLayout.WebViewSwipeContainer swipeContainer;
private BotWebViewContainer webViewContainer;
private ChatAttachAlertBotWebViewLayout.WebProgressView progressView;
private Theme.ResourcesProvider resourcesProvider;
private boolean ignoreLayout;
private int currentAccount;
private long botId;
private long peerId;
private long queryId;
private int replyToMsgId;
private boolean silent;
private String buttonText;
private Paint linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint dimPaint = new Paint();
private Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int actionBarColor;
private Paint actionBarPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private boolean overrideBackgroundColor;
private ActionBar actionBar;
private Drawable actionBarShadow;
private ActionBarMenuSubItem settingsItem;
private boolean dismissed;
private Activity parentActivity;
private boolean mainButtonWasVisible, mainButtonProgressWasVisible;
private TextView mainButton;
private RadialProgressView radialProgressView;
private boolean needCloseConfirmation;
private VerticalPositionAutoAnimator mainButtonAutoAnimator, radialProgressAutoAnimator;
private Runnable pollRunnable = () -> {
if (!dismissed) {
TLRPC.TL_messages_prolongWebView prolongWebView = new TLRPC.TL_messages_prolongWebView();
prolongWebView.bot = MessagesController.getInstance(currentAccount).getInputUser(botId);
prolongWebView.peer = MessagesController.getInstance(currentAccount).getInputPeer(peerId);
prolongWebView.query_id = queryId;
prolongWebView.silent = silent;
if (replyToMsgId != 0) {
prolongWebView.reply_to_msg_id = replyToMsgId;
prolongWebView.flags |= 1;
}
ConnectionsManager.getInstance(currentAccount).sendRequest(prolongWebView, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (dismissed) {
return;
}
if (error != null) {
dismiss();
} else {
AndroidUtilities.runOnUIThread(this.pollRunnable, POLL_PERIOD);
}
}));
}
};
public BotWebViewSheet(@NonNull Context context, Theme.ResourcesProvider resourcesProvider) {
super(context, R.style.TransparentDialog);
this.resourcesProvider = resourcesProvider;
swipeContainer = new ChatAttachAlertBotWebViewLayout.WebViewSwipeContainer(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int availableHeight = MeasureSpec.getSize(heightMeasureSpec);
int padding;
if (!AndroidUtilities.isTablet() && AndroidUtilities.displaySize.x > AndroidUtilities.displaySize.y) {
padding = (int) (availableHeight / 3.5f);
} else {
padding = (availableHeight / 5 * 2);
}
if (padding < 0) {
padding = 0;
}
if (getOffsetY() != padding && !dismissed) {
ignoreLayout = true;
setOffsetY(padding);
ignoreLayout = false;
}
if (AndroidUtilities.isTablet() && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isSmallTablet()) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.8f), MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec) - ActionBar.getCurrentActionBarHeight() - AndroidUtilities.statusBarHeight + AndroidUtilities.dp(24) - (mainButtonWasVisible ? mainButton.getLayoutParams().height : 0), MeasureSpec.EXACTLY));
}
@Override
public void requestLayout() {
if (ignoreLayout) {
return;
}
super.requestLayout();
}
};
webViewContainer = new BotWebViewContainer(context, resourcesProvider, getColor(Theme.key_windowBackgroundWhite));
webViewContainer.setDelegate(new BotWebViewContainer.Delegate() {
private boolean sentWebViewData;
@Override
public void onCloseRequested(Runnable callback) {
dismiss(callback);
}
@Override
public void onWebAppSetupClosingBehavior(boolean needConfirmation) {
BotWebViewSheet.this.needCloseConfirmation = needConfirmation;
}
@Override
public void onSendWebViewData(String data) {
if (queryId != 0 || sentWebViewData) {
return;
}
sentWebViewData = true;
TLRPC.TL_messages_sendWebViewData sendWebViewData = new TLRPC.TL_messages_sendWebViewData();
sendWebViewData.bot = MessagesController.getInstance(currentAccount).getInputUser(botId);
sendWebViewData.random_id = Utilities.random.nextLong();
sendWebViewData.button_text = buttonText;
sendWebViewData.data = data;
ConnectionsManager.getInstance(currentAccount).sendRequest(sendWebViewData, (response, error) -> {
if (response instanceof TLRPC.TL_updates) {
MessagesController.getInstance(currentAccount).processUpdates((TLRPC.TL_updates) response, false);
}
AndroidUtilities.runOnUIThread(BotWebViewSheet.this::dismiss);
});
}
@Override
public void onWebAppSetActionBarColor(String colorKey) {
int from = actionBarColor;
int to = getColor(colorKey);
ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(200);
animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
animator.addUpdateListener(animation -> {
actionBarColor = ColorUtils.blendARGB(from, to, (Float) animation.getAnimatedValue());
frameLayout.invalidate();
});
animator.start();
}
@Override
public void onWebAppSetBackgroundColor(int color) {
overrideBackgroundColor = true;
int from = backgroundPaint.getColor();
ValueAnimator animator = ValueAnimator.ofFloat(0, 1).setDuration(200);
animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
animator.addUpdateListener(animation -> {
backgroundPaint.setColor(ColorUtils.blendARGB(from, color, (Float) animation.getAnimatedValue()));
frameLayout.invalidate();
});
animator.start();
}
@Override
public void onSetBackButtonVisible(boolean visible) {
AndroidUtilities.updateImageViewImageAnimated(actionBar.getBackButton(), visible ? R.drawable.ic_ab_back : R.drawable.ic_close_white);
}
@Override
public void onWebAppOpenInvoice(String slug, TLObject response) {
BaseFragment parentFragment = ((LaunchActivity) parentActivity).getActionBarLayout().getLastFragment();
PaymentFormActivity paymentFormActivity = null;
if (response instanceof TLRPC.TL_payments_paymentForm) {
TLRPC.TL_payments_paymentForm form = (TLRPC.TL_payments_paymentForm) response;
MessagesController.getInstance(currentAccount).putUsers(form.users, false);
paymentFormActivity = new PaymentFormActivity(form, slug, parentFragment);
} else if (response instanceof TLRPC.TL_payments_paymentReceipt) {
paymentFormActivity = new PaymentFormActivity((TLRPC.TL_payments_paymentReceipt) response);
}
if (paymentFormActivity != null) {
swipeContainer.stickTo(-swipeContainer.getOffsetY() + swipeContainer.getTopActionBarOffsetY());
AndroidUtilities.hideKeyboard(frameLayout);
OverlayActionBarLayoutDialog overlayActionBarLayoutDialog = new OverlayActionBarLayoutDialog(context, resourcesProvider);
overlayActionBarLayoutDialog.show();
paymentFormActivity.setPaymentFormCallback(status -> {
if (status != PaymentFormActivity.InvoiceStatus.PENDING) {
overlayActionBarLayoutDialog.dismiss();
}
webViewContainer.onInvoiceStatusUpdate(slug, status.name().toLowerCase(Locale.ROOT));
});
paymentFormActivity.setResourcesProvider(resourcesProvider);
overlayActionBarLayoutDialog.addFragment(paymentFormActivity);
}
}
@Override
public void onWebAppExpand() {
if (/* System.currentTimeMillis() - lastSwipeTime <= 1000 || */ swipeContainer.isSwipeInProgress()) {
return;
}
swipeContainer.stickTo(-swipeContainer.getOffsetY() + swipeContainer.getTopActionBarOffsetY());
}
@Override
public void onSetupMainButton(boolean isVisible, boolean isActive, String text, int color, int textColor, boolean isProgressVisible) {
mainButton.setClickable(isActive);
mainButton.setText(text);
mainButton.setTextColor(textColor);
mainButton.setBackground(BotWebViewContainer.getMainButtonRippleDrawable(color));
if (isVisible != mainButtonWasVisible) {
mainButtonWasVisible = isVisible;
mainButton.animate().cancel();
if (isVisible) {
mainButton.setAlpha(0f);
mainButton.setVisibility(View.VISIBLE);
}
mainButton.animate().alpha(isVisible ? 1f : 0f).setDuration(150).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (!isVisible) {
mainButton.setVisibility(View.GONE);
}
swipeContainer.requestLayout();
}
}).start();
}
radialProgressView.setProgressColor(textColor);
if (isProgressVisible != mainButtonProgressWasVisible) {
mainButtonProgressWasVisible = isProgressVisible;
radialProgressView.animate().cancel();
if (isProgressVisible) {
radialProgressView.setAlpha(0f);
radialProgressView.setVisibility(View.VISIBLE);
}
radialProgressView.animate().alpha(isProgressVisible ? 1f : 0f)
.scaleX(isProgressVisible ? 1f : 0.1f)
.scaleY(isProgressVisible ? 1f : 0.1f)
.setDuration(250)
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
if (!isProgressVisible) {
radialProgressView.setVisibility(View.GONE);
}
}
}).start();
}
}
});
linePaint.setStyle(Paint.Style.FILL_AND_STROKE);
linePaint.setStrokeWidth(AndroidUtilities.dp(4));
linePaint.setStrokeCap(Paint.Cap.ROUND);
dimPaint.setColor(0x40000000);
actionBarColor = getColor(Theme.key_windowBackgroundWhite);
frameLayout = new SizeNotifierFrameLayout(context) {
{
setWillNotDraw(false);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (!overrideBackgroundColor) {
backgroundPaint.setColor(getColor(Theme.key_windowBackgroundWhite));
}
AndroidUtilities.rectTmp.set(0, 0, getWidth(), getHeight());
canvas.drawRect(AndroidUtilities.rectTmp, dimPaint);
actionBarPaint.setColor(ColorUtils.blendARGB(actionBarColor, getColor(Theme.key_windowBackgroundWhite), actionBarTransitionProgress));
float radius = AndroidUtilities.dp(16) * (AndroidUtilities.isTablet() ? 1f : 1f - actionBarTransitionProgress);
AndroidUtilities.rectTmp.set(swipeContainer.getLeft(), AndroidUtilities.lerp(swipeContainer.getTranslationY(), 0, actionBarTransitionProgress), swipeContainer.getRight(), swipeContainer.getTranslationY() + AndroidUtilities.dp(24) + radius);
canvas.drawRoundRect(AndroidUtilities.rectTmp, radius, radius, actionBarPaint);
AndroidUtilities.rectTmp.set(swipeContainer.getLeft(), swipeContainer.getTranslationY() + AndroidUtilities.dp(24), swipeContainer.getRight(), getHeight());
canvas.drawRect(AndroidUtilities.rectTmp, backgroundPaint);
}
@Override
public void draw(Canvas canvas) {
super.draw(canvas);
float transitionProgress = AndroidUtilities.isTablet() ? 0 : actionBarTransitionProgress;
linePaint.setColor(Theme.getColor(Theme.key_sheet_scrollUp));
linePaint.setAlpha((int) (linePaint.getAlpha() * (1f - Math.min(0.5f, transitionProgress) / 0.5f)));
canvas.save();
float scale = 1f - transitionProgress;
float y = AndroidUtilities.isTablet() ? AndroidUtilities.lerp(swipeContainer.getTranslationY() + AndroidUtilities.dp(12), AndroidUtilities.statusBarHeight / 2f, actionBarTransitionProgress) :
(AndroidUtilities.lerp(swipeContainer.getTranslationY(), AndroidUtilities.statusBarHeight + ActionBar.getCurrentActionBarHeight() / 2f, transitionProgress) + AndroidUtilities.dp(12));
canvas.scale(scale, scale, getWidth() / 2f, y);
canvas.drawLine(getWidth() / 2f - AndroidUtilities.dp(16), y, getWidth() / 2f + AndroidUtilities.dp(16), y, linePaint);
canvas.restore();
actionBarShadow.setAlpha((int) (actionBar.getAlpha() * 0xFF));
y = actionBar.getY() + actionBar.getTranslationY() + actionBar.getHeight();
actionBarShadow.setBounds(0, (int)y, getWidth(), (int)(y + actionBarShadow.getIntrinsicHeight()));
actionBarShadow.draw(canvas);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN && (event.getY() <= AndroidUtilities.lerp(swipeContainer.getTranslationY() + AndroidUtilities.dp(24), 0, actionBarTransitionProgress) ||
event.getX() > swipeContainer.getRight() || event.getX() < swipeContainer.getLeft())) {
onCheckDismissByUser();
return true;
}
return super.onTouchEvent(event);
}
};
frameLayout.setDelegate((keyboardHeight, isWidthGreater) -> {
if (keyboardHeight > AndroidUtilities.dp(20)) {
swipeContainer.stickTo(-swipeContainer.getOffsetY() + swipeContainer.getTopActionBarOffsetY());
}
});
frameLayout.addView(swipeContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL, 0, 24, 0, 0));
mainButton = new TextView(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (AndroidUtilities.isTablet() && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isSmallTablet()) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.8f), MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
mainButton.setVisibility(View.GONE);
mainButton.setAlpha(0f);
mainButton.setSingleLine();
mainButton.setGravity(Gravity.CENTER);
mainButton.setTypeface(AndroidUtilities.getTypeface("fonts/rmedium.ttf"));
int padding = AndroidUtilities.dp(16);
mainButton.setPadding(padding, 0, padding, 0);
mainButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 14);
mainButton.setOnClickListener(v -> webViewContainer.onMainButtonPressed());
frameLayout.addView(mainButton, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, 48, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL));
mainButtonAutoAnimator = VerticalPositionAutoAnimator.attach(mainButton);
radialProgressView = new RadialProgressView(context) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) getLayoutParams();
if (AndroidUtilities.isTablet() && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isSmallTablet()) {
params.rightMargin = (int) (AndroidUtilities.dp(10) + Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.1f);
} else {
params.rightMargin = AndroidUtilities.dp(10);
}
}
};
radialProgressView.setSize(AndroidUtilities.dp(18));
radialProgressView.setAlpha(0f);
radialProgressView.setScaleX(0.1f);
radialProgressView.setScaleY(0.1f);
radialProgressView.setVisibility(View.GONE);
frameLayout.addView(radialProgressView, LayoutHelper.createFrame(28, 28, Gravity.BOTTOM | Gravity.RIGHT, 0, 0, 10, 10));
radialProgressAutoAnimator = VerticalPositionAutoAnimator.attach(radialProgressView);
actionBarShadow = ContextCompat.getDrawable(getContext(), R.drawable.header_shadow).mutate();
actionBar = new ActionBar(context, resourcesProvider) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (AndroidUtilities.isTablet() && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isSmallTablet()) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.8f), MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
};
actionBar.setBackgroundColor(Color.TRANSPARENT);
actionBar.setBackButtonImage(R.drawable.ic_close_white);
updateActionBarColors();
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
onCheckDismissByUser();
}
}
});
actionBar.setAlpha(0f);
frameLayout.addView(actionBar, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.TOP | Gravity.CENTER_HORIZONTAL));
frameLayout.addView(progressView = new ChatAttachAlertBotWebViewLayout.WebProgressView(context, resourcesProvider) {
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (AndroidUtilities.isTablet() && !AndroidUtilities.isInMultiwindow && !AndroidUtilities.isSmallTablet()) {
widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (Math.min(AndroidUtilities.displaySize.x, AndroidUtilities.displaySize.y) * 0.8f), MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.WRAP_CONTENT, Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, 0, 0, 0));
webViewContainer.setWebViewProgressListener(progress -> {
progressView.setLoadProgressAnimated(progress);
if (progress == 1f) {
ValueAnimator animator = ValueAnimator.ofFloat(1, 0).setDuration(200);
animator.setInterpolator(CubicBezierInterpolator.DEFAULT);
animator.addUpdateListener(animation -> progressView.setAlpha((Float) animation.getAnimatedValue()));
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
progressView.setVisibility(View.GONE);
}
});
animator.start();
}
});
swipeContainer.addView(webViewContainer, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
swipeContainer.setScrollListener(()->{
if (swipeContainer.getSwipeOffsetY() > 0) {
dimPaint.setAlpha((int) (0x40 * (1f - MathUtils.clamp(swipeContainer.getSwipeOffsetY() / (float)swipeContainer.getHeight(), 0, 1))));
} else {
dimPaint.setAlpha(0x40);
}
frameLayout.invalidate();
webViewContainer.invalidateViewPortHeight();
if (springAnimation != null) {
float progress = (1f - Math.min(swipeContainer.getTopActionBarOffsetY(), swipeContainer.getTranslationY() - swipeContainer.getTopActionBarOffsetY()) / swipeContainer.getTopActionBarOffsetY());
float newPos = (progress > 0.5f ? 1 : 0) * 100f;
if (springAnimation.getSpring().getFinalPosition() != newPos) {
springAnimation.getSpring().setFinalPosition(newPos);
springAnimation.start();
}
}
float offsetY = Math.max(0, swipeContainer.getSwipeOffsetY());
mainButtonAutoAnimator.setOffsetY(offsetY);
radialProgressAutoAnimator.setOffsetY(offsetY);
lastSwipeTime = System.currentTimeMillis();
});
swipeContainer.setScrollEndListener(()-> webViewContainer.invalidateViewPortHeight(true));
swipeContainer.setDelegate(() -> {
if (!onCheckDismissByUser()) {
swipeContainer.stickTo(0);
}
});
swipeContainer.setTopActionBarOffsetY(ActionBar.getCurrentActionBarHeight() + AndroidUtilities.statusBarHeight - AndroidUtilities.dp(24));
swipeContainer.setIsKeyboardVisible(obj -> frameLayout.getKeyboardHeight() >= AndroidUtilities.dp(20));
setContentView(frameLayout, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
}
public void setParentActivity(Activity parentActivity) {
this.parentActivity = parentActivity;
}
private void updateActionBarColors() {
actionBar.setTitleColor(getColor(Theme.key_windowBackgroundWhiteBlackText));
actionBar.setItemsColor(getColor(Theme.key_windowBackgroundWhiteBlackText), false);
actionBar.setItemsBackgroundColor(getColor(Theme.key_actionBarWhiteSelector), false);
actionBar.setPopupBackgroundColor(getColor(Theme.key_actionBarDefaultSubmenuBackground), false);
actionBar.setPopupItemsColor(getColor(Theme.key_actionBarDefaultSubmenuItem), false, false);
actionBar.setPopupItemsColor(getColor(Theme.key_actionBarDefaultSubmenuItemIcon), true, false);
actionBar.setPopupItemsSelectorColor(getColor(Theme.key_dialogButtonSelector), false);
}
private void updateLightStatusBar() {
int color = Theme.getColor(Theme.key_windowBackgroundWhite, null, true);
boolean lightStatusBar = !AndroidUtilities.isTablet() && ColorUtils.calculateLuminance(color) >= 0.9 && actionBarTransitionProgress >= 0.85f;
if (wasLightStatusBar != null && wasLightStatusBar == lightStatusBar) {
return;
}
wasLightStatusBar = lightStatusBar;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
int flags = frameLayout.getSystemUiVisibility();
if (lightStatusBar) {
flags |= View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
} else {
flags &= ~View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
}
frameLayout.setSystemUiVisibility(flags);
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Window window = getWindow();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN | WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
}
window.setWindowAnimations(R.style.DialogNoAnimation);
WindowManager.LayoutParams params = window.getAttributes();
params.width = ViewGroup.LayoutParams.MATCH_PARENT;
params.gravity = Gravity.TOP | Gravity.LEFT;
params.dimAmount = 0;
params.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
params.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
params.height = ViewGroup.LayoutParams.MATCH_PARENT;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
params.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
}
window.setAttributes(params);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
window.setStatusBarColor(Color.TRANSPARENT);
}
frameLayout.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
frameLayout.setOnApplyWindowInsetsListener((v, insets) -> {
v.setPadding(0, 0, 0, insets.getSystemWindowInsetBottom());
return insets;
});
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
int color = Theme.getColor(Theme.key_windowBackgroundWhite, null, true);
AndroidUtilities.setLightNavigationBar(window, ColorUtils.calculateLuminance(color) >= 0.9);
}
NotificationCenter.getGlobalInstance().addObserver(this, NotificationCenter.didSetNewTheme);
}
@Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
if (springAnimation == null) {
springAnimation = new SpringAnimation(this, ACTION_BAR_TRANSITION_PROGRESS_VALUE)
.setSpring(new SpringForce()
.setStiffness(1200f)
.setDampingRatio(SpringForce.DAMPING_RATIO_NO_BOUNCY)
);
}
}
@Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
if (springAnimation != null) {
springAnimation.cancel();
springAnimation = null;
}
}
public void requestWebView(int currentAccount, long peerId, long botId, String buttonText, String buttonUrl, @WebViewType int type, int replyToMsgId, boolean silent) {
this.currentAccount = currentAccount;
this.peerId = peerId;
this.botId = botId;
this.replyToMsgId = replyToMsgId;
this.silent = silent;
this.buttonText = buttonText;
actionBar.setTitle(UserObject.getUserName(MessagesController.getInstance(currentAccount).getUser(botId)));
ActionBarMenu menu = actionBar.createMenu();
menu.removeAllViews();
ActionBarMenuItem otherItem = menu.addItem(0, R.drawable.ic_ab_other);
otherItem.addSubItem(R.id.menu_open_bot, R.drawable.msg_bot, LocaleController.getString(R.string.BotWebViewOpenBot));
otherItem.addSubItem(R.id.menu_reload_page, R.drawable.msg_retry, LocaleController.getString(R.string.BotWebViewReloadPage));
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
@Override
public void onItemClick(int id) {
if (id == -1) {
if (!webViewContainer.onBackPressed()) {
onCheckDismissByUser();
}
} else if (id == R.id.menu_open_bot) {
Bundle bundle = new Bundle();
bundle.putLong("user_id", botId);
if (parentActivity instanceof LaunchActivity) {
((LaunchActivity) parentActivity).presentFragment(new ChatActivity(bundle));
}
dismiss();
} else if (id == R.id.menu_reload_page) {
if (webViewContainer.getWebView() != null) {
webViewContainer.getWebView().animate().cancel();
webViewContainer.getWebView().animate().alpha(0).start();
}
progressView.setLoadProgress(0);
progressView.setAlpha(1f);
progressView.setVisibility(View.VISIBLE);
webViewContainer.setBotUser(MessagesController.getInstance(currentAccount).getUser(botId));
webViewContainer.loadFlickerAndSettingsItem(currentAccount, botId, settingsItem);
webViewContainer.reload();
} else if (id == R.id.menu_settings) {
webViewContainer.onSettingsButtonPressed();
}
}
});
boolean hasThemeParams = true;
String themeParams = null;
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("bg_color", getColor(Theme.key_windowBackgroundWhite));
jsonObject.put("secondary_bg_color", getColor(Theme.key_windowBackgroundGray));
jsonObject.put("text_color", getColor(Theme.key_windowBackgroundWhiteBlackText));
jsonObject.put("hint_color", getColor(Theme.key_windowBackgroundWhiteHintText));
jsonObject.put("link_color", getColor(Theme.key_windowBackgroundWhiteLinkText));
jsonObject.put("button_color", getColor(Theme.key_featuredStickers_addButton));
jsonObject.put("button_text_color", getColor(Theme.key_featuredStickers_buttonText));
themeParams = jsonObject.toString();
} catch (Exception e) {
FileLog.e(e);
hasThemeParams = false;
}
webViewContainer.setBotUser(MessagesController.getInstance(currentAccount).getUser(botId));
webViewContainer.loadFlickerAndSettingsItem(currentAccount, botId, settingsItem);
switch (type) {
case TYPE_BOT_MENU_BUTTON: {
TLRPC.TL_messages_requestWebView req = new TLRPC.TL_messages_requestWebView();
req.bot = MessagesController.getInstance(currentAccount).getInputUser(botId);
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(botId);
req.url = buttonUrl;
req.flags |= 2;
if (hasThemeParams) {
req.theme_params = new TLRPC.TL_dataJSON();
req.theme_params.data = themeParams;
req.flags |= 4;
}
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_webViewResultUrl) {
TLRPC.TL_webViewResultUrl resultUrl = (TLRPC.TL_webViewResultUrl) response;
queryId = resultUrl.query_id;
webViewContainer.loadUrl(currentAccount, resultUrl.url);
swipeContainer.setWebView(webViewContainer.getWebView());
AndroidUtilities.runOnUIThread(pollRunnable, POLL_PERIOD);
}
}));
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.webViewResultSent);
break;
}
case TYPE_SIMPLE_WEB_VIEW_BUTTON: {
TLRPC.TL_messages_requestSimpleWebView req = new TLRPC.TL_messages_requestSimpleWebView();
req.bot = MessagesController.getInstance(currentAccount).getInputUser(botId);
if (hasThemeParams) {
req.theme_params = new TLRPC.TL_dataJSON();
req.theme_params.data = themeParams;
req.flags |= 1;
}
req.url = buttonUrl;
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_simpleWebViewResultUrl) {
TLRPC.TL_simpleWebViewResultUrl resultUrl = (TLRPC.TL_simpleWebViewResultUrl) response;
queryId = 0;
webViewContainer.loadUrl(currentAccount, resultUrl.url);
swipeContainer.setWebView(webViewContainer.getWebView());
}
}));
break;
}
case TYPE_WEB_VIEW_BUTTON: {
TLRPC.TL_messages_requestWebView req = new TLRPC.TL_messages_requestWebView();
req.peer = MessagesController.getInstance(currentAccount).getInputPeer(peerId);
req.bot = MessagesController.getInstance(currentAccount).getInputUser(botId);
if (buttonUrl != null) {
req.url = buttonUrl;
req.flags |= 2;
}
if (replyToMsgId != 0) {
req.reply_to_msg_id = replyToMsgId;
req.flags |= 1;
}
if (hasThemeParams) {
req.theme_params = new TLRPC.TL_dataJSON();
req.theme_params.data = themeParams;
req.flags |= 4;
}
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
if (response instanceof TLRPC.TL_webViewResultUrl) {
TLRPC.TL_webViewResultUrl resultUrl = (TLRPC.TL_webViewResultUrl) response;
queryId = resultUrl.query_id;
webViewContainer.loadUrl(currentAccount, resultUrl.url);
swipeContainer.setWebView(webViewContainer.getWebView());
AndroidUtilities.runOnUIThread(pollRunnable, POLL_PERIOD);
}
}));
NotificationCenter.getInstance(currentAccount).addObserver(this, NotificationCenter.webViewResultSent);
break;
}
}
}
private int getColor(String key) {
Integer color;
if (resourcesProvider != null) {
color = resourcesProvider.getColor(key);
} else {
color = Theme.getColor(key);
}
return color != null ? color : Theme.getColor(key);
}
@Override
public void show() {
frameLayout.setAlpha(0f);
frameLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
v.removeOnLayoutChangeListener(this);
swipeContainer.setSwipeOffsetY(swipeContainer.getHeight());
frameLayout.setAlpha(1f);
new SpringAnimation(swipeContainer, ChatAttachAlertBotWebViewLayout.WebViewSwipeContainer.SWIPE_OFFSET_Y, 0)
.setSpring(new SpringForce(0)
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
.setStiffness(500.0f)
).start();
}
});
super.show();
}
@Override
public void onBackPressed() {
if (webViewContainer.onBackPressed()) {
return;
}
onCheckDismissByUser();
}
@Override
public void dismiss() {
dismiss(null);
}
public boolean onCheckDismissByUser() {
if (needCloseConfirmation) {
String botName = null;
TLRPC.User user = MessagesController.getInstance(currentAccount).getUser(botId);
if (user != null) {
botName = ContactsController.formatName(user.first_name, user.last_name);
}
AlertDialog dialog = new AlertDialog.Builder(getContext())
.setTitle(botName)
.setMessage(LocaleController.getString(R.string.BotWebViewChangesMayNotBeSaved))
.setPositiveButton(LocaleController.getString(R.string.BotWebViewCloseAnyway), (dialog2, which) -> dismiss())
.setNegativeButton(LocaleController.getString(R.string.Cancel), null)
.create();
dialog.show();
TextView textView = (TextView) dialog.getButton(AlertDialog.BUTTON_POSITIVE);
textView.setTextColor(getColor(Theme.key_dialogTextRed));
return false;
} else {
dismiss();
return true;
}
}
public void dismiss(Runnable callback) {
if (dismissed) {
return;
}
dismissed = true;
AndroidUtilities.cancelRunOnUIThread(pollRunnable);
webViewContainer.destroyWebView();
NotificationCenter.getInstance(currentAccount).removeObserver(this, NotificationCenter.webViewResultSent);
NotificationCenter.getGlobalInstance().removeObserver(this, NotificationCenter.didSetNewTheme);
swipeContainer.stickTo(swipeContainer.getHeight() + frameLayout.measureKeyboardHeight(), ()->{
super.dismiss();
if (callback != null) {
callback.run();
}
});
}
@Override
public void didReceivedNotification(int id, int account, Object... args) {
if (id == NotificationCenter.webViewResultSent) {
long queryId = (long) args[0];
if (this.queryId == queryId) {
dismiss();
}
} else if (id == NotificationCenter.didSetNewTheme) {
frameLayout.invalidate();
webViewContainer.updateFlickerBackgroundColor(getColor(Theme.key_windowBackgroundWhite));
updateActionBarColors();
updateLightStatusBar();
}
}
}