implement swipe to refresh on webview

Signed-off-by: androidacy-user <opensource@androidacy.com>
pull/27/head
androidacy-user 2 years ago
parent dbc4797c80
commit d4ccb5a056

@ -20,6 +20,7 @@ import android.widget.Toast;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.core.content.FileProvider; import androidx.core.content.FileProvider;
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import androidx.webkit.WebResourceErrorCompat; import androidx.webkit.WebResourceErrorCompat;
import androidx.webkit.WebSettingsCompat; import androidx.webkit.WebSettingsCompat;
import androidx.webkit.WebViewClientCompat; import androidx.webkit.WebViewClientCompat;
@ -66,7 +67,7 @@ public final class AndroidacyActivity extends FoxActivity {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
@Override @Override
@SuppressLint({"SetJavaScriptEnabled", "JavascriptInterface", "RestrictedApi"}) @SuppressLint({"SetJavaScriptEnabled", "JavascriptInterface", "RestrictedApi", "ClickableViewAccessibility"})
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
this.moduleFile = new File(this.getCacheDir(), "module.zip"); this.moduleFile = new File(this.getCacheDir(), "module.zip");
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -132,8 +133,7 @@ public final class AndroidacyActivity extends FoxActivity {
IntentHelper.openConfig(this, config); IntentHelper.openConfig(this, config);
return true; return true;
}); });
} catch ( } catch (PackageManager.NameNotFoundException ignored) {
PackageManager.NameNotFoundException ignored) {
} }
} }
} }
@ -150,6 +150,8 @@ public final class AndroidacyActivity extends FoxActivity {
webSettings.setAllowFileAccessFromFileURLs(false); webSettings.setAllowFileAccessFromFileURLs(false);
webSettings.setAllowUniversalAccessFromFileURLs(false); webSettings.setAllowUniversalAccessFromFileURLs(false);
webSettings.setMediaPlaybackRequiresUserGesture(false); webSettings.setMediaPlaybackRequiresUserGesture(false);
// enable swiping to refresh
// if app is in dark mode, force dark mode on webview // if app is in dark mode, force dark mode on webview
if (MainApplication.getINSTANCE().isDarkTheme()) { if (MainApplication.getINSTANCE().isDarkTheme()) {
// for api 33, use setAlgorithmicDarkeningAllowed, for api 29-32 use setForceDark, for api 28 and below use setForceDarkStrategy // for api 33, use setAlgorithmicDarkeningAllowed, for api 29-32 use setForceDark, for api 28 and below use setForceDarkStrategy
@ -167,6 +169,8 @@ public final class AndroidacyActivity extends FoxActivity {
allowList.add("https://*.androidacy.com"); allowList.add("https://*.androidacy.com");
WebSettingsCompat.setRequestedWithHeaderOriginAllowList(webSettings, allowList); WebSettingsCompat.setRequestedWithHeaderOriginAllowList(webSettings, allowList);
} }
// get swipe to refresh layout
SwipeRefreshLayout swipeRefreshLayout = this.findViewById(R.id.swipe_refresh_layout);
this.webView.setWebViewClient(new WebViewClientCompat() { this.webView.setWebViewClient(new WebViewClientCompat() {
private String pageUrl; private String pageUrl;
@ -175,8 +179,7 @@ public final class AndroidacyActivity extends FoxActivity {
public boolean shouldOverrideUrlLoading(@NonNull WebView view, @NonNull WebResourceRequest request) { public boolean shouldOverrideUrlLoading(@NonNull WebView view, @NonNull WebResourceRequest request) {
// Don't open non Androidacy urls inside WebView // Don't open non Androidacy urls inside WebView
if (request.isForMainFrame() && !AndroidacyUtil.isAndroidacyLink(request.getUrl())) { if (request.isForMainFrame() && !AndroidacyUtil.isAndroidacyLink(request.getUrl())) {
if (downloadMode || backOnResume) if (downloadMode || backOnResume) return true;
return true;
// sanitize url // sanitize url
String url = request.getUrl().toString(); String url = request.getUrl().toString();
//noinspection UnnecessaryCallToStringValueOf //noinspection UnnecessaryCallToStringValueOf
@ -230,6 +233,11 @@ public final class AndroidacyActivity extends FoxActivity {
} }
} }
}); });
// logic for swipe to refresh
swipeRefreshLayout.setOnRefreshListener(() -> {
webView.reload();
swipeRefreshLayout.setRefreshing(false);
});
this.webView.setWebChromeClient(new WebChromeClient() { this.webView.setWebChromeClient(new WebChromeClient() {
@Override @Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) { public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
@ -253,8 +261,7 @@ public final class AndroidacyActivity extends FoxActivity {
@Override @Override
public void onProgressChanged(WebView view, int newProgress) { public void onProgressChanged(WebView view, int newProgress) {
if (downloadMode) if (downloadMode) return;
return;
if (newProgress != 100 && // Show progress bar if (newProgress != 100 && // Show progress bar
progressIndicator.getVisibility() != View.VISIBLE) progressIndicator.getVisibility() != View.VISIBLE)
progressIndicator.setVisibility(View.VISIBLE); progressIndicator.setVisibility(View.VISIBLE);
@ -265,15 +272,13 @@ public final class AndroidacyActivity extends FoxActivity {
} }
}); });
this.webView.setDownloadListener((downloadUrl, userAgent, contentDisposition, mimetype, contentLength) -> { this.webView.setDownloadListener((downloadUrl, userAgent, contentDisposition, mimetype, contentLength) -> {
if (this.downloadMode || this.isDownloadUrl(downloadUrl)) if (this.downloadMode || this.isDownloadUrl(downloadUrl)) return;
return;
if (AndroidacyUtil.isAndroidacyLink(downloadUrl) && !this.backOnResume) { if (AndroidacyUtil.isAndroidacyLink(downloadUrl) && !this.backOnResume) {
AndroidacyWebAPI androidacyWebAPI = this.androidacyWebAPI; AndroidacyWebAPI androidacyWebAPI = this.androidacyWebAPI;
if (androidacyWebAPI != null) { if (androidacyWebAPI != null) {
if (!androidacyWebAPI.downloadMode) { if (!androidacyWebAPI.downloadMode) {
// Native module popup may cause download after consumed action // Native module popup may cause download after consumed action
if (androidacyWebAPI.consumedAction) if (androidacyWebAPI.consumedAction) return;
return;
// Workaround Androidacy bug // Workaround Androidacy bug
final String moduleId = moduleIdOfUrl(downloadUrl); final String moduleId = moduleIdOfUrl(downloadUrl);
if (this.megaIntercept(webView.getUrl(), downloadUrl)) { if (this.megaIntercept(webView.getUrl(), downloadUrl)) {
@ -301,8 +306,7 @@ public final class AndroidacyActivity extends FoxActivity {
this.androidacyWebAPI = new AndroidacyWebAPI(this, allowInstall); this.androidacyWebAPI = new AndroidacyWebAPI(this, allowInstall);
XHooks.onWebViewInitialize(this.webView, allowInstall); XHooks.onWebViewInitialize(this.webView, allowInstall);
this.webView.addJavascriptInterface(this.androidacyWebAPI, "mmm"); this.webView.addJavascriptInterface(this.androidacyWebAPI, "mmm");
if (compatLevel != 0) if (compatLevel != 0) androidacyWebAPI.notifyCompatModeRaw(compatLevel);
androidacyWebAPI.notifyCompatModeRaw(compatLevel);
HashMap<String, String> headers = new HashMap<>(); HashMap<String, String> headers = new HashMap<>();
headers.put("Accept-Language", this.getResources().getConfiguration().locale.toLanguageTag()); headers.put("Accept-Language", this.getResources().getConfiguration().locale.toLanguageTag());
if (BuildConfig.DEBUG) { if (BuildConfig.DEBUG) {
@ -326,10 +330,8 @@ public final class AndroidacyActivity extends FoxActivity {
private String moduleIdOfUrl(String url) { private String moduleIdOfUrl(String url) {
for (String prefix : new String[]{"https://production-api.androidacy.com/downloads/", "https://staging-api.androidacy.com/downloads/", "https://production-api.androidacy.com/magisk/readme/", "https://staging-api.androidacy.com/magisk/readme/", "https://prodiuction-api.androidacy.com/magisk/info/", "https://staging-api.androidacy.com/magisk/info/"}) { // Make both staging and non staging act the same for (String prefix : new String[]{"https://production-api.androidacy.com/downloads/", "https://staging-api.androidacy.com/downloads/", "https://production-api.androidacy.com/magisk/readme/", "https://staging-api.androidacy.com/magisk/readme/", "https://prodiuction-api.androidacy.com/magisk/info/", "https://staging-api.androidacy.com/magisk/info/"}) { // Make both staging and non staging act the same
int i = url.indexOf('?', prefix.length()); int i = url.indexOf('?', prefix.length());
if (i == -1) if (i == -1) i = url.length();
i = url.length(); if (url.startsWith(prefix)) return url.substring(prefix.length(), i);
if (url.startsWith(prefix))
return url.substring(prefix.length(), i);
} }
if (this.isFileUrl(url)) { if (this.isFileUrl(url)) {
int i = url.indexOf("&module="); int i = url.indexOf("&module=");
@ -346,29 +348,24 @@ public final class AndroidacyActivity extends FoxActivity {
} }
private boolean isFileUrl(String url) { private boolean isFileUrl(String url) {
if (url == null) if (url == null) return false;
return false;
for (String prefix : new String[]{"https://production-api.androidacy.com/downloads/", "https://staging-api.androidacy.com/downloads/"}) { // Make both staging and non staging act the same for (String prefix : new String[]{"https://production-api.androidacy.com/downloads/", "https://staging-api.androidacy.com/downloads/"}) { // Make both staging and non staging act the same
if (url.startsWith(prefix)) if (url.startsWith(prefix)) return true;
return true;
} }
return false; return false;
} }
private boolean isDownloadUrl(String url) { private boolean isDownloadUrl(String url) {
for (String prefix : new String[]{"https://production-api.androidacy.com/magisk/downloads/", "https://staging-api.androidacy.com/magisk/downloads/"}) { // Make both staging and non staging act the same for (String prefix : new String[]{"https://production-api.androidacy.com/magisk/downloads/", "https://staging-api.androidacy.com/magisk/downloads/"}) { // Make both staging and non staging act the same
if (url.startsWith(prefix)) if (url.startsWith(prefix)) return true;
return true;
} }
return false; return false;
} }
private boolean megaIntercept(String pageUrl, String fileUrl) { private boolean megaIntercept(String pageUrl, String fileUrl) {
if (pageUrl == null || fileUrl == null) if (pageUrl == null || fileUrl == null) return false;
return false;
// ensure neither pageUrl nor fileUrl are going to cause a crash // ensure neither pageUrl nor fileUrl are going to cause a crash
if (pageUrl.contains(" ") || fileUrl.contains(" ")) if (pageUrl.contains(" ") || fileUrl.contains(" ")) return false;
return false;
if (!this.isFileUrl(fileUrl)) { if (!this.isFileUrl(fileUrl)) {
return false; return false;
} }

@ -22,7 +22,7 @@
android:id="@+id/blur_frame" android:id="@+id/blur_frame"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:paddingBottom="84dp"> android:paddingBottom="84dp" >
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/module_list" android:id="@+id/module_list"

@ -5,17 +5,28 @@
android:layout_height="match_parent" android:layout_height="match_parent"
app:fitsSystemWindowsInsets="left|right"> app:fitsSystemWindowsInsets="left|right">
<WebView <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe_refresh_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:id="@+id/webView" /> app:layout_constraintBottom_toTopOf="parent"
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_bar"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:indeterminate="false"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent">
<WebView
android:id="@+id/webView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<com.google.android.material.progressindicator.LinearProgressIndicator
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
Loading…
Cancel
Save