Compare commits

..

7 Commits

Author SHA1 Message Date
B. Petersen 5c6e84b21b bump version 2018-10-19 15:30:59 +02:00
B. Petersen 00f0f143af send voice messages as such 2018-10-19 15:29:40 +02:00
B. Petersen 7bcfec2367 send images, audio, documents 2018-10-19 15:07:15 +02:00
daniel.boehrs 17e5fe5a89 Verify icon layout broken #93 2018-10-19 10:11:26 +02:00
Florian Haar 4b8fef6918 Merge branch 'master' of https://github.com/deltachat/deltachat-android-ii 2018-10-19 09:03:08 +02:00
Florian Haar 44afb50c81 Allow for customized Background image #50 2018-10-19 09:01:47 +02:00
B. Petersen 39f14a4a9a basically send media with URIs 2018-10-19 01:40:27 +02:00
11 changed files with 148 additions and 218 deletions
+2 -2
View File
@@ -255,8 +255,8 @@ android {
}
defaultConfig {
versionCode 394
versionName "0.0.4"
versionCode 395
versionName "0.0.5"
applicationId "chat.delta.androidii"
minSdkVersion 14
+15 -18
View File
@@ -36,7 +36,7 @@
android:weightSum="1"
android:orientation="horizontal">
<android.support.constraint.ConstraintLayout
<RelativeLayout
android:id="@+id/from"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -49,39 +49,36 @@
<org.thoughtcrime.securesms.components.FromTextView
android:id="@+id/from_text"
style="@style/Signal.Text.Body"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginBottom="2dp"
android:layout_toLeftOf="@id/verified_indicator"
android:layout_toStartOf="@id/verified_indicator"
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:id="@+id/verified_indicator"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingLeft="5dp"
android:paddingStart="5dp"
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" />
android:layout_marginLeft="5dp"
android:layout_marginStart="5dp"
android:layout_marginTop="4dp"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</android.support.constraint.ConstraintLayout>
</RelativeLayout>
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/subject"
+18 -19
View File
@@ -39,9 +39,9 @@
tools:src="@drawable/ic_contact_picture"
android:contentDescription="@string/conversation_list_item_view__contact_photo_image"/>
<android.support.constraint.ConstraintLayout
<RelativeLayout
android:id="@+id/content"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toEndOf="@id/contact_photo_image"
@@ -50,33 +50,32 @@
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/title"
style="@style/TextSecure.TitleTextStyle"
android:layout_width="0dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_toLeftOf="@id/verified_indicator"
android:layout_toStartOf="@id/verified_indicator"
android:drawablePadding="5dp"
android:ellipsize="end"
android:maxLines="1"
android:textSize="18dp"
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_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_verified"
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"
android:layout_marginStart="5dp" />
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginRight="5dp"
android:layout_marginEnd="5dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:src="@drawable/ic_verified"
android:visibility="gone" />
<org.thoughtcrime.securesms.components.emoji.EmojiTextView
android:id="@+id/subtitle"
@@ -87,9 +86,9 @@
android:maxLines="1"
android:textDirection="ltr"
android:textSize="13dp"
app:layout_constraintTop_toBottomOf="@id/title"
android:layout_below="@id/title"
tools:text="(123) 123-1234" />
</android.support.constraint.ConstraintLayout>
</RelativeLayout>
</org.thoughtcrime.securesms.ConversationTitleView>
+6
View File
@@ -41,8 +41,14 @@
<string name="ApplicationPreferencesActivity_sms_mms_summary">SMS %1$s, MMS %2$s</string>
<string name="ApplicationPreferencesActivity_privacy_summary">Screen lock %1$s, Read receipts %2$s</string>
<string name="ApplicationPreferencesActivity_appearance_summary">Theme %1$s, Language %2$s</string>
<string name="ApplicationPreferencesActivity_appearance_summary_new">Theme %1$s, Language %2$s, Background %3$s</string>
<string name="ApplicationPreferencesActivity_appearance_background_default">default</string>
<string name="ApplicationPreferencesActivity_appearance_background_custom">custom</string>
<!-- AppearancePreferenceFragment -->
<string name="AppearancePreferencesFragment_background_save_error">Background image could not be saved</string>
<string name="AppearancePreferencesFragment_background_custom_summary">Custom</string>
<string name="AppearancePreferencesFragment_background_default_summary">Default</string>
<!-- AppProtectionPreferenceFragment -->
<plurals name="AppProtectionPreferenceFragment_minutes">
+1 -1
View File
@@ -16,7 +16,7 @@
android:entryValues="@array/language_values"
android:defaultValue="zz"/>
<Preference
<org.thoughtcrime.securesms.preferences.widgets.SignalPreference
android:key="pref_chat_background"
android:title="@string/preferences__chat_background"
/>
@@ -25,6 +25,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.PorterDuff.Mode;
import android.graphics.drawable.Drawable;
@@ -35,6 +36,7 @@ import android.os.Bundle;
import android.os.Vibrator;
import android.provider.Browser;
import android.provider.ContactsContract;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.view.MenuItemCompat;
@@ -56,6 +58,7 @@ import android.view.View.OnFocusChangeListener;
import android.view.View.OnKeyListener;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.webkit.MimeTypeMap;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
@@ -66,12 +69,14 @@ import android.widget.Toast;
import com.b44t.messenger.DcChat;
import com.b44t.messenger.DcContext;
import com.b44t.messenger.DcEventCenter;
import com.b44t.messenger.DcMsg;
import com.google.android.gms.location.places.ui.PlacePicker;
import com.google.protobuf.ByteString;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.audio.AudioRecorder;
import org.thoughtcrime.securesms.audio.AudioSlidePlayer;
import org.thoughtcrime.securesms.components.AnimatingToggle;
@@ -120,8 +125,7 @@ import org.thoughtcrime.securesms.mms.LocationSlide;
import org.thoughtcrime.securesms.mms.MediaConstraints;
import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage;
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.mms.QuoteId;
import org.thoughtcrime.securesms.mms.QuoteModel;
import org.thoughtcrime.securesms.mms.Slide;
@@ -156,8 +160,14 @@ import org.thoughtcrime.securesms.util.views.Stub;
import org.whispersystems.libsignal.InvalidMessageException;
import org.whispersystems.libsignal.util.guava.Optional;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -1419,42 +1429,88 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
sendMediaMessage(forceSms, getMessage(), attachmentManager.buildSlideDeck(), Collections.emptyList(), expiresIn, subscriptionId, initiating);
}
private String getRealPathFromAttachment(Attachment attachment) {
try {
// get file in the blobdir as `<blobdir>/<name>[-<uniqueNumber>].<ext>`
String filename = attachment.getFileName();
String ext = "";
if(filename==null) {
filename = new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date());
ext = "."+MimeTypeMap.getSingleton().getExtensionFromMimeType(attachment.getContentType());
}
else {
int i = filename.lastIndexOf(".");
if(i>=0) {
ext = filename.substring(i);
filename = filename.substring(0, i);
}
}
String path = null;
for (int i=0; i<1000; i++) {
path = dcContext.getBlobdir()+"/"+filename+(i==0? "" : i<100? "-"+i : "-"+(new Date().getTime()+i))+ext;
if (!new File(path).exists()) {
break;
}
}
// copy content to this file
if(path!=null) {
InputStream inputStream = PartAuthority.getAttachmentStream(this, attachment.getDataUri());
OutputStream outputStream = new FileOutputStream(path);
Util.copy(inputStream, outputStream);
}
return path;
}
catch(Exception e) {
e.printStackTrace();
return null;
}
}
private ListenableFuture<Void> sendMediaMessage(final boolean forceSms, String body, SlideDeck slideDeck, List<Contact> contacts, final long expiresIn, final int subscriptionId, final boolean initiating) {
OutgoingMediaMessage outgoingMessageCandidate = new OutgoingMediaMessage(recipient, slideDeck, body, System.currentTimeMillis(), subscriptionId, expiresIn, distributionType, inputPanel.getQuote().orNull(), contacts);
final SettableFuture<Void> future = new SettableFuture<>();
final Context context = getApplicationContext();
final OutgoingMediaMessage outgoingMessage;
if (isSecureText && !forceSms) {
outgoingMessage = new OutgoingSecureMediaMessage(outgoingMessageCandidate);
} else {
outgoingMessage = outgoingMessageCandidate;
}
inputPanel.clearQuote();
attachmentManager.clear(glideRequests, false);
composeText.setText("");
final long id = fragment.stageOutgoingMessage(outgoingMessage);
new AsyncTask<Void, Void, Long>() {
@Override
protected Long doInBackground(Void... param) {
if (initiating) {
DatabaseFactory.getRecipientDatabase(context).setProfileSharing(recipient, true);
try {
DcMsg msg = null;
List<Attachment> attachments = slideDeck.asAttachments();
for (Attachment attachment : attachments) {
String contentType = attachment.getContentType();
if (MediaUtil.isImageType(contentType)) {
msg = new DcMsg(dcContext, DcMsg.DC_MSG_IMAGE);
msg.setDimension(attachment.getWidth(), attachment.getHeight());
}
else if (MediaUtil.isAudioType(contentType)) {
msg = new DcMsg(dcContext,
attachment.isVoiceNote()? DcMsg.DC_MSG_VOICE : DcMsg.DC_MSG_AUDIO);
}
else if (MediaUtil.isVideoType(contentType)) {
msg = new DcMsg(dcContext, DcMsg.DC_MSG_VIDEO);
}
else {
msg = new DcMsg(dcContext, DcMsg.DC_MSG_FILE);
}
return MessageSender.send(context, outgoingMessage, threadId, false, () -> fragment.releaseOutgoingMessage(id));
String path = getRealPathFromAttachment(attachment);
msg.setFile(path, null);
}
@Override
protected void onPostExecute(Long result) {
sendComplete(result);
future.set(null);
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
msg.setText(body);
dcContext.sendMsg(dcChat.getId(), msg);
}
catch(Exception e) {
e.printStackTrace();
}
sendComplete(dcChat.getId());
future.set(null);
return future;
}
@@ -408,13 +408,5 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
recordCache.clear();
notifyDataSetChanged();
}
public void addFastRecord(@NonNull MessageRecord record) {
// TODO: i think this is not need, we simply should reload the view
}
public void releaseFastRecord(long id) {
// TODO: i think this is not need, we simply should reload the view
}
}
@@ -557,36 +557,6 @@ public class ConversationFragment extends Fragment
}
}
public long stageOutgoingMessage(OutgoingMediaMessage message) {
MessageRecord messageRecord = DatabaseFactory.getMmsDatabase(getContext()).readerFor(message, threadId).getCurrent();
if (getListAdapter() != null) {
//getListAdapter().setHeaderView(null);
setLastSeen(0);
getListAdapter().addFastRecord(messageRecord);
}
return messageRecord.getId();
}
public long stageOutgoingMessage(OutgoingTextMessage message) {
MessageRecord messageRecord = DatabaseFactory.getSmsDatabase(getContext()).readerFor(message, threadId).getCurrent();
if (getListAdapter() != null) {
//getListAdapter().setHeaderView(null);
setLastSeen(0);
getListAdapter().addFastRecord(messageRecord);
}
return messageRecord.getId();
}
public void releaseOutgoingMessage(long id) {
if (getListAdapter() != null) {
getListAdapter().releaseFastRecord(id);
}
}
private void scrollToStartingPosition(final int startingPosition) {
list.post(() -> {
list.getLayoutManager().scrollToPosition(startingPosition);
@@ -1,112 +0,0 @@
package org.thoughtcrime.securesms.database;
import android.content.Context;
import android.database.Cursor;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public abstract class FastCursorRecyclerViewAdapter<VH extends RecyclerView.ViewHolder, T>
extends CursorRecyclerViewAdapter<VH>
{
private static final String TAG = FastCursorRecyclerViewAdapter.class.getSimpleName();
private final LinkedList<T> fastRecords = new LinkedList<>();
private final List<Long> releasedRecordIds = new LinkedList<>();
protected FastCursorRecyclerViewAdapter(Context context, Cursor cursor) {
super(context, cursor);
}
public void addFastRecord(@NonNull T record) {
fastRecords.addFirst(record);
notifyDataSetChanged();
}
public void releaseFastRecord(long id) {
synchronized (releasedRecordIds) {
releasedRecordIds.add(id);
}
}
protected void cleanFastRecords() {
synchronized (releasedRecordIds) {
Iterator<Long> releaseIdIterator = releasedRecordIds.iterator();
while (releaseIdIterator.hasNext()) {
long releasedId = releaseIdIterator.next();
Iterator<T> fastRecordIterator = fastRecords.iterator();
while (fastRecordIterator.hasNext()) {
if (isRecordForId(fastRecordIterator.next(), releasedId)) {
fastRecordIterator.remove();
releaseIdIterator.remove();
break;
}
}
}
}
}
protected abstract T getRecordFromCursor(@NonNull Cursor cursor);
protected abstract void onBindItemViewHolder(VH viewHolder, @NonNull T record);
protected abstract long getItemId(@NonNull T record);
protected abstract int getItemViewType(@NonNull T record);
protected abstract boolean isRecordForId(@NonNull T record, long id);
@Override
public int getItemViewType(@NonNull Cursor cursor) {
T record = getRecordFromCursor(cursor);
return getItemViewType(record);
}
@Override
public void onBindItemViewHolder(VH viewHolder, @NonNull Cursor cursor) {
T record = getRecordFromCursor(cursor);
onBindItemViewHolder(viewHolder, record);
}
@Override
public void onBindFastAccessItemViewHolder(VH viewHolder, int position) {
int calculatedPosition = getCalculatedPosition(position);
onBindItemViewHolder(viewHolder, fastRecords.get(calculatedPosition));
}
@Override
protected int getFastAccessSize() {
return fastRecords.size();
}
protected T getRecordForPositionOrThrow(int position) {
if (isFastAccessPosition(position)) {
return fastRecords.get(getCalculatedPosition(position));
} else {
Cursor cursor = getCursorAtPositionOrThrow(position);
return getRecordFromCursor(cursor);
}
}
protected int getFastAccessItemViewType(int position) {
return getItemViewType(fastRecords.get(getCalculatedPosition(position)));
}
protected boolean isFastAccessPosition(int position) {
position = getCalculatedPosition(position);
return position >= 0 && position < fastRecords.size();
}
protected long getFastAccessItemId(int position) {
return getItemId(fastRecords.get(getCalculatedPosition(position)));
}
private int getCalculatedPosition(int position) {
return hasHeaderView() ? position - 1 : position;
}
}
@@ -6,6 +6,7 @@ import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.util.Log;
import org.thoughtcrime.securesms.ApplicationPreferencesActivity;
import org.thoughtcrime.securesms.R;
@@ -41,6 +42,15 @@ public class AppearancePreferenceFragment extends ListSummaryPreferenceFragment
public void onResume() {
super.onResume();
((ApplicationPreferencesActivity) getActivity()).getSupportActionBar().setTitle(R.string.preferences__appearance);
String imagePath = TextSecurePreferences.getBackgroundImagePath(getContext());
String backgroundString;
if(imagePath.isEmpty()){
backgroundString = this.getString(R.string.AppearancePreferencesFragment_background_default_summary);
}
else{
backgroundString = this.getString(R.string.AppearancePreferencesFragment_background_custom_summary);
}
this.findPreference(TextSecurePreferences.BACKGROUND_PREF).setSummary(backgroundString);
}
@Override
@@ -61,9 +71,18 @@ public class AppearancePreferenceFragment extends ListSummaryPreferenceFragment
if (langIndex == -1) langIndex = 0;
if (themeIndex == -1) themeIndex = 0;
return context.getString(R.string.ApplicationPreferencesActivity_appearance_summary,
String imagePath = TextSecurePreferences.getBackgroundImagePath(context);
String backgroundString;
if(imagePath.isEmpty()){
backgroundString = context.getString(R.string.ApplicationPreferencesActivity_appearance_background_default);
}
else{
backgroundString = context.getString(R.string.ApplicationPreferencesActivity_appearance_background_custom);
}
return context.getString(R.string.ApplicationPreferencesActivity_appearance_summary_new,
themeEntries[themeIndex],
languageEntries[langIndex]);
languageEntries[langIndex], backgroundString);
}
private class BackgroundClickListener implements Preference.OnPreferenceClickListener {
@@ -86,8 +86,8 @@ public class ChatBackgroundActivity extends BaseActionBarActivity {
@Override
public void run() {
String destination = context.getFilesDir().getAbsolutePath() + "/background";
scaleAndSaveImage(context, destination);
TextSecurePreferences.setBackgroundImagePath(context, destination);
scaleAndSaveImage(context, destination);
}
};
thread.start();
@@ -123,12 +123,15 @@ public class ChatBackgroundActivity extends BaseActionBarActivity {
scaledBitmap.compress(Bitmap.CompressFormat.JPEG, 85, outStream);
} catch (InterruptedException e) {
e.printStackTrace();
TextSecurePreferences.setBackgroundImagePath(context, "");
showBackgroundSaveError();
} catch (ExecutionException e) {
e.printStackTrace();
TextSecurePreferences.setBackgroundImagePath(context, "");
showBackgroundSaveError();
} catch (FileNotFoundException e) {
e.printStackTrace();
TextSecurePreferences.setBackgroundImagePath(context, "");
showBackgroundSaveError();
}
}