/* * Copyright (C) 2017 Drakeet <drakeet.me@gmail.com> * * This file is part of rebase-android * * rebase-android is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * rebase-android is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with rebase-android. If not, see <http://www.gnu.org/licenses/>. */ package com.drakeet.rebase.web; import android.annotation.SuppressLint; import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.text.TextUtils; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.TextSwitcher; import android.widget.TextView; import android.widget.Toast; import android.widget.ViewSwitcher; import com.daimajia.numberprogressbar.NumberProgressBar; import com.liuguangqiang.swipeback.SwipeBackLayout.DragEdge; import java.util.HashMap; import java.util.Map; import static android.widget.Toast.makeText; public class WebActivity extends ToolbarActivity implements ObservableWebView.OnScrollChangedListener { private static final String TAG = WebActivity.class.getSimpleName(); private static final String EXTRA_URL = "extra_url"; private static final String EXTRA_TITLE = "extra_title"; private static final Map<String, Integer> URL_POSITION_CACHES = new HashMap<>(); NumberProgressBar progressbar; ObservableWebView webView; TextSwitcher textSwitcher; String url, title; int positionHolder; boolean overrideTitleEnabled = true; SwipeBackDelegate swipeBackDelegate; /** * Using newIntent trick, return WebActivity Intent, to avoid `public static` * constant * variable everywhere * * @return Intent to start WebActivity */ public static Intent newIntent(Context context, String extraTitle, String extraURL) { Intent intent = new Intent(context, WebActivity.class); intent.putExtra(EXTRA_TITLE, extraTitle); intent.putExtra(EXTRA_URL, extraURL); return intent; } @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { overridePendingTransition(0, 0); super.onCreate(savedInstanceState); swipeBackDelegate = new SwipeBackDelegate(); swipeBackDelegate.attach(this, R.layout.web_activity_web); swipeBackDelegate.setDragEdge(DragEdge.VERTICAL); /* setContentView(R.layout.web_activity_web); */ progressbar = (NumberProgressBar) findViewById(R.id.progressbar); webView = (ObservableWebView) findViewById(R.id.web_view); textSwitcher = (TextSwitcher) findViewById(R.id.title); url = getIntent().getStringExtra(EXTRA_URL); title = getIntent().getStringExtra(EXTRA_TITLE); WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); settings.setLoadWithOverviewMode(true); settings.setAppCacheEnabled(true); settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.SINGLE_COLUMN); settings.setSupportZoom(true); settings.setDomStorageEnabled(true); webView.setWebChromeClient(new ChromeClient()); webView.setWebViewClient(new ReloadableClient()); webView.setOnScrollChangedListener(this); // webView.addJavascriptInterface(new JSInterface(), "JSInterface"); webView.loadUrl(url); textSwitcher.setFactory(new ViewSwitcher.ViewFactory() { @SuppressWarnings("deprecation") @Override public View makeView() { final Context context = WebActivity.this; final TextView textView = new TextView(context); textView.setTextAppearance(context, R.style.WebTitle); textView.setSingleLine(true); textView.setEllipsize(TextUtils.TruncateAt.MARQUEE); textView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(final View v) { v.setSelected(!v.isSelected()); } }); return textView; } }); textSwitcher.setInAnimation(this, android.R.anim.fade_in); textSwitcher.setOutAnimation(this, android.R.anim.fade_out); if (title != null) setTitle(title); } public void setOverrideTitleEnabled(boolean enabled) { this.overrideTitleEnabled = enabled; } @Override public void setTitle(CharSequence title) { super.setTitle(title); textSwitcher.setText(title); } private void refresh() { webView.reload(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: if (webView.canGoBack()) { webView.goBack(); } else { finish(); } return true; } } return super.onKeyDown(keyCode, event); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.web_menu_web, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_refresh) { refresh(); return true; } else if (id == R.id.action_copy_url) { ClipBoards.copyToClipBoard(this, webView.getUrl()); makeText(this, R.string.web_tip_copy_done, Toast.LENGTH_SHORT).show(); return true; } else if (id == R.id.action_open_url) { Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } else { makeText(this, R.string.web_tip_open_fail, Toast.LENGTH_LONG).show(); } return true; } return super.onOptionsItemSelected(item); } @SuppressWarnings("deprecation") @Override protected void onDestroy() { final String url = webView.getUrl(); int bottom = (int) Math.floor(webView.getContentHeight() * webView.getScale() * 0.8f); if (positionHolder >= bottom) { URL_POSITION_CACHES.remove(url); } else { URL_POSITION_CACHES.put(url, positionHolder); } super.onDestroy(); if (webView != null) webView.destroy(); } @Override public void finish() { super.finish(); overridePendingTransition(0, 0); } @Override public void onScrollChanged(WebView v, int x, int y, int oldX, int oldY) { positionHolder = y; } private class ChromeClient extends WebChromeClient { @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); progressbar.setProgress(newProgress); if (newProgress == 100) { progressbar.setVisibility(View.INVISIBLE); } else { progressbar.setVisibility(View.VISIBLE); } } @Override public void onReceivedTitle(WebView view, String title) { super.onReceivedTitle(view, title); if (overrideTitleEnabled) { setTitle(title); } } } private class ReloadableClient extends WebViewClient { @SuppressWarnings("deprecation") public boolean shouldOverrideUrlLoading(WebView view, String url) { if (url != null) view.loadUrl(url); return true; } @Override public void onPageCommitVisible(WebView view, String url) { super.onPageCommitVisible(view, url); Integer _position = URL_POSITION_CACHES.get(url); int position = _position == null ? 0 : _position; view.scrollTo(0, position); } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); boolean isBlackPage = false; for (String blackKey : SwipeBlacklist.get()) { if (url.contains(blackKey)) { isBlackPage = true; break; } } if (isBlackPage) { Toast.makeText(WebActivity.this, R.string.web_tip_swipe_back_disabled, Toast.LENGTH_LONG) .show(); swipeBackDelegate.setSwipeBackEnabled(false); } else { swipeBackDelegate.setSwipeBackEnabled(true); } } } }