Adds a link to the text of a post when media is attached.
This commit is contained in:
parent
bd687fb45d
commit
f313884f7d
@ -54,7 +54,10 @@ import android.support.v7.app.ActionBar;
|
|||||||
import android.support.v7.content.res.AppCompatResources;
|
import android.support.v7.content.res.AppCompatResources;
|
||||||
import android.support.v7.widget.Toolbar;
|
import android.support.v7.widget.Toolbar;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.text.Spanned;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
|
import android.text.style.URLSpan;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.webkit.MimeTypeMap;
|
import android.webkit.MimeTypeMap;
|
||||||
@ -90,6 +93,7 @@ import okhttp3.MultipartBody;
|
|||||||
import okhttp3.RequestBody;
|
import okhttp3.RequestBody;
|
||||||
import retrofit2.Call;
|
import retrofit2.Call;
|
||||||
import retrofit2.Callback;
|
import retrofit2.Callback;
|
||||||
|
import retrofit2.Response;
|
||||||
|
|
||||||
public class ComposeActivity extends BaseActivity implements ComposeOptionsFragment.Listener {
|
public class ComposeActivity extends BaseActivity implements ComposeOptionsFragment.Listener {
|
||||||
private static final String TAG = "ComposeActivity"; // logging tag
|
private static final String TAG = "ComposeActivity"; // logging tag
|
||||||
@ -143,6 +147,7 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
Uri uri;
|
Uri uri;
|
||||||
String id;
|
String id;
|
||||||
Call<Media> uploadRequest;
|
Call<Media> uploadRequest;
|
||||||
|
URLSpan uploadUrl;
|
||||||
ReadyStage readyStage;
|
ReadyStage readyStage;
|
||||||
byte[] content;
|
byte[] content;
|
||||||
long mediaSize;
|
long mediaSize;
|
||||||
@ -224,7 +229,7 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
floatingBtn.setOnClickListener(new View.OnClickListener() {
|
floatingBtn.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
prepareStatus();
|
onSendClicked();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
pickBtn.setOnClickListener(new View.OnClickListener() {
|
pickBtn.setOnClickListener(new View.OnClickListener() {
|
||||||
@ -584,24 +589,12 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
enableButtons();
|
enableButtons();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void prepareStatus() {
|
private void onSendClicked() {
|
||||||
if (statusAlreadyInFlight) {
|
if (statusAlreadyInFlight) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String contentText = textEditor.getText().toString();
|
|
||||||
String spoilerText = "";
|
|
||||||
if (statusHideText) {
|
|
||||||
spoilerText = contentWarningEditor.getText().toString();
|
|
||||||
}
|
|
||||||
int characterCount = contentText.length() + spoilerText.length();
|
|
||||||
if (characterCount > 0 && characterCount <= STATUS_CHARACTER_LIMIT) {
|
|
||||||
setStateToReadying();
|
setStateToReadying();
|
||||||
readyStatus(contentText, statusVisibility, statusMarkSensitive, spoilerText);
|
readyStatus(statusVisibility, statusMarkSensitive);
|
||||||
} else if (characterCount <= 0) {
|
|
||||||
textEditor.setError(getString(R.string.error_empty));
|
|
||||||
} else {
|
|
||||||
textEditor.setError(getString(R.string.error_compose_character_limit));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -705,7 +698,7 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
|
|
||||||
mastodonAPI.createStatus(content, inReplyToId, spoilerText, visibility, sensitive, mediaIds).enqueue(new Callback<Status>() {
|
mastodonAPI.createStatus(content, inReplyToId, spoilerText, visibility, sensitive, mediaIds).enqueue(new Callback<Status>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<Status> call, retrofit2.Response<Status> response) {
|
public void onResponse(Call<Status> call, Response<Status> response) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
onSendSuccess();
|
onSendSuccess();
|
||||||
} else {
|
} else {
|
||||||
@ -732,8 +725,7 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
setStateToNotReadying();
|
setStateToNotReadying();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readyStatus(final String content, final String visibility, final boolean sensitive,
|
private void readyStatus(final String visibility, final boolean sensitive) {
|
||||||
final String spoilerText) {
|
|
||||||
finishingUploadDialog = ProgressDialog.show(
|
finishingUploadDialog = ProgressDialog.show(
|
||||||
this, getString(R.string.dialog_title_finishing_media_upload),
|
this, getString(R.string.dialog_title_finishing_media_upload),
|
||||||
getString(R.string.dialog_message_uploading_media), true, true);
|
getString(R.string.dialog_message_uploading_media), true, true);
|
||||||
@ -755,9 +747,9 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
finishingUploadDialog.dismiss();
|
finishingUploadDialog.dismiss();
|
||||||
finishingUploadDialog = null;
|
finishingUploadDialog = null;
|
||||||
if (successful) {
|
if (successful) {
|
||||||
sendStatus(content, visibility, sensitive, spoilerText);
|
onReadySuccess(visibility, sensitive);
|
||||||
} else {
|
} else {
|
||||||
onReadyFailure(content, visibility, sensitive, spoilerText);
|
onReadyFailure(visibility, sensitive);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -780,13 +772,33 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
waitForMediaTask.execute();
|
waitForMediaTask.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onReadyFailure(final String content, final String visibility,
|
private void onReadySuccess(String visibility, boolean sensitive) {
|
||||||
final boolean sensitive, final String spoilerText) {
|
/* Validate the status meets the character limit. This has to be delayed until after all
|
||||||
|
* uploads finish because their links are added when the upload succeeds and that affects
|
||||||
|
* whether the limit is met or not. */
|
||||||
|
String contentText = textEditor.getText().toString();
|
||||||
|
String spoilerText = "";
|
||||||
|
if (statusHideText) {
|
||||||
|
spoilerText = contentWarningEditor.getText().toString();
|
||||||
|
}
|
||||||
|
int characterCount = contentText.length() + spoilerText.length();
|
||||||
|
if (characterCount > 0 && characterCount <= STATUS_CHARACTER_LIMIT) {
|
||||||
|
sendStatus(contentText, visibility, sensitive, spoilerText);
|
||||||
|
} else if (characterCount <= 0) {
|
||||||
|
textEditor.setError(getString(R.string.error_empty));
|
||||||
|
setStateToNotReadying();
|
||||||
|
} else {
|
||||||
|
textEditor.setError(getString(R.string.error_compose_character_limit));
|
||||||
|
setStateToNotReadying();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onReadyFailure(final String visibility, final boolean sensitive) {
|
||||||
doErrorDialog(R.string.error_media_upload_sending, R.string.action_retry,
|
doErrorDialog(R.string.error_media_upload_sending, R.string.action_retry,
|
||||||
new View.OnClickListener() {
|
new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
readyStatus(content, visibility, sensitive, spoilerText);
|
readyStatus(visibility, sensitive);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
setStateToNotReadying();
|
setStateToNotReadying();
|
||||||
@ -951,6 +963,15 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
textEditor.setPadding(textEditor.getPaddingLeft(), textEditor.getPaddingTop(),
|
textEditor.setPadding(textEditor.getPaddingLeft(), textEditor.getPaddingTop(),
|
||||||
textEditor.getPaddingRight(), 0);
|
textEditor.getPaddingRight(), 0);
|
||||||
}
|
}
|
||||||
|
// Remove the text URL associated with this media.
|
||||||
|
if (item.uploadUrl != null) {
|
||||||
|
Editable text = textEditor.getText();
|
||||||
|
int start = text.getSpanStart(item.uploadUrl);
|
||||||
|
int end = text.getSpanEnd(item.uploadUrl);
|
||||||
|
if (start != -1 && end != -1) {
|
||||||
|
text.delete(start, end);
|
||||||
|
}
|
||||||
|
}
|
||||||
enableMediaButtons();
|
enableMediaButtons();
|
||||||
cancelReadyingMedia(item);
|
cancelReadyingMedia(item);
|
||||||
}
|
}
|
||||||
@ -1052,8 +1073,7 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
@Override
|
@Override
|
||||||
public void onResponse(Call<Media> call, retrofit2.Response<Media> response) {
|
public void onResponse(Call<Media> call, retrofit2.Response<Media> response) {
|
||||||
if (response.isSuccessful()) {
|
if (response.isSuccessful()) {
|
||||||
item.id = response.body().id;
|
onUploadSuccess(item, response.body());
|
||||||
waitForMediaLatch.countDown();
|
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "Upload request failed. " + response.message());
|
Log.d(TAG, "Upload request failed. " + response.message());
|
||||||
onUploadFailure(item, call.isCanceled());
|
onUploadFailure(item, call.isCanceled());
|
||||||
@ -1068,6 +1088,22 @@ public class ComposeActivity extends BaseActivity implements ComposeOptionsFrag
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void onUploadSuccess(final QueuedMedia item, Media media) {
|
||||||
|
item.id = media.id;
|
||||||
|
|
||||||
|
/* Add the upload URL to the text field. Also, keep a reference to the span so if the user
|
||||||
|
* chooses to remove the media, the URL is also automatically removed. */
|
||||||
|
item.uploadUrl = new URLSpan(media.textUrl);
|
||||||
|
int end = 1 + media.textUrl.length();
|
||||||
|
SpannableStringBuilder builder = new SpannableStringBuilder();
|
||||||
|
builder.append(' ');
|
||||||
|
builder.append(media.textUrl);
|
||||||
|
builder.setSpan(item.uploadUrl, 0, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
|
textEditor.append(builder);
|
||||||
|
|
||||||
|
waitForMediaLatch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
private void onUploadFailure(QueuedMedia item, boolean isCanceled) {
|
private void onUploadFailure(QueuedMedia item, boolean isCanceled) {
|
||||||
if (!isCanceled) {
|
if (!isCanceled) {
|
||||||
/* if the upload was voluntarily cancelled, such as if the user clicked on it to remove
|
/* if the upload was voluntarily cancelled, such as if the user clicked on it to remove
|
||||||
|
Loading…
x
Reference in New Issue
Block a user