mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
Merge branch 'master' of https://github.com/deltachat/deltachat-android-ii
This commit is contained in:
+9
-1
@@ -300,6 +300,14 @@
|
||||
android:windowSoftInputMode="stateVisible"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".QrScanActivity"
|
||||
android:theme="@style/TextSecure.LightTheme"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".QrShowActivity"
|
||||
android:theme="@style/TextSecure.LightTheme"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".ClearProfileAvatarActivity"
|
||||
android:theme="@style/Theme.AppCompat.Dialog.Alert"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"
|
||||
@@ -324,7 +332,7 @@
|
||||
android:theme="@style/TextSecure.LightNoActionBar"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
<activity android:name=".preferences.ChatBackgroundDialogFragment"
|
||||
<activity android:name=".preferences.ChatBackgroundActivity"
|
||||
android:theme="@style/TextSecure.LightTheme"
|
||||
android:configChanges="touchscreen|keyboard|keyboardHidden|orientation|screenLayout|screenSize"/>
|
||||
|
||||
|
||||
+2
-2
@@ -83,6 +83,8 @@ dependencies {
|
||||
compile 'org.whispersystems:signal-service-android:2.7.6'
|
||||
compile 'org.whispersystems:webrtc-android:M68'
|
||||
|
||||
compile 'com.journeyapps:zxing-android-embedded:3.4.0'
|
||||
|
||||
compile "me.leolin:ShortcutBadger:1.1.16"
|
||||
compile 'se.emilsjolander:stickylistheaders:2.7.0'
|
||||
compile 'com.jpardogo.materialtabstrip:library:1.0.9'
|
||||
@@ -96,7 +98,6 @@ dependencies {
|
||||
compile 'pl.tajchert:waitingdots:0.1.0'
|
||||
compile 'com.soundcloud.android:android-crop:0.9.10@aar'
|
||||
compile 'com.melnykov:floatingactionbutton:1.3.0'
|
||||
compile 'com.google.zxing:android-integration:3.1.0'
|
||||
compile 'com.squareup.dagger:dagger:1.2.2'
|
||||
annotationProcessor 'com.squareup.dagger:dagger-compiler:1.2.2'
|
||||
compile 'mobi.upod:time-duration-picker:1.1.3'
|
||||
@@ -185,7 +186,6 @@ dependencyVerification {
|
||||
'com.makeramen:roundedimageview:1f5a1865796b308c6cdd114acc6e78408b110f0a62fc63553278fbeacd489cd1',
|
||||
'org.greenrobot:eventbus:180d4212467df06f2fbc9c8d8a2984533ac79c87769ad883bc421612f0b4e17c',
|
||||
'com.soundcloud.android:android-crop:ffd4b973cf6e97f7d64118a0dc088df50e9066fd5634fe6911dd0c0c5d346177',
|
||||
'com.google.zxing:android-integration:89e56aadf1164bd71e57949163c53abf90af368b51669c0d4a47a163335f95c4',
|
||||
'com.squareup.dagger:dagger:789aca24537022e49f91fc6444078d9de8f1dd99e1bfb090f18491b186967883',
|
||||
'com.amulyakhare:com.amulyakhare.textdrawable:54c92b5fba38cfd316a07e5a30528068f45ce8515a6890f1297df4c401af5dcb',
|
||||
'com.google.zxing:core:b4d82452e7a6bf6ec2698904b332431717ed8f9a850224f295aec89de80f2259',
|
||||
|
||||
+2
-2
@@ -982,9 +982,9 @@ JNIEXPORT void Java_com_b44t_messenger_DcMsg_lateFilingMediaSize(JNIEnv *env, jo
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT jint Java_com_b44t_messenger_DcMsg_getBytes(JNIEnv *env, jobject obj)
|
||||
JNIEXPORT jlong Java_com_b44t_messenger_DcMsg_getFilebytes(JNIEnv *env, jobject obj)
|
||||
{
|
||||
return (jint)dc_msg_get_filebytes(get_dc_msg(env, obj));
|
||||
return (jlong)dc_msg_get_filebytes(get_dc_msg(env, obj));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 314 B |
Binary file not shown.
|
After Width: | Height: | Size: 4.9 KiB |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.journeyapps.barcodescanner.CompoundBarcodeView
|
||||
android:id="@+id/zxing_barcode_scanner"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_alignParentBottom="true" />
|
||||
|
||||
</RelativeLayout>
|
||||
@@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/qrImage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:contentDescription="@string/qr_scan_activity__title" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/qrShowHint"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text=""
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat"
|
||||
android:textSize="16sp" />
|
||||
|
||||
</LinearLayout>
|
||||
+16
-6
@@ -3,25 +3,35 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/layout_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
>
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/preview"
|
||||
android:scaleType="centerCrop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_gravity="bottom">
|
||||
|
||||
<Button
|
||||
android:id="@+id/set_default_button"
|
||||
android:theme="@style/Button.Primary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="0.5"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Set default"/>
|
||||
android:layout_weight="0.5"
|
||||
android:text="Set default" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/from_gallery_button"
|
||||
android:theme="@style/Button.Primary"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="0.5"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="From gallery"/>
|
||||
android:layout_weight="0.5"
|
||||
android:text="From gallery" />
|
||||
</LinearLayout>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -36,11 +36,10 @@
|
||||
android:weightSum="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/from"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
@@ -49,28 +48,40 @@
|
||||
|
||||
<org.thoughtcrime.securesms.components.FromTextView
|
||||
android:id="@+id/from_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/Signal.Text.Body"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:textColor="?attr/conversation_list_item_contact_color"
|
||||
android:maxLines="1"
|
||||
tools:text="Jules Bonnot"
|
||||
android:ellipsize="end"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="2dp"
|
||||
android:drawablePadding="5dp"/>
|
||||
android:drawablePadding="5dp"
|
||||
android:ellipsize="end"
|
||||
android:fontFamily="sans-serif-medium"
|
||||
android:maxLines="1"
|
||||
android:textColor="?attr/conversation_list_item_contact_color"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/verified_indicator"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintHorizontal_weight="0.9"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Jules Bonnot" />
|
||||
|
||||
<ImageView
|
||||
android:src="@drawable/ic_verified"
|
||||
android:id="@+id/verified_indicator"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:paddingLeft="5dp"
|
||||
android:paddingStart="5dp"
|
||||
android:visibility="gone"/>
|
||||
android:src="@drawable/ic_verified"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintHorizontal_weight="0.1"
|
||||
app:layout_constraintStart_toEndOf="@id/from_text"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</LinearLayout>
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
|
||||
android:id="@+id/subject"
|
||||
|
||||
@@ -56,15 +56,23 @@
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textSize="18dp"
|
||||
android:transitionName="recipient_name" />
|
||||
android:transitionName="recipient_name"
|
||||
app:layout_constraintEnd_toStartOf="@id/verified_indicator"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintHorizontal_weight="0.9"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:text="Jules Bonnot" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/verified_indicator"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_verified"
|
||||
android:visibility="visible"
|
||||
android:visibility="gone"
|
||||
android:layout_marginLeft="5dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintHorizontal_weight="0.1"
|
||||
app:layout_constraintBottom_toBottomOf="@id/title"
|
||||
app:layout_constraintStart_toEndOf="@id/title"
|
||||
app:layout_constraintTop_toTopOf="@id/title"
|
||||
|
||||
@@ -68,25 +68,47 @@
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<com.dd.CircularProgressButton
|
||||
android:id="@+id/add_member_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:background="@color/signal_primary"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingStart="12dp"
|
||||
android:textColor="@color/white"
|
||||
app:cpb_colorIndicator="@color/white"
|
||||
app:cpb_colorProgress="@color/textsecure_primary"
|
||||
app:cpb_cornerRadius="20dp"
|
||||
app:cpb_selectorIdle="@drawable/progress_button_state"
|
||||
app:cpb_textIdle="@string/recipients_panel__add_members"
|
||||
app:layout_constraintBottom_toTopOf="@id/skip_button_bottom_spacer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"/>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<com.dd.CircularProgressButton
|
||||
android:id="@+id/add_member_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:background="@color/signal_primary"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingStart="12dp"
|
||||
android:textColor="@color/white"
|
||||
app:cpb_colorIndicator="@color/white"
|
||||
app:cpb_colorProgress="@color/textsecure_primary"
|
||||
app:cpb_cornerRadius="20dp"
|
||||
app:cpb_selectorIdle="@drawable/progress_button_state"
|
||||
app:cpb_textIdle="@string/recipients_panel__add_members"/>
|
||||
|
||||
<com.dd.CircularProgressButton
|
||||
android:id="@+id/verify_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="40dp"
|
||||
android:background="@color/signal_primary"
|
||||
android:layout_marginStart="15dp"
|
||||
android:layout_marginLeft="15dp"
|
||||
android:layout_marginBottom="15dp"
|
||||
android:paddingEnd="12dp"
|
||||
android:paddingStart="12dp"
|
||||
android:textColor="@color/white"
|
||||
app:cpb_colorIndicator="@color/white"
|
||||
app:cpb_colorProgress="@color/textsecure_primary"
|
||||
app:cpb_cornerRadius="20dp"
|
||||
app:cpb_selectorIdle="@drawable/progress_button_state"
|
||||
android:visibility="gone"
|
||||
app:cpb_textIdle="@string/qr_show_activity__title"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<ListView android:id="@+id/selected_contacts_list"
|
||||
android:layout_width="match_parent"
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item android:title="@string/qr_scan_activity__title"
|
||||
android:id="@+id/menu_qr_scan"
|
||||
android:icon="@drawable/ic_ab_qr"
|
||||
app:showAsAction="always"/>
|
||||
|
||||
<item android:title="@string/qr_show_activity__title"
|
||||
android:id="@+id/menu_qr_show" />
|
||||
|
||||
<item android:title="@string/text_secure_normal__menu_new_chat"
|
||||
android:id="@+id/menu_new_chat" />
|
||||
|
||||
@@ -1314,6 +1314,32 @@
|
||||
<string name="new_conversation_activity__refresh">Refresh</string>
|
||||
<!-- redphone_audio_popup_menu -->
|
||||
|
||||
<!-- qr_scan_activity -->
|
||||
<string name="qr_scan_activity__title">Scan QR code</string>
|
||||
<string name="qr_scan_activity__hint">Place your camera over the QR code</string>
|
||||
|
||||
<!-- qr_scan_handler -->
|
||||
<string name="qr_scan_handler_join_verified_group">Do you want to join the verified group <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>?</string>
|
||||
<string name="qr_scan_handler_fingerprint_ask_oob">Verify contact and start chatting with <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>?</string>
|
||||
<string name="qr_scan_handler_fingerprint_ok">Contact <![CDATA[<i>]]>%1$s<![CDATA[</i>]]> verified. Start chatting?</string>
|
||||
<string name="qr_scan_handler_fingerprint_mismatch">The scanned fingerprint does <![CDATA[<b>]]>not match<![CDATA[</b>]]> the fingerprint last seen for <![CDATA[<i>]]>%1$s<![CDATA[</i>]]>.</string>
|
||||
<string name="qr_scan_handler_fingerprint_without_address">This QR code contains a fingerprint but no email address.\n\nFor an out-of-band-verification, please establish an encrpyted connection to the recipient first.</string>
|
||||
<string name="qr_scan_handler_Scan_contains_text">Scanned QR code text:\n\n%1$s</string>
|
||||
<string name="qr_scan_handler_qr_scan_contains_url">Scanned QR code URL:\n\n%1$s</string>
|
||||
<string name="qr_scan_handler_fingerprint">Fingerprint</string>
|
||||
<string name="qr_scan_handler_ask_start_chat_with">Chat with <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>?</string>
|
||||
<string name="qr_scan_handler_verfied_introduce_myself">%1$s verified, introduce myself …</string>
|
||||
|
||||
<!-- qr_show_activity -->
|
||||
<string name="qr_show_activity__title">Show QR verify code</string>
|
||||
<string name="qr_show_activity__joining">%1$s joins.</string>
|
||||
<string name="qr_show_activity__verified">%1$s verified.</string>
|
||||
<string name="qr_show_activity__group_joined">%1$s securely joined the group.</string>
|
||||
<string name="qr_show_activity__join_verified_group_hint">Scan this to join the verified group <![CDATA[<b>]]>%1$s<![CDATA[</b>]]>.</string>
|
||||
<string name="qr_show_activity__join_verified_group_title">QR invite code</string>
|
||||
<string name="qr_show_activity__join_contact_title">QR verify code</string>
|
||||
<string name="qr_show_activity__join_contact_hint"><![CDATA[<b>]]>%1$s<![CDATA[</b><br>]]>Scan this to set up a verified contact.</string>
|
||||
|
||||
<!-- Trimmer -->
|
||||
<string name="trimmer__deleting">Deleting</string>
|
||||
<string name="trimmer__deleting_old_messages">Deleting old messages...</string>
|
||||
@@ -1489,5 +1515,8 @@
|
||||
<string name="default_status_hint">Status text</string>
|
||||
<string name="registration_activity__login">Login</string>
|
||||
<string name="preferences__chat_background">Chat-Background</string>
|
||||
<string name="copy_to_clipboard">Copy to clipboard</string>
|
||||
<string name="open">Open</string>
|
||||
<string name="done">Done</string>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -182,6 +182,7 @@
|
||||
|
||||
<style name="Button.Primary" parent="Base.Widget.AppCompat.Button.Colored">
|
||||
<item name="colorAccent">@color/signal_primary</item>
|
||||
<item name="colorButtonNormal">@color/signal_primary</item>
|
||||
<item name="android:textColor">@color/white</item>
|
||||
</style>
|
||||
|
||||
|
||||
@@ -93,7 +93,6 @@ public class DcMsg {
|
||||
public native int getHeight (int def);
|
||||
public native int getDuration ();
|
||||
public native void lateFilingMediaSize(int width, int height, int duration);
|
||||
public native int getBytes ();
|
||||
public @NonNull DcLot getSummary (DcChat chat) { return new DcLot(getSummaryCPtr(chat.getChatCPtr())); }
|
||||
public native String getSummarytext (int approx_characters);
|
||||
public native int showPadlock ();
|
||||
@@ -101,6 +100,7 @@ public class DcMsg {
|
||||
public native String getFile ();
|
||||
public native String getFilemime ();
|
||||
public native String getFilename ();
|
||||
public native long getFilebytes ();
|
||||
public native boolean isForwarded ();
|
||||
public native boolean isInfo ();
|
||||
public native boolean isSetupMessage ();
|
||||
|
||||
@@ -17,12 +17,9 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.support.v7.widget.TooltipCompat;
|
||||
@@ -33,10 +30,13 @@ import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.zxing.integration.android.IntentIntegrator;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
import org.thoughtcrime.securesms.components.SearchToolbar;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.lock.RegistrationLockDialog;
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
import org.thoughtcrime.securesms.qr.QrScanHandler;
|
||||
import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.search.SearchFragment;
|
||||
import org.thoughtcrime.securesms.service.KeyCachingService;
|
||||
@@ -163,11 +163,22 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
case R.id.menu_clear_passphrase: handleClearPassphrase(); return true;
|
||||
case R.id.menu_invite: handleInvite(); return true;
|
||||
case R.id.menu_help: handleHelp(); return true;
|
||||
case R.id.menu_qr_scan: handleQrScan(); return true;
|
||||
case R.id.menu_qr_show: handleQrShow(); return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void handleQrScan() {
|
||||
new IntentIntegrator(this).setCaptureActivity(QrScanActivity.class).initiateScan();
|
||||
}
|
||||
|
||||
private void handleQrShow() {
|
||||
Intent qrIntent = new Intent(this, QrShowActivity.class);
|
||||
startActivity(qrIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateConversation(long threadId, Recipient recipient, int distributionType, long lastSeen) {
|
||||
openConversation(threadId, recipient, distributionType, lastSeen, -1);
|
||||
@@ -227,4 +238,13 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
||||
Toast.makeText(this, R.string.ConversationListActivity_there_is_no_browser_installed_on_your_device, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
if (requestCode == IntentIntegrator.REQUEST_CODE) {
|
||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
|
||||
QrScanHandler qrScanHandler = new QrScanHandler(this);
|
||||
qrScanHandler.onScanPerformed(scanResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ import android.widget.Toast;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.request.target.SimpleTarget;
|
||||
import com.bumptech.glide.request.transition.Transition;
|
||||
import com.dd.CircularProgressButton;
|
||||
import com.soundcloud.android.crop.Crop;
|
||||
|
||||
import org.thoughtcrime.securesms.connect.ApplicationDcContext;
|
||||
@@ -97,6 +98,7 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
private ImageView avatar;
|
||||
private TextView creatingText;
|
||||
private Bitmap avatarBmp;
|
||||
private CircularProgressButton verifyButton;
|
||||
|
||||
@NonNull private Optional<GroupData> groupToUpdate = Optional.absent();
|
||||
|
||||
@@ -200,11 +202,16 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
avatar = ViewUtil.findById(this, R.id.avatar);
|
||||
groupName = ViewUtil.findById(this, R.id.group_name);
|
||||
creatingText = ViewUtil.findById(this, R.id.creating_group_text);
|
||||
verifyButton = ViewUtil.findById(this, R.id.verify_button);
|
||||
SelectedRecipientsAdapter adapter = new SelectedRecipientsAdapter(this);
|
||||
adapter.setOnRecipientDeletedListener(this);
|
||||
lv.setAdapter(adapter);
|
||||
|
||||
findViewById(R.id.add_member_button).setOnClickListener(new AddRecipientButtonListener());
|
||||
if (createVerified) {
|
||||
verifyButton.setOnClickListener(new ShowQrButtonListener());
|
||||
verifyButton.setVisibility(View.VISIBLE);
|
||||
}
|
||||
avatar.setImageDrawable(new ResourceContactPhoto(R.drawable.ic_group_white_24dp).asDrawable(this, ContactColors.UNKNOWN_COLOR.toConversationColor(this)));
|
||||
avatar.setOnClickListener(view -> Crop.pickImage(GroupCreateActivity.this));
|
||||
}
|
||||
@@ -363,6 +370,15 @@ public class GroupCreateActivity extends PassphraseRequiredActionBarActivity
|
||||
}
|
||||
}
|
||||
|
||||
private class ShowQrButtonListener implements View.OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
Intent qrIntent = new Intent(GroupCreateActivity.this, QrShowActivity.class);
|
||||
startActivity(qrIntent);
|
||||
}
|
||||
}
|
||||
|
||||
private static class FillExistingGroupInfoAsyncTask extends ProgressDialogAsyncTask<String,Void,Optional<GroupData>> {
|
||||
private GroupCreateActivity activity;
|
||||
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.journeyapps.barcodescanner.CaptureManager;
|
||||
import com.journeyapps.barcodescanner.CompoundBarcodeView;
|
||||
|
||||
import org.thoughtcrime.securesms.permissions.Permissions;
|
||||
|
||||
public class QrScanActivity extends AppCompatActivity {
|
||||
|
||||
private CaptureManager capture;
|
||||
|
||||
private CompoundBarcodeView barcodeScannerView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_qr_scan);
|
||||
|
||||
assert getSupportActionBar() != null;
|
||||
getSupportActionBar().setTitle(R.string.qr_scan_activity__title);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
barcodeScannerView = findViewById(R.id.zxing_barcode_scanner);
|
||||
barcodeScannerView.setStatusText(getString(R.string.qr_scan_activity__hint) + "\n ");
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
init(barcodeScannerView, getIntent(), savedInstanceState);
|
||||
}
|
||||
|
||||
Permissions.with(this)
|
||||
.request(Manifest.permission.CAMERA)
|
||||
.ifNecessary()
|
||||
.onAnyResult(this::handleQrScanWithPermissions)
|
||||
.onAnyDenied(this::handleQrScanWithDeniedPermission)
|
||||
.execute();
|
||||
}
|
||||
|
||||
private void handleQrScanWithPermissions() {
|
||||
init(barcodeScannerView, getIntent(), null);
|
||||
}
|
||||
|
||||
private void handleQrScanWithDeniedPermission() {
|
||||
setResult(Activity.RESULT_CANCELED);
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
|
||||
Permissions.onRequestPermissionsResult(this, requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
private void init(CompoundBarcodeView barcodeScannerView, Intent intent, Bundle savedInstanceState) {
|
||||
capture = new CaptureManager(this, barcodeScannerView);
|
||||
capture.initializeFromIntent(intent, savedInstanceState);
|
||||
capture.decode();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
if (capture != null) {
|
||||
capture.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
if (capture != null) {
|
||||
capture.onPause();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (capture != null) {
|
||||
capture.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
if (capture != null) {
|
||||
capture.onSaveInstanceState(outState);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, KeyEvent event) {
|
||||
return barcodeScannerView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
package org.thoughtcrime.securesms;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.text.Html;
|
||||
import android.view.MenuItem;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.b44t.messenger.DcContext;
|
||||
import com.b44t.messenger.DcEventCenter;
|
||||
import com.google.zxing.BarcodeFormat;
|
||||
import com.google.zxing.MultiFormatWriter;
|
||||
import com.google.zxing.WriterException;
|
||||
import com.google.zxing.common.BitMatrix;
|
||||
|
||||
import org.thoughtcrime.securesms.connect.ApplicationDcContext;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
|
||||
public class QrShowActivity extends AppCompatActivity implements DcEventCenter.DcEventDelegate {
|
||||
|
||||
public final static int WHITE = 0xFFFFFFFF;
|
||||
public final static int BLACK = 0xFF000000;
|
||||
public final static int WIDTH = 400;
|
||||
public final static int HEIGHT = 400;
|
||||
|
||||
public int numJoiners;
|
||||
|
||||
DcEventCenter dcEventCenter;
|
||||
|
||||
ApplicationDcContext dcContext;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_qr_show);
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // keeping the screen on also avoids falling back from IDLE to POLL
|
||||
|
||||
dcContext = DcHelper.getContext(this);
|
||||
dcEventCenter = dcContext.eventCenter;
|
||||
|
||||
Bundle extras = getIntent().getExtras();
|
||||
int chatId = 0;
|
||||
if (extras != null) {
|
||||
chatId = extras.getInt("chat_id");
|
||||
}
|
||||
|
||||
ActionBar supportActionBar = getSupportActionBar();
|
||||
assert supportActionBar != null;
|
||||
supportActionBar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
String hint;
|
||||
if (chatId != 0) {
|
||||
// verified-group
|
||||
String groupName = dcContext.getChat(chatId).getName();
|
||||
hint = String.format(this.getString(R.string.qr_show_activity__join_verified_group_hint), groupName);
|
||||
supportActionBar.setTitle(groupName);
|
||||
supportActionBar.setSubtitle(R.string.qr_show_activity__join_verified_group_title);
|
||||
} else {
|
||||
// verify-contact
|
||||
String selfName = DcHelper.get(this, DcHelper.CONFIG_DISPLAY_NAME); // we cannot use MrContact.getDisplayName() as this would result in "Me" instead of
|
||||
String nameAndAddress;
|
||||
if (selfName.isEmpty()) {
|
||||
selfName = DcHelper.get(this, DcHelper.CONFIG_ADDRESS, "unknown");
|
||||
nameAndAddress = selfName;
|
||||
} else {
|
||||
nameAndAddress = String.format("%s (%s)", selfName, DcHelper.get(this, DcHelper.CONFIG_ADDRESS));
|
||||
}
|
||||
hint = String.format(this.getString(R.string.qr_show_activity__join_contact_hint), nameAndAddress);
|
||||
supportActionBar.setTitle(selfName);
|
||||
supportActionBar.setSubtitle(R.string.qr_show_activity__join_contact_title);
|
||||
}
|
||||
TextView hintBelowQr = findViewById(R.id.qrShowHint);
|
||||
hintBelowQr.setText(Html.fromHtml(hint));
|
||||
|
||||
numJoiners = 0;
|
||||
|
||||
ImageView imageView = findViewById(R.id.qrImage);
|
||||
try {
|
||||
Bitmap bitmap = encodeAsBitmap(dcContext.getSecurejoinQr(chatId));
|
||||
imageView.setImageBitmap(bitmap);
|
||||
} catch (WriterException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
dcEventCenter.addObserver(this, DcContext.DC_EVENT_SECUREJOIN_INVITER_PROGRESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
dcEventCenter.removeObserver(this, DcContext.DC_EVENT_SECUREJOIN_INVITER_PROGRESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
super.onOptionsItemSelected(item);
|
||||
|
||||
switch (item.getItemId()) {
|
||||
case android.R.id.home:
|
||||
finish();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Bitmap encodeAsBitmap(String str) throws WriterException {
|
||||
BitMatrix result;
|
||||
try {
|
||||
result = new MultiFormatWriter().encode(str,
|
||||
BarcodeFormat.QR_CODE, WIDTH, HEIGHT, null);
|
||||
} catch (IllegalArgumentException iae) {
|
||||
// Unsupported format
|
||||
return null;
|
||||
}
|
||||
|
||||
int w = result.getWidth();
|
||||
int h = result.getHeight();
|
||||
int[] pixels = new int[w * h];
|
||||
for (int y = 0; y < h; y++) {
|
||||
int offset = y * w;
|
||||
for (int x = 0; x < w; x++) {
|
||||
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
|
||||
}
|
||||
}
|
||||
|
||||
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
|
||||
bitmap.setPixels(pixels, 0, w, 0, 0, w, h);
|
||||
|
||||
int configQrOverlayLogo = DcHelper.getInt(this, DcHelper.CONFIG_QR_OVERLAY_LOGO, 1);
|
||||
if (configQrOverlayLogo != 0) {
|
||||
Bitmap overlay = BitmapFactory.decodeResource(this.getResources(), R.drawable.qr_overlay);
|
||||
putOverlay(bitmap, overlay);
|
||||
}
|
||||
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
public void putOverlay(Bitmap bitmap, Bitmap overlay) {
|
||||
int bw = bitmap.getWidth();
|
||||
int bh = bitmap.getHeight();
|
||||
int ow = bw / 6;
|
||||
int oh = bh / 6;
|
||||
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
|
||||
canvas.drawBitmap(overlay, null, new Rect(bw / 2 - ow / 2, bh / 2 - oh / 2, bw / 2 + ow / 2, bh / 2 + oh / 2), paint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(int eventId, Object data1, Object data2) {
|
||||
if (eventId == DcContext.DC_EVENT_SECUREJOIN_INVITER_PROGRESS) {
|
||||
DcContext dcContext = DcHelper.getContext(this);
|
||||
int contact_id = ((Long) data1).intValue();
|
||||
long progress = (Long) data2;
|
||||
String msg = null;
|
||||
if (progress == 300) {
|
||||
msg = String.format(getString(R.string.qr_show_activity__joining), dcContext.getContact(contact_id).getNameNAddr());
|
||||
numJoiners++;
|
||||
} else if (progress == 600) {
|
||||
msg = String.format(getString(R.string.qr_show_activity__verified), dcContext.getContact(contact_id).getNameNAddr());
|
||||
} else if (progress == 800) {
|
||||
msg = String.format(getString(R.string.qr_show_activity__group_joined), dcContext.getContact(contact_id).getNameNAddr());
|
||||
}
|
||||
|
||||
if (msg != null) {
|
||||
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
if (progress == 1000) {
|
||||
numJoiners--;
|
||||
if (numJoiners <= 0) {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ public abstract class Attachment {
|
||||
|
||||
@NonNull
|
||||
private final String contentType;
|
||||
private final int transferState;
|
||||
private int transferState;
|
||||
private final long size;
|
||||
|
||||
@Nullable
|
||||
@@ -63,6 +63,10 @@ public abstract class Attachment {
|
||||
@Nullable
|
||||
public abstract Uri getThumbnailUri();
|
||||
|
||||
public void setTransferState(int transferState) {
|
||||
this.transferState = transferState;
|
||||
}
|
||||
|
||||
public int getTransferState() {
|
||||
return transferState;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
package org.thoughtcrime.securesms.attachments;
|
||||
|
||||
import java.io.File;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
|
||||
public class DcAttachment extends Attachment {
|
||||
|
||||
private final DcMsg dcMsg;
|
||||
|
||||
public DcAttachment(DcMsg dcMsg) {
|
||||
// todo: width, height, quote
|
||||
super(dcMsg.getFilemime(), AttachmentDatabase.TRANSFER_PROGRESS_DONE, dcMsg.getFilebytes(),
|
||||
dcMsg.getFilename(),
|
||||
Uri.fromFile(new File(dcMsg.getFile())).toString(), String.valueOf(dcMsg.getId()), null, null,
|
||||
null, dcMsg.getType() == DcMsg.DC_MSG_VOICE,
|
||||
0, 0, false);
|
||||
this.dcMsg = dcMsg;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Uri getDataUri() {
|
||||
return Uri.fromFile(new File(dcMsg.getFile()));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Uri getThumbnailUri() {
|
||||
return Uri.fromFile(new File(dcMsg.getFile()));
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,14 @@ import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
import org.thoughtcrime.securesms.mms.Slide;
|
||||
import org.thoughtcrime.securesms.mms.SlideClickListener;
|
||||
import org.thoughtcrime.securesms.util.ThemeUtil;
|
||||
import org.thoughtcrime.securesms.util.concurrent.ListenableFuture;
|
||||
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class ConversationItemThumbnail extends FrameLayout {
|
||||
|
||||
@@ -145,11 +149,25 @@ public class ConversationItemThumbnail extends FrameLayout {
|
||||
return footer;
|
||||
}
|
||||
|
||||
private void refreshSlideAttachmentState(ListenableFuture<Boolean> signal, Slide slide) {
|
||||
signal.addListener(new ListenableFuture.Listener<Boolean>() {
|
||||
@Override
|
||||
public void onSuccess(Boolean result) {
|
||||
slide.asAttachment().setTransferState(AttachmentDatabase.TRANSFER_PROGRESS_DONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(ExecutionException e) {
|
||||
slide.asAttachment().setTransferState(AttachmentDatabase.TRANSFER_PROGRESS_FAILED);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void setImageResource(@NonNull GlideRequests glideRequests, @NonNull Slide slide,
|
||||
boolean showControls, boolean isPreview)
|
||||
{
|
||||
thumbnail.setImageResource(glideRequests, slide, showControls, isPreview);
|
||||
refreshSlideAttachmentState(thumbnail.setImageResource(glideRequests, slide, showControls, isPreview), slide);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
@@ -157,7 +175,8 @@ public class ConversationItemThumbnail extends FrameLayout {
|
||||
boolean showControls, boolean isPreview, int naturalWidth,
|
||||
int naturalHeight)
|
||||
{
|
||||
thumbnail.setImageResource(glideRequests, slide, showControls, isPreview, naturalWidth, naturalHeight);
|
||||
refreshSlideAttachmentState(thumbnail.setImageResource(glideRequests, slide, showControls, isPreview, naturalWidth, naturalHeight), slide);
|
||||
|
||||
}
|
||||
|
||||
public void setImageResource(@NonNull GlideRequests glideRequests, @NonNull Uri uri) {
|
||||
|
||||
@@ -22,6 +22,7 @@ public class DcHelper {
|
||||
public static final String CONFIG_SELF_STATUS = "selfstatus";
|
||||
public static final String CONFIG_SELF_AVATAR = "selfavatar";
|
||||
public static final String CONFIG_E2EE_ENABLED = "e2ee_enabled";
|
||||
public static final String CONFIG_QR_OVERLAY_LOGO = "qr_overlay_logo";
|
||||
|
||||
public static ApplicationDcContext getContext(Context context) {
|
||||
return ApplicationContext.getInstance(context).dcContext;
|
||||
@@ -32,9 +33,18 @@ public class DcHelper {
|
||||
return dcContext.isConfigured() == 1;
|
||||
}
|
||||
|
||||
public static String get(Context context, String key) {
|
||||
public static int getInt(Context context, String key, int defaultValue) {
|
||||
DcContext dcContext = getContext(context);
|
||||
return dcContext.getConfig(key, "");
|
||||
return dcContext.getConfigInt(key, defaultValue);
|
||||
}
|
||||
|
||||
public static String get(Context context, String key, String defaultValue) {
|
||||
DcContext dcContext = getContext(context);
|
||||
return dcContext.getConfig(key, defaultValue);
|
||||
}
|
||||
|
||||
public static String get(Context context, String key) {
|
||||
return get(context, key, "");
|
||||
}
|
||||
|
||||
public static void set(Context context, String key, String value) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.DcAttachment;
|
||||
import org.thoughtcrime.securesms.attachments.UriAttachment;
|
||||
import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
@@ -38,7 +39,7 @@ import java.io.File;
|
||||
public class AudioSlide extends Slide {
|
||||
|
||||
public AudioSlide(Context context, DcMsg dcMsg) {
|
||||
this(context, Uri.fromFile(new File(dcMsg.getFile())), dcMsg.getBytes(), dcMsg.getType()==DcMsg.DC_MSG_VOICE);
|
||||
super(context, new DcAttachment(dcMsg));
|
||||
dcMsgId = dcMsg.getId();
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ import android.support.annotation.Nullable;
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.DcAttachment;
|
||||
import org.thoughtcrime.securesms.util.StorageUtil;
|
||||
|
||||
import java.io.File;
|
||||
@@ -20,7 +21,7 @@ public class DocumentSlide extends Slide {
|
||||
}
|
||||
|
||||
public DocumentSlide(Context context, DcMsg dcMsg) {
|
||||
this(context, Uri.fromFile(new File(dcMsg.getFile())), dcMsg.getFilemime(), dcMsg.getBytes(), dcMsg.getFilename());
|
||||
this(context, new DcAttachment(dcMsg));
|
||||
dcMsgId = dcMsg.getId();
|
||||
}
|
||||
|
||||
|
||||
@@ -4,11 +4,17 @@ import android.content.Context;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
|
||||
public class GifSlide extends ImageSlide {
|
||||
|
||||
public GifSlide(Context context, DcMsg dcMsg) {
|
||||
super(context, dcMsg);
|
||||
}
|
||||
|
||||
public GifSlide(Context context, Attachment attachment) {
|
||||
super(context, attachment);
|
||||
}
|
||||
|
||||
@@ -23,8 +23,11 @@ import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.DcAttachment;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
|
||||
public class ImageSlide extends Slide {
|
||||
@@ -32,6 +35,10 @@ public class ImageSlide extends Slide {
|
||||
@SuppressWarnings("unused")
|
||||
private static final String TAG = ImageSlide.class.getSimpleName();
|
||||
|
||||
public ImageSlide(@NonNull Context context, @NonNull DcMsg dcMsg) {
|
||||
super(context, new DcAttachment(dcMsg));
|
||||
}
|
||||
|
||||
public ImageSlide(@NonNull Context context, @NonNull Attachment attachment) {
|
||||
super(context, attachment);
|
||||
}
|
||||
|
||||
@@ -4,10 +4,16 @@ package org.thoughtcrime.securesms.mms;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
|
||||
public class MmsSlide extends ImageSlide {
|
||||
|
||||
public MmsSlide(@NonNull Context context, @NonNull DcMsg dcMsg) {
|
||||
super(context, dcMsg);
|
||||
}
|
||||
|
||||
public MmsSlide(@NonNull Context context, @NonNull Attachment attachment) {
|
||||
super(context, attachment);
|
||||
}
|
||||
|
||||
@@ -22,8 +22,11 @@ import android.net.Uri;
|
||||
import android.support.annotation.DrawableRes;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.b44t.messenger.DcMsg;
|
||||
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.attachments.Attachment;
|
||||
import org.thoughtcrime.securesms.attachments.DcAttachment;
|
||||
import org.thoughtcrime.securesms.util.MediaUtil;
|
||||
import org.thoughtcrime.securesms.util.ResUtil;
|
||||
|
||||
@@ -33,6 +36,10 @@ public class VideoSlide extends Slide {
|
||||
super(context, constructAttachmentFromUri(context, uri, MediaUtil.VIDEO_UNSPECIFIED, dataSize, 0, 0, MediaUtil.hasVideoThumbnail(uri), null, false, false));
|
||||
}
|
||||
|
||||
public VideoSlide(Context context, DcMsg dcMsg) {
|
||||
super(context, new DcAttachment(dcMsg));
|
||||
}
|
||||
|
||||
public VideoSlide(Context context, Attachment attachment) {
|
||||
super(context, attachment);
|
||||
}
|
||||
|
||||
@@ -2,32 +2,16 @@ package org.thoughtcrime.securesms.preferences;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Point;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.preference.ListPreference;
|
||||
import android.support.v7.preference.Preference;
|
||||
import android.view.Display;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
|
||||
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.mms.GlideApp;
|
||||
import org.thoughtcrime.securesms.util.ServiceUtil;
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static android.app.Activity.RESULT_OK;
|
||||
|
||||
public class AppearancePreferenceFragment extends ListSummaryPreferenceFragment {
|
||||
|
||||
@@ -85,7 +69,7 @@ public class AppearancePreferenceFragment extends ListSummaryPreferenceFragment
|
||||
private class BackgroundClickListener implements Preference.OnPreferenceClickListener {
|
||||
@Override
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
Intent intent = new Intent(getContext(), ChatBackgroundDialogFragment.class);
|
||||
Intent intent = new Intent(getContext(), ChatBackgroundActivity.class);
|
||||
getActivity().startActivity(intent);
|
||||
return true;
|
||||
}
|
||||
|
||||
+10
-15
@@ -8,21 +8,14 @@ import android.graphics.Point;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.PersistableBundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Display;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.Button;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
@@ -38,12 +31,12 @@ import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class ChatBackgroundDialogFragment extends BaseActionBarActivity {
|
||||
public class ChatBackgroundActivity extends BaseActionBarActivity {
|
||||
|
||||
Button galleryButton;
|
||||
Button defaultButton;
|
||||
FrameLayout layoutContainer;
|
||||
MenuItem acceptMenuItem;
|
||||
ImageView preview;
|
||||
|
||||
String tempDestinationPath;
|
||||
Uri imageUri;
|
||||
@@ -51,11 +44,11 @@ public class ChatBackgroundDialogFragment extends BaseActionBarActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.select_chat_background_dialog);
|
||||
setContentView(R.layout.activity_select_chat_background);
|
||||
|
||||
defaultButton = findViewById(R.id.set_default_button);
|
||||
galleryButton = findViewById(R.id.from_gallery_button);
|
||||
layoutContainer = findViewById(R.id.layout_container);
|
||||
preview = findViewById(R.id.preview);
|
||||
|
||||
defaultButton.setOnClickListener(new DefaultClickListener());
|
||||
galleryButton.setOnClickListener(new GalleryClickListener());
|
||||
@@ -64,8 +57,10 @@ public class ChatBackgroundDialogFragment extends BaseActionBarActivity {
|
||||
setLayoutBackgroundImage(backgroundImagePath);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
|
||||
if (actionBar != null) {
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setHomeAsUpIndicator(R.drawable.ic_close_white_24dp);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -140,7 +135,7 @@ public class ChatBackgroundDialogFragment extends BaseActionBarActivity {
|
||||
|
||||
private void setLayoutBackgroundImage(String backgroundImagePath) {
|
||||
Drawable image = Drawable.createFromPath(backgroundImagePath);
|
||||
layoutContainer.setBackground(image);
|
||||
preview.setImageDrawable(image);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +1,221 @@
|
||||
package org.thoughtcrime.securesms.qr;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.StringRes;
|
||||
import android.text.Html;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.b44t.messenger.DcContext;
|
||||
import com.b44t.messenger.DcEventCenter;
|
||||
import com.b44t.messenger.DcLot;
|
||||
import com.google.zxing.integration.android.IntentResult;
|
||||
|
||||
import org.thoughtcrime.securesms.ConversationActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.connect.ApplicationDcContext;
|
||||
import org.thoughtcrime.securesms.connect.DcHelper;
|
||||
import org.thoughtcrime.securesms.database.Address;
|
||||
import org.thoughtcrime.securesms.util.IntentUtils;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
|
||||
public class QrScanHandler implements DcEventCenter.DcEventDelegate {
|
||||
|
||||
private Activity activity;
|
||||
ProgressDialog progressDialog;
|
||||
|
||||
private ApplicationDcContext dcContext;
|
||||
|
||||
public QrScanHandler(Activity activity) {
|
||||
this.activity = activity;
|
||||
dcContext = DcHelper.getContext(activity);
|
||||
}
|
||||
|
||||
public void onScanPerformed(IntentResult scanResult) {
|
||||
if (scanResult == null || scanResult.getFormatName() == null) {
|
||||
return; // Should not happen!
|
||||
}
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||
final String qrRawString = scanResult.getContents();
|
||||
final DcLot qrParsed = dcContext.checkQr(qrRawString);
|
||||
String nameAndAddress = dcContext.getContact(qrParsed.getId()).getNameNAddr();
|
||||
switch (qrParsed.getState()) {
|
||||
case DcContext.DC_QR_ASK_VERIFYCONTACT:
|
||||
case DcContext.DC_QR_ASK_VERIFYGROUP:
|
||||
showVerifyContactOrGroup(activity, builder, qrRawString, qrParsed, nameAndAddress);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_FPR_WITHOUT_ADDR:
|
||||
showVerifyFingerprintWithoutAddress(builder, qrParsed);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_FPR_MISMATCH:
|
||||
showFingerPrintError(builder, nameAndAddress);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_FPR_OK:
|
||||
case DcContext.DC_QR_ADDR:
|
||||
showFingerprintOrQrSuccess(builder, qrParsed, nameAndAddress);
|
||||
break;
|
||||
|
||||
case DcContext.DC_QR_URL:
|
||||
showQrUrl(builder, qrParsed);
|
||||
break;
|
||||
|
||||
default:
|
||||
handleDefault(builder, qrRawString, qrParsed);
|
||||
break;
|
||||
}
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
private void handleDefault(AlertDialog.Builder builder, String qrRawString, DcLot qrParsed) {
|
||||
String msg;
|
||||
final String scannedText;
|
||||
switch (qrParsed.getState()) {
|
||||
case DcContext.DC_QR_ERROR:
|
||||
scannedText = qrRawString;
|
||||
msg = qrParsed.getText1() + "<br><br><c#808080>" + String.format(activity.getString(R.string.qr_scan_handler_Scan_contains_text), scannedText) + "</c>";
|
||||
break;
|
||||
case DcContext.DC_QR_TEXT:
|
||||
scannedText = qrParsed.getText1();
|
||||
msg = String.format(activity.getString(R.string.qr_scan_handler_Scan_contains_text), scannedText);
|
||||
break;
|
||||
default:
|
||||
scannedText = qrRawString;
|
||||
msg = String.format(activity.getString(R.string.qr_scan_handler_Scan_contains_text), scannedText);
|
||||
break;
|
||||
}
|
||||
builder.setMessage(Html.fromHtml(msg));
|
||||
builder.setPositiveButton(android.R.string.ok, null);
|
||||
builder.setNeutralButton(R.string.copy_to_clipboard, (dialog, which) -> {
|
||||
Util.writeTextToClipboard(activity, scannedText);
|
||||
showDoneToast(activity);
|
||||
});
|
||||
}
|
||||
|
||||
private void showQrUrl(AlertDialog.Builder builder, DcLot qrParsed) {
|
||||
final String url = qrParsed.getText1();
|
||||
String msg = String.format(activity.getString(R.string.qr_scan_handler_qr_scan_contains_url), url);
|
||||
builder.setMessage(msg);
|
||||
builder.setPositiveButton(R.string.open, (dialog, which) -> IntentUtils.showBrowserIntent(activity, url));
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
builder.setNeutralButton(R.string.copy_to_clipboard, (dialog, which) -> {
|
||||
Util.writeTextToClipboard(activity, url);
|
||||
showDoneToast(activity);
|
||||
});
|
||||
}
|
||||
|
||||
private void showDoneToast(Activity activity) {
|
||||
Toast.makeText(activity, activity.getString(R.string.done), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
private void showFingerprintOrQrSuccess(AlertDialog.Builder builder, DcLot qrParsed, String nameAndAddress) {
|
||||
@StringRes int resId = qrParsed.getState() == DcContext.DC_QR_ADDR ? R.string.qr_scan_handler_ask_start_chat_with : R.string.qr_scan_handler_fingerprint_ok;
|
||||
builder.setMessage(Html.fromHtml(String.format(activity.getString(resId, nameAndAddress))));
|
||||
builder.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
|
||||
Bundle bundle = new Bundle();
|
||||
bundle.putInt(ConversationActivity.THREAD_ID_EXTRA, dcContext.createChatByContactId(qrParsed.getId()));
|
||||
Intent intent = new Intent(activity, ConversationActivity.class);
|
||||
//TODO how to we get the contact ID here? We need it to avoid crashing when starting the ConversationActivity
|
||||
activity.startActivity(intent, bundle);
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
}
|
||||
|
||||
private void showFingerPrintError(AlertDialog.Builder builder, String nameAndAddress) {
|
||||
builder.setMessage(Html.fromHtml(String.format(activity.getString(R.string.qr_scan_handler_fingerprint_mismatch), nameAndAddress)));
|
||||
builder.setPositiveButton(android.R.string.ok, null);
|
||||
}
|
||||
|
||||
private void showVerifyFingerprintWithoutAddress(AlertDialog.Builder builder, DcLot qrParsed) {
|
||||
builder.setMessage(Html.fromHtml(activity.getString(R.string.qr_scan_handler_fingerprint_without_address) + "<br><br><c#808080>" + activity.getString(R.string.qr_scan_handler_fingerprint) + ":<br>" + qrParsed.getText1() + "</c>"));
|
||||
builder.setPositiveButton(android.R.string.ok, null);
|
||||
builder.setNeutralButton(R.string.copy_to_clipboard, (dialog, which) -> {
|
||||
Util.writeTextToClipboard(activity, qrParsed.getText1());
|
||||
showDoneToast(activity);
|
||||
});
|
||||
}
|
||||
|
||||
private void showVerifyContactOrGroup(Activity activity, AlertDialog.Builder builder, String qrRawString, DcLot qrParsed, String nameNAddr) {
|
||||
if (progressDialog != null) {
|
||||
progressDialog.dismiss();
|
||||
progressDialog = null;
|
||||
}
|
||||
|
||||
String msg;
|
||||
switch (qrParsed.getState()) {
|
||||
case DcContext.DC_QR_ASK_VERIFYGROUP:
|
||||
msg = String.format(activity.getString(R.string.qr_scan_handler_join_verified_group), qrParsed.getText1());
|
||||
break;
|
||||
default:
|
||||
msg = String.format(activity.getString(R.string.qr_scan_handler_fingerprint_ask_oob), nameNAddr);
|
||||
break;
|
||||
}
|
||||
builder.setMessage(Html.fromHtml(msg));
|
||||
builder.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> {
|
||||
progressDialog = new ProgressDialog(activity);
|
||||
progressDialog.setMessage(activity.getString(R.string.one_moment));
|
||||
progressDialog.setCanceledOnTouchOutside(false);
|
||||
progressDialog.setCancelable(false);
|
||||
progressDialog.setButton(DialogInterface.BUTTON_NEGATIVE, activity.getString(android.R.string.cancel), (dialog, which) -> dcContext.stopOngoingProcess());
|
||||
progressDialog.show();
|
||||
|
||||
dcContext.captureNextError();
|
||||
|
||||
new Thread(() -> {
|
||||
|
||||
dcContext.eventCenter.addObserver(this, DcContext.DC_EVENT_SECUREJOIN_JOINER_PROGRESS);
|
||||
int newChatId = dcContext.joinSecurejoin(qrRawString); // joinSecurejoin() runs until all needed messages are sent+received!
|
||||
dcContext.eventCenter.removeObservers(this);
|
||||
|
||||
Util.runOnMain(() -> {
|
||||
if (progressDialog != null) {
|
||||
progressDialog.dismiss();
|
||||
progressDialog = null;
|
||||
}
|
||||
|
||||
String errorString = dcContext.getCapturedError();
|
||||
dcContext.endCaptureNextError();
|
||||
if (newChatId != 0) {
|
||||
Intent intent = new Intent(activity, ConversationActivity.class);
|
||||
intent.putExtra(ConversationActivity.ADDRESS_EXTRA, Address.fromChat(newChatId));
|
||||
intent.putExtra(ConversationActivity.THREAD_ID_EXTRA, (long)newChatId);
|
||||
activity.startActivity(intent);
|
||||
} else if (!errorString.isEmpty()) {
|
||||
AlertDialog.Builder builder1 = new AlertDialog.Builder(activity);
|
||||
builder1.setMessage(errorString);
|
||||
builder1.setPositiveButton(android.R.string.ok, null);
|
||||
builder1.create().show();
|
||||
}
|
||||
});
|
||||
}
|
||||
).start();
|
||||
|
||||
|
||||
});
|
||||
builder.setNegativeButton(android.R.string.cancel, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEvent(int eventId, Object data1, Object data2) {
|
||||
if (eventId == DcContext.DC_EVENT_SECUREJOIN_JOINER_PROGRESS) {
|
||||
long contact_id = (Long)data1;
|
||||
long progress = (Long)data2;
|
||||
String msg = null;
|
||||
if( progress == 400) {
|
||||
msg = activity.getString(R.string.qr_scan_handler_verfied_introduce_myself, dcContext.getContact((int)contact_id).getNameNAddr());
|
||||
}
|
||||
|
||||
if( progressDialog != null && msg != null ) {
|
||||
progressDialog.setMessage(msg);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ package org.thoughtcrime.securesms.util;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ResolveInfo;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -15,4 +16,9 @@ public class IntentUtils {
|
||||
return resolveInfoList != null && resolveInfoList.size() > 1;
|
||||
}
|
||||
|
||||
public static void showBrowserIntent(Context context, String url) {
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
context.startActivity(browserIntent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ import android.util.Log;
|
||||
import android.util.Pair;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import com.b44t.messenger.DcMsg;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.resource.gif.GifDrawable;
|
||||
|
||||
@@ -47,6 +48,25 @@ public class MediaUtil {
|
||||
public static final String VCARD = "text/x-vcard";
|
||||
|
||||
|
||||
public static Slide getSlideForMsg(Context context, DcMsg dcMsg) {
|
||||
Slide slide = null;
|
||||
if (isGif(dcMsg.getFilemime())) {
|
||||
slide = new GifSlide(context, dcMsg);
|
||||
} else if (isImageType(dcMsg.getFilemime())) {
|
||||
slide = new ImageSlide(context, dcMsg);
|
||||
} else if (isVideoType(dcMsg.getFilemime())) {
|
||||
slide = new VideoSlide(context, dcMsg);
|
||||
} else if (isAudioType(dcMsg.getFilemime())) {
|
||||
slide = new AudioSlide(context, dcMsg);
|
||||
} else if (isMms(dcMsg.getFilemime())) {
|
||||
slide = new MmsSlide(context, dcMsg);
|
||||
} else if (dcMsg.getFilemime() != null) {
|
||||
slide = new DocumentSlide(context, dcMsg);
|
||||
}
|
||||
|
||||
return slide;
|
||||
}
|
||||
|
||||
public static Slide getSlideForAttachment(Context context, Attachment attachment) {
|
||||
Slide slide = null;
|
||||
if (isGif(attachment.getContentType())) {
|
||||
|
||||
Reference in New Issue
Block a user