From b65b535cdcf46adf2d137027d5984291bdb51dfc Mon Sep 17 00:00:00 2001 From: adbenitez Date: Thu, 20 Jul 2023 02:27:52 +0200 Subject: [PATCH] allow to select as app to open .xdc files, remove zhv --- AndroidManifest.xml | 51 +--- assets/markdown-reader.html | 1 - .../android/en-US/full_description.txt | 4 +- .../thoughtcrime/securesms/ShareActivity.java | 5 + .../thoughtcrime/securesms/ZhvActivity.java | 284 ------------------ 5 files changed, 20 insertions(+), 325 deletions(-) delete mode 100644 assets/markdown-reader.html delete mode 100644 src/org/thoughtcrime/securesms/ZhvActivity.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7ea7bcf72..afc3bdaa3 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -65,6 +65,20 @@ android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize" android:exported="true"> + + + + + + + + + + + + + + @@ -336,43 +350,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/assets/markdown-reader.html b/assets/markdown-reader.html deleted file mode 100644 index 7725907fa..000000000 --- a/assets/markdown-reader.html +++ /dev/null @@ -1 +0,0 @@ -Markdown Reader \ No newline at end of file diff --git a/fastlane/metadata/android/en-US/full_description.txt b/fastlane/metadata/android/en-US/full_description.txt index 9aa156224..9626494c9 100644 --- a/fastlane/metadata/android/en-US/full_description.txt +++ b/fastlane/metadata/android/en-US/full_description.txt @@ -22,11 +22,9 @@ DeltaLab was created with a focus on usability, good user experience, and saving
  • When you select a message you have additional options to remove/add the sender from the current group easily
  • Voice messages have more aggressive compression in "worse quality" mode to save data plan
  • Default configuration changed: automatic download of messages limited to 160KB
  • -
  • Messages in groups are ignored if the sender is not a group member
  • Account's display name is shown in the app's title bar instead of the name of the app
  • Your avatar is visible to other users in Mailing Lists
  • -
  • Can open/display mardown (*.md) attachments
  • -
  • Can open/display *.htmlzip attachments
  • Can be selected as application when clicking/opening links, this is useful to share the link with web grabber bots
  • +
  • Can be selected as app to open .xdc files
  • For mini-apps developers: there are some differences in the WebXDC API, check https://github.com/adbenitez/deltalab-android/#webxdc
  • diff --git a/src/org/thoughtcrime/securesms/ShareActivity.java b/src/org/thoughtcrime/securesms/ShareActivity.java index 3f53f7dcb..c5e8664ff 100644 --- a/src/org/thoughtcrime/securesms/ShareActivity.java +++ b/src/org/thoughtcrime/securesms/ShareActivity.java @@ -124,6 +124,11 @@ public class ShareActivity extends PassphraseRequiredActionBarActivity implement streamExtras.add(uri); } else if (getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM) != null) { streamExtras = getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM); + } else { + Uri uri = getIntent().getData(); + if (uri != null) { + streamExtras.add(uri); + } } if (needsFilePermission(streamExtras)) { diff --git a/src/org/thoughtcrime/securesms/ZhvActivity.java b/src/org/thoughtcrime/securesms/ZhvActivity.java deleted file mode 100644 index ba3f03c18..000000000 --- a/src/org/thoughtcrime/securesms/ZhvActivity.java +++ /dev/null @@ -1,284 +0,0 @@ -package org.thoughtcrime.securesms; - -import android.annotation.SuppressLint; -import android.app.Activity; -import java.util.Objects; -import android.os.Bundle; -import java.io.InputStream; -import java.io.IOException; -import android.net.Uri; -import android.view.Menu; -import android.view.View; -import android.view.inputmethod.EditorInfo; -import android.webkit.JavascriptInterface; -import android.widget.SearchView; -import android.widget.Toast; -import android.webkit.WebView; -import android.webkit.WebSettings; -import android.webkit.WebChromeClient; - -import androidx.annotation.NonNull; -import androidx.webkit.WebSettingsCompat; -import androidx.webkit.WebViewFeature; - -import java.io.BufferedInputStream; -import java.io.ByteArrayOutputStream; -import java.io.FileNotFoundException; -import java.util.zip.ZipInputStream; -import java.util.zip.ZipEntry; - -import org.thoughtcrime.securesms.R; -import org.thoughtcrime.securesms.util.DynamicLanguage; -import org.thoughtcrime.securesms.util.DynamicTheme; - -public class ZhvActivity extends PassphraseRequiredActionBarActivity implements View.OnClickListener { - private static final String MD_TEXT = "MD_TEXT"; - private static final String FIRST_TIME_INIT = "FirstTimeInit"; - private static final String IS_SEARCHING = "Searching"; - private static final String TITLE_WEB = "TitleWeb"; - private static final int ZHV_VERSION_CODE = 8; - private boolean firstTimeInit = true; - private boolean isSearching = false; - private JsObject jsObject; - private String titleWEB = "ZHV"; - protected WebView webView; - - private final DynamicTheme dynamicTheme = new DynamicTheme(); - private final DynamicLanguage dynamicLanguage = new DynamicLanguage(); - - @Override - protected void onPreCreate() { - dynamicTheme.onCreate(this); - dynamicLanguage.onCreate(this); - } - - @Override - protected void onCreate(Bundle savedInstanceState, boolean ready) { - super.onCreate(savedInstanceState, ready); - if (savedInstanceState != null) { - firstTimeInit = savedInstanceState.getBoolean(FIRST_TIME_INIT, true); - isSearching = savedInstanceState.getBoolean(IS_SEARCHING, false); - titleWEB = savedInstanceState.getString(TITLE_WEB, titleWEB); - String text = savedInstanceState.getString(MD_TEXT, ""); - if (text.equals("")) { - jsObject = new JsObject("", false); - } else { - jsObject = new JsObject(text, true); - } - } - - setContentView(R.layout.activity_zhv); - webView = findViewById(R.id.webview); - - if (firstTimeInit) { - handleIntent(); - } else { - registerForContextMenu(webView); - webView.restoreState(savedInstanceState); - configureWebView(webView); - this.setTitle(titleWEB); - } - } - - @SuppressLint("SetJavaScriptEnabled") - public void configureWebView(WebView web) { - WebSettings webSettings = web.getSettings(); - webSettings.setBlockNetworkLoads(true); - webSettings.setJavaScriptEnabled(false); - webSettings.setSupportZoom(true); - webSettings.setBuiltInZoomControls(true); - webSettings.setDomStorageEnabled(true); - web.addJavascriptInterface(jsObject, "zhv"); - web.setWebChromeClient(new WebChromeClient() { - - @Override - public void onReceivedTitle(WebView view, String title) { - super.onReceivedTitle(view, title); - ZhvActivity.this.titleWEB = title; - ZhvActivity.this.setTitle(title); - } - }); - - if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) { - if (DynamicTheme.isDarkTheme(this)) { - WebSettingsCompat.setForceDark(webSettings, WebSettingsCompat.FORCE_DARK_ON); - } else { - WebSettingsCompat.setForceDark(webSettings, WebSettingsCompat.FORCE_DARK_OFF); - } - } - } - - @Override - public boolean onCreateOptionsMenu(Menu menu) { - getMenuInflater().inflate(R.menu.search_menu, menu); - final SearchView searchView = (SearchView) menu.findItem(R.id.search_menu_item).getActionView(); - searchView.setImeOptions(EditorInfo.IME_FLAG_NAVIGATE_PREVIOUS | EditorInfo.IME_ACTION_NEXT | EditorInfo.IME_FLAG_NAVIGATE_NEXT); - searchView.setOnSearchClickListener(this); - searchView.setSubmitButtonEnabled(true); - searchView.setOnCloseListener(() -> { - isSearching = false; - return false; - }); - searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String query) { - webView.findNext(true); - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - webView.findAllAsync(newText); - return true; - } - }); - return super.onCreateOptionsMenu(menu); - } - - @Override - public void onBackPressed() { - if (isSearching) { - SearchView searchView = findViewById(R.id.search_menu_item); - //if text closes it completly - searchView.setIconified(true); - searchView.setIconified(true); - isSearching = false; - } else { - super.onBackPressed(); - } - } - - private void handleIntent() { - Uri uri = getIntent().getData(); - if (uri == null) { - tellUserThatCouldNotOpenFile(); - return; - } - String text = null; - Boolean isMarkdown = false; - try { - InputStream inputStream = getContentResolver().openInputStream(uri); - if (uri.getPath() != null) { - String path = uri.getPath(); - if (path.endsWith(".html.zip") || path.endsWith(".htmlzip")) { - // zip html mode - text = getStringFromZip(inputStream); - } else { - // load file into memory (html or markdown) - ByteArrayOutputStream result = new ByteArrayOutputStream(); - byte[] buffer = new byte[1024]; - int length; - while ((length = inputStream.read(buffer)) != -1) { - result.write(buffer, 0, length); - } - text = result.toString(); - if(path.endsWith(".md")){ - // markdown mode - isMarkdown = true; - } - } - } - } catch (IOException e) { - e.printStackTrace(); - } - - if (text == null) { - tellUserThatCouldNotOpenFile(); - return; - } - - jsObject = new JsObject(text, isMarkdown); - configureWebView(webView); - - webView.loadData("", "text/html", null); - if(isMarkdown){ - // markdown mode - webView.loadUrl("file:///android_asset/markdown-reader.html"); - } else { - // html mode - webView.loadDataWithBaseURL("file://index.html", text, "text/html", null, null); - } - firstTimeInit = false; - } - - private void tellUserThatCouldNotOpenFile() { - Toast.makeText(this, getString(R.string.could_not_open_file), Toast.LENGTH_SHORT).show(); - } - - public static String getStringFromZip(InputStream stream) throws IOException { - ByteArrayOutputStream fout = new ByteArrayOutputStream(); - if (!unpackZip(stream, fout)) { - throw new IOException(); - } - return fout.toString(); - } - - private static boolean unpackZip(InputStream is, ByteArrayOutputStream fout) { - ZipInputStream zis; - try { - zis = new ZipInputStream(new BufferedInputStream(is)); - ZipEntry ze; - byte[] buffer = new byte[1024]; - int count; - while ((ze = zis.getNextEntry()) != null) { - if (ze.isDirectory()) - continue; - //android 4.1 Compatibility fix Objects class access do a crash - if (!ze.getName().contentEquals("index.html")) - continue; - - while ((count = zis.read(buffer)) != -1) { - fout.write(buffer, 0, count); - } - zis.closeEntry(); - } - zis.close(); - } catch (IOException e) { - e.printStackTrace(); - return false; - } - return true; - } - - @Override - protected void onSaveInstanceState(@NonNull Bundle outState) { - webView.saveState(outState); - outState.putBoolean(IS_SEARCHING, isSearching); - outState.putBoolean(FIRST_TIME_INIT, firstTimeInit); - outState.putString(TITLE_WEB, titleWEB); - outState.putString(MD_TEXT, jsObject.getMarkdown()); - super.onSaveInstanceState(outState); - } - - @Override - public void onClick(View v) { - isSearching = true; - } - - - class JsObject { - String contentText = ""; - boolean isMarkdownReader = false; - - public JsObject(String contentText, boolean isMarkdownReader) { - this.contentText = contentText; - this.isMarkdownReader = isMarkdownReader; - } - - @JavascriptInterface - public int getVersion() { return ZHV_VERSION_CODE; } - - @NonNull - @JavascriptInterface - public String toString() { return "[ZippedHTMLViewer Object]"; } - - @JavascriptInterface - public String getMarkdown() { - if (isMarkdownReader) { - return contentText; - } else { - return ""; - } - } - } -}