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