More place for media description

This commit is contained in:
Thomas 2023-08-15 16:58:31 +02:00
parent 4c00aa9a2e
commit 302b3e47d4
3 changed files with 106 additions and 35 deletions

View File

@ -33,12 +33,14 @@ import android.os.Bundle;
import android.os.Handler; import android.os.Handler;
import android.os.Looper; import android.os.Looper;
import android.text.Editable; import android.text.Editable;
import android.text.InputFilter;
import android.text.TextWatcher; import android.text.TextWatcher;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.MotionEvent; import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.Toast; import android.widget.Toast;
@ -55,6 +57,7 @@ import androidx.work.OneTimeWorkRequest;
import androidx.work.OutOfQuotaPolicy; import androidx.work.OutOfQuotaPolicy;
import androidx.work.WorkManager; import androidx.work.WorkManager;
import com.bumptech.glide.Glide;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import java.io.File; import java.io.File;
@ -64,6 +67,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.Timer; import java.util.Timer;
import java.util.TimerTask; import java.util.TimerTask;
@ -99,7 +103,7 @@ import app.fedilab.android.mastodon.viewmodel.mastodon.AccountsVM;
import app.fedilab.android.mastodon.viewmodel.mastodon.StatusesVM; import app.fedilab.android.mastodon.viewmodel.mastodon.StatusesVM;
import es.dmoral.toasty.Toasty; import es.dmoral.toasty.Toasty;
public class ComposeActivity extends BaseActivity implements ComposeAdapter.ManageDrafts, AccountsReplyAdapter.ActionDone, ComposeAdapter.promptDraftListener { public class ComposeActivity extends BaseActivity implements ComposeAdapter.ManageDrafts, AccountsReplyAdapter.ActionDone, ComposeAdapter.promptDraftListener, ComposeAdapter.MediaDescriptionCallBack {
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754; public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754;
@ -206,7 +210,9 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
@Override @Override
public void onBackPressed() { public void onBackPressed() {
storeDraftWarning(); if (binding.recyclerView.getVisibility() == View.VISIBLE) {
storeDraftWarning();
}
} }
private void storeDraftWarning() { private void storeDraftWarning() {
@ -290,6 +296,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
statusList.add(initialStatus); statusList.add(initialStatus);
statusList.add(statusDraft.statusDraftList.get(0)); statusList.add(statusDraft.statusDraftList.get(0));
composeAdapter = new ComposeAdapter(statusList, context.ancestors.size(), account, accountMention, visibility, editMessageId); composeAdapter = new ComposeAdapter(statusList, context.ancestors.size(), account, accountMention, visibility, editMessageId);
composeAdapter.mediaDescriptionCallBack = this;
composeAdapter.promptDraftListener = this; composeAdapter.promptDraftListener = this;
composeAdapter.manageDrafts = this; composeAdapter.manageDrafts = this;
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
@ -617,6 +624,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
int statusCount = statusList.size(); int statusCount = statusList.size();
statusList.addAll(statusDraft.statusDraftList); statusList.addAll(statusDraft.statusDraftList);
composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility, editMessageId); composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility, editMessageId);
composeAdapter.mediaDescriptionCallBack = this;
composeAdapter.manageDrafts = this; composeAdapter.manageDrafts = this;
composeAdapter.promptDraftListener = this; composeAdapter.promptDraftListener = this;
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
@ -689,6 +697,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
//StatusDraftList at this point should only have one element //StatusDraftList at this point should only have one element
statusList.addAll(statusDraftList); statusList.addAll(statusDraftList);
composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility, editMessageId); composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility, editMessageId);
composeAdapter.mediaDescriptionCallBack = this;
composeAdapter.manageDrafts = this; composeAdapter.manageDrafts = this;
composeAdapter.promptDraftListener = this; composeAdapter.promptDraftListener = this;
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
@ -703,6 +712,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
//StatusDraftList at this point should only have one element //StatusDraftList at this point should only have one element
statusList.addAll(statusDraftList); statusList.addAll(statusDraftList);
composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility, editMessageId); composeAdapter = new ComposeAdapter(statusList, statusCount, account, accountMention, visibility, editMessageId);
composeAdapter.mediaDescriptionCallBack = this;
composeAdapter.manageDrafts = this; composeAdapter.manageDrafts = this;
composeAdapter.promptDraftListener = this; composeAdapter.promptDraftListener = this;
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
@ -712,6 +722,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
//Compose without replying //Compose without replying
statusList.addAll(statusDraftList); statusList.addAll(statusDraftList);
composeAdapter = new ComposeAdapter(statusList, 0, account, accountMention, visibility, editMessageId); composeAdapter = new ComposeAdapter(statusList, 0, account, accountMention, visibility, editMessageId);
composeAdapter.mediaDescriptionCallBack = this;
composeAdapter.manageDrafts = this; composeAdapter.manageDrafts = this;
composeAdapter.promptDraftListener = this; composeAdapter.promptDraftListener = this;
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this); LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
@ -1010,6 +1021,36 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
promptSaveDraft = true; promptSaveDraft = true;
} }
@Override
public void click(ComposeAdapter.ComposeViewHolder holder, Attachment attachment, int messagePosition, int mediaPosition) {
binding.description.setVisibility(View.VISIBLE);
binding.recyclerView.setVisibility(View.GONE);
binding.mediaDescription.setText("");
String attachmentPath = attachment.local_path != null && !attachment.local_path.trim().isEmpty() ? attachment.local_path : attachment.preview_url;
Glide.with(binding.mediaPreview.getContext())
.load(attachmentPath)
.into(binding.mediaPreview);
if (attachment.description != null) {
binding.mediaDescription.setText(attachment.description);
binding.mediaDescription.setSelection(binding.mediaDescription.getText().length());
}
binding.mediaDescription.setFilters(new InputFilter[]{new InputFilter.LengthFilter(1500)});
binding.mediaDescription.requestFocus();
Objects.requireNonNull(getWindow()).setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
binding.mediaDescription.requestFocus();
binding.mediaSave.setOnClickListener(v -> {
binding.description.setVisibility(View.GONE);
binding.recyclerView.setVisibility(View.VISIBLE);
composeAdapter.openDescriptionActivity(true, binding.mediaDescription.getText().toString().trim(), holder, attachment, messagePosition, mediaPosition);
});
binding.mediaCancel.setOnClickListener(v -> {
binding.description.setVisibility(View.GONE);
binding.recyclerView.setVisibility(View.VISIBLE);
composeAdapter.openDescriptionActivity(false, binding.mediaDescription.getText().toString().trim(), holder, attachment, messagePosition, mediaPosition);
});
}
public enum mediaType { public enum mediaType {
PHOTO, PHOTO,

View File

@ -46,7 +46,6 @@ import android.text.TextWatcher;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityEvent;
import android.view.inputmethod.InputMethodManager; import android.view.inputmethod.InputMethodManager;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
@ -69,7 +68,6 @@ import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide; import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy; import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.load.resource.bitmap.RoundedCorners;
import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.RequestOptions;
import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.dialog.MaterialAlertDialogBuilder;
import com.google.gson.Gson; import com.google.gson.Gson;
@ -91,7 +89,6 @@ import java.util.Date;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
@ -105,7 +102,6 @@ import app.fedilab.android.databinding.ComposePollBinding;
import app.fedilab.android.databinding.ComposePollItemBinding; import app.fedilab.android.databinding.ComposePollItemBinding;
import app.fedilab.android.databinding.DrawerStatusComposeBinding; import app.fedilab.android.databinding.DrawerStatusComposeBinding;
import app.fedilab.android.databinding.DrawerStatusSimpleBinding; import app.fedilab.android.databinding.DrawerStatusSimpleBinding;
import app.fedilab.android.databinding.PopupMediaDescriptionBinding;
import app.fedilab.android.mastodon.activities.ComposeActivity; import app.fedilab.android.mastodon.activities.ComposeActivity;
import app.fedilab.android.mastodon.client.entities.api.Account; import app.fedilab.android.mastodon.client.entities.api.Account;
import app.fedilab.android.mastodon.client.entities.api.Attachment; import app.fedilab.android.mastodon.client.entities.api.Attachment;
@ -170,6 +166,8 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
private boolean unlisted_changed = false; private boolean unlisted_changed = false;
private RecyclerView mRecyclerView; private RecyclerView mRecyclerView;
public MediaDescriptionCallBack mediaDescriptionCallBack;
public ComposeAdapter(List<Status> statusList, int statusCount, BaseAccount account, Account mentionedAccount, String visibility, String editMessageId) { public ComposeAdapter(List<Status> statusList, int statusCount, BaseAccount account, Account mentionedAccount, String visibility, String editMessageId) {
this.statusList = statusList; this.statusList = statusList;
@ -1146,7 +1144,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
intent.putExtras(b); intent.putExtras(b);
context.startActivity(intent); context.startActivity(intent);
}); });
composeAttachmentItemBinding.buttonDescription.setOnClickListener(v -> openDescription(holder, attachment, position, finalMediaPosition)); composeAttachmentItemBinding.buttonDescription.setOnClickListener(v -> mediaDescriptionCallBack.click(holder, attachment, position, finalMediaPosition));
composeAttachmentItemBinding.buttonOrderUp.setOnClickListener(v -> { composeAttachmentItemBinding.buttonOrderUp.setOnClickListener(v -> {
if (finalMediaPosition > 0 && attachmentList.size() > 1) { if (finalMediaPosition > 0 && attachmentList.size() > 1) {
@ -1235,7 +1233,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
for (Attachment attachment : status.media_attachments) { for (Attachment attachment : status.media_attachments) {
if (attachment.description == null || attachment.description.trim().isEmpty()) { if (attachment.description == null || attachment.description.trim().isEmpty()) {
ComposeViewHolder composeViewHolder = (ComposeViewHolder) mRecyclerView.findViewHolderForAdapterPosition(position); ComposeViewHolder composeViewHolder = (ComposeViewHolder) mRecyclerView.findViewHolderForAdapterPosition(position);
openDescription(composeViewHolder, attachment, position, mediaPosition); mediaDescriptionCallBack.click(composeViewHolder, attachment, position, mediaPosition);
return; return;
} }
mediaPosition++; mediaPosition++;
@ -1246,34 +1244,15 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
} }
} }
public void openDescriptionActivity(boolean saved, String content, ComposeViewHolder holder, Attachment attachment, int messagePosition, int mediaPosition) {
private void openDescription(ComposeViewHolder holder, Attachment attachment, int messagePosition, int mediaPosition) { if (saved) {
String attachmentPath = attachment.local_path != null && !attachment.local_path.trim().isEmpty() ? attachment.local_path : attachment.preview_url; attachment.description = content;
AlertDialog.Builder builderInner = new MaterialAlertDialogBuilder(context);
// builderInner.setTitle(R.string.upload_form_description);
PopupMediaDescriptionBinding popupMediaDescriptionBinding = PopupMediaDescriptionBinding.inflate(LayoutInflater.from(context), null, false);
builderInner.setView(popupMediaDescriptionBinding.getRoot());
popupMediaDescriptionBinding.mediaDescription.setFilters(new InputFilter[]{new InputFilter.LengthFilter(1500)});
popupMediaDescriptionBinding.mediaDescription.requestFocus();
Glide.with(popupMediaDescriptionBinding.mediaPicture.getContext())
.load(attachmentPath)
.apply(new RequestOptions().transform(new RoundedCorners(30)))
.into(popupMediaDescriptionBinding.mediaPicture);
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
if (attachment.description != null) {
popupMediaDescriptionBinding.mediaDescription.setText(attachment.description);
popupMediaDescriptionBinding.mediaDescription.setSelection(popupMediaDescriptionBinding.mediaDescription.getText().length());
}
builderInner.setPositiveButton(R.string.validate, (dialog, which) -> {
attachment.description = popupMediaDescriptionBinding.mediaDescription.getText().toString();
displayAttachments(holder, messagePosition, mediaPosition); displayAttachments(holder, messagePosition, mediaPosition);
dialog.dismiss(); }
}); }
AlertDialog alertDialog = builderInner.create();
Objects.requireNonNull(alertDialog.getWindow()).setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); public interface MediaDescriptionCallBack {
alertDialog.show(); void click(ComposeViewHolder holder, Attachment attachment, int messagePosition, int mediaPosition);
popupMediaDescriptionBinding.mediaDescription.requestFocus();
} }
/** /**

View File

@ -66,5 +66,56 @@
android:scrollbars="none" android:scrollbars="none"
app:layout_behavior="@string/appbar_scrolling_view_behavior" /> app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<ScrollView
android:id="@+id/description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="5dp"
android:visibility="gone">
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:id="@+id/media_preview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:contentDescription="@string/preview"
android:scaleType="centerInside" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/media_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:minLines="5" />
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="end"
android:orientation="horizontal">
<com.google.android.material.button.MaterialButton
android:id="@+id/media_cancel"
style="@style/Widget.Material3.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/cancel" />
<com.google.android.material.button.MaterialButton
android:id="@+id/media_save"
style="@style/Widget.Material3.Button.IconButton.Filled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:text="@string/save" />
</androidx.appcompat.widget.LinearLayoutCompat>
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</androidx.drawerlayout.widget.DrawerLayout> </androidx.drawerlayout.widget.DrawerLayout>