package me.devsaki.hentoid.activities;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebBackForwardList;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import java.util.Date;
import me.devsaki.hentoid.BuildConfig;
import me.devsaki.hentoid.HentoidApp;
import me.devsaki.hentoid.R;
import me.devsaki.hentoid.abstracts.BaseActivity;
import me.devsaki.hentoid.database.HentoidDB;
import me.devsaki.hentoid.database.domains.Content;
import me.devsaki.hentoid.enums.Site;
import me.devsaki.hentoid.enums.StatusContent;
import me.devsaki.hentoid.parsers.ASMHentaiParser;
import me.devsaki.hentoid.parsers.HentaiCafeParser;
import me.devsaki.hentoid.parsers.HitomiParser;
import me.devsaki.hentoid.parsers.NhentaiParser;
import me.devsaki.hentoid.parsers.TsuminoParser;
import me.devsaki.hentoid.services.DownloadService;
import me.devsaki.hentoid.util.Consts;
import me.devsaki.hentoid.util.ConstsImport;
import me.devsaki.hentoid.util.FileHelper;
import me.devsaki.hentoid.util.Helper;
import me.devsaki.hentoid.util.LogHelper;
import me.devsaki.hentoid.views.ObservableWebView;
/**
* Browser activity which allows the user to navigate a supported source.
* No particular source should be filtered/defined here.
* The source itself should contain every method it needs to function.
*/
public class BaseWebActivity extends BaseActivity {
private static final String TAG = LogHelper.makeLogTag(BaseWebActivity.class);
private Content currentContent;
private HentoidDB db;
private ObservableWebView webView;
private Site site;
private boolean webViewIsLoading;
private FloatingActionButton fabRead, fabDownload, fabRefreshOrStop, fabHome;
private boolean fabReadEnabled, fabDownloadEnabled;
private SwipeRefreshLayout swipeLayout;
Site getSite() {
return site;
}
void setSite(Site site) {
this.site = site;
}
ObservableWebView getWebView() {
return webView;
}
void setWebView(ObservableWebView webView) {
this.webView = webView;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_base_web);
db = HentoidDB.getInstance(this);
setSite(getSite());
if (site == null) {
LogHelper.w(TAG, "Site is null!");
} else {
LogHelper.d(TAG, "Loading site: " + site);
}
fabRead = (FloatingActionButton) findViewById(R.id.fabRead);
fabDownload = (FloatingActionButton) findViewById(R.id.fabDownload);
fabRefreshOrStop = (FloatingActionButton) findViewById(R.id.fabRefreshStop);
fabHome = (FloatingActionButton) findViewById(R.id.fabHome);
hideFab(fabRead);
hideFab(fabDownload);
initWebView();
initSwipeLayout();
setWebView(getWebView());
String intentVar = getIntent().getStringExtra(Consts.INTENT_URL);
webView.loadUrl(intentVar == null ? site.getUrl() : intentVar);
}
@Override
protected void onResume() {
super.onResume();
checkPermissions();
}
// Validate permissions
private void checkPermissions() {
if (Helper.permissionsCheck(this, ConstsImport.RQST_STORAGE_PERMISSION, false)) {
LogHelper.d(TAG, "Storage permission allowed!");
} else {
LogHelper.d(TAG, "Storage permission denied!");
reset();
}
}
private void reset() {
Helper.reset(HentoidApp.getAppContext(), this);
}
@SuppressLint("SetJavaScriptEnabled")
private void initWebView() {
webView = (ObservableWebView) findViewById(R.id.wbMain);
webView.setOnLongClickListener(v -> {
WebView.HitTestResult result = webView.getHitTestResult();
if (result.getType() == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
if (result.getExtra().contains(site.getUrl())) {
backgroundRequest(result.getExtra());
}
} else {
return true;
}
return false;
});
webView.setHapticFeedbackEnabled(false);
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if (newProgress == 100) {
swipeLayout.post(() -> swipeLayout.setRefreshing(false));
} else {
swipeLayout.post(() -> swipeLayout.setRefreshing(true));
}
}
});
webView.setOnScrollChangedCallback((l, t) -> {
if (!webViewIsLoading) {
if (webView.canScrollVertically(1) || t == 0) {
fabRefreshOrStop.show();
fabHome.show();
if (fabReadEnabled) {
fabRead.show();
} else if (fabDownloadEnabled) {
fabDownload.show();
}
} else {
fabRefreshOrStop.hide();
fabHome.hide();
fabRead.hide();
fabDownload.hide();
}
}
});
WebSettings webSettings = webView.getSettings();
webSettings.setBuiltInZoomControls(true);
webSettings.setDisplayZoomControls(false);
String userAgent;
try {
userAgent = Helper.getAppUserAgent(this);
} catch (PackageManager.NameNotFoundException e) {
userAgent = Consts.USER_AGENT;
}
webSettings.setUserAgentString(userAgent);
webSettings.setDomStorageEnabled(true);
webSettings.setUseWideViewPort(true);
webSettings.setJavaScriptEnabled(true);
webSettings.setLoadWithOverviewMode(true);
}
private void initSwipeLayout() {
swipeLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_container);
swipeLayout.setOnRefreshListener(() -> {
if (!swipeLayout.isRefreshing() || !webViewIsLoading) {
webView.reload();
}
});
swipeLayout.setColorSchemeResources(
android.R.color.holo_blue_bright,
android.R.color.holo_green_light,
android.R.color.holo_orange_light,
android.R.color.holo_red_light);
}
@SuppressWarnings("UnusedParameters")
public void onRefreshStopFabClick(View view) {
if (webViewIsLoading) {
webView.stopLoading();
} else {
webView.reload();
}
}
private void goHome() {
Intent intent = new Intent(this, DownloadsActivity.class);
// If FLAG_ACTIVITY_CLEAR_TOP is not set,
// it can interfere with Double-Back (press back twice) to exit
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
finish();
}
@Override
public void onBackPressed() {
if (!getWebView().canGoBack()) {
goHome();
}
}
@SuppressWarnings("UnusedParameters")
public void onHomeFabClick(View view) {
goHome();
}
@SuppressWarnings("UnusedParameters")
public void onReadFabClick(View view) {
if (currentContent != null) {
currentContent = db.selectContentById(currentContent.getId());
if (StatusContent.DOWNLOADED == currentContent.getStatus()
|| StatusContent.ERROR == currentContent.getStatus()) {
FileHelper.openContent(this, currentContent);
} else {
hideFab(fabRead);
}
}
}
@SuppressWarnings("UnusedParameters")
public void onDownloadFabClick(View view) {
processDownload();
}
void processDownload() {
currentContent = db.selectContentById(currentContent.getId());
if (StatusContent.DOWNLOADED == currentContent.getStatus()) {
Helper.toast(this, R.string.already_downloaded);
hideFab(fabDownload);
return;
}
Helper.toast(this, R.string.add_to_queue);
currentContent.setDownloadDate(new Date().getTime())
.setStatus(StatusContent.DOWNLOADING);
db.updateContentStatus(currentContent);
Intent intent = new Intent(Intent.ACTION_SYNC, null, this, DownloadService.class);
startService(intent);
hideFab(fabDownload);
}
private void hideFab(FloatingActionButton fab) {
fab.hide();
if (fab.equals(fabDownload)) {
fabDownloadEnabled = false;
} else if (fab.equals(fabRead)) {
fabReadEnabled = false;
}
}
private void showFab(FloatingActionButton fab) {
fab.show();
if (fab.equals(fabDownload)) {
fabDownloadEnabled = true;
} else if (fab.equals(fabRead)) {
fabReadEnabled = true;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK) {
WebBackForwardList webBFL = webView.copyBackForwardList();
int i = webBFL.getCurrentIndex();
do {
i--;
}
while (i >= 0 && webView.getOriginalUrl()
.equals(webBFL.getItemAtIndex(i).getOriginalUrl()));
if (webView.canGoBackOrForward(i - webBFL.getCurrentIndex())) {
webView.goBackOrForward(i - webBFL.getCurrentIndex());
} else {
super.onBackPressed();
}
return true;
}
return false;
}
void processContent(Content content) {
if (content == null) {
return;
}
addContentToDB(content);
StatusContent contentStatus = content.getStatus();
if (contentStatus != StatusContent.DOWNLOADED
&& contentStatus != StatusContent.DOWNLOADING) {
currentContent = content;
runOnUiThread(() -> showFab(fabDownload));
} else {
runOnUiThread(() -> hideFab(fabDownload));
}
if (contentStatus == StatusContent.DOWNLOADED
|| contentStatus == StatusContent.ERROR) {
currentContent = content;
runOnUiThread(() -> showFab(fabRead));
} else {
runOnUiThread(() -> hideFab(fabRead));
}
// Allows debugging parsers without starting a content download
if (BuildConfig.DEBUG) {
attachToDebugger(content);
}
}
private void addContentToDB(Content content) {
Content contentDB = db.selectContentById(content.getUrl().hashCode());
if (contentDB != null) {
content.setStatus(contentDB.getStatus())
.setImageFiles(contentDB.getImageFiles())
.setDownloadDate(contentDB.getDownloadDate());
}
db.insertContent(content);
}
private void attachToDebugger(Content content) {
switch (content.getSite()) {
case HITOMI:
HitomiParser.parseImageList(content);
break;
case NHENTAI:
NhentaiParser.parseImageList(content);
break;
case TSUMINO:
TsuminoParser.parseImageList(content);
break;
case ASMHENTAI:
ASMHentaiParser.parseImageList(content);
break;
case HENTAICAFE:
HentaiCafeParser.parseImageList(content);
break;
default:
break;
}
}
void backgroundRequest(String extra) {
LogHelper.d(TAG, "Extras: " + extra);
}
class CustomWebViewClient extends WebViewClient {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
webViewIsLoading = true;
fabRefreshOrStop.setImageResource(R.drawable.ic_action_clear);
fabRefreshOrStop.show();
fabHome.show();
hideFab(fabDownload);
hideFab(fabRead);
}
@Override
public void onPageFinished(WebView view, String url) {
webViewIsLoading = false;
fabRefreshOrStop.setImageResource(R.drawable.ic_action_refresh);
}
}
}