Fix issue #449 - Fix draft issues
This commit is contained in:
parent
869b4d25e2
commit
962a59ac4f
|
@ -97,7 +97,7 @@ import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
||||||
import app.fedilab.android.viewmodel.mastodon.StatusesVM;
|
import app.fedilab.android.viewmodel.mastodon.StatusesVM;
|
||||||
import es.dmoral.toasty.Toasty;
|
import es.dmoral.toasty.Toasty;
|
||||||
|
|
||||||
public class ComposeActivity extends BaseActivity implements ComposeAdapter.ManageDrafts, AccountsReplyAdapter.ActionDone {
|
public class ComposeActivity extends BaseActivity implements ComposeAdapter.ManageDrafts, AccountsReplyAdapter.ActionDone, ComposeAdapter.promptDraftListener {
|
||||||
|
|
||||||
|
|
||||||
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754;
|
public static final int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 754;
|
||||||
|
@ -109,6 +109,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
||||||
private Status statusReply, statusMention;
|
private Status statusReply, statusMention;
|
||||||
private StatusDraft statusDraft;
|
private StatusDraft statusDraft;
|
||||||
private ComposeAdapter composeAdapter;
|
private ComposeAdapter composeAdapter;
|
||||||
|
private boolean promptSaveDraft;
|
||||||
|
|
||||||
|
|
||||||
private final BroadcastReceiver imageReceiver = new BroadcastReceiver() {
|
private final BroadcastReceiver imageReceiver = new BroadcastReceiver() {
|
||||||
|
@ -213,25 +214,34 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
||||||
statusDraft = prepareDraft(statusList, composeAdapter, account.instance, account.user_id);
|
statusDraft = prepareDraft(statusList, composeAdapter, account.instance, account.user_id);
|
||||||
}
|
}
|
||||||
if (canBeSent(statusDraft)) {
|
if (canBeSent(statusDraft)) {
|
||||||
AlertDialog.Builder alt_bld = new AlertDialog.Builder(ComposeActivity.this, Helper.dialogStyle());
|
if (promptSaveDraft) {
|
||||||
alt_bld.setMessage(R.string.save_draft);
|
AlertDialog.Builder alt_bld = new AlertDialog.Builder(ComposeActivity.this, Helper.dialogStyle());
|
||||||
alt_bld.setPositiveButton(R.string.save, (dialog, id) -> {
|
alt_bld.setMessage(R.string.save_draft);
|
||||||
dialog.dismiss();
|
alt_bld.setPositiveButton(R.string.save, (dialog, id) -> {
|
||||||
storeDraft(false);
|
dialog.dismiss();
|
||||||
finish();
|
storeDraft(false);
|
||||||
|
finish();
|
||||||
|
|
||||||
});
|
});
|
||||||
alt_bld.setNegativeButton(R.string.no, (dialog, id) -> {
|
alt_bld.setNegativeButton(R.string.no, (dialog, id) -> {
|
||||||
|
try {
|
||||||
|
new StatusDraft(ComposeActivity.this).removeDraft(statusDraft);
|
||||||
|
} catch (DBException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
dialog.dismiss();
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
AlertDialog alert = alt_bld.create();
|
||||||
|
alert.show();
|
||||||
|
} else {
|
||||||
try {
|
try {
|
||||||
new StatusDraft(ComposeActivity.this).removeDraft(statusDraft);
|
new StatusDraft(ComposeActivity.this).removeDraft(statusDraft);
|
||||||
|
finish();
|
||||||
} catch (DBException e) {
|
} catch (DBException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
dialog.dismiss();
|
}
|
||||||
finish();
|
|
||||||
});
|
|
||||||
AlertDialog alert = alt_bld.create();
|
|
||||||
alert.show();
|
|
||||||
} else {
|
} else {
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
@ -278,6 +288,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.promptDraftListener = this;
|
||||||
composeAdapter.manageDrafts = this;
|
composeAdapter.manageDrafts = this;
|
||||||
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
|
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
|
||||||
binding.recyclerView.setLayoutManager(mLayoutManager);
|
binding.recyclerView.setLayoutManager(mLayoutManager);
|
||||||
|
@ -434,6 +445,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
||||||
binding = ActivityPaginationBinding.inflate(getLayoutInflater());
|
binding = ActivityPaginationBinding.inflate(getLayoutInflater());
|
||||||
setContentView(binding.getRoot());
|
setContentView(binding.getRoot());
|
||||||
setSupportActionBar(binding.toolbar);
|
setSupportActionBar(binding.toolbar);
|
||||||
|
promptSaveDraft = false;
|
||||||
ActionBar actionBar = getSupportActionBar();
|
ActionBar actionBar = getSupportActionBar();
|
||||||
//Remove title
|
//Remove title
|
||||||
if (actionBar != null) {
|
if (actionBar != null) {
|
||||||
|
@ -572,6 +584,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
||||||
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.manageDrafts = this;
|
composeAdapter.manageDrafts = this;
|
||||||
|
composeAdapter.promptDraftListener = this;
|
||||||
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
|
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
|
||||||
binding.recyclerView.setLayoutManager(mLayoutManager);
|
binding.recyclerView.setLayoutManager(mLayoutManager);
|
||||||
binding.recyclerView.setAdapter(composeAdapter);
|
binding.recyclerView.setAdapter(composeAdapter);
|
||||||
|
@ -627,6 +640,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
||||||
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.manageDrafts = this;
|
composeAdapter.manageDrafts = this;
|
||||||
|
composeAdapter.promptDraftListener = this;
|
||||||
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
|
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
|
||||||
binding.recyclerView.setLayoutManager(mLayoutManager);
|
binding.recyclerView.setLayoutManager(mLayoutManager);
|
||||||
binding.recyclerView.setAdapter(composeAdapter);
|
binding.recyclerView.setAdapter(composeAdapter);
|
||||||
|
@ -637,6 +651,7 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
||||||
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.manageDrafts = this;
|
composeAdapter.manageDrafts = this;
|
||||||
|
composeAdapter.promptDraftListener = this;
|
||||||
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
|
LinearLayoutManager mLayoutManager = new LinearLayoutManager(ComposeActivity.this);
|
||||||
binding.recyclerView.setLayoutManager(mLayoutManager);
|
binding.recyclerView.setLayoutManager(mLayoutManager);
|
||||||
binding.recyclerView.setAdapter(composeAdapter);
|
binding.recyclerView.setAdapter(composeAdapter);
|
||||||
|
@ -653,7 +668,9 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
||||||
timer.scheduleAtFixedRate(new TimerTask() {
|
timer.scheduleAtFixedRate(new TimerTask() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
storeDraft(false);
|
if (promptSaveDraft) {
|
||||||
|
storeDraft(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, 0, 10000);
|
}, 0, 10000);
|
||||||
}
|
}
|
||||||
|
@ -872,6 +889,11 @@ public class ComposeActivity extends BaseActivity implements ComposeAdapter.Mana
|
||||||
composeAdapter.updateContent(isChecked, acct);
|
composeAdapter.updateContent(isChecked, acct);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void promptDraft() {
|
||||||
|
promptSaveDraft = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public enum mediaType {
|
public enum mediaType {
|
||||||
PHOTO,
|
PHOTO,
|
||||||
|
|
|
@ -142,6 +142,7 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||||
private Context context;
|
private Context context;
|
||||||
private AlertDialog alertDialogEmoji;
|
private AlertDialog alertDialogEmoji;
|
||||||
private List<Emoji> emojisList = new ArrayList<>();
|
private List<Emoji> emojisList = new ArrayList<>();
|
||||||
|
public promptDraftListener promptDraftListener;
|
||||||
|
|
||||||
public ComposeAdapter(List<Status> statusList, int statusCount, BaseAccount account, app.fedilab.android.client.entities.api.Account mentionedAccount, String visibility, String editMessageId) {
|
public ComposeAdapter(List<Status> statusList, int statusCount, BaseAccount account, app.fedilab.android.client.entities.api.Account mentionedAccount, String visibility, String editMessageId) {
|
||||||
this.statusList = statusList;
|
this.statusList = statusList;
|
||||||
|
@ -153,6 +154,30 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an attachment from ComposeActivity
|
||||||
|
*
|
||||||
|
* @param position int - position of the drawer that added a media
|
||||||
|
* @param uris List<Uri> - uris of the media
|
||||||
|
*/
|
||||||
|
public void addAttachment(int position, List<Uri> uris) {
|
||||||
|
if (position == -1) {
|
||||||
|
position = statusList.size() - 1;
|
||||||
|
}
|
||||||
|
// position = statusCount-1+position;
|
||||||
|
if (statusList.get(position).media_attachments == null) {
|
||||||
|
statusList.get(position).media_attachments = new ArrayList<>();
|
||||||
|
}
|
||||||
|
if (promptDraftListener != null) {
|
||||||
|
promptDraftListener.promptDraft();
|
||||||
|
}
|
||||||
|
int finalPosition = position;
|
||||||
|
Helper.createAttachmentFromUri(context, uris, attachment -> {
|
||||||
|
statusList.get(finalPosition).media_attachments.add(attachment);
|
||||||
|
notifyItemChanged(finalPosition);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private static void updateCharacterCount(ComposeViewHolder composeViewHolder) {
|
private static void updateCharacterCount(ComposeViewHolder composeViewHolder) {
|
||||||
int charCount = MastodonHelper.countLength(composeViewHolder);
|
int charCount = MastodonHelper.countLength(composeViewHolder);
|
||||||
composeViewHolder.binding.characterCount.setText(String.valueOf(charCount));
|
composeViewHolder.binding.characterCount.setText(String.valueOf(charCount));
|
||||||
|
@ -391,327 +416,6 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||||
&& (draft.spoiler_text == null || draft.spoiler_text.trim().length() == 0);
|
&& (draft.spoiler_text == null || draft.spoiler_text.trim().length() == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add an attachment from ComposeActivity
|
|
||||||
*
|
|
||||||
* @param position int - position of the drawer that added a media
|
|
||||||
* @param uris List<Uri> - uris of the media
|
|
||||||
*/
|
|
||||||
public void addAttachment(int position, List<Uri> uris) {
|
|
||||||
if (position == -1) {
|
|
||||||
position = statusList.size() - 1;
|
|
||||||
}
|
|
||||||
// position = statusCount-1+position;
|
|
||||||
if (statusList.get(position).media_attachments == null) {
|
|
||||||
statusList.get(position).media_attachments = new ArrayList<>();
|
|
||||||
}
|
|
||||||
int finalPosition = position;
|
|
||||||
Helper.createAttachmentFromUri(context, uris, attachment -> {
|
|
||||||
statusList.get(finalPosition).media_attachments.add(attachment);
|
|
||||||
notifyItemChanged(finalPosition);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a shared element
|
|
||||||
* If title and description are empty, it will use subject and content coming from the intent
|
|
||||||
*
|
|
||||||
* @param url - String url that is shared
|
|
||||||
* @param title - String title gather from the URL
|
|
||||||
* @param description - String description gathered from the URL
|
|
||||||
* @param subject - String subject (title) comming from the shared elements
|
|
||||||
* @param content - String content (description) coming from the shared elements
|
|
||||||
*/
|
|
||||||
public void addSharing(String url, String title, String description, String subject, String content, String saveFilePath) {
|
|
||||||
|
|
||||||
if (description == null && content == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
int position = statusList.size() - 1;
|
|
||||||
statusList.get(position).text = "";
|
|
||||||
if (title != null && title.trim().length() > 0) {
|
|
||||||
statusList.get(position).text += title + "\n\n";
|
|
||||||
} else if (subject != null && subject.trim().length() > 0) {
|
|
||||||
statusList.get(position).text += subject + "\n\n";
|
|
||||||
}
|
|
||||||
if (description != null && description.trim().length() > 0) {
|
|
||||||
statusList.get(position).text += description + "\n\n";
|
|
||||||
if (url != null && !description.contains(url)) {
|
|
||||||
statusList.get(position).text += url;
|
|
||||||
}
|
|
||||||
} else if (content != null && content.trim().length() > 0) {
|
|
||||||
statusList.get(position).text += content + "\n\n";
|
|
||||||
if (!content.contains(url)) {
|
|
||||||
statusList.get(position).text += url;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
statusList.get(position).text += url;
|
|
||||||
}
|
|
||||||
if (saveFilePath != null) {
|
|
||||||
Attachment attachment = new Attachment();
|
|
||||||
attachment.mimeType = "image/*";
|
|
||||||
String extension = "jpg";
|
|
||||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_", Locale.getDefault());
|
|
||||||
attachment.local_path = saveFilePath;
|
|
||||||
Date now = new Date();
|
|
||||||
attachment.filename = formatter.format(now) + "." + extension;
|
|
||||||
if (statusList.get(position).media_attachments == null) {
|
|
||||||
statusList.get(position).media_attachments = new ArrayList<>();
|
|
||||||
}
|
|
||||||
statusList.get(position).media_attachments.add(attachment);
|
|
||||||
}
|
|
||||||
notifyItemChanged(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
//<------ Manage contact from compose activity
|
|
||||||
//It only targets last message in a thread
|
|
||||||
//Return content of last compose message
|
|
||||||
public String getLastComposeContent() {
|
|
||||||
return statusList.get(statusList.size() - 1).text != null ? statusList.get(statusList.size() - 1).text : "";
|
|
||||||
}
|
|
||||||
//------- end contact ----->
|
|
||||||
|
|
||||||
//Used to write contact when composing
|
|
||||||
public void updateContent(boolean checked, String acct) {
|
|
||||||
if (checked) {
|
|
||||||
if (!statusList.get(statusList.size() - 1).text.contains(acct))
|
|
||||||
statusList.get(statusList.size() - 1).text = String.format("%s %s", acct, statusList.get(statusList.size() - 1).text);
|
|
||||||
} else {
|
|
||||||
statusList.get(statusList.size() - 1).text = statusList.get(statusList.size() - 1).text.replaceAll("\\s*" + acct, "");
|
|
||||||
}
|
|
||||||
notifyItemChanged(statusList.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Put cursor to the end after changing contacts
|
|
||||||
public void putCursor() {
|
|
||||||
statusList.get(statusList.size() - 1).setCursorToEnd = true;
|
|
||||||
notifyItemChanged(statusList.size() - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display attachment for a holder
|
|
||||||
*
|
|
||||||
* @param holder - view related to a compose element {@link ComposeViewHolder}
|
|
||||||
* @param position - int position of the message in the thread
|
|
||||||
* @param scrollToMediaPosition - int the position to scroll to media
|
|
||||||
*/
|
|
||||||
private void displayAttachments(ComposeViewHolder holder, int position, int scrollToMediaPosition) {
|
|
||||||
if (statusList.size() > position && statusList.get(position).media_attachments != null) {
|
|
||||||
holder.binding.attachmentsList.removeAllViews();
|
|
||||||
List<Attachment> attachmentList = statusList.get(position).media_attachments;
|
|
||||||
if (attachmentList != null && attachmentList.size() > 0) {
|
|
||||||
holder.binding.sensitiveMedia.setVisibility(View.VISIBLE);
|
|
||||||
if (!statusList.get(position).sensitive) {
|
|
||||||
if (currentAccount != null && currentAccount.mastodon_account != null && currentAccount.mastodon_account.source != null) {
|
|
||||||
holder.binding.sensitiveMedia.setChecked(currentAccount.mastodon_account.source.sensitive);
|
|
||||||
statusList.get(position).sensitive = currentAccount.mastodon_account.source.sensitive;
|
|
||||||
} else {
|
|
||||||
statusList.get(position).sensitive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
holder.binding.sensitiveMedia.setOnCheckedChangeListener((buttonView, isChecked) -> statusList.get(position).sensitive = isChecked);
|
|
||||||
int mediaPosition = 0;
|
|
||||||
for (Attachment attachment : attachmentList) {
|
|
||||||
ComposeAttachmentItemBinding composeAttachmentItemBinding = ComposeAttachmentItemBinding.inflate(LayoutInflater.from(context), holder.binding.attachmentsList, false);
|
|
||||||
composeAttachmentItemBinding.buttonPlay.setVisibility(View.GONE);
|
|
||||||
String attachmentPath = attachment.local_path != null && !attachment.local_path.trim().isEmpty() ? attachment.local_path : attachment.preview_url;
|
|
||||||
if (attachment.type != null || attachment.mimeType != null) {
|
|
||||||
if ((attachment.type != null && attachment.type.toLowerCase().startsWith("image")) || (attachment.mimeType != null && attachment.mimeType.toLowerCase().startsWith("image"))) {
|
|
||||||
Glide.with(composeAttachmentItemBinding.preview.getContext())
|
|
||||||
.load(attachmentPath)
|
|
||||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
|
||||||
.skipMemoryCache(true)
|
|
||||||
.into(composeAttachmentItemBinding.preview);
|
|
||||||
} else if ((attachment.type != null && attachment.type.toLowerCase().startsWith("video")) || (attachment.mimeType != null && attachment.mimeType.toLowerCase().startsWith("video"))) {
|
|
||||||
composeAttachmentItemBinding.buttonPlay.setVisibility(View.VISIBLE);
|
|
||||||
long interval = 2000;
|
|
||||||
RequestOptions options = new RequestOptions().frame(interval);
|
|
||||||
Glide.with(composeAttachmentItemBinding.preview.getContext()).asBitmap()
|
|
||||||
.load(attachmentPath)
|
|
||||||
.apply(options)
|
|
||||||
.into(composeAttachmentItemBinding.preview);
|
|
||||||
} else if ((attachment.type != null && attachment.type.toLowerCase().startsWith("audio")) || (attachment.mimeType != null && attachment.mimeType.toLowerCase().startsWith("audio"))) {
|
|
||||||
Glide.with(composeAttachmentItemBinding.preview.getContext())
|
|
||||||
.load(R.drawable.ic_baseline_audio_file_24)
|
|
||||||
.into(composeAttachmentItemBinding.preview);
|
|
||||||
} else {
|
|
||||||
Glide.with(composeAttachmentItemBinding.preview.getContext())
|
|
||||||
.load(R.drawable.ic_baseline_insert_drive_file_24)
|
|
||||||
.into(composeAttachmentItemBinding.preview);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Glide.with(composeAttachmentItemBinding.preview.getContext())
|
|
||||||
.load(R.drawable.ic_baseline_insert_drive_file_24)
|
|
||||||
.into(composeAttachmentItemBinding.preview);
|
|
||||||
}
|
|
||||||
if (mediaPosition == 0) {
|
|
||||||
composeAttachmentItemBinding.buttonOrderUp.setVisibility(View.INVISIBLE);
|
|
||||||
} else {
|
|
||||||
composeAttachmentItemBinding.buttonOrderUp.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
if (mediaPosition == attachmentList.size() - 1) {
|
|
||||||
composeAttachmentItemBinding.buttonOrderDown.setVisibility(View.INVISIBLE);
|
|
||||||
} else {
|
|
||||||
composeAttachmentItemBinding.buttonOrderDown.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
//Remote attachments when deleting/redrafting can't be ordered
|
|
||||||
if (attachment.local_path == null) {
|
|
||||||
composeAttachmentItemBinding.buttonOrderUp.setVisibility(View.INVISIBLE);
|
|
||||||
composeAttachmentItemBinding.buttonOrderDown.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
int finalMediaPosition = mediaPosition;
|
|
||||||
composeAttachmentItemBinding.editPreview.setOnClickListener(v -> {
|
|
||||||
Intent intent = new Intent(context, EditImageActivity.class);
|
|
||||||
Bundle b = new Bundle();
|
|
||||||
intent.putExtra("imageUri", attachment.local_path);
|
|
||||||
intent.putExtras(b);
|
|
||||||
context.startActivity(intent);
|
|
||||||
});
|
|
||||||
composeAttachmentItemBinding.buttonDescription.setOnClickListener(v -> {
|
|
||||||
AlertDialog.Builder builderInner = new AlertDialog.Builder(context, Helper.dialogStyle());
|
|
||||||
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())
|
|
||||||
.asBitmap()
|
|
||||||
.load(attachmentPath)
|
|
||||||
.into(new CustomTarget<Bitmap>() {
|
|
||||||
@Override
|
|
||||||
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
|
||||||
popupMediaDescriptionBinding.mediaPicture.setImageBitmap(resource);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLoadCleared(@Nullable Drawable placeholder) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
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, position, finalMediaPosition);
|
|
||||||
dialog.dismiss();
|
|
||||||
});
|
|
||||||
AlertDialog alertDialog = builderInner.create();
|
|
||||||
Objects.requireNonNull(alertDialog.getWindow()).setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
|
||||||
alertDialog.show();
|
|
||||||
popupMediaDescriptionBinding.mediaDescription.requestFocus();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
composeAttachmentItemBinding.buttonOrderUp.setOnClickListener(v -> {
|
|
||||||
if (finalMediaPosition > 0 && attachmentList.size() > 1) {
|
|
||||||
Attachment at1 = attachmentList.get(finalMediaPosition);
|
|
||||||
Attachment at2 = attachmentList.get(finalMediaPosition - 1);
|
|
||||||
attachmentList.set(finalMediaPosition - 1, at1);
|
|
||||||
attachmentList.set(finalMediaPosition, at2);
|
|
||||||
displayAttachments(holder, position, finalMediaPosition - 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
composeAttachmentItemBinding.buttonOrderDown.setOnClickListener(v -> {
|
|
||||||
if (finalMediaPosition < (attachmentList.size() - 1) && attachmentList.size() > 1) {
|
|
||||||
Attachment at1 = attachmentList.get(finalMediaPosition);
|
|
||||||
Attachment at2 = attachmentList.get(finalMediaPosition + 1);
|
|
||||||
attachmentList.set(finalMediaPosition, at2);
|
|
||||||
attachmentList.set(finalMediaPosition + 1, at1);
|
|
||||||
displayAttachments(holder, position, finalMediaPosition + 1);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
composeAttachmentItemBinding.buttonRemove.setOnClickListener(v -> {
|
|
||||||
AlertDialog.Builder builderInner = new AlertDialog.Builder(context, Helper.dialogStyle());
|
|
||||||
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
|
||||||
builderInner.setPositiveButton(R.string.delete, (dialog, which) -> {
|
|
||||||
attachmentList.remove(attachment);
|
|
||||||
displayAttachments(holder, position, finalMediaPosition);
|
|
||||||
new Thread(() -> {
|
|
||||||
if (attachment.local_path != null) {
|
|
||||||
File fileToDelete = new File(attachment.local_path);
|
|
||||||
if (fileToDelete.exists()) {
|
|
||||||
//noinspection ResultOfMethodCallIgnored
|
|
||||||
fileToDelete.delete();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
|
|
||||||
});
|
|
||||||
builderInner.setMessage(R.string.toot_delete_media);
|
|
||||||
builderInner.show();
|
|
||||||
});
|
|
||||||
composeAttachmentItemBinding.preview.setOnClickListener(v -> displayAttachments(holder, position, finalMediaPosition));
|
|
||||||
if (attachment.description == null || attachment.description.trim().isEmpty()) {
|
|
||||||
composeAttachmentItemBinding.buttonDescription.setIconResource(R.drawable.ic_baseline_warning_24);
|
|
||||||
composeAttachmentItemBinding.buttonDescription.setStrokeColor(ThemeHelper.getNoDescriptionColorStateList(context));
|
|
||||||
composeAttachmentItemBinding.buttonDescription.setTextColor(ContextCompat.getColor(context, R.color.no_description));
|
|
||||||
Helper.changeDrawableColor(context, R.drawable.ic_baseline_warning_24, ContextCompat.getColor(context, R.color.no_description));
|
|
||||||
composeAttachmentItemBinding.buttonDescription.setIconTint(ThemeHelper.getNoDescriptionColorStateList(context));
|
|
||||||
} else {
|
|
||||||
composeAttachmentItemBinding.buttonDescription.setIconTint(ThemeHelper.getHavingDescriptionColorStateList(context));
|
|
||||||
composeAttachmentItemBinding.buttonDescription.setIconResource(R.drawable.ic_baseline_check_circle_24);
|
|
||||||
composeAttachmentItemBinding.buttonDescription.setTextColor(ContextCompat.getColor(context, R.color.having_description));
|
|
||||||
composeAttachmentItemBinding.buttonDescription.setStrokeColor(ThemeHelper.getHavingDescriptionColorStateList(context));
|
|
||||||
Helper.changeDrawableColor(context, R.drawable.ic_baseline_check_circle_24, ContextCompat.getColor(context, R.color.having_description));
|
|
||||||
}
|
|
||||||
holder.binding.attachmentsList.addView(composeAttachmentItemBinding.getRoot());
|
|
||||||
mediaPosition++;
|
|
||||||
}
|
|
||||||
holder.binding.attachmentsList.setVisibility(View.VISIBLE);
|
|
||||||
if (scrollToMediaPosition >= 0 && holder.binding.attachmentsList.getChildCount() < scrollToMediaPosition) {
|
|
||||||
holder.binding.attachmentsList.requestChildFocus(holder.binding.attachmentsList.getChildAt(scrollToMediaPosition), holder.binding.attachmentsList.getChildAt(scrollToMediaPosition));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
holder.binding.attachmentsList.setVisibility(View.GONE);
|
|
||||||
holder.binding.sensitiveMedia.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
holder.binding.attachmentsList.setVisibility(View.GONE);
|
|
||||||
holder.binding.sensitiveMedia.setVisibility(View.GONE);
|
|
||||||
}
|
|
||||||
buttonState(holder);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manage state of media and poll button
|
|
||||||
*
|
|
||||||
* @param holder ComposeViewHolder
|
|
||||||
*/
|
|
||||||
private void buttonState(ComposeViewHolder holder) {
|
|
||||||
if (BaseMainActivity.software == null || BaseMainActivity.software.toUpperCase().compareTo("MASTODON") == 0) {
|
|
||||||
if (holder.getBindingAdapterPosition() > 0) {
|
|
||||||
Status statusDraft = statusList.get(holder.getBindingAdapterPosition());
|
|
||||||
if (statusDraft.poll == null) {
|
|
||||||
holder.binding.buttonAttachImage.setEnabled(true);
|
|
||||||
holder.binding.buttonAttachVideo.setEnabled(true);
|
|
||||||
holder.binding.buttonAttachAudio.setEnabled(true);
|
|
||||||
holder.binding.buttonAttachManual.setEnabled(true);
|
|
||||||
} else {
|
|
||||||
holder.binding.buttonAttachImage.setEnabled(false);
|
|
||||||
holder.binding.buttonAttachVideo.setEnabled(false);
|
|
||||||
holder.binding.buttonAttachAudio.setEnabled(false);
|
|
||||||
holder.binding.buttonAttachManual.setEnabled(false);
|
|
||||||
holder.binding.buttonPoll.setEnabled(true);
|
|
||||||
}
|
|
||||||
holder.binding.buttonPoll.setEnabled(statusDraft.media_attachments == null || statusDraft.media_attachments.size() <= 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return position;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int getItemCount() {
|
|
||||||
return statusList.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize text watcher for content writing
|
* Initialize text watcher for content writing
|
||||||
* It will allow to complete autocomplete edit text while starting words with @, #, : etc.
|
* It will allow to complete autocomplete edit text while starting words with @, #, : etc.
|
||||||
|
@ -747,6 +451,9 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
int currentLength = MastodonHelper.countLength(holder);
|
int currentLength = MastodonHelper.countLength(holder);
|
||||||
|
if (promptDraftListener != null) {
|
||||||
|
promptDraftListener.promptDraft();
|
||||||
|
}
|
||||||
statusList.get(holder.getLayoutPosition()).cursorPosition = holder.binding.content.getSelectionStart();
|
statusList.get(holder.getLayoutPosition()).cursorPosition = holder.binding.content.getSelectionStart();
|
||||||
//Copy/past
|
//Copy/past
|
||||||
int max_car = MastodonHelper.getInstanceMaxChars(context);
|
int max_car = MastodonHelper.getInstanceMaxChars(context);
|
||||||
|
@ -1060,6 +767,306 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||||
return textw;
|
return textw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a shared element
|
||||||
|
* If title and description are empty, it will use subject and content coming from the intent
|
||||||
|
*
|
||||||
|
* @param url - String url that is shared
|
||||||
|
* @param title - String title gather from the URL
|
||||||
|
* @param description - String description gathered from the URL
|
||||||
|
* @param subject - String subject (title) comming from the shared elements
|
||||||
|
* @param content - String content (description) coming from the shared elements
|
||||||
|
*/
|
||||||
|
public void addSharing(String url, String title, String description, String subject, String content, String saveFilePath) {
|
||||||
|
|
||||||
|
if (description == null && content == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int position = statusList.size() - 1;
|
||||||
|
statusList.get(position).text = "";
|
||||||
|
if (title != null && title.trim().length() > 0) {
|
||||||
|
statusList.get(position).text += title + "\n\n";
|
||||||
|
} else if (subject != null && subject.trim().length() > 0) {
|
||||||
|
statusList.get(position).text += subject + "\n\n";
|
||||||
|
}
|
||||||
|
if (description != null && description.trim().length() > 0) {
|
||||||
|
statusList.get(position).text += description + "\n\n";
|
||||||
|
if (url != null && !description.contains(url)) {
|
||||||
|
statusList.get(position).text += url;
|
||||||
|
}
|
||||||
|
} else if (content != null && content.trim().length() > 0) {
|
||||||
|
statusList.get(position).text += content + "\n\n";
|
||||||
|
if (!content.contains(url)) {
|
||||||
|
statusList.get(position).text += url;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
statusList.get(position).text += url;
|
||||||
|
}
|
||||||
|
if (saveFilePath != null) {
|
||||||
|
Attachment attachment = new Attachment();
|
||||||
|
attachment.mimeType = "image/*";
|
||||||
|
String extension = "jpg";
|
||||||
|
SimpleDateFormat formatter = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_", Locale.getDefault());
|
||||||
|
attachment.local_path = saveFilePath;
|
||||||
|
Date now = new Date();
|
||||||
|
attachment.filename = formatter.format(now) + "." + extension;
|
||||||
|
if (statusList.get(position).media_attachments == null) {
|
||||||
|
statusList.get(position).media_attachments = new ArrayList<>();
|
||||||
|
}
|
||||||
|
statusList.get(position).media_attachments.add(attachment);
|
||||||
|
}
|
||||||
|
notifyItemChanged(position);
|
||||||
|
}
|
||||||
|
|
||||||
|
//<------ Manage contact from compose activity
|
||||||
|
//It only targets last message in a thread
|
||||||
|
//Return content of last compose message
|
||||||
|
public String getLastComposeContent() {
|
||||||
|
return statusList.get(statusList.size() - 1).text != null ? statusList.get(statusList.size() - 1).text : "";
|
||||||
|
}
|
||||||
|
//------- end contact ----->
|
||||||
|
|
||||||
|
//Used to write contact when composing
|
||||||
|
public void updateContent(boolean checked, String acct) {
|
||||||
|
if (checked) {
|
||||||
|
if (!statusList.get(statusList.size() - 1).text.contains(acct))
|
||||||
|
statusList.get(statusList.size() - 1).text = String.format("%s %s", acct, statusList.get(statusList.size() - 1).text);
|
||||||
|
} else {
|
||||||
|
statusList.get(statusList.size() - 1).text = statusList.get(statusList.size() - 1).text.replaceAll("\\s*" + acct, "");
|
||||||
|
}
|
||||||
|
notifyItemChanged(statusList.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//Put cursor to the end after changing contacts
|
||||||
|
public void putCursor() {
|
||||||
|
statusList.get(statusList.size() - 1).setCursorToEnd = true;
|
||||||
|
notifyItemChanged(statusList.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display attachment for a holder
|
||||||
|
*
|
||||||
|
* @param holder - view related to a compose element {@link ComposeViewHolder}
|
||||||
|
* @param position - int position of the message in the thread
|
||||||
|
* @param scrollToMediaPosition - int the position to scroll to media
|
||||||
|
*/
|
||||||
|
private void displayAttachments(ComposeViewHolder holder, int position, int scrollToMediaPosition) {
|
||||||
|
if (statusList.size() > position && statusList.get(position).media_attachments != null) {
|
||||||
|
holder.binding.attachmentsList.removeAllViews();
|
||||||
|
List<Attachment> attachmentList = statusList.get(position).media_attachments;
|
||||||
|
if (attachmentList != null && attachmentList.size() > 0) {
|
||||||
|
holder.binding.sensitiveMedia.setVisibility(View.VISIBLE);
|
||||||
|
if (!statusList.get(position).sensitive) {
|
||||||
|
if (currentAccount != null && currentAccount.mastodon_account != null && currentAccount.mastodon_account.source != null) {
|
||||||
|
holder.binding.sensitiveMedia.setChecked(currentAccount.mastodon_account.source.sensitive);
|
||||||
|
statusList.get(position).sensitive = currentAccount.mastodon_account.source.sensitive;
|
||||||
|
} else {
|
||||||
|
statusList.get(position).sensitive = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
holder.binding.sensitiveMedia.setOnCheckedChangeListener((buttonView, isChecked) -> statusList.get(position).sensitive = isChecked);
|
||||||
|
int mediaPosition = 0;
|
||||||
|
for (Attachment attachment : attachmentList) {
|
||||||
|
ComposeAttachmentItemBinding composeAttachmentItemBinding = ComposeAttachmentItemBinding.inflate(LayoutInflater.from(context), holder.binding.attachmentsList, false);
|
||||||
|
composeAttachmentItemBinding.buttonPlay.setVisibility(View.GONE);
|
||||||
|
String attachmentPath = attachment.local_path != null && !attachment.local_path.trim().isEmpty() ? attachment.local_path : attachment.preview_url;
|
||||||
|
if (attachment.type != null || attachment.mimeType != null) {
|
||||||
|
if ((attachment.type != null && attachment.type.toLowerCase().startsWith("image")) || (attachment.mimeType != null && attachment.mimeType.toLowerCase().startsWith("image"))) {
|
||||||
|
Glide.with(composeAttachmentItemBinding.preview.getContext())
|
||||||
|
.load(attachmentPath)
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||||
|
.skipMemoryCache(true)
|
||||||
|
.into(composeAttachmentItemBinding.preview);
|
||||||
|
} else if ((attachment.type != null && attachment.type.toLowerCase().startsWith("video")) || (attachment.mimeType != null && attachment.mimeType.toLowerCase().startsWith("video"))) {
|
||||||
|
composeAttachmentItemBinding.buttonPlay.setVisibility(View.VISIBLE);
|
||||||
|
long interval = 2000;
|
||||||
|
RequestOptions options = new RequestOptions().frame(interval);
|
||||||
|
Glide.with(composeAttachmentItemBinding.preview.getContext()).asBitmap()
|
||||||
|
.load(attachmentPath)
|
||||||
|
.apply(options)
|
||||||
|
.into(composeAttachmentItemBinding.preview);
|
||||||
|
} else if ((attachment.type != null && attachment.type.toLowerCase().startsWith("audio")) || (attachment.mimeType != null && attachment.mimeType.toLowerCase().startsWith("audio"))) {
|
||||||
|
Glide.with(composeAttachmentItemBinding.preview.getContext())
|
||||||
|
.load(R.drawable.ic_baseline_audio_file_24)
|
||||||
|
.into(composeAttachmentItemBinding.preview);
|
||||||
|
} else {
|
||||||
|
Glide.with(composeAttachmentItemBinding.preview.getContext())
|
||||||
|
.load(R.drawable.ic_baseline_insert_drive_file_24)
|
||||||
|
.into(composeAttachmentItemBinding.preview);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Glide.with(composeAttachmentItemBinding.preview.getContext())
|
||||||
|
.load(R.drawable.ic_baseline_insert_drive_file_24)
|
||||||
|
.into(composeAttachmentItemBinding.preview);
|
||||||
|
}
|
||||||
|
if (mediaPosition == 0) {
|
||||||
|
composeAttachmentItemBinding.buttonOrderUp.setVisibility(View.INVISIBLE);
|
||||||
|
} else {
|
||||||
|
composeAttachmentItemBinding.buttonOrderUp.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
if (mediaPosition == attachmentList.size() - 1) {
|
||||||
|
composeAttachmentItemBinding.buttonOrderDown.setVisibility(View.INVISIBLE);
|
||||||
|
} else {
|
||||||
|
composeAttachmentItemBinding.buttonOrderDown.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
//Remote attachments when deleting/redrafting can't be ordered
|
||||||
|
if (attachment.local_path == null) {
|
||||||
|
composeAttachmentItemBinding.buttonOrderUp.setVisibility(View.INVISIBLE);
|
||||||
|
composeAttachmentItemBinding.buttonOrderDown.setVisibility(View.INVISIBLE);
|
||||||
|
}
|
||||||
|
int finalMediaPosition = mediaPosition;
|
||||||
|
composeAttachmentItemBinding.editPreview.setOnClickListener(v -> {
|
||||||
|
Intent intent = new Intent(context, EditImageActivity.class);
|
||||||
|
Bundle b = new Bundle();
|
||||||
|
intent.putExtra("imageUri", attachment.local_path);
|
||||||
|
intent.putExtras(b);
|
||||||
|
context.startActivity(intent);
|
||||||
|
});
|
||||||
|
composeAttachmentItemBinding.buttonDescription.setOnClickListener(v -> {
|
||||||
|
AlertDialog.Builder builderInner = new AlertDialog.Builder(context, Helper.dialogStyle());
|
||||||
|
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())
|
||||||
|
.asBitmap()
|
||||||
|
.load(attachmentPath)
|
||||||
|
.into(new CustomTarget<Bitmap>() {
|
||||||
|
@Override
|
||||||
|
public void onResourceReady(@NonNull Bitmap resource, Transition<? super Bitmap> transition) {
|
||||||
|
popupMediaDescriptionBinding.mediaPicture.setImageBitmap(resource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoadCleared(@Nullable Drawable placeholder) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
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, position, finalMediaPosition);
|
||||||
|
dialog.dismiss();
|
||||||
|
});
|
||||||
|
AlertDialog alertDialog = builderInner.create();
|
||||||
|
Objects.requireNonNull(alertDialog.getWindow()).setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
|
||||||
|
alertDialog.show();
|
||||||
|
popupMediaDescriptionBinding.mediaDescription.requestFocus();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
composeAttachmentItemBinding.buttonOrderUp.setOnClickListener(v -> {
|
||||||
|
if (finalMediaPosition > 0 && attachmentList.size() > 1) {
|
||||||
|
Attachment at1 = attachmentList.get(finalMediaPosition);
|
||||||
|
Attachment at2 = attachmentList.get(finalMediaPosition - 1);
|
||||||
|
attachmentList.set(finalMediaPosition - 1, at1);
|
||||||
|
attachmentList.set(finalMediaPosition, at2);
|
||||||
|
displayAttachments(holder, position, finalMediaPosition - 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
composeAttachmentItemBinding.buttonOrderDown.setOnClickListener(v -> {
|
||||||
|
if (finalMediaPosition < (attachmentList.size() - 1) && attachmentList.size() > 1) {
|
||||||
|
Attachment at1 = attachmentList.get(finalMediaPosition);
|
||||||
|
Attachment at2 = attachmentList.get(finalMediaPosition + 1);
|
||||||
|
attachmentList.set(finalMediaPosition, at2);
|
||||||
|
attachmentList.set(finalMediaPosition + 1, at1);
|
||||||
|
displayAttachments(holder, position, finalMediaPosition + 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
composeAttachmentItemBinding.buttonRemove.setOnClickListener(v -> {
|
||||||
|
AlertDialog.Builder builderInner = new AlertDialog.Builder(context, Helper.dialogStyle());
|
||||||
|
builderInner.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||||
|
builderInner.setPositiveButton(R.string.delete, (dialog, which) -> {
|
||||||
|
attachmentList.remove(attachment);
|
||||||
|
displayAttachments(holder, position, finalMediaPosition);
|
||||||
|
new Thread(() -> {
|
||||||
|
if (attachment.local_path != null) {
|
||||||
|
File fileToDelete = new File(attachment.local_path);
|
||||||
|
if (fileToDelete.exists()) {
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
fileToDelete.delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).start();
|
||||||
|
|
||||||
|
});
|
||||||
|
builderInner.setMessage(R.string.toot_delete_media);
|
||||||
|
builderInner.show();
|
||||||
|
});
|
||||||
|
composeAttachmentItemBinding.preview.setOnClickListener(v -> displayAttachments(holder, position, finalMediaPosition));
|
||||||
|
if (attachment.description == null || attachment.description.trim().isEmpty()) {
|
||||||
|
composeAttachmentItemBinding.buttonDescription.setIconResource(R.drawable.ic_baseline_warning_24);
|
||||||
|
composeAttachmentItemBinding.buttonDescription.setStrokeColor(ThemeHelper.getNoDescriptionColorStateList(context));
|
||||||
|
composeAttachmentItemBinding.buttonDescription.setTextColor(ContextCompat.getColor(context, R.color.no_description));
|
||||||
|
Helper.changeDrawableColor(context, R.drawable.ic_baseline_warning_24, ContextCompat.getColor(context, R.color.no_description));
|
||||||
|
composeAttachmentItemBinding.buttonDescription.setIconTint(ThemeHelper.getNoDescriptionColorStateList(context));
|
||||||
|
} else {
|
||||||
|
composeAttachmentItemBinding.buttonDescription.setIconTint(ThemeHelper.getHavingDescriptionColorStateList(context));
|
||||||
|
composeAttachmentItemBinding.buttonDescription.setIconResource(R.drawable.ic_baseline_check_circle_24);
|
||||||
|
composeAttachmentItemBinding.buttonDescription.setTextColor(ContextCompat.getColor(context, R.color.having_description));
|
||||||
|
composeAttachmentItemBinding.buttonDescription.setStrokeColor(ThemeHelper.getHavingDescriptionColorStateList(context));
|
||||||
|
Helper.changeDrawableColor(context, R.drawable.ic_baseline_check_circle_24, ContextCompat.getColor(context, R.color.having_description));
|
||||||
|
}
|
||||||
|
holder.binding.attachmentsList.addView(composeAttachmentItemBinding.getRoot());
|
||||||
|
mediaPosition++;
|
||||||
|
}
|
||||||
|
holder.binding.attachmentsList.setVisibility(View.VISIBLE);
|
||||||
|
if (scrollToMediaPosition >= 0 && holder.binding.attachmentsList.getChildCount() < scrollToMediaPosition) {
|
||||||
|
holder.binding.attachmentsList.requestChildFocus(holder.binding.attachmentsList.getChildAt(scrollToMediaPosition), holder.binding.attachmentsList.getChildAt(scrollToMediaPosition));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
holder.binding.attachmentsList.setVisibility(View.GONE);
|
||||||
|
holder.binding.sensitiveMedia.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
holder.binding.attachmentsList.setVisibility(View.GONE);
|
||||||
|
holder.binding.sensitiveMedia.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
buttonState(holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage state of media and poll button
|
||||||
|
*
|
||||||
|
* @param holder ComposeViewHolder
|
||||||
|
*/
|
||||||
|
private void buttonState(ComposeViewHolder holder) {
|
||||||
|
if (BaseMainActivity.software == null || BaseMainActivity.software.toUpperCase().compareTo("MASTODON") == 0) {
|
||||||
|
if (holder.getBindingAdapterPosition() > 0) {
|
||||||
|
Status statusDraft = statusList.get(holder.getBindingAdapterPosition());
|
||||||
|
if (statusDraft.poll == null) {
|
||||||
|
holder.binding.buttonAttachImage.setEnabled(true);
|
||||||
|
holder.binding.buttonAttachVideo.setEnabled(true);
|
||||||
|
holder.binding.buttonAttachAudio.setEnabled(true);
|
||||||
|
holder.binding.buttonAttachManual.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
holder.binding.buttonAttachImage.setEnabled(false);
|
||||||
|
holder.binding.buttonAttachVideo.setEnabled(false);
|
||||||
|
holder.binding.buttonAttachAudio.setEnabled(false);
|
||||||
|
holder.binding.buttonAttachManual.setEnabled(false);
|
||||||
|
holder.binding.buttonPoll.setEnabled(true);
|
||||||
|
}
|
||||||
|
holder.binding.buttonPoll.setEnabled(statusDraft.media_attachments == null || statusDraft.media_attachments.size() <= 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getItemId(int position) {
|
||||||
|
return position;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return statusList.size();
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("ClickableViewAccessibility")
|
@SuppressLint("ClickableViewAccessibility")
|
||||||
@Override
|
@Override
|
||||||
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position) {
|
||||||
|
@ -1339,6 +1346,9 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterTextChanged(Editable s) {
|
public void afterTextChanged(Editable s) {
|
||||||
|
if (promptDraftListener != null) {
|
||||||
|
promptDraftListener.promptDraft();
|
||||||
|
}
|
||||||
int currentLength = MastodonHelper.countLength(holder);
|
int currentLength = MastodonHelper.countLength(holder);
|
||||||
int max_car = MastodonHelper.getInstanceMaxChars(context);
|
int max_car = MastodonHelper.getInstanceMaxChars(context);
|
||||||
if (currentLength > max_car) {
|
if (currentLength > max_car) {
|
||||||
|
@ -1440,40 +1450,6 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Display the emoji picker in the current message
|
|
||||||
*
|
|
||||||
* @param holder - view for the message {@link ComposeViewHolder}
|
|
||||||
* @throws DBException
|
|
||||||
*/
|
|
||||||
private void displayEmojiPicker(ComposeViewHolder holder) throws DBException {
|
|
||||||
|
|
||||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context, Helper.dialogStyle());
|
|
||||||
int paddingPixel = 15;
|
|
||||||
float density = context.getResources().getDisplayMetrics().density;
|
|
||||||
int paddingDp = (int) (paddingPixel * density);
|
|
||||||
builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
|
||||||
builder.setTitle(R.string.insert_emoji);
|
|
||||||
if (emojis != null && emojis.size() > 0) {
|
|
||||||
GridView gridView = new GridView(context);
|
|
||||||
gridView.setAdapter(new EmojiAdapter(emojis.get(BaseMainActivity.currentInstance)));
|
|
||||||
gridView.setNumColumns(5);
|
|
||||||
gridView.setOnItemClickListener((parent, view, position, id) -> {
|
|
||||||
holder.binding.content.getText().insert(holder.binding.content.getSelectionStart(), " :" + emojis.get(BaseMainActivity.currentInstance).get(position).shortcode + ": ");
|
|
||||||
alertDialogEmoji.dismiss();
|
|
||||||
});
|
|
||||||
gridView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);
|
|
||||||
builder.setView(gridView);
|
|
||||||
} else {
|
|
||||||
TextView textView = new TextView(context);
|
|
||||||
textView.setText(context.getString(R.string.no_emoji));
|
|
||||||
textView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);
|
|
||||||
builder.setView(textView);
|
|
||||||
}
|
|
||||||
alertDialogEmoji = builder.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Display the popup to attach a poll to message
|
* Display the popup to attach a poll to message
|
||||||
*
|
*
|
||||||
|
@ -1655,7 +1631,9 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||||
expire = 864000;
|
expire = 864000;
|
||||||
}
|
}
|
||||||
statusDraft.poll.expire_in = expire;
|
statusDraft.poll.expire_in = expire;
|
||||||
|
if (promptDraftListener != null) {
|
||||||
|
promptDraftListener.promptDraft();
|
||||||
|
}
|
||||||
List<Poll.PollItem> pollItems = new ArrayList<>();
|
List<Poll.PollItem> pollItems = new ArrayList<>();
|
||||||
int childCount = composePollBinding.optionsList.getChildCount();
|
int childCount = composePollBinding.optionsList.getChildCount();
|
||||||
for (int i = 0; i < childCount; i++) {
|
for (int i = 0; i < childCount; i++) {
|
||||||
|
@ -1689,6 +1667,44 @@ public class ComposeAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder
|
||||||
alertPollDiaslog.show();
|
alertPollDiaslog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the emoji picker in the current message
|
||||||
|
*
|
||||||
|
* @param holder - view for the message {@link ComposeViewHolder}
|
||||||
|
* @throws DBException
|
||||||
|
*/
|
||||||
|
private void displayEmojiPicker(ComposeViewHolder holder) throws DBException {
|
||||||
|
|
||||||
|
final AlertDialog.Builder builder = new AlertDialog.Builder(context, Helper.dialogStyle());
|
||||||
|
int paddingPixel = 15;
|
||||||
|
float density = context.getResources().getDisplayMetrics().density;
|
||||||
|
int paddingDp = (int) (paddingPixel * density);
|
||||||
|
builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||||
|
builder.setTitle(R.string.insert_emoji);
|
||||||
|
if (emojis != null && emojis.size() > 0) {
|
||||||
|
GridView gridView = new GridView(context);
|
||||||
|
gridView.setAdapter(new EmojiAdapter(emojis.get(BaseMainActivity.currentInstance)));
|
||||||
|
gridView.setNumColumns(5);
|
||||||
|
gridView.setOnItemClickListener((parent, view, position, id) -> {
|
||||||
|
holder.binding.content.getText().insert(holder.binding.content.getSelectionStart(), " :" + emojis.get(BaseMainActivity.currentInstance).get(position).shortcode + ": ");
|
||||||
|
alertDialogEmoji.dismiss();
|
||||||
|
});
|
||||||
|
gridView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);
|
||||||
|
builder.setView(gridView);
|
||||||
|
} else {
|
||||||
|
TextView textView = new TextView(context);
|
||||||
|
textView.setText(context.getString(R.string.no_emoji));
|
||||||
|
textView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);
|
||||||
|
builder.setView(textView);
|
||||||
|
}
|
||||||
|
alertDialogEmoji = builder.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface promptDraftListener {
|
||||||
|
void promptDraft();
|
||||||
|
}
|
||||||
|
|
||||||
public interface ManageDrafts {
|
public interface ManageDrafts {
|
||||||
void onItemDraftAdded(int position);
|
void onItemDraftAdded(int position);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue