diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 89a1c6008..abe04b6bd 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -270,6 +270,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/markdown-reader.html b/assets/markdown-reader.html new file mode 100644 index 000000000..7725907fa --- /dev/null +++ b/assets/markdown-reader.html @@ -0,0 +1 @@ +Markdown Reader \ No newline at end of file diff --git a/build.gradle b/build.gradle index b61b14a1f..4e8d639d8 100644 --- a/build.gradle +++ b/build.gradle @@ -89,13 +89,13 @@ android { } defaultConfig { - versionCode 583 + versionCode 584 versionName "1.10.0" applicationId "com.b44t.messenger" multiDexEnabled true - minSdkVersion 16 + minSdkVersion 15 targetSdkVersion 28 vectorDrawables.useSupportLibrary = true @@ -151,7 +151,7 @@ android { buildTypes { debug { minifyEnabled false - applicationIdSuffix ".beta" + applicationIdSuffix ".lite" } release { // minification and proguard disabled for now. diff --git a/res/drawable/send_button_bg_blue.xml b/res/drawable/send_button_bg_blue.xml new file mode 100644 index 000000000..7b37f6065 --- /dev/null +++ b/res/drawable/send_button_bg_blue.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/res/drawable/send_button_bg_green.xml b/res/drawable/send_button_bg_green.xml new file mode 100644 index 000000000..7cb24b0cd --- /dev/null +++ b/res/drawable/send_button_bg_green.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/res/drawable/send_button_bg_purple.xml b/res/drawable/send_button_bg_purple.xml new file mode 100644 index 000000000..31350f558 --- /dev/null +++ b/res/drawable/send_button_bg_purple.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/res/drawable/send_button_bg_red.xml b/res/drawable/send_button_bg_red.xml new file mode 100644 index 000000000..0848fb189 --- /dev/null +++ b/res/drawable/send_button_bg_red.xml @@ -0,0 +1,6 @@ + + + + + diff --git a/res/layout/activity_zhv.xml b/res/layout/activity_zhv.xml new file mode 100644 index 000000000..6f1a1e871 --- /dev/null +++ b/res/layout/activity_zhv.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/res/menu/conversation_context.xml b/res/menu/conversation_context.xml index 8fc78f365..d5e566f53 100644 --- a/res/menu/conversation_context.xml +++ b/res/menu/conversation_context.xml @@ -7,7 +7,7 @@ diff --git a/res/values/arrays.xml b/res/values/arrays.xml index aaa77e810..d72d9b0ae 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -85,11 +85,19 @@ @string/pref_light_theme @string/pref_dark_theme + @string/purple + @string/green + @string/blue + @string/red light dark + purple + green + blue + red diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 3c55270f2..88500cf97 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -12,6 +12,7 @@ + diff --git a/res/values/colors.xml b/res/values/colors.xml index 037c1ea23..9375dd886 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -1,5 +1,45 @@ + + #ff785c8d + #ff604a71 + #ff785c8d + #785c8d + #fffff9d9 + #ff8754b4 + #7b00c8 + + + + #ff43a047 + #ff2f7d32 + #ff43a047 + #43a047 + #fffff9d9 + #ff58ab43 + #5fbf41 + + + + #ff517da2 + #ff426382 + #ff517da2 + #517da2 + #fffff9d9 + #ff2f97d6 + #1ab7c8 + + + + #ffb61c1c + #ffa41a1a + #ffb61c1c + #b61c1c + #fffff9d9 + #ffce303e + #d51431 + + #ff415e6b #ff364e59 #4c6e7d diff --git a/res/values/strings.xml b/res/values/strings.xml index 20ca523f7..68bb3bf96 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,7 +1,8 @@ + Could not open file - Delta Chat + Delta Chat Lite OK Cancel Yes diff --git a/res/values/styles.xml b/res/values/styles.xml index f0cc3f5db..48945005f 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -71,7 +71,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values/themes.xml b/res/values/themes.xml index 7fc252145..a1df674fc 100644 --- a/res/values/themes.xml +++ b/res/values/themes.xml @@ -88,6 +88,7 @@ @color/white + @color/green_A700 @drawable/conversation_list_item_background @drawable/pinned_list_item_background @color/pinned_bg @@ -236,6 +237,7 @@ @color/gray95 + @color/green_A700 @drawable/conversation_list_item_background_dark @drawable/pinned_list_item_background_dark @color/pinned_bg_dark @@ -368,4 +370,686 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/debug/res/mipmap-hdpi/ic_launcher.png b/src/debug/res/mipmap-hdpi/ic_launcher.png index 16f95be85..e673c8010 100644 Binary files a/src/debug/res/mipmap-hdpi/ic_launcher.png and b/src/debug/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png b/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png index b89a95b37..702551c53 100644 Binary files a/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png and b/src/debug/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/src/debug/res/mipmap-hdpi/ic_launcher_round.png b/src/debug/res/mipmap-hdpi/ic_launcher_round.png index ddb420754..ed42c0cfe 100644 Binary files a/src/debug/res/mipmap-hdpi/ic_launcher_round.png and b/src/debug/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/src/debug/res/mipmap-mdpi/ic_launcher.png b/src/debug/res/mipmap-mdpi/ic_launcher.png index 11c09b483..02cfab89a 100644 Binary files a/src/debug/res/mipmap-mdpi/ic_launcher.png and b/src/debug/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png b/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png index 042cf883b..05b770aa1 100644 Binary files a/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png and b/src/debug/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/src/debug/res/mipmap-mdpi/ic_launcher_round.png b/src/debug/res/mipmap-mdpi/ic_launcher_round.png index b7b6e43c8..6442bf96f 100644 Binary files a/src/debug/res/mipmap-mdpi/ic_launcher_round.png and b/src/debug/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/src/debug/res/mipmap-xhdpi/ic_launcher.png b/src/debug/res/mipmap-xhdpi/ic_launcher.png index e3eea1841..d2f6f80fb 100644 Binary files a/src/debug/res/mipmap-xhdpi/ic_launcher.png and b/src/debug/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/debug/res/mipmap-xhdpi/ic_launcher_foreground.png b/src/debug/res/mipmap-xhdpi/ic_launcher_foreground.png index 7c3ebc0f7..ced102144 100644 Binary files a/src/debug/res/mipmap-xhdpi/ic_launcher_foreground.png and b/src/debug/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/src/debug/res/mipmap-xhdpi/ic_launcher_round.png b/src/debug/res/mipmap-xhdpi/ic_launcher_round.png index 40ac8f801..9f1ba6f4e 100644 Binary files a/src/debug/res/mipmap-xhdpi/ic_launcher_round.png and b/src/debug/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/src/debug/res/mipmap-xxhdpi/ic_launcher.png b/src/debug/res/mipmap-xxhdpi/ic_launcher.png index fc7ca07f1..1815c6235 100644 Binary files a/src/debug/res/mipmap-xxhdpi/ic_launcher.png and b/src/debug/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/debug/res/mipmap-xxhdpi/ic_launcher_foreground.png b/src/debug/res/mipmap-xxhdpi/ic_launcher_foreground.png index 122a5530e..fd0c7e8ae 100644 Binary files a/src/debug/res/mipmap-xxhdpi/ic_launcher_foreground.png and b/src/debug/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png b/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png index 616657c99..6373c3f2b 100644 Binary files a/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png and b/src/debug/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/src/debug/res/mipmap-xxxhdpi/ic_launcher.png b/src/debug/res/mipmap-xxxhdpi/ic_launcher.png index cc933c4fb..5bf3f2d05 100644 Binary files a/src/debug/res/mipmap-xxxhdpi/ic_launcher.png and b/src/debug/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/debug/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/src/debug/res/mipmap-xxxhdpi/ic_launcher_foreground.png index 0119c4450..3cb48fde5 100644 Binary files a/src/debug/res/mipmap-xxxhdpi/ic_launcher_foreground.png and b/src/debug/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png b/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png index ffeb7062c..a1640f76e 100644 Binary files a/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png and b/src/debug/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/src/org/thoughtcrime/securesms/CmdFilter.java b/src/org/thoughtcrime/securesms/CmdFilter.java new file mode 100644 index 000000000..1ccbb4f1c --- /dev/null +++ b/src/org/thoughtcrime/securesms/CmdFilter.java @@ -0,0 +1,11 @@ +package org.thoughtcrime.securesms; + +import android.text.util.Linkify; +import java.util.regex.Matcher; + + +public class CmdFilter implements Linkify.TransformFilter { + public String transformUrl(Matcher match, String url) { + return url.trim(); + } +} diff --git a/src/org/thoughtcrime/securesms/ConversationActivity.java b/src/org/thoughtcrime/securesms/ConversationActivity.java index 33348ddea..b04c65e69 100644 --- a/src/org/thoughtcrime/securesms/ConversationActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationActivity.java @@ -123,6 +123,7 @@ import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.ExecutionException; +import java.util.regex.Matcher; import static org.thoughtcrime.securesms.TransportOption.Type; import static org.thoughtcrime.securesms.util.RelayUtil.getForwardedMessageIDs; @@ -1042,7 +1043,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity msg.setDimension(attachment.getWidth(), attachment.getHeight()); // recompress jpeg-files unless sent as documents - if (MediaUtil.isJpegType(contentType) && slideDeck.getDocumentSlide()==null) { + if ((MediaUtil.isJpegType(contentType) || MediaUtil.isPngType(contentType)) && slideDeck.getDocumentSlide()==null) { recompress = DcMsg.DC_MSG_IMAGE; } } @@ -1533,7 +1534,41 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity } @Override - public void handleReplyMessage(DcMsg messageRecord) { + public void handleReplyMessage(DcMsg msg) { + DcContact contact = dcContext.getContact(msg.getFromId()); + String prefix = "> "; + String quote; + if(msg.getType() == DcMsg.DC_MSG_TEXT) { + quote = msg.getText(); + } + else { + quote = msg.getSummarytext(1000); + } + + quote = quote.replaceAll("> .*\n", "").trim(); + + int nl_count = 0; + for(int i=0; i < quote.length(); i++) { + if(quote.charAt(i) == '\n') { + nl_count += 1; + if (nl_count == 4) { + quote = quote.substring(0, i); + break; + } + } + } + + if (quote.length() > 60) { + quote = quote.substring(0, 60) + "[...]"; + } else if (nl_count == 4) { + quote += "[...]"; + } + + quote = "@" + contact.getDisplayName() + ":\n" + quote; + quote = prefix+quote.replaceAll("(?:\r\n?|\n)(?!\\z)", "$0"+Matcher.quoteReplacement(prefix)) + "\n\n\n"; + composeText.setText(quote); + composeText.setSelection(composeText.getText().length()); + container.showSoftkey(composeText); } @Override diff --git a/src/org/thoughtcrime/securesms/ConversationFragment.java b/src/org/thoughtcrime/securesms/ConversationFragment.java index 25aaf38ca..c1babd6a8 100644 --- a/src/org/thoughtcrime/securesms/ConversationFragment.java +++ b/src/org/thoughtcrime/securesms/ConversationFragment.java @@ -290,10 +290,14 @@ public class ConversationFragment extends Fragment if (messageRecords.size() > 1) { menu.findItem(R.id.menu_context_details).setVisible(false); menu.findItem(R.id.menu_context_save_attachment).setVisible(false); + + menu.findItem(R.id.menu_context_reply).setVisible(false); } else { DcMsg messageRecord = messageRecords.iterator().next(); menu.findItem(R.id.menu_context_details).setVisible(true); menu.findItem(R.id.menu_context_save_attachment).setVisible(messageRecord.hasFile()); + + menu.findItem(R.id.menu_context_reply).setVisible(true); } } diff --git a/src/org/thoughtcrime/securesms/ConversationItem.java b/src/org/thoughtcrime/securesms/ConversationItem.java index f540cb1c4..8e960d68a 100644 --- a/src/org/thoughtcrime/securesms/ConversationItem.java +++ b/src/org/thoughtcrime/securesms/ConversationItem.java @@ -66,6 +66,8 @@ import org.thoughtcrime.securesms.util.views.Stub; import java.util.HashSet; import java.util.Locale; import java.util.Set; +import java.util.regex.Pattern; +import org.thoughtcrime.securesms.CmdFilter; /** * A view that displays an individual conversation item within a conversation @@ -78,6 +80,7 @@ import java.util.Set; public class ConversationItem extends LinearLayout implements BindableConversationItem { + private static final String TAG = ConversationItem.class.getSimpleName(); private static final int MAX_MEASURE_CALLS = 3; @@ -504,12 +507,15 @@ public class ConversationItem extends LinearLayout boolean hasLinks = Linkify.addLinks(messageBody, shouldLinkifyAllLinks ? Linkify.EMAIL_ADDRESSES|Linkify.WEB_URLS|Linkify.PHONE_NUMBERS : 0); - if (hasLinks) { + Pattern cmdPattern = Pattern.compile("(^|\\s)/[a-zA-Z@\\d_/]{1,255}"); + boolean hasCommands = Linkify.addLinks(messageBody, cmdPattern, "mailto:", null, new CmdFilter()); + + if (hasLinks || hasCommands) { URLSpan[] urlSpans = messageBody.getSpans(0, messageBody.length(), URLSpan.class); for (URLSpan urlSpan : urlSpans) { int start = messageBody.getSpanStart(urlSpan); int end = messageBody.getSpanEnd(urlSpan); - messageBody.setSpan(new LongClickCopySpan(urlSpan.getURL()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + messageBody.setSpan(new LongClickCopySpan(urlSpan.getURL(), this.dcChat.getId()), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); } } return messageBody; diff --git a/src/org/thoughtcrime/securesms/ConversationListActivity.java b/src/org/thoughtcrime/securesms/ConversationListActivity.java index 9983def02..593529866 100644 --- a/src/org/thoughtcrime/securesms/ConversationListActivity.java +++ b/src/org/thoughtcrime/securesms/ConversationListActivity.java @@ -86,9 +86,38 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit protected void onCreate(Bundle icicle, boolean ready) { ApplicationDcContext dcContext = DcHelper.getContext(this); + DcMsg msg; + // add welcome message dcContext.updateDeviceChats(); + msg = new DcMsg(dcContext, DcMsg.DC_MSG_TEXT); + msg.setText( + "💡TIP - Estos son algunos bots para Delta Chat:\n" + + "✳️ adb_bot1@testrun.org para grupos públicos, mega-groupos con más de 20 personas!, canales y directorio de amigos.\n" + + "✳️ simplebot@testrun.org puente entre delta chat y la red social mastodon.\n" + + "✳️ simple-facebook-bridge@testrun.org puente para chatear desde delta chat con tus amigos de facebook.\n" + + "✳️ simplebot@riseup.net bot de navegación en internet, búsqueda y descargas de archivos, fotos, estado del tiempo, wikipedia, RSS, memes etc.\n" + + "✳️ simplebot@deltanode.eu bot para navegación en internet parecido a simplebot@riseup.net además permite jugar ajedrez y reversi con tus amigos\n" + + "✳️ xmpp@deltanode.eu el cual es un puente entre delta chat y la red XMPP\n\n" + + "ℹ️ para ver cada comando que soporta un bot, enviale un mensaje que diga:\n" + + "/help"); + dcContext.addDeviceMsg("lite-update1.6.2", msg); + + // msg = new DcMsg(dcContext, DcMsg.DC_MSG_TEXT); + // msg.setText( + // "🆕 Registro de cambios v1.9.2:\n" + + // "✳️ integrado un visor de .html,.md y .html.zip en la app para poder abrir con facilidad los html que envían los bots.\n" + + // "✳️ añadido nuevos temas para la selección de apariencia de la app.\n" + + // "✳️ mejorada la calidad de los audios aún así el consumo sigue siendo bajo con una taza de 1KB por segundo.\n" + + // "✳️ un poco más de compresión de imágenes.\n" + + // "✳️ ahora el area de escribir se expande por más líneas para que la redacción de textos largos sea más fácil.\n" + + + // "✳️ añadido soporte para Android 4.0.3, esto no ha sido comprobado por no contar con un teléfono con dicha versión, por lo que puede que no funcione.\n" + + // "✳️ modificado el icono de la app."); + // dcContext.addDeviceMsg("lite-1.9.2-chlog", msg); + + setContentView(R.layout.conversation_list_activity); Toolbar toolbar = findViewById(R.id.toolbar); diff --git a/src/org/thoughtcrime/securesms/ConversationListItem.java b/src/org/thoughtcrime/securesms/ConversationListItem.java index 77a2ba4a7..d43c09aa4 100644 --- a/src/org/thoughtcrime/securesms/ConversationListItem.java +++ b/src/org/thoughtcrime/securesms/ConversationListItem.java @@ -274,6 +274,10 @@ public class ConversationListItem extends RelativeLayout unreadIndicator.setVisibility(View.GONE); } else { + final TypedArray attrs = getContext().obtainStyledAttributes(new int[] { + R.attr.conversation_list_item_unreadcount_color, + }); + unreadIndicator.setImageDrawable(TextDrawable.builder() .beginConfig() .width(ViewUtil.dpToPx(getContext(), 24)) @@ -281,7 +285,7 @@ public class ConversationListItem extends RelativeLayout .textColor(Color.WHITE) .bold() .endConfig() - .buildRound(String.valueOf(unreadCount), getResources().getColor(R.color.green_A700))); + .buildRound(String.valueOf(unreadCount), attrs.getColor(0, Color.BLACK))); unreadIndicator.setVisibility(View.VISIBLE); } } diff --git a/src/org/thoughtcrime/securesms/ZhvActivity.java b/src/org/thoughtcrime/securesms/ZhvActivity.java new file mode 100644 index 000000000..4f8f2c389 --- /dev/null +++ b/src/org/thoughtcrime/securesms/ZhvActivity.java @@ -0,0 +1,153 @@ +package org.thoughtcrime.securesms; + +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.webkit.JavascriptInterface; +import android.widget.Toast; +import android.webkit.WebView; +import android.webkit.WebSettings; +import android.webkit.WebChromeClient; +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; + +public class ZhvActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + try { + this.getActionBar().hide(); + } catch (NullPointerException e) { + } + + setContentView(R.layout.activity_zhv); + + handleIntent(); + } + + 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().contains("zip")) { + // 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(uri.getPath().contains("md")){ + // markdown mode + isMarkdown = true; + } + } else { + // zip html mode + text = getStringFromZip(inputStream); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + if (text == null) { + tellUserThatCouldNotOpenFile(); + return; + } + + WebView myWebView = findViewById(R.id.webview); + WebSettings webSettings = myWebView.getSettings(); + webSettings.setJavaScriptEnabled(true); + webSettings.setSupportZoom(true); + webSettings.setBuiltInZoomControls(true); + webSettings.setBlockNetworkLoads(true); + webSettings.setDomStorageEnabled(true); + + // myWebView.setWebContentsDebuggingEnabled(true); + + final Boolean isMarkdownReader = isMarkdown; + final String contentText = text; + class JsObject { + @JavascriptInterface + public int getVersion() { return 14; } + @JavascriptInterface + public String toString() { return "[ZippedHTMLViewer Object]"; } + @JavascriptInterface + public String getMarkdown() { + if(isMarkdownReader){ + return contentText; + } else { + return ""; + } + } + } + myWebView.addJavascriptInterface(new JsObject(), "zhv"); + myWebView.setWebChromeClient(new WebChromeClient()); + myWebView.loadData("", "text/html", null); + if(isMarkdown){ + // markdown mode + myWebView.loadUrl("file:///android_asset/markdown-reader.html"); + } else { + // html mode + myWebView.loadDataWithBaseURL("file://index.html", contentText, "text/html", null, null); + } + } + + 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; + if (!Objects.equals(ze.getName(), "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; + } + +} diff --git a/src/org/thoughtcrime/securesms/audio/AudioCodec.java b/src/org/thoughtcrime/securesms/audio/AudioCodec.java index 6c585c481..690a9981b 100644 --- a/src/org/thoughtcrime/securesms/audio/AudioCodec.java +++ b/src/org/thoughtcrime/securesms/audio/AudioCodec.java @@ -23,11 +23,11 @@ public class AudioCodec { private static final String TAG = AudioCodec.class.getSimpleName(); - private static final int SAMPLE_RATE = 44100; - private static final int SAMPLE_RATE_INDEX = 4; + private static final int SAMPLE_RATE = 16000; + private static final int SAMPLE_RATE_INDEX = 8; private static final int CHANNELS = 1; - private static final int BIT_RATE_BALANCED = 32000; - private static final int BIT_RATE_WORSE = 24000; + private static final int BIT_RATE_BALANCED = 24000; + private static final int BIT_RATE_WORSE = 8000; private final int bufferSize; private final MediaCodec mediaCodec; diff --git a/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java b/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java index 6af73bee2..fdef6c530 100644 --- a/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java +++ b/src/org/thoughtcrime/securesms/connect/ApplicationDcContext.java @@ -40,6 +40,8 @@ import java.util.Date; import java.util.HashMap; import java.util.Set; +import org.thoughtcrime.securesms.ZhvActivity; + public class ApplicationDcContext extends DcContext { public static final String TAG = "DeltaChat"; @@ -207,10 +209,17 @@ public class ApplicationDcContext extends DcContext { if (cmd.equals(Intent.ACTION_VIEW)) { mimeType = checkMime(path, mimeType); - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setDataAndType(uri, mimeType); - intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - activity.startActivity(intent); + if(mimeType.equals("text/html") || path.endsWith(".md") || path.endsWith(".html") || path.endsWith(".htmlzip") || path.endsWith(".html.zip")) { + Intent intent = new Intent(activity, ZhvActivity.class); + intent.setDataAndType(uri, mimeType); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + activity.startActivity(intent); + } else { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setDataAndType(uri, mimeType); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + activity.startActivity(intent); + } } else { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType(mimeType); diff --git a/src/org/thoughtcrime/securesms/util/BitmapUtil.java b/src/org/thoughtcrime/securesms/util/BitmapUtil.java index 2efce9e51..4fc61a498 100644 --- a/src/org/thoughtcrime/securesms/util/BitmapUtil.java +++ b/src/org/thoughtcrime/securesms/util/BitmapUtil.java @@ -411,14 +411,14 @@ public class BitmapUtil { // recode jpeg ////////////////////////////////////////////////////////////////////////////////////////////////// - public static void recodeImageMsg(Context context, DcMsg msg) + public static void recodeImageMsg(Context context, DcMsg msg) { - int desiredWH = 1280; - int desiredJpegQuality = 85; + int desiredWH = 640; + int desiredJpegQuality = 75; if (Prefs.isHardCompressionEnabled(context)) { - desiredWH = 640; - desiredJpegQuality = 75; + desiredWH = 500; + desiredJpegQuality = 60; } try { diff --git a/src/org/thoughtcrime/securesms/util/DynamicNoActionBarTheme.java b/src/org/thoughtcrime/securesms/util/DynamicNoActionBarTheme.java index bc7132e27..d90f898a0 100644 --- a/src/org/thoughtcrime/securesms/util/DynamicNoActionBarTheme.java +++ b/src/org/thoughtcrime/securesms/util/DynamicNoActionBarTheme.java @@ -9,7 +9,11 @@ public class DynamicNoActionBarTheme extends DynamicTheme { protected int getSelectedTheme(Activity activity) { String theme = Prefs.getTheme(activity); - if (theme.equals("dark")) return R.style.TextSecure_DarkNoActionBar; + if (theme.equals(DynamicTheme.DARK)) return R.style.TextSecure_DarkNoActionBar; + if (theme.equals(DynamicTheme.PURPLE)) return R.style.TextSecure_PurpleNoActionBar; + if (theme.equals(DynamicTheme.GREEN)) return R.style.TextSecure_GreenNoActionBar; + if (theme.equals(DynamicTheme.BLUE)) return R.style.TextSecure_BlueNoActionBar; + if (theme.equals(DynamicTheme.RED)) return R.style.TextSecure_RedNoActionBar; return R.style.TextSecure_LightNoActionBar; } diff --git a/src/org/thoughtcrime/securesms/util/DynamicTheme.java b/src/org/thoughtcrime/securesms/util/DynamicTheme.java index 0ff7c780e..9fba219fe 100644 --- a/src/org/thoughtcrime/securesms/util/DynamicTheme.java +++ b/src/org/thoughtcrime/securesms/util/DynamicTheme.java @@ -10,6 +10,10 @@ public class DynamicTheme { public static final String DARK = "dark"; public static final String LIGHT = "light"; + public static final String PURPLE = "purple"; + public static final String GREEN = "green"; + public static final String BLUE = "blue"; + public static final String RED = "red"; private int currentTheme; @@ -32,6 +36,10 @@ public class DynamicTheme { String theme = Prefs.getTheme(activity); if (theme.equals(DARK)) return R.style.TextSecure_DarkTheme; + if (theme.equals(PURPLE)) return R.style.TextSecure_PurpleTheme; + if (theme.equals(GREEN)) return R.style.TextSecure_GreenTheme; + if (theme.equals(BLUE)) return R.style.TextSecure_BlueTheme; + if (theme.equals(RED)) return R.style.TextSecure_RedTheme; return R.style.TextSecure_LightTheme; } diff --git a/src/org/thoughtcrime/securesms/util/LongClickCopySpan.java b/src/org/thoughtcrime/securesms/util/LongClickCopySpan.java index 523cd47ad..ad60fd48f 100644 --- a/src/org/thoughtcrime/securesms/util/LongClickCopySpan.java +++ b/src/org/thoughtcrime/securesms/util/LongClickCopySpan.java @@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.ConversationActivity; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.connect.DcHelper; + public class LongClickCopySpan extends URLSpan { private static final String PREFIX_MAILTO = "mailto:"; private static final String PREFIX_TEL = "tel:"; @@ -26,10 +27,17 @@ public class LongClickCopySpan extends URLSpan { private boolean isHighlighted; @ColorInt private int highlightColor; + private int chatId; - public LongClickCopySpan(String url) { - super(url); - } + public LongClickCopySpan(String url) { + super(url); + this.chatId = 0; + } + + public LongClickCopySpan(String url, int chatId) { + super(url); + this.chatId = chatId; + } private void openChat(Activity activity, DcContact contact) { DcContext dcContext = DcHelper.getContext(activity); @@ -44,7 +52,17 @@ public class LongClickCopySpan extends URLSpan { @Override public void onClick(View widget) { String url = getURL(); - if (url.startsWith(PREFIX_MAILTO)) { + if (url.startsWith(PREFIX_MAILTO+"/")) { + try { + String cmd = prepareUrl(url); + Activity activity = (Activity) widget.getContext(); + DcContext dcContext = DcHelper.getContext(activity); + dcContext.sendTextMsg(this.chatId, cmd); + } + catch(Exception e) { + e.printStackTrace(); + } + } else if (url.startsWith(PREFIX_MAILTO)) { try { String addr = prepareUrl(url); Activity activity = (Activity) widget.getContext(); @@ -72,20 +90,25 @@ public class LongClickCopySpan extends URLSpan { } void onLongClick(View widget) { + String url = getURL(); Context context = widget.getContext(); - String preparedUrl = prepareUrl(getURL()); - - new AlertDialog.Builder(context) - .setTitle(preparedUrl) - .setItems(new CharSequence[]{ - context.getString(R.string.menu_copy_to_clipboard) - }, - (dialogInterface, i) -> { - copyUrl(context, preparedUrl); - Toast.makeText(context, context.getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show(); - }) - .setNegativeButton(R.string.cancel, null) - .show(); + String preparedUrl = prepareUrl(url); + if (url.startsWith(PREFIX_MAILTO+"/")) { + copyUrl(context, preparedUrl); + Toast.makeText(context, context.getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show(); + } else { + new AlertDialog.Builder(context) + .setTitle(preparedUrl) + .setItems(new CharSequence[]{ + context.getString(R.string.menu_copy_to_clipboard) + }, + (dialogInterface, i) -> { + copyUrl(context, preparedUrl); + Toast.makeText(context, context.getString(R.string.copied_to_clipboard), Toast.LENGTH_SHORT).show(); + }) + .setNegativeButton(R.string.cancel, null) + .show(); + } } @Override diff --git a/src/org/thoughtcrime/securesms/util/MediaUtil.java b/src/org/thoughtcrime/securesms/util/MediaUtil.java index a83fac7b1..d24554e57 100644 --- a/src/org/thoughtcrime/securesms/util/MediaUtil.java +++ b/src/org/thoughtcrime/securesms/util/MediaUtil.java @@ -226,6 +226,10 @@ public class MediaUtil { return !TextUtils.isEmpty(contentType) && contentType.trim().equals(IMAGE_JPEG); } + public static boolean isPngType(String contentType) { + return !TextUtils.isEmpty(contentType) && contentType.trim().equals(IMAGE_PNG); + } + public static boolean isFile(Attachment attachment) { return !isGif(attachment) && !isImage(attachment) && !isAudio(attachment) && !isVideo(attachment); } diff --git a/src/org/thoughtcrime/securesms/video/recode/VideoRecoder.java b/src/org/thoughtcrime/securesms/video/recode/VideoRecoder.java index a6493540f..658273099 100644 --- a/src/org/thoughtcrime/securesms/video/recode/VideoRecoder.java +++ b/src/org/thoughtcrime/securesms/video/recode/VideoRecoder.java @@ -802,7 +802,7 @@ public class VideoRecoder { // check if video bitrate is already reasonable final int MAX_KBPS = 1500000; - final long MAX_BYTES = DcHelper.getInt(context, "sys.msgsize_max_recommended"); + final long MAX_BYTES = 100000; //DcHelper.getInt(context, "sys.msgsize_max_recommended"); long inBytes = new File(inPath).length(); if (inBytes > 0 && inBytes <= MAX_BYTES && vei.originalVideoBitrate <= MAX_KBPS*2 /*be tolerant as long the file size matches*/) { Log.i(TAG, String.format("recoding for %s is not needed, %d bytes and %d kbps are ok", inPath, inBytes, vei.originalVideoBitrate)); @@ -814,21 +814,10 @@ public class VideoRecoder { long maxVideoBytes = MAX_BYTES - vei.originalAudioBytes - resultDurationMs /*10 kbps codec overhead*/; vei.resultVideoBitrate = (int) (maxVideoBytes / Math.max(1, resultDurationMs / 1000) * 8); - if (vei.resultVideoBitrate < 200000) { - vei.resultVideoBitrate = 200000; - } else if (vei.resultVideoBitrate > 500000) { - boolean hardCompression = Prefs.isHardCompressionEnabled(context); - if (resultDurationMs < 30 * 1000 && !hardCompression) { - vei.resultVideoBitrate = MAX_KBPS; // ~ 12 MB/minute, plus Audio - } else if (resultDurationMs < 60 * 1000 && !hardCompression) { - vei.resultVideoBitrate = 1000000; // ~ 8 MB/minute, plus Audio - } else { - vei.resultVideoBitrate = 500000; // ~ 3.7 MB/minute, plus Audio - } - } + vei.resultVideoBitrate = 200000; // calculate video dimensions - int maxSide = vei.resultVideoBitrate > 400000 ? 640 : 480; + int maxSide = 480; vei.resultWidth = vei.originalWidth; vei.resultHeight = vei.originalHeight; if (vei.resultWidth > maxSide || vei.resultHeight > maxSide) {