Compare commits
6 Commits
1473-displ
...
1242-displ
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e6e077ff40 | ||
|
|
4e5e354af2 | ||
|
|
9ea3623c85 | ||
|
|
84089f5e16 | ||
|
|
a994966095 | ||
|
|
2bea581654 |
@@ -20,6 +20,7 @@ import org.briarproject.briar.android.contact.ContactModule;
|
|||||||
import org.briarproject.briar.android.conversation.AliasDialogFragment;
|
import org.briarproject.briar.android.conversation.AliasDialogFragment;
|
||||||
import org.briarproject.briar.android.conversation.ConversationActivity;
|
import org.briarproject.briar.android.conversation.ConversationActivity;
|
||||||
import org.briarproject.briar.android.conversation.ImageActivity;
|
import org.briarproject.briar.android.conversation.ImageActivity;
|
||||||
|
import org.briarproject.briar.android.conversation.ImageFragment;
|
||||||
import org.briarproject.briar.android.forum.CreateForumActivity;
|
import org.briarproject.briar.android.forum.CreateForumActivity;
|
||||||
import org.briarproject.briar.android.forum.ForumActivity;
|
import org.briarproject.briar.android.forum.ForumActivity;
|
||||||
import org.briarproject.briar.android.forum.ForumListFragment;
|
import org.briarproject.briar.android.forum.ForumListFragment;
|
||||||
@@ -218,4 +219,6 @@ public interface ActivityComponent {
|
|||||||
|
|
||||||
void inject(AliasDialogFragment aliasDialogFragment);
|
void inject(AliasDialogFragment aliasDialogFragment);
|
||||||
|
|
||||||
|
void inject(ImageFragment imageFragment);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.briarproject.briar.android.conversation;
|
|||||||
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
import org.briarproject.bramble.api.nullsafety.NotNullByDefault;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
import org.briarproject.bramble.api.sync.MessageId;
|
||||||
@@ -111,4 +112,10 @@ public class AttachmentItem implements Parcelable {
|
|||||||
dest.writeByte((byte) (hasError ? 1 : 0));
|
dest.writeByte((byte) (hasError ? 1 : 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(@Nullable Object o) {
|
||||||
|
return o instanceof AttachmentItem &&
|
||||||
|
messageId.equals(((AttachmentItem) o).messageId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import android.content.DialogInterface;
|
|||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Parcelable;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
@@ -107,7 +108,6 @@ import static android.support.v4.app.ActivityOptionsCompat.makeSceneTransitionAn
|
|||||||
import static android.support.v4.view.ViewCompat.setTransitionName;
|
import static android.support.v4.view.ViewCompat.setTransitionName;
|
||||||
import static android.support.v7.util.SortedList.INVALID_POSITION;
|
import static android.support.v7.util.SortedList.INVALID_POSITION;
|
||||||
import static android.view.Gravity.RIGHT;
|
import static android.view.Gravity.RIGHT;
|
||||||
import static android.widget.Toast.LENGTH_LONG;
|
|
||||||
import static android.widget.Toast.LENGTH_SHORT;
|
import static android.widget.Toast.LENGTH_SHORT;
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static java.util.Collections.sort;
|
import static java.util.Collections.sort;
|
||||||
@@ -121,7 +121,8 @@ import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
|||||||
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_IMAGE_ATTACHMENTS;
|
import static org.briarproject.briar.android.TestingConstants.FEATURE_FLAG_IMAGE_ATTACHMENTS;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_ATTACH_IMAGE;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_ATTACH_IMAGE;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_INTRODUCTION;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_INTRODUCTION;
|
||||||
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENT;
|
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENTS;
|
||||||
|
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENT_POSITION;
|
||||||
import static org.briarproject.briar.android.conversation.ImageActivity.DATE;
|
import static org.briarproject.briar.android.conversation.ImageActivity.DATE;
|
||||||
import static org.briarproject.briar.android.conversation.ImageActivity.NAME;
|
import static org.briarproject.briar.android.conversation.ImageActivity.NAME;
|
||||||
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
|
import static org.briarproject.briar.android.settings.SettingsFragment.SETTINGS_NAMESPACE;
|
||||||
@@ -193,6 +194,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
ViewModelProvider.Factory viewModelFactory;
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
private volatile ContactId contactId;
|
private volatile ContactId contactId;
|
||||||
|
@Nullable
|
||||||
|
private Parcelable layoutManagerState;
|
||||||
|
|
||||||
private final Observer<String> contactNameObserver = name -> {
|
private final Observer<String> contactNameObserver = name -> {
|
||||||
requireNonNull(name);
|
requireNonNull(name);
|
||||||
@@ -308,6 +311,21 @@ public class ConversationActivity extends BriarActivity
|
|||||||
list.stopPeriodicUpdate();
|
list.stopPeriodicUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onSaveInstanceState(Bundle outState) {
|
||||||
|
super.onSaveInstanceState(outState);
|
||||||
|
if (layoutManager != null) {
|
||||||
|
layoutManagerState = layoutManager.onSaveInstanceState();
|
||||||
|
outState.putParcelable("layoutManager", layoutManagerState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestoreInstanceState(Bundle savedInstanceState) {
|
||||||
|
super.onRestoreInstanceState(savedInstanceState);
|
||||||
|
layoutManagerState = savedInstanceState.getParcelable("layoutManager");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
// Inflate the menu items for use in the action bar
|
// Inflate the menu items for use in the action bar
|
||||||
@@ -427,8 +445,12 @@ public class ConversationActivity extends BriarActivity
|
|||||||
List<ConversationItem> items = createItems(headers);
|
List<ConversationItem> items = createItems(headers);
|
||||||
adapter.addAll(items);
|
adapter.addAll(items);
|
||||||
list.showData();
|
list.showData();
|
||||||
// Scroll to the bottom
|
if (layoutManagerState == null) {
|
||||||
list.scrollToPosition(adapter.getItemCount() - 1);
|
// Scroll to the bottom
|
||||||
|
list.scrollToPosition(adapter.getItemCount() - 1);
|
||||||
|
} else {
|
||||||
|
layoutManager.onRestoreInstanceState(layoutManagerState);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG.info("Concurrent update, reloading");
|
LOG.info("Concurrent update, reloading");
|
||||||
loadMessages();
|
loadMessages();
|
||||||
@@ -470,7 +492,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
adapter.getMessageItem(m);
|
adapter.getMessageItem(m);
|
||||||
if (pair != null) {
|
if (pair != null) {
|
||||||
pair.getSecond().setText(text);
|
pair.getSecond().setText(text);
|
||||||
boolean bottom = adapter.isScrolledToBottom(layoutManager);
|
boolean bottom = layoutManagerState == null &&
|
||||||
|
adapter.isScrolledToBottom(layoutManager);
|
||||||
adapter.notifyItemChanged(pair.getFirst());
|
adapter.notifyItemChanged(pair.getFirst());
|
||||||
if (bottom) list.scrollToPosition(adapter.getItemCount() - 1);
|
if (bottom) list.scrollToPosition(adapter.getItemCount() - 1);
|
||||||
}
|
}
|
||||||
@@ -501,7 +524,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
adapter.getMessageItem(m);
|
adapter.getMessageItem(m);
|
||||||
if (pair != null) {
|
if (pair != null) {
|
||||||
pair.getSecond().setAttachments(items);
|
pair.getSecond().setAttachments(items);
|
||||||
boolean bottom = adapter.isScrolledToBottom(layoutManager);
|
boolean bottom = layoutManagerState == null &&
|
||||||
|
adapter.isScrolledToBottom(layoutManager);
|
||||||
adapter.notifyItemChanged(pair.getFirst());
|
adapter.notifyItemChanged(pair.getFirst());
|
||||||
if (bottom) list.scrollToPosition(adapter.getItemCount() - 1);
|
if (bottom) list.scrollToPosition(adapter.getItemCount() - 1);
|
||||||
}
|
}
|
||||||
@@ -552,7 +576,8 @@ public class ConversationActivity extends BriarActivity
|
|||||||
|
|
||||||
private void addConversationItem(ConversationItem item) {
|
private void addConversationItem(ConversationItem item) {
|
||||||
runOnUiThreadUnlessDestroyed(() -> {
|
runOnUiThreadUnlessDestroyed(() -> {
|
||||||
boolean bottom = adapter.isScrolledToBottom(layoutManager);
|
boolean bottom = layoutManagerState == null &&
|
||||||
|
adapter.isScrolledToBottom(layoutManager);
|
||||||
adapter.incrementRevision();
|
adapter.incrementRevision();
|
||||||
adapter.add(item);
|
adapter.add(item);
|
||||||
if (bottom) list.scrollToPosition(adapter.getItemCount() - 1);
|
if (bottom) list.scrollToPosition(adapter.getItemCount() - 1);
|
||||||
@@ -812,19 +837,18 @@ public class ConversationActivity extends BriarActivity
|
|||||||
} else {
|
} else {
|
||||||
name = getString(R.string.you);
|
name = getString(R.string.you);
|
||||||
}
|
}
|
||||||
|
ArrayList<AttachmentItem> attachments =
|
||||||
|
new ArrayList<>(messageItem.getAttachments());
|
||||||
Intent i = new Intent(this, ImageActivity.class);
|
Intent i = new Intent(this, ImageActivity.class);
|
||||||
i.putExtra(ATTACHMENT, item);
|
i.putParcelableArrayListExtra(ATTACHMENTS, attachments);
|
||||||
|
i.putExtra(ATTACHMENT_POSITION, attachments.indexOf(item));
|
||||||
i.putExtra(NAME, name);
|
i.putExtra(NAME, name);
|
||||||
i.putExtra(DATE, messageItem.getTime());
|
i.putExtra(DATE, messageItem.getTime());
|
||||||
if (SDK_INT >= 23) {
|
// restoring list position should not trigger android bug #224270
|
||||||
String transitionName = item.getTransitionName();
|
String transitionName = item.getTransitionName();
|
||||||
ActivityOptionsCompat options =
|
ActivityOptionsCompat options =
|
||||||
makeSceneTransitionAnimation(this, view, transitionName);
|
makeSceneTransitionAnimation(this, view, transitionName);
|
||||||
ActivityCompat.startActivity(this, i, options.toBundle());
|
ActivityCompat.startActivity(this, i, options.toBundle());
|
||||||
} else {
|
|
||||||
// work-around for android bug #224270
|
|
||||||
startActivity(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DatabaseExecutor
|
@DatabaseExecutor
|
||||||
|
|||||||
@@ -4,15 +4,18 @@ import android.arch.lifecycle.ViewModelProvider;
|
|||||||
import android.arch.lifecycle.ViewModelProviders;
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
import android.content.DialogInterface.OnClickListener;
|
import android.content.DialogInterface.OnClickListener;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.drawable.Animatable;
|
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.RequiresApi;
|
import android.support.annotation.RequiresApi;
|
||||||
import android.support.design.widget.AppBarLayout;
|
import android.support.design.widget.AppBarLayout;
|
||||||
import android.support.design.widget.Snackbar;
|
import android.support.design.widget.Snackbar;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.support.v4.app.FragmentManager;
|
||||||
|
import android.support.v4.app.FragmentStatePagerAdapter;
|
||||||
import android.support.v4.content.ContextCompat;
|
import android.support.v4.content.ContextCompat;
|
||||||
import android.support.v4.graphics.drawable.DrawableCompat;
|
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||||
|
import android.support.v4.view.ViewPager;
|
||||||
import android.support.v7.app.AlertDialog.Builder;
|
import android.support.v7.app.AlertDialog.Builder;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.transition.Fade;
|
import android.transition.Fade;
|
||||||
@@ -20,23 +23,18 @@ import android.transition.Transition;
|
|||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||||
import android.view.Window;
|
import android.view.Window;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import com.bumptech.glide.load.DataSource;
|
|
||||||
import com.bumptech.glide.load.engine.GlideException;
|
|
||||||
import com.bumptech.glide.request.RequestListener;
|
|
||||||
import com.bumptech.glide.request.target.Target;
|
|
||||||
import com.github.chrisbanes.photoview.PhotoView;
|
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
import org.briarproject.briar.android.conversation.glide.GlideApp;
|
|
||||||
import org.briarproject.briar.android.view.PullDownLayout;
|
import org.briarproject.briar.android.view.PullDownLayout;
|
||||||
|
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -53,16 +51,15 @@ import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
|
|||||||
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_STABLE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
|
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
|
||||||
import static android.widget.ImageView.ScaleType.FIT_START;
|
|
||||||
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
|
||||||
import static java.util.Objects.requireNonNull;
|
import static java.util.Objects.requireNonNull;
|
||||||
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_SAVE_ATTACHMENT;
|
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_SAVE_ATTACHMENT;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.formatDateAbsolute;
|
import static org.briarproject.briar.android.util.UiUtils.formatDateAbsolute;
|
||||||
|
|
||||||
public class ImageActivity extends BriarActivity
|
public class ImageActivity extends BriarActivity
|
||||||
implements PullDownLayout.Callback {
|
implements PullDownLayout.Callback, OnGlobalLayoutListener {
|
||||||
|
|
||||||
final static String ATTACHMENT = "attachment";
|
final static String ATTACHMENTS = "attachments";
|
||||||
|
final static String ATTACHMENT_POSITION = "position";
|
||||||
final static String NAME = "name";
|
final static String NAME = "name";
|
||||||
final static String DATE = "date";
|
final static String DATE = "date";
|
||||||
|
|
||||||
@@ -72,8 +69,8 @@ public class ImageActivity extends BriarActivity
|
|||||||
private ImageViewModel viewModel;
|
private ImageViewModel viewModel;
|
||||||
private PullDownLayout layout;
|
private PullDownLayout layout;
|
||||||
private AppBarLayout appBarLayout;
|
private AppBarLayout appBarLayout;
|
||||||
private PhotoView photoView;
|
private ViewPager viewPager;
|
||||||
private AttachmentItem attachment;
|
private List<AttachmentItem> attachments;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectActivity(ActivityComponent component) {
|
public void injectActivity(ActivityComponent component) {
|
||||||
@@ -85,7 +82,7 @@ public class ImageActivity extends BriarActivity
|
|||||||
super.onCreate(state);
|
super.onCreate(state);
|
||||||
|
|
||||||
// Transitions
|
// Transitions
|
||||||
supportPostponeEnterTransition();
|
if (state == null) supportPostponeEnterTransition();
|
||||||
Window window = getWindow();
|
Window window = getWindow();
|
||||||
if (SDK_INT >= 21) {
|
if (SDK_INT >= 21) {
|
||||||
Transition transition = new Fade();
|
Transition transition = new Fade();
|
||||||
@@ -102,6 +99,7 @@ public class ImageActivity extends BriarActivity
|
|||||||
layout = findViewById(R.id.layout);
|
layout = findViewById(R.id.layout);
|
||||||
layout.getBackground().setAlpha(255);
|
layout.getBackground().setAlpha(255);
|
||||||
layout.setCallback(this);
|
layout.setCallback(this);
|
||||||
|
layout.getViewTreeObserver().addOnGlobalLayoutListener(this);
|
||||||
|
|
||||||
// Status Bar
|
// Status Bar
|
||||||
if (SDK_INT >= 21) {
|
if (SDK_INT >= 21) {
|
||||||
@@ -118,59 +116,29 @@ public class ImageActivity extends BriarActivity
|
|||||||
TextView dateView = toolbar.findViewById(R.id.dateView);
|
TextView dateView = toolbar.findViewById(R.id.dateView);
|
||||||
|
|
||||||
// Intent Extras
|
// Intent Extras
|
||||||
attachment = getIntent().getParcelableExtra(ATTACHMENT);
|
Intent i = getIntent();
|
||||||
String name = getIntent().getStringExtra(NAME);
|
attachments = i.getParcelableArrayListExtra(ATTACHMENTS);
|
||||||
long time = getIntent().getLongExtra(DATE, 0);
|
int position = i.getIntExtra(ATTACHMENT_POSITION, -1);
|
||||||
|
if (position == -1) throw new IllegalStateException();
|
||||||
|
String name = i.getStringExtra(NAME);
|
||||||
|
long time = i.getLongExtra(DATE, 0);
|
||||||
String date = formatDateAbsolute(this, time);
|
String date = formatDateAbsolute(this, time);
|
||||||
contactName.setText(name);
|
contactName.setText(name);
|
||||||
dateView.setText(date);
|
dateView.setText(date);
|
||||||
|
|
||||||
// Image View
|
// Set up image ViewPager
|
||||||
photoView = findViewById(R.id.photoView);
|
viewPager = findViewById(R.id.viewPager);
|
||||||
|
ImagePagerAdapter pagerAdapter =
|
||||||
|
new ImagePagerAdapter(getSupportFragmentManager());
|
||||||
|
viewPager.setAdapter(pagerAdapter);
|
||||||
|
viewPager.setCurrentItem(position);
|
||||||
|
|
||||||
if (SDK_INT >= 16) {
|
if (SDK_INT >= 16) {
|
||||||
photoView.setOnClickListener(view -> toggleSystemUi());
|
viewModel.getOnImageClicked().observe(this, this::onImageClicked);
|
||||||
window.getDecorView().setSystemUiVisibility(
|
window.getDecorView().setSystemUiVisibility(
|
||||||
SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
SYSTEM_UI_FLAG_LAYOUT_STABLE |
|
||||||
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request Listener
|
|
||||||
RequestListener<Drawable> listener = new RequestListener<Drawable>() {
|
|
||||||
@Override
|
|
||||||
public boolean onLoadFailed(@Nullable GlideException e,
|
|
||||||
Object model, Target<Drawable> target,
|
|
||||||
boolean isFirstResource) {
|
|
||||||
supportStartPostponedEnterTransition();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onResourceReady(Drawable resource, Object model,
|
|
||||||
Target<Drawable> target, DataSource dataSource,
|
|
||||||
boolean isFirstResource) {
|
|
||||||
if (SDK_INT >= 21 && !(resource instanceof Animatable)) {
|
|
||||||
// set transition name only when not animatable,
|
|
||||||
// because the animation won't start otherwise
|
|
||||||
photoView.setTransitionName(
|
|
||||||
attachment.getTransitionName());
|
|
||||||
}
|
|
||||||
// Move image to the top if overlapping toolbar
|
|
||||||
if (isOverlappingToolbar(resource)) {
|
|
||||||
photoView.setScaleType(FIT_START);
|
|
||||||
}
|
|
||||||
supportStartPostponedEnterTransition();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Load Image
|
|
||||||
GlideApp.with(this)
|
|
||||||
.load(attachment)
|
|
||||||
.diskCacheStrategy(NONE)
|
|
||||||
.error(R.drawable.ic_image_broken)
|
|
||||||
.dontTransform()
|
|
||||||
.addListener(listener)
|
|
||||||
.into(photoView);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -193,11 +161,23 @@ public class ImageActivity extends BriarActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onGlobalLayout() {
|
||||||
|
viewModel.setToolbarPosition(
|
||||||
|
appBarLayout.getTop(), appBarLayout.getBottom()
|
||||||
|
);
|
||||||
|
if (SDK_INT >= 16) {
|
||||||
|
layout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
|
||||||
|
} else {
|
||||||
|
layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int request, int result, Intent data) {
|
protected void onActivityResult(int request, int result, Intent data) {
|
||||||
super.onActivityResult(request, result, data);
|
super.onActivityResult(request, result, data);
|
||||||
if (request == REQUEST_SAVE_ATTACHMENT && result == RESULT_OK) {
|
if (request == REQUEST_SAVE_ATTACHMENT && result == RESULT_OK) {
|
||||||
viewModel.saveImage(attachment, data.getData());
|
viewModel.saveImage(getVisibleAttachment(), data.getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,6 +205,14 @@ public class ImageActivity extends BriarActivity
|
|||||||
supportFinishAfterTransition();
|
supportFinishAfterTransition();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(api = 16)
|
||||||
|
private void onImageClicked(@Nullable Boolean clicked) {
|
||||||
|
if (clicked != null && clicked) {
|
||||||
|
toggleSystemUi();
|
||||||
|
viewModel.onOnImageClickSeen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(api = 16)
|
@RequiresApi(api = 16)
|
||||||
private void toggleSystemUi() {
|
private void toggleSystemUi() {
|
||||||
View decorView = getWindow().getDecorView();
|
View decorView = getWindow().getDecorView();
|
||||||
@@ -259,29 +247,13 @@ public class ImageActivity extends BriarActivity
|
|||||||
.start();
|
.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isOverlappingToolbar(Drawable drawable) {
|
|
||||||
int width = drawable.getIntrinsicWidth();
|
|
||||||
int height = drawable.getIntrinsicHeight();
|
|
||||||
float widthPercentage = photoView.getWidth() / (float) width;
|
|
||||||
float heightPercentage = photoView.getHeight() / (float) height;
|
|
||||||
float scaleFactor = Math.min(widthPercentage, heightPercentage);
|
|
||||||
int realWidth = (int) (width * scaleFactor);
|
|
||||||
int realHeight = (int) (height * scaleFactor);
|
|
||||||
// return if photo doesn't use the full width,
|
|
||||||
// because it will be moved to the right otherwise
|
|
||||||
if (realWidth < photoView.getWidth()) return false;
|
|
||||||
int drawableTop = (photoView.getHeight() - realHeight) / 2;
|
|
||||||
return drawableTop < appBarLayout.getBottom() &&
|
|
||||||
drawableTop != appBarLayout.getTop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showSaveImageDialog() {
|
private void showSaveImageDialog() {
|
||||||
OnClickListener okListener = (dialog, which) -> {
|
OnClickListener okListener = (dialog, which) -> {
|
||||||
if (SDK_INT >= 19) {
|
if (SDK_INT >= 19) {
|
||||||
Intent intent = getCreationIntent();
|
Intent intent = getCreationIntent();
|
||||||
startActivityForResult(intent, REQUEST_SAVE_ATTACHMENT);
|
startActivityForResult(intent, REQUEST_SAVE_ATTACHMENT);
|
||||||
} else {
|
} else {
|
||||||
viewModel.saveImage(attachment);
|
viewModel.saveImage(getVisibleAttachment());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Builder builder = new Builder(this, R.style.BriarDialogTheme);
|
Builder builder = new Builder(this, R.style.BriarDialogTheme);
|
||||||
@@ -303,7 +275,7 @@ public class ImageActivity extends BriarActivity
|
|||||||
String fileName = sdf.format(new Date());
|
String fileName = sdf.format(new Date());
|
||||||
Intent intent = new Intent(ACTION_CREATE_DOCUMENT);
|
Intent intent = new Intent(ACTION_CREATE_DOCUMENT);
|
||||||
intent.addCategory(CATEGORY_OPENABLE);
|
intent.addCategory(CATEGORY_OPENABLE);
|
||||||
intent.setType(attachment.getMimeType());
|
intent.setType(getVisibleAttachment().getMimeType());
|
||||||
intent.putExtra(EXTRA_TITLE, fileName);
|
intent.putExtra(EXTRA_TITLE, fileName);
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
@@ -320,4 +292,31 @@ public class ImageActivity extends BriarActivity
|
|||||||
viewModel.onSaveStateSeen();
|
viewModel.onSaveStateSeen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AttachmentItem getVisibleAttachment() {
|
||||||
|
return attachments.get(viewPager.getCurrentItem());
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ImagePagerAdapter extends FragmentStatePagerAdapter {
|
||||||
|
|
||||||
|
private boolean isFirst = true;
|
||||||
|
|
||||||
|
private ImagePagerAdapter(FragmentManager fm) {
|
||||||
|
super(fm);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Fragment getItem(int position) {
|
||||||
|
Fragment f = ImageFragment
|
||||||
|
.newInstance(attachments.get(position), isFirst);
|
||||||
|
isFirst = false;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCount() {
|
||||||
|
return attachments.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,131 @@
|
|||||||
|
package org.briarproject.briar.android.conversation;
|
||||||
|
|
||||||
|
import android.arch.lifecycle.ViewModelProvider;
|
||||||
|
import android.arch.lifecycle.ViewModelProviders;
|
||||||
|
import android.graphics.drawable.Animatable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
import android.support.v4.app.Fragment;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import com.bumptech.glide.load.DataSource;
|
||||||
|
import com.bumptech.glide.load.engine.GlideException;
|
||||||
|
import com.bumptech.glide.request.RequestListener;
|
||||||
|
import com.bumptech.glide.request.target.Target;
|
||||||
|
import com.github.chrisbanes.photoview.PhotoView;
|
||||||
|
|
||||||
|
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
|
||||||
|
import org.briarproject.briar.R;
|
||||||
|
import org.briarproject.briar.android.activity.BaseActivity;
|
||||||
|
import org.briarproject.briar.android.conversation.glide.GlideApp;
|
||||||
|
|
||||||
|
import javax.annotation.ParametersAreNonnullByDefault;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
|
import static android.widget.ImageView.ScaleType.FIT_START;
|
||||||
|
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
||||||
|
import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
|
||||||
|
import static org.briarproject.briar.android.conversation.ImageActivity.ATTACHMENT_POSITION;
|
||||||
|
|
||||||
|
@MethodsNotNullByDefault
|
||||||
|
@ParametersAreNonnullByDefault
|
||||||
|
public class ImageFragment extends Fragment {
|
||||||
|
|
||||||
|
private final static String IS_FIRST = "isFirst";
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ViewModelProvider.Factory viewModelFactory;
|
||||||
|
|
||||||
|
private AttachmentItem attachment;
|
||||||
|
private boolean isFirst;
|
||||||
|
private ImageViewModel viewModel;
|
||||||
|
private PhotoView photoView;
|
||||||
|
|
||||||
|
static ImageFragment newInstance(AttachmentItem a, boolean isFirst) {
|
||||||
|
ImageFragment f = new ImageFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putParcelable(ATTACHMENT_POSITION, a);
|
||||||
|
args.putBoolean(IS_FIRST, isFirst);
|
||||||
|
f.setArguments(args);
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onActivityCreated(savedInstanceState);
|
||||||
|
BaseActivity a = (BaseActivity) requireNonNull(getActivity());
|
||||||
|
a.getActivityComponent().inject(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
Bundle args = requireNonNull(getArguments());
|
||||||
|
attachment = requireNonNull(args.getParcelable(ATTACHMENT_POSITION));
|
||||||
|
isFirst = args.getBoolean(IS_FIRST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
@Override
|
||||||
|
public View onCreateView(LayoutInflater inflater,
|
||||||
|
@Nullable ViewGroup container,
|
||||||
|
@Nullable Bundle savedInstanceState) {
|
||||||
|
View v = inflater.inflate(R.layout.fragment_image, container,
|
||||||
|
false);
|
||||||
|
|
||||||
|
viewModel = ViewModelProviders.of(requireNonNull(getActivity()),
|
||||||
|
viewModelFactory).get(ImageViewModel.class);
|
||||||
|
|
||||||
|
photoView = v.findViewById(R.id.photoView);
|
||||||
|
photoView.setOnClickListener(view -> viewModel.clickImage());
|
||||||
|
|
||||||
|
// Request Listener
|
||||||
|
RequestListener<Drawable> listener = new RequestListener<Drawable>() {
|
||||||
|
@Override
|
||||||
|
public boolean onLoadFailed(@Nullable GlideException e,
|
||||||
|
Object model, Target<Drawable> target,
|
||||||
|
boolean isFirstResource) {
|
||||||
|
if (getActivity() != null && isFirst)
|
||||||
|
getActivity().supportStartPostponedEnterTransition();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onResourceReady(Drawable resource, Object model,
|
||||||
|
Target<Drawable> target, DataSource dataSource,
|
||||||
|
boolean isFirstResource) {
|
||||||
|
if (SDK_INT >= 21 && !(resource instanceof Animatable)) {
|
||||||
|
// set transition name only when not animatable,
|
||||||
|
// because the animation won't start otherwise
|
||||||
|
photoView.setTransitionName(
|
||||||
|
attachment.getTransitionName());
|
||||||
|
}
|
||||||
|
// Move image to the top if overlapping toolbar
|
||||||
|
if (viewModel.isOverlappingToolbar(photoView, resource)) {
|
||||||
|
photoView.setScaleType(FIT_START);
|
||||||
|
}
|
||||||
|
if (getActivity() != null && isFirst) {
|
||||||
|
getActivity().supportStartPostponedEnterTransition();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Load Image
|
||||||
|
GlideApp.with(this)
|
||||||
|
.load(attachment)
|
||||||
|
.diskCacheStrategy(NONE)
|
||||||
|
.error(R.drawable.ic_image_broken)
|
||||||
|
.dontTransform()
|
||||||
|
.addListener(listener)
|
||||||
|
.into(photoView);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ import org.briarproject.briar.android.conversation.glide.BriarImageTransformatio
|
|||||||
import org.briarproject.briar.android.conversation.glide.GlideApp;
|
import org.briarproject.briar.android.conversation.glide.GlideApp;
|
||||||
import org.briarproject.briar.android.conversation.glide.Radii;
|
import org.briarproject.briar.android.conversation.glide.Radii;
|
||||||
|
|
||||||
|
import static android.os.Build.VERSION.SDK_INT;
|
||||||
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
import static com.bumptech.glide.load.engine.DiskCacheStrategy.NONE;
|
||||||
import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
|
import static com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions.withCrossFade;
|
||||||
|
|
||||||
@@ -42,6 +43,9 @@ class ImageViewHolder extends ViewHolder {
|
|||||||
} else {
|
} else {
|
||||||
setImageViewDimensions(attachment, single, needsStretch);
|
setImageViewDimensions(attachment, single, needsStretch);
|
||||||
loadImage(attachment, r);
|
loadImage(attachment, r);
|
||||||
|
if (SDK_INT >= 21) {
|
||||||
|
imageView.setTransitionName(attachment.getTransitionName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,9 +4,11 @@ import android.app.Application;
|
|||||||
import android.arch.lifecycle.AndroidViewModel;
|
import android.arch.lifecycle.AndroidViewModel;
|
||||||
import android.arch.lifecycle.LiveData;
|
import android.arch.lifecycle.LiveData;
|
||||||
import android.arch.lifecycle.MutableLiveData;
|
import android.arch.lifecycle.MutableLiveData;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.annotation.UiThread;
|
import android.support.annotation.UiThread;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
@@ -48,7 +50,10 @@ public class ImageViewModel extends AndroidViewModel {
|
|||||||
@IoExecutor
|
@IoExecutor
|
||||||
private final Executor ioExecutor;
|
private final Executor ioExecutor;
|
||||||
|
|
||||||
|
private final MutableLiveData<Boolean> imageClicked =
|
||||||
|
new MutableLiveData<>();
|
||||||
private final MutableLiveData<Boolean> saveState = new MutableLiveData<>();
|
private final MutableLiveData<Boolean> saveState = new MutableLiveData<>();
|
||||||
|
private int toolbarTop, toolbarBottom;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ImageViewModel(Application application,
|
ImageViewModel(Application application,
|
||||||
@@ -61,6 +66,45 @@ public class ImageViewModel extends AndroidViewModel {
|
|||||||
this.ioExecutor = ioExecutor;
|
this.ioExecutor = ioExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void clickImage() {
|
||||||
|
imageClicked.setValue(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A LiveData that is true if the image was clicked,
|
||||||
|
* false if it wasn't.
|
||||||
|
*
|
||||||
|
* Call {@link #onOnImageClickSeen()} after consuming an update.
|
||||||
|
*/
|
||||||
|
LiveData<Boolean> getOnImageClicked() {
|
||||||
|
return imageClicked;
|
||||||
|
}
|
||||||
|
|
||||||
|
@UiThread
|
||||||
|
void onOnImageClickSeen() {
|
||||||
|
imageClicked.setValue(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setToolbarPosition(int top, int bottom) {
|
||||||
|
toolbarTop = top;
|
||||||
|
toolbarBottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isOverlappingToolbar(View screenView, Drawable drawable) {
|
||||||
|
int width = drawable.getIntrinsicWidth();
|
||||||
|
int height = drawable.getIntrinsicHeight();
|
||||||
|
float widthPercentage = screenView.getWidth() / (float) width;
|
||||||
|
float heightPercentage = screenView.getHeight() / (float) height;
|
||||||
|
float scaleFactor = Math.min(widthPercentage, heightPercentage);
|
||||||
|
int realWidth = (int) (width * scaleFactor);
|
||||||
|
int realHeight = (int) (height * scaleFactor);
|
||||||
|
// return if image doesn't use the full width,
|
||||||
|
// because it will be moved to the right otherwise
|
||||||
|
if (realWidth < screenView.getWidth()) return false;
|
||||||
|
int drawableTop = (screenView.getHeight() - realHeight) / 2;
|
||||||
|
return drawableTop < toolbarBottom && drawableTop != toolbarTop;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A LiveData that is true if the image was saved,
|
* A LiveData that is true if the image was saved,
|
||||||
* false if there was an error and null otherwise.
|
* false if there was an error and null otherwise.
|
||||||
|
|||||||
@@ -49,7 +49,8 @@
|
|||||||
android:id="@+id/conversationView"
|
android:id="@+id/conversationView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="2"/>
|
android:layout_weight="2"
|
||||||
|
app:scrollToEnd="false"/>
|
||||||
|
|
||||||
<org.briarproject.briar.android.view.ImagePreview
|
<org.briarproject.briar.android.view.ImagePreview
|
||||||
android:id="@+id/imagePreview"
|
android:id="@+id/imagePreview"
|
||||||
|
|||||||
@@ -8,12 +8,11 @@
|
|||||||
android:background="@color/briar_black"
|
android:background="@color/briar_black"
|
||||||
tools:context=".android.conversation.ImageActivity">
|
tools:context=".android.conversation.ImageActivity">
|
||||||
|
|
||||||
<com.github.chrisbanes.photoview.PhotoView
|
<android.support.v4.view.ViewPager
|
||||||
android:id="@+id/photoView"
|
android:id="@+id/viewPager"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:ignore="ContentDescription"
|
tools:background="@color/briar_green_light"/>
|
||||||
tools:srcCompat="@tools:sample/backgrounds/scenic"/>
|
|
||||||
|
|
||||||
<android.support.design.widget.AppBarLayout
|
<android.support.design.widget.AppBarLayout
|
||||||
android:id="@+id/appBarLayout"
|
android:id="@+id/appBarLayout"
|
||||||
|
|||||||
9
briar-android/src/main/res/layout/fragment_image.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<com.github.chrisbanes.photoview.PhotoView
|
||||||
|
android:id="@+id/photoView"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
tools:ignore="ContentDescription"
|
||||||
|
tools:srcCompat="@tools:sample/backgrounds/scenic"/>
|
||||||
@@ -32,11 +32,11 @@ import org.briarproject.briar.api.messaging.PrivateMessageHeader;
|
|||||||
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
import org.briarproject.briar.api.messaging.event.PrivateMessageReceivedEvent;
|
||||||
import org.briarproject.briar.client.ConversationClientImpl;
|
import org.briarproject.briar.client.ConversationClientImpl;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ import javax.annotation.concurrent.Immutable;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import static java.util.Collections.emptyList;
|
import static java.util.Collections.emptyList;
|
||||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
import static org.briarproject.briar.client.MessageTrackerConstants.MSG_KEY_READ;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -219,8 +219,18 @@ class MessagingManagerImpl extends ConversationClientImpl
|
|||||||
long timestamp = meta.getLong("timestamp");
|
long timestamp = meta.getLong("timestamp");
|
||||||
boolean local = meta.getBoolean("local");
|
boolean local = meta.getBoolean("local");
|
||||||
boolean read = meta.getBoolean("read");
|
boolean read = meta.getBoolean("read");
|
||||||
|
// TODO replace fake attachments by real ones
|
||||||
|
int num = (int) (timestamp % 5);
|
||||||
|
boolean hasText = num == 0 || id.hashCode() % 2 == 0;
|
||||||
|
List<AttachmentHeader> attachments = new ArrayList<>(num);
|
||||||
|
for (int i = 0; i < num; i++) {
|
||||||
|
byte[] aIdBytes = id.getBytes().clone();
|
||||||
|
aIdBytes[0] = (byte) i;
|
||||||
|
MessageId aId = new MessageId(aIdBytes);
|
||||||
|
attachments.add(new AttachmentHeader(aId, "image/jpeg"));
|
||||||
|
}
|
||||||
headers.add(new PrivateMessageHeader(id, g, timestamp, local,
|
headers.add(new PrivateMessageHeader(id, g, timestamp, local,
|
||||||
read, s.isSent(), s.isSeen(), true, emptyList()));
|
read, s.isSent(), s.isSeen(), hasText, attachments));
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -241,11 +251,30 @@ class MessagingManagerImpl extends ConversationClientImpl
|
|||||||
@Override
|
@Override
|
||||||
public Attachment getAttachment(MessageId m) {
|
public Attachment getAttachment(MessageId m) {
|
||||||
// TODO add real implementation
|
// TODO add real implementation
|
||||||
byte[] bytes = fromHexString("89504E470D0A1A0A0000000D49484452" +
|
String[] files = new String[] {
|
||||||
"000000010000000108060000001F15C4" +
|
// "error_animated.gif",
|
||||||
"890000000A49444154789C6300010000" +
|
// "error_high.jpg",
|
||||||
"0500010D0A2DB40000000049454E44AE426082");
|
// "error_wide.jpg",
|
||||||
return new Attachment(new ByteArrayInputStream(bytes));
|
// "error_huge.gif",
|
||||||
|
// "error_large.gif",
|
||||||
|
// "error_malformed.jpg",
|
||||||
|
// "wide.jpg",
|
||||||
|
// "high.jpg",
|
||||||
|
// "small.png",
|
||||||
|
"kitten1.jpg",
|
||||||
|
"kitten2.jpg",
|
||||||
|
"kitten3.gif",
|
||||||
|
"kitten4.jpg",
|
||||||
|
"kitten5.jpg",
|
||||||
|
"kitten6.png",
|
||||||
|
};
|
||||||
|
int index = Math.abs(m.hashCode() % files.length);
|
||||||
|
String file = files[index];
|
||||||
|
getLogger(MessagingManagerImpl.class.getName())
|
||||||
|
.warning("Loading file: " + file);
|
||||||
|
|
||||||
|
InputStream is = getClass().getClassLoader().getResourceAsStream(file);
|
||||||
|
return new Attachment(is);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
briar-core/src/main/resources/error_animated.gif
Normal file
|
After Width: | Height: | Size: 43 B |
BIN
briar-core/src/main/resources/error_high.jpg
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
briar-core/src/main/resources/error_huge.gif
Normal file
|
After Width: | Height: | Size: 43 B |
BIN
briar-core/src/main/resources/error_large.gif
Normal file
|
After Width: | Height: | Size: 43 B |
0
briar-core/src/main/resources/error_malformed.jpg
Normal file
BIN
briar-core/src/main/resources/error_wide.jpg
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
briar-core/src/main/resources/high.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
briar-core/src/main/resources/kitten1.jpg
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
briar-core/src/main/resources/kitten2.jpg
Normal file
|
After Width: | Height: | Size: 128 KiB |
BIN
briar-core/src/main/resources/kitten3.gif
Normal file
|
After Width: | Height: | Size: 288 KiB |
BIN
briar-core/src/main/resources/kitten4.jpg
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
briar-core/src/main/resources/kitten5.jpg
Normal file
|
After Width: | Height: | Size: 79 KiB |
BIN
briar-core/src/main/resources/kitten6.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
BIN
briar-core/src/main/resources/small.png
Normal file
|
After Width: | Height: | Size: 133 B |
BIN
briar-core/src/main/resources/wide.jpg
Normal file
|
After Width: | Height: | Size: 1.2 KiB |