Skip to content

Commit

Permalink
#189 Attach multiple images. Note editor works.
Browse files Browse the repository at this point in the history
  • Loading branch information
yvolk committed Oct 27, 2019
1 parent 6276b02 commit 42cb651
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 61 deletions.
50 changes: 37 additions & 13 deletions app/src/androidTest/java/org/andstatus/app/note/NoteEditorTest.java
Expand Up @@ -22,6 +22,7 @@
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
Expand Down Expand Up @@ -187,11 +188,18 @@ private void editingStep2() throws InterruptedException {
MyLog.v(this, method + " ended");
}

// TODO: Test two attachments
@Test
public void attachOneImage() throws InterruptedException {
attachImages(1);
}

@Test
public void testAttachImage() throws InterruptedException {
final String method = "testAttachImage";
public void attachTwoImages() throws InterruptedException {
attachImages(2);
}

private void attachImages(int numberOfAttachments) throws InterruptedException {
final String method = "attachImages" + numberOfAttachments;
MyLog.v(this, method + " started");

ActivityTestHelper<TimelineActivity> helper = new ActivityTestHelper<>(getActivity());
Expand All @@ -203,12 +211,33 @@ public void testAttachImage() throws InterruptedException {
assertTextCleared();

TestSuite.waitForIdleSync();
final String noteName = "A note can have a title (name)";
final String content = "Note with an attachment " + demoData.testRunUid;
final String noteName = "A note " + numberOfAttachments + " can have a title (name)";
final String content = "Note with " + numberOfAttachments + " attachment" +
(numberOfAttachments == 1 ? "" : "s") + " " +
demoData.testRunUid;
onView(withId(R.id.note_name_edit)).perform(new TypeTextAction(noteName));
onView(withId(R.id.noteBodyEditText)).perform(new TypeTextAction(content));

attachImage(editorView, demoData.localImageTestUri2);
if (numberOfAttachments == 2) {
attachImage(editorView, demoData.localImageTestUri);
}
final NoteEditor editor = getActivity().getNoteEditor();
assertEquals("All image attached " + editor.getData().getAttachedImageFiles(), numberOfAttachments,
editor.getData().getAttachedImageFiles().list.size());

onView(withId(R.id.noteBodyEditText)).check(matches(withText(content + " ")));
onView(withId(R.id.note_name_edit)).check(matches(withText(noteName)));
helper.clickMenuItem(method + " clicker save draft", R.id.saveDraftButton);

MyLog.v(this, method + " ended");
}

private void attachImage(View editorView, Uri imageUri) throws InterruptedException {
final String method = "attachImage";
TestSuite.waitForIdleSync();

ActivityTestHelper<TimelineActivity> helper = new ActivityTestHelper<>(getActivity());
getActivity().setSelectorActivityMock(helper);
helper.clickMenuItem(method + " clicker attach_menu_id", R.id.attach_menu_id);
assertNotNull(helper.waitForSelectorStart(method, ActivityRequestCode.ATTACH.id));
Expand All @@ -229,7 +258,7 @@ public void testAttachImage() throws InterruptedException {

MyLog.i(method, "Callback from a selector");
Intent intent2 = new Intent();
intent2.setDataAndType(demoData.localImageTestUri2, MyContentType.IMAGE.generalMimeType);
intent2.setDataAndType(imageUri, MyContentType.IMAGE.generalMimeType);
getActivity().runOnUiThread(() -> {
getActivity().onActivityResult(ActivityRequestCode.ATTACH.id, Activity.RESULT_OK, intent2);
});
Expand All @@ -238,20 +267,15 @@ public void testAttachImage() throws InterruptedException {
for (int attempt=0; attempt < 4; attempt++) {
ActivityTestHelper.waitViewVisible(method, editorView);
// Due to a race the editor may open before this change first.
if (editor.getData().getAttachedImageFiles().forUri(demoData.localImageTestUri2).isPresent()) {
if (editor.getData().getAttachedImageFiles().forUri(imageUri).isPresent()) {
break;
}
if (DbUtils.waitMs(method, 2000)) {
break;
}
}
assertTrue("Image attached", editor.getData().getAttachedImageFiles()
.forUri(demoData.localImageTestUri2).isPresent());
onView(withId(R.id.noteBodyEditText)).check(matches(withText(content + " ")));
onView(withId(R.id.note_name_edit)).check(matches(withText(noteName)));
helper.clickMenuItem(method + " clicker save draft", R.id.saveDraftButton);

MyLog.v(this, method + " ended");
.forUri(imageUri).isPresent());
}

private void assertInitialText(final String description) throws InterruptedException {
Expand Down
44 changes: 34 additions & 10 deletions app/src/main/java/org/andstatus/app/note/NoteEditor.java
Expand Up @@ -32,7 +32,7 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.inputmethod.InputMethodManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
Expand All @@ -42,10 +42,12 @@
import org.andstatus.app.account.MyAccount;
import org.andstatus.app.actor.ActorAutoCompleteAdapter;
import org.andstatus.app.context.MyPreferences;
import org.andstatus.app.data.AttachedImageFile;
import org.andstatus.app.data.DownloadStatus;
import org.andstatus.app.data.MyQuery;
import org.andstatus.app.data.TextMediaType;
import org.andstatus.app.database.table.NoteTable;
import org.andstatus.app.graphics.IdentifiableImageView;
import org.andstatus.app.net.social.Connection.ApiRoutineEnum;
import org.andstatus.app.os.AsyncTaskLauncher;
import org.andstatus.app.os.MyAsyncTask;
Expand Down Expand Up @@ -453,7 +455,7 @@ public void updateScreen() {
editorData.activity.getNote().getInReplyTo().getNote().getContent(), TextMediaType.HTML,
false, false);
mCharsLeftText.setText(String.valueOf(editorData.getMyAccount().charactersLeftForNote(editorData.getContent())));
showAttachedImage();
showAttachedImages();
}

static boolean subjectHasAdditionalContent(Optional<String> name, Optional<String> content) {
Expand Down Expand Up @@ -543,14 +545,36 @@ private boolean shouldShowAccountName() {
return getActivity().getMyContext().accounts().size() > 1;
}

private void showAttachedImage() {
ImageView imageView = editorView.findViewById(R.id.attachment_image);
if (editorData.image == null || screenToggleState == ScreenToggleState.SHOW_TIMELINE) {
imageView.setVisibility(View.GONE);
} else {
imageView.setImageDrawable(editorData.image.getDrawable());
imageView.setVisibility(View.VISIBLE);
private void showAttachedImages() {
final LinearLayout attachmentsList = editorView.findViewById(R.id.attachments_wrapper);
if (attachmentsList == null) return;

if (!getActivity().isMyResumed() || screenToggleState == ScreenToggleState.SHOW_TIMELINE) {
attachmentsList.setVisibility(View.GONE);
return;
}

attachmentsList.removeAllViewsInLayout();

for (AttachedImageFile imageFile: editorData.getAttachedImageFiles().list) {
if (!imageFile.imageOrLinkMayBeShown()) continue;

int attachmentLayout = imageFile.imageMayBeShown()
? (imageFile.isTargetVideo() ? R.layout.attachment_video_preview : R.layout.attachment_image)
: R.layout.attachment_link;
final View attachmentView = LayoutInflater.from(getActivity())
.inflate(attachmentLayout, attachmentsList, false);
if (imageFile.imageMayBeShown()) {
IdentifiableImageView imageView = attachmentView.findViewById(R.id.attachment_image);
imageFile.showImage(getActivity(), imageView);
} else {
MyUrlSpan.showText(attachmentView, R.id.attachment_link,
imageFile.getTargetUri().toString(), true, false);
}
attachmentsList.addView(attachmentView);
}

attachmentsList.setVisibility(View.VISIBLE);
}

private void sendAndHide() {
Expand Down Expand Up @@ -744,6 +768,6 @@ public void onScreenToggle(boolean isNextState, boolean isFullscreen) {
bodyView.setMaxLines(8);
break;
}
showAttachedImage();
showAttachedImages();
}
}
Expand Up @@ -127,4 +127,8 @@ public void setMediaType(Optional<String> mediaType) {
public Optional<String> getMediaType() {
return mediaType;
}

public boolean hasMedia() {
return UriUtils.nonEmpty(mediaUri);
}
}
30 changes: 8 additions & 22 deletions app/src/main/java/org/andstatus/app/note/NoteEditorData.java
Expand Up @@ -36,7 +36,6 @@
import org.andstatus.app.database.table.ActorTable;
import org.andstatus.app.database.table.NoteTable;
import org.andstatus.app.graphics.CacheName;
import org.andstatus.app.graphics.CachedImage;
import org.andstatus.app.net.social.AActivity;
import org.andstatus.app.net.social.Actor;
import org.andstatus.app.net.social.Attachment;
Expand All @@ -48,7 +47,6 @@
import org.andstatus.app.util.MyStringBuilder;
import org.andstatus.app.util.StringUtils;
import org.andstatus.app.util.TriState;
import org.andstatus.app.util.UriUtils;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -57,7 +55,6 @@

import androidx.annotation.NonNull;

import static org.andstatus.app.data.DownloadStatus.LOADED;
import static org.andstatus.app.data.DownloadStatus.UNKNOWN;
import static org.andstatus.app.util.MyLog.COMMA;

Expand All @@ -66,10 +63,7 @@ public class NoteEditorData implements IsEmpty {
static final NoteEditorData EMPTY = NoteEditorData.newEmpty(MyAccount.EMPTY);

public final AActivity activity;

private AttachedImageFiles attachedImageFiles = AttachedImageFiles.EMPTY;
// TODO: List<CachedImage> image = ...;
CachedImage image = null;

private boolean replyToConversationParticipants = false;
private boolean replyToMentionedActors = false;
Expand Down Expand Up @@ -140,13 +134,9 @@ private NoteEditorData(MyAccount myAccount, MyContext myContext, @NonNull AActiv
}

attachedImageFiles = AttachedImageFiles.load(myContext, noteId);
attachedImageFiles.list.forEach( att -> {
if (att.downloadStatus == LOADED) {
image = att.loadAndGetImage(CacheName.ATTACHED_IMAGE);
note.attachments.add(Attachment.fromUri(att.uri));
} else {
// TODO
}
attachedImageFiles.list.forEach( imageFile -> {
imageFile.preloadImageAsync(CacheName.ATTACHED_IMAGE);
note.attachments.add(Attachment.fromAttachedImageFile(imageFile));
});
MyLog.v(TAG, () -> "Loaded " + this);
}
Expand Down Expand Up @@ -232,22 +222,18 @@ NoteEditorData copy() {
NoteEditorData data = new NoteEditorData(ma, MyContextHolder.get(), activity,
activity.getNote().getInReplyTo().getNote().noteId, false);
data.attachedImageFiles = attachedImageFiles;
data.image = image;
data.replyToConversationParticipants = replyToConversationParticipants;
return data;
} else {
return EMPTY;
}
}

// TODO: Explicitly add in a separate method
public void save(Uri imageUriToSave, Optional<String> mediaType) {
Note note = activity.getNote();
note.attachments.clear();
attachedImageFiles.list.forEach(item -> note.attachments.add(Attachment.fromAttachedImageFile(item)));
if (UriUtils.nonEmpty(imageUriToSave)) {
note.attachments.add(Attachment.fromUriAndMimeType(imageUriToSave, mediaType.orElse("")));
}
public void addAttachment(Uri uri, Optional<String> mediaType) {
activity.getNote().attachments.add(Attachment.fromUriAndMimeType(uri, mediaType.orElse("")));
}

public void save() {
new DataUpdater(getMyAccount()).onActivity(activity);
// TODO: Delete previous draft activities of this note
}
Expand Down
11 changes: 5 additions & 6 deletions app/src/main/java/org/andstatus/app/note/NoteSaver.java
Expand Up @@ -16,8 +16,6 @@

package org.andstatus.app.note;

import android.net.Uri;

import org.andstatus.app.context.MyContextHolder;
import org.andstatus.app.context.MyPreferences;
import org.andstatus.app.data.DownloadStatus;
Expand All @@ -31,8 +29,6 @@
import org.andstatus.app.service.MyServiceState;
import org.andstatus.app.util.MyLog;

import java.util.Optional;

/**
* Asynchronously save, delete and send a note, prepared by {@link NoteEditor}
*/
Expand Down Expand Up @@ -65,7 +61,7 @@ protected NoteEditorData doInBackground2(NoteEditorCommand commandIn) {
private void savePreviousData() {
if (command.needToSavePreviousData()) {
MyLog.v(NoteEditorData.TAG, () -> "Saving previous data:" + command.previousData);
command.previousData.save(Uri.EMPTY, Optional.empty());
command.previousData.save();
broadcastDataChanged(command.previousData);
}
}
Expand All @@ -75,7 +71,10 @@ private void saveCurrentData() {
if (command.currentData.activity.getNote().getStatus() == DownloadStatus.DELETED) {
MyProvider.deleteNoteAndItsActivities(MyContextHolder.get(), command.currentData.getNoteId());
} else {
command.currentData.save(command.getMediaUri(), command.getMediaType());
if (command.hasMedia()) {
command.currentData.addAttachment(command.getMediaUri(), command.getMediaType());
}
command.currentData.save();
if (command.beingEdited) {
MyPreferences.setBeingEditedNoteId(command.currentData.getNoteId());
}
Expand Down
15 changes: 5 additions & 10 deletions app/src/main/res/layout/note_editor.xml
Expand Up @@ -116,16 +116,11 @@
android:layout_height="match_parent"
android:orientation="vertical">

<ImageView
android:id="@+id/attachment_image"
android:layout_width="160dip"
android:layout_height="90dip"
android:contentDescription="@string/attachments"
android:paddingLeft="1dp"
android:paddingRight="1dp"
android:paddingTop="2dp"
android:scaleType="fitCenter"
tools:src="@drawable/splash_logo"/>
<LinearLayout
android:id="@+id/attachments_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />

<LinearLayout
android:layout_width="match_parent"
Expand Down

0 comments on commit 42cb651

Please sign in to comment.