parent
83ec4e0627
commit
759f9d8016
8 changed files with 108 additions and 42 deletions
|
@ -51,6 +51,7 @@
|
|||
<string name="DraftDatabase_Draft_image_snippet">(image)</string>
|
||||
<string name="DraftDatabase_Draft_audio_snippet">(audio)</string>
|
||||
<string name="DraftDatabase_Draft_video_snippet">(video)</string>
|
||||
<string name="DraftDatabase_Draft_location_snippet">(location)</string>
|
||||
|
||||
<!-- AttchmentManager -->
|
||||
<string name="AttachmentManager_cant_open_media_selection">Can\'t find an app to select media.</string>
|
||||
|
|
|
@ -56,7 +56,6 @@ import android.widget.LinearLayout;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.google.android.gms.location.places.Place;
|
||||
import com.google.android.gms.location.places.ui.PlacePicker;
|
||||
import com.google.protobuf.ByteString;
|
||||
|
||||
|
@ -78,6 +77,7 @@ import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer;
|
|||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer.AttachmentDrawerListener;
|
||||
import org.thoughtcrime.securesms.components.camera.QuickAttachmentDrawer.DrawerState;
|
||||
import org.thoughtcrime.securesms.components.emoji.EmojiDrawer;
|
||||
import org.thoughtcrime.securesms.components.location.SignalPlace;
|
||||
import org.thoughtcrime.securesms.components.reminder.InviteReminder;
|
||||
import org.thoughtcrime.securesms.components.reminder.ReminderView;
|
||||
import org.thoughtcrime.securesms.contacts.ContactAccessor;
|
||||
|
@ -97,6 +97,7 @@ import org.thoughtcrime.securesms.mms.AttachmentManager;
|
|||
import org.thoughtcrime.securesms.mms.AttachmentManager.MediaType;
|
||||
import org.thoughtcrime.securesms.mms.AttachmentTypeSelectorAdapter;
|
||||
import org.thoughtcrime.securesms.mms.AudioSlide;
|
||||
import org.thoughtcrime.securesms.mms.LocationSlide;
|
||||
import org.thoughtcrime.securesms.mms.MediaConstraints;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
|
||||
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
|
||||
|
@ -353,7 +354,8 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
fragment.reloadList();
|
||||
break;
|
||||
case PICK_LOCATION:
|
||||
attachmentManager.setLocation(masterSecret, PlacePicker.getPlace(data, this), getCurrentMediaConstraints());
|
||||
SignalPlace place = new SignalPlace(PlacePicker.getPlace(data, this));
|
||||
attachmentManager.setLocation(masterSecret, place, getCurrentMediaConstraints());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -748,14 +750,20 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
@Override
|
||||
protected void onPostExecute(List<Draft> drafts) {
|
||||
for (Draft draft : drafts) {
|
||||
if (draft.getType().equals(Draft.TEXT)) {
|
||||
composeText.setText(draft.getValue());
|
||||
} else if (draft.getType().equals(Draft.IMAGE)) {
|
||||
setMedia(Uri.parse(draft.getValue()), MediaType.IMAGE);
|
||||
} else if (draft.getType().equals(Draft.AUDIO)) {
|
||||
setMedia(Uri.parse(draft.getValue()), MediaType.AUDIO);
|
||||
} else if (draft.getType().equals(Draft.VIDEO)) {
|
||||
setMedia(Uri.parse(draft.getValue()), MediaType.VIDEO);
|
||||
try {
|
||||
if (draft.getType().equals(Draft.TEXT)) {
|
||||
composeText.setText(draft.getValue());
|
||||
} else if (draft.getType().equals(Draft.LOCATION)) {
|
||||
attachmentManager.setLocation(masterSecret, SignalPlace.deserialize(draft.getValue()), getCurrentMediaConstraints());
|
||||
} else if (draft.getType().equals(Draft.IMAGE)) {
|
||||
setMedia(Uri.parse(draft.getValue()), MediaType.IMAGE);
|
||||
} else if (draft.getType().equals(Draft.AUDIO)) {
|
||||
setMedia(Uri.parse(draft.getValue()), MediaType.AUDIO);
|
||||
} else if (draft.getType().equals(Draft.VIDEO)) {
|
||||
setMedia(Uri.parse(draft.getValue()), MediaType.VIDEO);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1053,9 +1061,10 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
}
|
||||
|
||||
for (Slide slide : attachmentManager.buildSlideDeck().getSlides()) {
|
||||
if (slide.hasAudio()) drafts.add(new Draft(Draft.AUDIO, slide.getUri().toString()));
|
||||
else if (slide.hasVideo()) drafts.add(new Draft(Draft.VIDEO, slide.getUri().toString()));
|
||||
else if (slide.hasImage()) drafts.add(new Draft(Draft.IMAGE, slide.getUri().toString()));
|
||||
if (slide.hasAudio()) drafts.add(new Draft(Draft.AUDIO, slide.getUri().toString()));
|
||||
else if (slide.hasVideo()) drafts.add(new Draft(Draft.VIDEO, slide.getUri().toString()));
|
||||
else if (slide.hasLocation()) drafts.add(new Draft(Draft.LOCATION, ((LocationSlide)slide).getPlace().serialize()));
|
||||
else if (slide.hasImage()) drafts.add(new Draft(Draft.IMAGE, slide.getUri().toString()));
|
||||
}
|
||||
|
||||
return drafts;
|
||||
|
|
|
@ -1,37 +1,77 @@
|
|||
package org.thoughtcrime.securesms.components.location;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.google.android.gms.location.places.Place;
|
||||
import com.google.android.gms.maps.model.LatLng;
|
||||
|
||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class SignalPlace {
|
||||
|
||||
private static final String URL = "https://maps.google.com/maps?q=%s,%s";
|
||||
private static final String TAG = SignalPlace.class.getSimpleName();
|
||||
|
||||
private final Place place;
|
||||
@JsonProperty
|
||||
private String name;
|
||||
|
||||
@JsonProperty
|
||||
private String address;
|
||||
|
||||
@JsonProperty
|
||||
private double latitude;
|
||||
|
||||
@JsonProperty
|
||||
private double longitude;
|
||||
|
||||
public SignalPlace(Place place) {
|
||||
this.place = place;
|
||||
this.name = place.getName().toString();
|
||||
this.address = place.getAddress().toString();
|
||||
this.latitude = place.getLatLng().latitude;
|
||||
this.longitude = place.getLatLng().longitude;
|
||||
}
|
||||
|
||||
public SignalPlace() {}
|
||||
|
||||
@JsonIgnore
|
||||
public LatLng getLatLong() {
|
||||
return place.getLatLng();
|
||||
return new LatLng(latitude, longitude);
|
||||
}
|
||||
|
||||
@JsonIgnore
|
||||
public String getDescription() {
|
||||
String description = "";
|
||||
|
||||
if (!TextUtils.isEmpty(place.getName())) {
|
||||
description += (place.getName() + "\n");
|
||||
if (!TextUtils.isEmpty(name)) {
|
||||
description += (name + "\n");
|
||||
}
|
||||
|
||||
if (!TextUtils.isEmpty(place.getAddress())) {
|
||||
description += (place.getAddress() + "\n");
|
||||
if (!TextUtils.isEmpty(address)) {
|
||||
description += (address + "\n");
|
||||
}
|
||||
|
||||
description += String.format(URL, place.getLatLng().latitude, place.getLatLng().longitude);
|
||||
description += String.format(URL, latitude, longitude);
|
||||
|
||||
return description;
|
||||
}
|
||||
|
||||
public @Nullable String serialize() {
|
||||
try {
|
||||
return JsonUtils.toJson(this);
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static SignalPlace deserialize(@NonNull String serialized) throws IOException {
|
||||
return JsonUtils.fromJson(serialized, SignalPlace.class);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ public class MasterCipher {
|
|||
return encryptBytes(privateKey.serialize());
|
||||
}
|
||||
|
||||
public String encryptBody(String body) {
|
||||
public String encryptBody(@NonNull String body) {
|
||||
return encryptAndEncodeBytes(body.getBytes());
|
||||
}
|
||||
|
||||
|
@ -149,7 +149,7 @@ public class MasterCipher {
|
|||
}
|
||||
}
|
||||
|
||||
private String encryptAndEncodeBytes(byte[] bytes) {
|
||||
private String encryptAndEncodeBytes(@NonNull byte[] bytes) {
|
||||
byte[] encryptedAndMacBody = encryptBytes(bytes);
|
||||
return Base64.encodeBytes(encryptedAndMacBody);
|
||||
}
|
||||
|
|
|
@ -103,10 +103,11 @@ public class DraftDatabase extends Database {
|
|||
}
|
||||
|
||||
public static class Draft {
|
||||
public static final String TEXT = "text";
|
||||
public static final String IMAGE = "image";
|
||||
public static final String VIDEO = "video";
|
||||
public static final String AUDIO = "audio";
|
||||
public static final String TEXT = "text";
|
||||
public static final String IMAGE = "image";
|
||||
public static final String VIDEO = "video";
|
||||
public static final String AUDIO = "audio";
|
||||
public static final String LOCATION = "location";
|
||||
|
||||
private final String type;
|
||||
private final String value;
|
||||
|
@ -126,11 +127,12 @@ public class DraftDatabase extends Database {
|
|||
|
||||
public String getSnippet(Context context) {
|
||||
switch (type) {
|
||||
case TEXT: return value;
|
||||
case IMAGE: return context.getString(R.string.DraftDatabase_Draft_image_snippet);
|
||||
case VIDEO: return context.getString(R.string.DraftDatabase_Draft_video_snippet);
|
||||
case AUDIO: return context.getString(R.string.DraftDatabase_Draft_audio_snippet);
|
||||
default: return null;
|
||||
case TEXT: return value;
|
||||
case IMAGE: return context.getString(R.string.DraftDatabase_Draft_image_snippet);
|
||||
case VIDEO: return context.getString(R.string.DraftDatabase_Draft_video_snippet);
|
||||
case AUDIO: return context.getString(R.string.DraftDatabase_Draft_audio_snippet);
|
||||
case LOCATION: return context.getString(R.string.DraftDatabase_Draft_location_snippet);
|
||||
default: return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -35,15 +35,14 @@ import android.widget.Toast;
|
|||
|
||||
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
|
||||
import com.google.android.gms.common.GooglePlayServicesRepairableException;
|
||||
import com.google.android.gms.location.places.Place;
|
||||
import com.google.android.gms.location.places.ui.PlacePicker;
|
||||
|
||||
import org.thoughtcrime.securesms.MediaPreviewActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.components.AudioView;
|
||||
import org.thoughtcrime.securesms.components.RemovableMediaView;
|
||||
import org.thoughtcrime.securesms.components.location.SignalMapView;
|
||||
import org.thoughtcrime.securesms.components.ThumbnailView;
|
||||
import org.thoughtcrime.securesms.components.location.SignalMapView;
|
||||
import org.thoughtcrime.securesms.components.location.SignalPlace;
|
||||
import org.thoughtcrime.securesms.crypto.MasterSecret;
|
||||
import org.thoughtcrime.securesms.providers.PersistentBlobProvider;
|
||||
|
@ -148,11 +147,10 @@ public class AttachmentManager {
|
|||
}
|
||||
|
||||
public void setLocation(@NonNull final MasterSecret masterSecret,
|
||||
@NonNull final Place place,
|
||||
@NonNull final SignalPlace place,
|
||||
@NonNull final MediaConstraints constraints)
|
||||
{
|
||||
final SignalPlace signalPlace = new SignalPlace(place);
|
||||
ListenableFuture<Bitmap> future = mapView.display(signalPlace);
|
||||
ListenableFuture<Bitmap> future = mapView.display(place);
|
||||
|
||||
attachmentView.setVisibility(View.VISIBLE);
|
||||
removableMediaView.display(mapView);
|
||||
|
@ -162,7 +160,7 @@ public class AttachmentManager {
|
|||
public void onSuccess(@NonNull Bitmap result) {
|
||||
byte[] blob = BitmapUtil.toByteArray(result);
|
||||
Uri uri = PersistentBlobProvider.getInstance(context).create(masterSecret, blob);
|
||||
LocationSlide locationSlide = new LocationSlide(context, uri, blob.length, signalPlace.getDescription());
|
||||
LocationSlide locationSlide = new LocationSlide(context, uri, blob.length, place);
|
||||
|
||||
setSlide(locationSlide);
|
||||
attachmentListener.onAttachmentChanged();
|
||||
|
|
|
@ -4,22 +4,34 @@ import android.content.Context;
|
|||
import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import org.thoughtcrime.securesms.components.location.SignalPlace;
|
||||
import org.whispersystems.libaxolotl.util.guava.Optional;
|
||||
|
||||
public class LocationSlide extends ImageSlide {
|
||||
|
||||
@NonNull
|
||||
private final String description;
|
||||
private final SignalPlace place;
|
||||
|
||||
public LocationSlide(@NonNull Context context, @NonNull Uri uri, long size, @NonNull String description)
|
||||
public LocationSlide(@NonNull Context context, @NonNull Uri uri, long size, @NonNull SignalPlace place)
|
||||
{
|
||||
super(context, uri, size);
|
||||
this.description = description;
|
||||
this.place = place;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Optional<String> getBody() {
|
||||
return Optional.of(description);
|
||||
return Optional.of(place.getDescription());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public SignalPlace getPlace() {
|
||||
return place;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLocation() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -72,6 +72,10 @@ public abstract class Slide {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean hasLocation() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public @NonNull String getContentDescription() { return ""; }
|
||||
|
||||
public Attachment asAttachment() {
|
||||
|
|
Loading…
Add table
Reference in a new issue