mirror of https://github.com/NekoX-Dev/NekoX.git
441 lines
21 KiB
Java
441 lines
21 KiB
Java
/*
|
|
* This is the source code of Telegram for Android v. 5.x.x.
|
|
* It is licensed under GNU GPL v. 2 or later.
|
|
* You should have received a copy of the license in this archive (see LICENSE).
|
|
*
|
|
* Copyright Nikolai Kudashov, 2013-2018.
|
|
*/
|
|
|
|
package org.telegram.ui;
|
|
|
|
import android.animation.Animator;
|
|
import android.animation.AnimatorListenerAdapter;
|
|
import android.animation.AnimatorSet;
|
|
import android.animation.ObjectAnimator;
|
|
import android.annotation.SuppressLint;
|
|
import android.app.Activity;
|
|
import android.content.ComponentName;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.SharedPreferences;
|
|
import android.net.Uri;
|
|
import android.os.Build;
|
|
import android.text.TextUtils;
|
|
import android.view.MotionEvent;
|
|
import android.view.View;
|
|
import android.view.ViewParent;
|
|
import android.webkit.CookieManager;
|
|
import android.webkit.JavascriptInterface;
|
|
import android.webkit.WebSettings;
|
|
import android.webkit.WebView;
|
|
import android.webkit.WebViewClient;
|
|
import android.widget.FrameLayout;
|
|
|
|
import org.telegram.messenger.AndroidUtilities;
|
|
import org.telegram.messenger.ApplicationLoader;
|
|
import org.telegram.messenger.BuildVars;
|
|
import org.telegram.messenger.FileLog;
|
|
import org.telegram.messenger.LocaleController;
|
|
import org.telegram.messenger.MessageObject;
|
|
import org.telegram.messenger.MessagesController;
|
|
import org.telegram.messenger.R;
|
|
import org.telegram.messenger.Utilities;
|
|
import org.telegram.messenger.browser.Browser;
|
|
import org.telegram.tgnet.ConnectionsManager;
|
|
import org.telegram.tgnet.SerializedData;
|
|
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.BaseFragment;
|
|
import org.telegram.ui.ActionBar.Theme;
|
|
import org.telegram.ui.ActionBar.ThemeDescription;
|
|
import org.telegram.ui.Components.ContextProgressView;
|
|
import org.telegram.ui.Components.LayoutHelper;
|
|
import org.telegram.ui.Components.ShareAlert;
|
|
|
|
import java.net.URLEncoder;
|
|
import java.util.ArrayList;
|
|
|
|
public class WebviewActivity extends BaseFragment {
|
|
|
|
private WebView webView;
|
|
private ActionBarMenuItem progressItem;
|
|
private ContextProgressView progressView;
|
|
|
|
private String currentUrl;
|
|
private long currentDialogId;
|
|
private String currentBot;
|
|
private String currentGame;
|
|
private String linkToCopy;
|
|
private MessageObject currentMessageObject;
|
|
private String short_param;
|
|
|
|
private boolean loadStats;
|
|
|
|
private final static int share = 1;
|
|
private final static int open_in = 2;
|
|
|
|
private static final int TYPE_GAME = 0;
|
|
private static final int TYPE_STAT = 1;
|
|
|
|
private int type;
|
|
|
|
private class TelegramWebviewProxy {
|
|
@JavascriptInterface
|
|
public void postEvent(final String eventName, final String eventData) {
|
|
AndroidUtilities.runOnUIThread(() -> {
|
|
if (getParentActivity() == null) {
|
|
return;
|
|
}
|
|
if (BuildVars.LOGS_ENABLED) {
|
|
FileLog.d(eventName);
|
|
}
|
|
switch (eventName) {
|
|
case "share_game":
|
|
currentMessageObject.messageOwner.with_my_score = false;
|
|
break;
|
|
case "share_score":
|
|
currentMessageObject.messageOwner.with_my_score = true;
|
|
break;
|
|
}
|
|
showDialog(ShareAlert.createShareAlert(getParentActivity(), currentMessageObject, null, false, linkToCopy, false));
|
|
});
|
|
}
|
|
}
|
|
|
|
public Runnable typingRunnable = new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
if (currentMessageObject == null || getParentActivity() == null || typingRunnable == null) {
|
|
return;
|
|
}
|
|
MessagesController.getInstance(currentAccount).sendTyping(currentMessageObject.getDialogId(), 6, 0);
|
|
AndroidUtilities.runOnUIThread(typingRunnable, 25000);
|
|
}
|
|
};
|
|
|
|
public WebviewActivity(String url, String botName, String gameName, String startParam, MessageObject messageObject) {
|
|
super();
|
|
currentUrl = url;
|
|
currentBot = botName;
|
|
currentGame = gameName;
|
|
currentMessageObject = messageObject;
|
|
short_param = startParam;
|
|
linkToCopy = "https://" + MessagesController.getInstance(currentAccount).linkPrefix + "/" + currentBot + (TextUtils.isEmpty(startParam) ? "" : "?game=" + startParam);
|
|
type = TYPE_GAME;
|
|
}
|
|
|
|
public WebviewActivity(String statUrl, long did) {
|
|
super();
|
|
currentUrl = statUrl;
|
|
currentDialogId = did;
|
|
type = TYPE_STAT;
|
|
}
|
|
|
|
@Override
|
|
public void onFragmentDestroy() {
|
|
super.onFragmentDestroy();
|
|
AndroidUtilities.cancelRunOnUIThread(typingRunnable);
|
|
webView.setLayerType(View.LAYER_TYPE_NONE, null);
|
|
typingRunnable = null;
|
|
try {
|
|
ViewParent parent = webView.getParent();
|
|
if (parent != null) {
|
|
((FrameLayout) parent).removeView(webView);
|
|
}
|
|
webView.stopLoading();
|
|
webView.loadUrl("about:blank");
|
|
webView.destroy();
|
|
webView = null;
|
|
} catch (Exception e) {
|
|
FileLog.e(e);
|
|
}
|
|
}
|
|
|
|
@SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"})
|
|
@Override
|
|
public View createView(Context context) {
|
|
actionBar.setBackButtonImage(R.drawable.ic_ab_back);
|
|
actionBar.setAllowOverlayTitle(true);
|
|
|
|
actionBar.setActionBarMenuOnItemClick(new ActionBar.ActionBarMenuOnItemClick() {
|
|
@Override
|
|
public void onItemClick(int id) {
|
|
if (id == -1) {
|
|
finishFragment();
|
|
} else if (id == share) {
|
|
if (currentMessageObject != null) {
|
|
currentMessageObject.messageOwner.with_my_score = false;
|
|
showDialog(ShareAlert.createShareAlert(getParentActivity(), currentMessageObject, null, false, linkToCopy, false));
|
|
}
|
|
} else if (id == open_in) {
|
|
openGameInBrowser(currentUrl, currentMessageObject, getParentActivity(), short_param, currentBot);
|
|
}
|
|
}
|
|
});
|
|
ActionBarMenu menu = actionBar.createMenu();
|
|
progressItem = menu.addItemWithWidth(share, R.drawable.share, AndroidUtilities.dp(54));
|
|
if (type == TYPE_GAME) {
|
|
ActionBarMenuItem menuItem = menu.addItem(0, R.drawable.ic_ab_other);
|
|
menuItem.addSubItem(open_in, R.drawable.msg_openin, LocaleController.getString("OpenInExternalApp", R.string.OpenInExternalApp));
|
|
|
|
actionBar.setTitle(currentGame);
|
|
actionBar.setSubtitle("@" + currentBot);
|
|
|
|
progressView = new ContextProgressView(context, 1);
|
|
progressItem.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
|
progressView.setAlpha(0.0f);
|
|
progressView.setScaleX(0.1f);
|
|
progressView.setScaleY(0.1f);
|
|
progressView.setVisibility(View.INVISIBLE);
|
|
} else if (type == TYPE_STAT) {
|
|
actionBar.setBackgroundColor(Theme.getColor(Theme.key_player_actionBar));
|
|
actionBar.setItemsColor(Theme.getColor(Theme.key_player_actionBarItems), false);
|
|
actionBar.setItemsBackgroundColor(Theme.getColor(Theme.key_player_actionBarSelector), false);
|
|
actionBar.setTitleColor(Theme.getColor(Theme.key_player_actionBarTitle));
|
|
actionBar.setSubtitleColor(Theme.getColor(Theme.key_player_actionBarSubtitle));
|
|
actionBar.setTitle(LocaleController.getString("Statistics", R.string.Statistics));
|
|
|
|
progressView = new ContextProgressView(context, 3);
|
|
progressItem.addView(progressView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
|
progressView.setAlpha(1.0f);
|
|
progressView.setScaleX(1.0f);
|
|
progressView.setScaleY(1.0f);
|
|
progressView.setVisibility(View.VISIBLE);
|
|
progressItem.getContentView().setVisibility(View.GONE);
|
|
progressItem.setEnabled(false);
|
|
}
|
|
|
|
webView = new WebView(context);
|
|
webView.getSettings().setJavaScriptEnabled(true);
|
|
webView.getSettings().setDomStorageEnabled(true);
|
|
|
|
fragmentView = new FrameLayout(context);
|
|
FrameLayout frameLayout = (FrameLayout) fragmentView;
|
|
if (Build.VERSION.SDK_INT >= 19) {
|
|
webView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
|
|
}
|
|
|
|
if (Build.VERSION.SDK_INT >= 21) {
|
|
webView.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
|
|
CookieManager cookieManager = CookieManager.getInstance();
|
|
cookieManager.setAcceptThirdPartyCookies(webView, true);
|
|
if (type == TYPE_GAME) {
|
|
webView.addJavascriptInterface(new TelegramWebviewProxy(), "TelegramWebviewProxy");
|
|
}
|
|
}
|
|
|
|
webView.setWebViewClient(new WebViewClient() {
|
|
|
|
private boolean isInternalUrl(String url) {
|
|
if (TextUtils.isEmpty(url)) {
|
|
return false;
|
|
}
|
|
Uri uri = Uri.parse(url);
|
|
if ("tg".equals(uri.getScheme())) {
|
|
if (type == TYPE_STAT) {
|
|
try {
|
|
uri = Uri.parse(url.replace("tg:statsrefresh", "tg://telegram.org"));
|
|
reloadStats(uri.getQueryParameter("params"));
|
|
} catch (Throwable e) {
|
|
FileLog.e(e);
|
|
}
|
|
} else {
|
|
finishFragment(false);
|
|
try {
|
|
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
|
|
ComponentName componentName = new ComponentName(ApplicationLoader.applicationContext.getPackageName(), LaunchActivity.class.getName());
|
|
intent.setComponent(componentName);
|
|
intent.putExtra(android.provider.Browser.EXTRA_APPLICATION_ID, ApplicationLoader.applicationContext.getPackageName());
|
|
ApplicationLoader.applicationContext.startActivity(intent);
|
|
} catch (Exception e) {
|
|
FileLog.e(e);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void onLoadResource(WebView view, String url) {
|
|
if (isInternalUrl(url)) {
|
|
return;
|
|
}
|
|
super.onLoadResource(view, url);
|
|
}
|
|
|
|
@Override
|
|
public boolean shouldOverrideUrlLoading(WebView view, String url) {
|
|
return isInternalUrl(url) || super.shouldOverrideUrlLoading(view, url);
|
|
}
|
|
|
|
@Override
|
|
public void onPageFinished(WebView view, String url) {
|
|
super.onPageFinished(view, url);
|
|
if (progressView != null && progressView.getVisibility() == View.VISIBLE) {
|
|
AnimatorSet animatorSet = new AnimatorSet();
|
|
if (type == TYPE_GAME) {
|
|
progressItem.getContentView().setVisibility(View.VISIBLE);
|
|
progressItem.setEnabled(true);
|
|
animatorSet.playTogether(
|
|
ObjectAnimator.ofFloat(progressView, "scaleX", 1.0f, 0.1f),
|
|
ObjectAnimator.ofFloat(progressView, "scaleY", 1.0f, 0.1f),
|
|
ObjectAnimator.ofFloat(progressView, "alpha", 1.0f, 0.0f),
|
|
ObjectAnimator.ofFloat(progressItem.getContentView(), "scaleX", 0.0f, 1.0f),
|
|
ObjectAnimator.ofFloat(progressItem.getContentView(), "scaleY", 0.0f, 1.0f),
|
|
ObjectAnimator.ofFloat(progressItem.getContentView(), "alpha", 0.0f, 1.0f));
|
|
} else {
|
|
animatorSet.playTogether(
|
|
ObjectAnimator.ofFloat(progressView, "scaleX", 1.0f, 0.1f),
|
|
ObjectAnimator.ofFloat(progressView, "scaleY", 1.0f, 0.1f),
|
|
ObjectAnimator.ofFloat(progressView, "alpha", 1.0f, 0.0f));
|
|
}
|
|
animatorSet.addListener(new AnimatorListenerAdapter() {
|
|
@Override
|
|
public void onAnimationEnd(Animator animator) {
|
|
if (type == TYPE_STAT) {
|
|
progressItem.setVisibility(View.GONE);
|
|
} else {
|
|
progressView.setVisibility(View.INVISIBLE);
|
|
}
|
|
}
|
|
});
|
|
animatorSet.setDuration(150);
|
|
animatorSet.start();
|
|
}
|
|
}
|
|
});
|
|
|
|
frameLayout.addView(webView, LayoutHelper.createFrame(LayoutHelper.MATCH_PARENT, LayoutHelper.MATCH_PARENT));
|
|
|
|
return fragmentView;
|
|
}
|
|
|
|
@Override
|
|
public void onResume() {
|
|
super.onResume();
|
|
AndroidUtilities.cancelRunOnUIThread(typingRunnable);
|
|
typingRunnable.run();
|
|
}
|
|
|
|
@Override
|
|
protected void onTransitionAnimationEnd(boolean isOpen, boolean backward) {
|
|
if (isOpen && !backward && webView != null) {
|
|
webView.loadUrl(currentUrl);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean isSwipeBackEnabled(MotionEvent event) {
|
|
return false;
|
|
}
|
|
|
|
public static boolean supportWebview() {
|
|
String manufacturer = Build.MANUFACTURER;
|
|
String model = Build.MODEL;
|
|
if ("samsung".equals(manufacturer)) {
|
|
if ("GT-I9500".equals(model)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private void reloadStats(String params) {
|
|
if (loadStats) {
|
|
return;
|
|
}
|
|
loadStats = true;
|
|
TLRPC.TL_messages_getStatsURL req = new TLRPC.TL_messages_getStatsURL();
|
|
req.peer = MessagesController.getInstance(currentAccount).getInputPeer((int) currentDialogId);
|
|
req.params = params != null ? params : "";
|
|
req.dark = Theme.getCurrentTheme().isDark();
|
|
ConnectionsManager.getInstance(currentAccount).sendRequest(req, (response, error) -> AndroidUtilities.runOnUIThread(() -> {
|
|
loadStats = false;
|
|
if (response != null) {
|
|
TLRPC.TL_statsURL url = (TLRPC.TL_statsURL) response;
|
|
webView.loadUrl(currentUrl = url.url);
|
|
}
|
|
}));
|
|
}
|
|
|
|
public static void openGameInBrowser(String urlStr, MessageObject messageObject, Activity parentActivity, String short_name, String username) {
|
|
try {
|
|
String url = urlStr;
|
|
SharedPreferences sharedPreferences = ApplicationLoader.applicationContext.getSharedPreferences("botshare", Activity.MODE_PRIVATE);
|
|
String existing = sharedPreferences.getString("" + messageObject.getId(), null);
|
|
StringBuilder hash = new StringBuilder(existing != null ? existing : "");
|
|
StringBuilder addHash = new StringBuilder("tgShareScoreUrl=" + URLEncoder.encode("tgb://share_game_score?hash=", "UTF-8"));
|
|
if (existing == null) {
|
|
final char[] chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
|
|
for (int i = 0; i < 20; i++) {
|
|
hash.append(chars[Utilities.random.nextInt(chars.length)]);
|
|
}
|
|
}
|
|
addHash.append(hash);
|
|
int index = url.indexOf('#');
|
|
if (index < 0) {
|
|
url += "#" + addHash;
|
|
} else {
|
|
String curHash = url.substring(index + 1);
|
|
if (curHash.indexOf('=') >= 0 || curHash.indexOf('?') >= 0) {
|
|
url += "&" + addHash;
|
|
} else {
|
|
if (curHash.length() > 0) {
|
|
url += "?" + addHash;
|
|
} else {
|
|
url += addHash;
|
|
}
|
|
}
|
|
}
|
|
SharedPreferences.Editor editor = sharedPreferences.edit();
|
|
editor.putInt(hash + "_date", (int) (System.currentTimeMillis() / 1000));
|
|
SerializedData serializedData = new SerializedData(messageObject.messageOwner.getObjectSize());
|
|
messageObject.messageOwner.serializeToStream(serializedData);
|
|
editor.putString(hash + "_m", Utilities.bytesToHex(serializedData.toByteArray()));
|
|
editor.putString(hash + "_link", "https://" + MessagesController.getInstance(messageObject.currentAccount).linkPrefix + "/" + username + (TextUtils.isEmpty(short_name) ? "" : "?game=" + short_name));
|
|
editor.commit();
|
|
Browser.openUrl(parentActivity, url, false);
|
|
serializedData.cleanup();
|
|
} catch (Exception e) {
|
|
FileLog.e(e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public ArrayList<ThemeDescription> getThemeDescriptions() {
|
|
ArrayList<ThemeDescription> themeDescriptions = new ArrayList<>();
|
|
if (type == TYPE_GAME) {
|
|
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite));
|
|
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_actionBarDefault));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_actionBarDefaultIcon));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_TITLECOLOR, null, null, null, null, Theme.key_actionBarDefaultTitle));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SELECTORCOLOR, null, null, null, null, Theme.key_actionBarDefaultSelector));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUBACKGROUND, null, null, null, null, Theme.key_actionBarDefaultSubmenuBackground));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM, null, null, null, null, Theme.key_actionBarDefaultSubmenuItem));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM | ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_actionBarDefaultSubmenuItemIcon));
|
|
|
|
themeDescriptions.add(new ThemeDescription(progressView, 0, null, null, null, null, Theme.key_contextProgressInner2));
|
|
themeDescriptions.add(new ThemeDescription(progressView, 0, null, null, null, null, Theme.key_contextProgressOuter2));
|
|
} else {
|
|
themeDescriptions.add(new ThemeDescription(fragmentView, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_windowBackgroundWhite));
|
|
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_BACKGROUND, null, null, null, null, Theme.key_player_actionBar));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_ITEMSCOLOR, null, null, null, null, Theme.key_player_actionBarItems));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_TITLECOLOR, null, null, null, null, Theme.key_player_actionBarTitle));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBTITLECOLOR, null, null, null, null, Theme.key_player_actionBarTitle));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SELECTORCOLOR, null, null, null, null, Theme.key_player_actionBarSelector));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUBACKGROUND, null, null, null, null, Theme.key_actionBarDefaultSubmenuBackground));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM, null, null, null, null, Theme.key_actionBarDefaultSubmenuItem));
|
|
themeDescriptions.add(new ThemeDescription(actionBar, ThemeDescription.FLAG_AB_SUBMENUITEM | ThemeDescription.FLAG_IMAGECOLOR, null, null, null, null, Theme.key_actionBarDefaultSubmenuItemIcon));
|
|
|
|
themeDescriptions.add(new ThemeDescription(progressView, 0, null, null, null, null, Theme.key_contextProgressInner4));
|
|
themeDescriptions.add(new ThemeDescription(progressView, 0, null, null, null, null, Theme.key_contextProgressOuter4));
|
|
}
|
|
return themeDescriptions;
|
|
}
|
|
}
|