use of com.keylesspalace.tusky.util.CountUpDownLatch in project Tusky by Vavassor.
the class ComposeActivity method onCreate.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_compose);
ButterKnife.bind(this);
// Setup the toolbar.
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(null);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
Drawable closeIcon = AppCompatResources.getDrawable(this, R.drawable.ic_close_24dp);
ThemeUtils.setDrawableTint(this, closeIcon, R.attr.compose_close_button_tint);
actionBar.setHomeAsUpIndicator(closeIcon);
}
// Setup the interface buttons.
floatingBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onSendClicked();
}
});
pickBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onMediaPick();
}
});
takeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
initiateCameraApp();
}
});
nsfwBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toggleNsfw();
}
});
visibilityBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
showComposeOptions();
}
});
/* Initialise all the state, or restore it from a previous run, to determine a "starting"
* state. */
SharedPreferences preferences = getPrivatePreferences();
String startingVisibility;
boolean startingHideText;
String startingContentWarning = null;
ArrayList<SavedQueuedMedia> savedMediaQueued = null;
if (savedInstanceState != null) {
showMarkSensitive = savedInstanceState.getBoolean("showMarkSensitive");
startingVisibility = savedInstanceState.getString("statusVisibility");
statusMarkSensitive = savedInstanceState.getBoolean("statusMarkSensitive");
startingHideText = savedInstanceState.getBoolean("statusHideText");
// Keep these until everything needed to put them in the queue is finished initializing.
savedMediaQueued = savedInstanceState.getParcelableArrayList("savedMediaQueued");
// These are for restoring an in-progress commit content operation.
InputContentInfoCompat previousInputContentInfo = InputContentInfoCompat.wrap(savedInstanceState.getParcelable("commitContentInputContentInfo"));
int previousFlags = savedInstanceState.getInt("commitContentFlags");
if (previousInputContentInfo != null) {
onCommitContentInternal(previousInputContentInfo, previousFlags);
}
} else {
showMarkSensitive = false;
startingVisibility = preferences.getString("rememberedVisibility", "public");
statusMarkSensitive = false;
startingHideText = false;
}
/* If the composer is started up as a reply to another post, override the "starting" state
* based on what the intent from the reply request passes. */
Intent intent = getIntent();
String[] mentionedUsernames = null;
inReplyToId = null;
if (intent != null) {
inReplyToId = intent.getStringExtra("in_reply_to_id");
String replyVisibility = intent.getStringExtra("reply_visibility");
if (replyVisibility != null && startingVisibility != null) {
// Lowest possible visibility setting in response
if (startingVisibility.equals("direct") || replyVisibility.equals("direct")) {
startingVisibility = "direct";
} else if (startingVisibility.equals("private") || replyVisibility.equals("private")) {
startingVisibility = "private";
} else if (startingVisibility.equals("unlisted") || replyVisibility.equals("unlisted")) {
startingVisibility = "unlisted";
} else {
startingVisibility = replyVisibility;
}
}
mentionedUsernames = intent.getStringArrayExtra("mentioned_usernames");
if (inReplyToId != null) {
startingHideText = !intent.getStringExtra("content_warning").equals("");
if (startingHideText) {
startingContentWarning = intent.getStringExtra("content_warning");
}
}
}
/* If the currently logged in account is locked, its posts should default to private. This
* should override even the reply settings, so this must be done after those are set up. */
if (preferences.getBoolean("loggedInAccountLocked", false)) {
startingVisibility = "private";
}
// After the starting state is finalised, the interface can be set to reflect this state.
setStatusVisibility(startingVisibility);
postProgress.setVisibility(View.INVISIBLE);
updateNsfwButtonColor();
final ParserUtils parser = new ParserUtils(this);
// Setup the main text field.
// new String[] { "image/gif", "image/webp" }
setEditTextMimeTypes(null);
final int mentionColour = ThemeUtils.getColor(this, R.attr.compose_mention_color);
SpanUtils.highlightSpans(textEditor.getText(), mentionColour);
textEditor.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
updateVisibleCharactersLeft();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable editable) {
SpanUtils.highlightSpans(editable, mentionColour);
}
});
textEditor.addOnPasteListener(new EditTextTyped.OnPasteListener() {
@Override
public void onPaste() {
parser.getPastedURLText(ComposeActivity.this);
}
});
// Add any mentions to the text field when a reply is first composed.
if (mentionedUsernames != null) {
StringBuilder builder = new StringBuilder();
for (String name : mentionedUsernames) {
builder.append('@');
builder.append(name);
builder.append(' ');
}
textEditor.setText(builder);
textEditor.setSelection(textEditor.length());
}
// Initialise the content warning editor.
contentWarningEditor.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
updateVisibleCharactersLeft();
}
@Override
public void afterTextChanged(Editable s) {
}
});
showContentWarning(startingHideText);
if (startingContentWarning != null) {
contentWarningEditor.setText(startingContentWarning);
}
// Initialise the empty media queue state.
mediaQueued = new ArrayList<>();
waitForMediaLatch = new CountUpDownLatch();
statusAlreadyInFlight = false;
// These can only be added after everything affected by the media queue is initialized.
if (savedMediaQueued != null) {
for (SavedQueuedMedia item : savedMediaQueued) {
addMediaToQueue(item.type, item.preview, item.uri, item.mediaSize);
}
} else if (intent != null && savedInstanceState == null) {
/* Get incoming images being sent through a share action from another app. Only do this
* when savedInstanceState is null, otherwise both the images from the intent and the
* instance state will be re-queued. */
String type = intent.getType();
if (type != null) {
if (type.startsWith("image/")) {
List<Uri> uriList = new ArrayList<>();
switch(intent.getAction()) {
case Intent.ACTION_SEND:
{
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (uri != null) {
uriList.add(uri);
}
break;
}
case Intent.ACTION_SEND_MULTIPLE:
{
ArrayList<Uri> list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (list != null) {
for (Uri uri : list) {
if (uri != null) {
uriList.add(uri);
}
}
}
break;
}
}
for (Uri uri : uriList) {
long mediaSize = getMediaSize(getContentResolver(), uri);
pickMedia(uri, mediaSize);
}
} else if (type.equals("text/plain")) {
String action = intent.getAction();
if (action != null && action.equals(Intent.ACTION_SEND)) {
String text = intent.getStringExtra(Intent.EXTRA_TEXT);
if (text != null) {
int start = Math.max(textEditor.getSelectionStart(), 0);
int end = Math.max(textEditor.getSelectionEnd(), 0);
int left = Math.min(start, end);
int right = Math.max(start, end);
textEditor.getText().replace(left, right, text, 0, text.length());
parser.putInClipboardManager(this, text);
textEditor.onPaste();
}
}
}
}
}
}
use of com.keylesspalace.tusky.util.CountUpDownLatch in project Tusky by tuskyapp.
the class ComposeActivity method onCreate.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_compose);
replyTextView = findViewById(R.id.reply_tv);
replyContentTextView = findViewById(R.id.reply_content_tv);
textEditor = findViewById(R.id.compose_edit_field);
mediaPreviewBar = findViewById(R.id.compose_media_preview_bar);
contentWarningBar = findViewById(R.id.compose_content_warning_bar);
contentWarningEditor = findViewById(R.id.field_content_warning);
charactersLeft = findViewById(R.id.characters_left);
floatingBtn = findViewById(R.id.floating_btn);
pickButton = findViewById(R.id.compose_photo_pick);
visibilityBtn = findViewById(R.id.action_toggle_visibility);
saveButton = findViewById(R.id.compose_save_draft);
hideMediaToggle = findViewById(R.id.action_hide_media);
postProgress = findViewById(R.id.postProgress);
// Setup the toolbar.
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setTitle(null);
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setDisplayShowHomeEnabled(true);
Drawable closeIcon = AppCompatResources.getDrawable(this, R.drawable.ic_close_24dp);
ThemeUtils.setDrawableTint(this, closeIcon, R.attr.compose_close_button_tint);
actionBar.setHomeAsUpIndicator(closeIcon);
}
// setup the account image
final AccountEntity activeAccount = accountManager.getActiveAccount();
if (activeAccount != null) {
ImageView composeAvatar = findViewById(R.id.composeAvatar);
if (TextUtils.isEmpty(activeAccount.getProfilePictureUrl())) {
composeAvatar.setImageResource(R.drawable.avatar_default);
} else {
Picasso.with(this).load(activeAccount.getProfilePictureUrl()).transform(new RoundedTransformation(25)).error(R.drawable.avatar_default).placeholder(R.drawable.avatar_default).into(composeAvatar);
}
composeAvatar.setContentDescription(getString(R.string.compose_active_account_description, activeAccount.getFullName()));
} else {
// do not do anything when not logged in, activity will be finished in super.onCreate() anyway
return;
}
// Setup the interface buttons.
floatingBtn.setOnClickListener(v -> onSendClicked());
floatingBtn.setOnLongClickListener(v -> saveDraft());
pickButton.setOnClickListener(v -> openPickDialog());
visibilityBtn.setOnClickListener(v -> showComposeOptions());
saveButton.setOnClickListener(v -> saveDraft());
hideMediaToggle.setOnClickListener(v -> toggleHideMedia());
// fix a bug with autocomplete and some keyboards
int newInputType = textEditor.getInputType() & (textEditor.getInputType() ^ InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE);
textEditor.setInputType(newInputType);
/* Initialise all the state, or restore it from a previous run, to determine a "starting"
* state. */
Status.Visibility startingVisibility = Status.Visibility.UNKNOWN;
boolean startingHideText;
String startingContentWarning = null;
ArrayList<SavedQueuedMedia> savedMediaQueued = null;
if (savedInstanceState != null) {
showMarkSensitive = savedInstanceState.getBoolean("showMarkSensitive");
startingVisibility = Status.Visibility.byNum(savedInstanceState.getInt("statusVisibility", Status.Visibility.PUBLIC.getNum()));
statusMarkSensitive = savedInstanceState.getBoolean("statusMarkSensitive");
startingHideText = savedInstanceState.getBoolean("statusHideText");
// Keep these until everything needed to put them in the queue is finished initializing.
savedMediaQueued = savedInstanceState.getParcelableArrayList("savedMediaQueued");
// These are for restoring an in-progress commit content operation.
InputContentInfoCompat previousInputContentInfo = InputContentInfoCompat.wrap(savedInstanceState.getParcelable("commitContentInputContentInfo"));
int previousFlags = savedInstanceState.getInt("commitContentFlags");
if (previousInputContentInfo != null) {
onCommitContentInternal(previousInputContentInfo, previousFlags);
}
photoUploadUri = savedInstanceState.getParcelable("photoUploadUri");
} else {
showMarkSensitive = false;
statusMarkSensitive = false;
startingHideText = false;
photoUploadUri = null;
}
/* If the composer is started up as a reply to another post, override the "starting" state
* based on what the intent from the reply request passes. */
Intent intent = getIntent();
String[] mentionedUsernames = null;
ArrayList<String> loadedDraftMediaUris = null;
inReplyToId = null;
if (intent != null) {
if (startingVisibility == Status.Visibility.UNKNOWN) {
Status.Visibility replyVisibility = Status.Visibility.byNum(intent.getIntExtra(REPLY_VISIBILITY_EXTRA, Status.Visibility.UNKNOWN.getNum()));
if (replyVisibility != Status.Visibility.UNKNOWN) {
startingVisibility = replyVisibility;
} else {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
startingVisibility = Status.Visibility.byString(preferences.getString("defaultPostPrivacy", Status.Visibility.PUBLIC.serverString()));
}
}
inReplyToId = intent.getStringExtra(IN_REPLY_TO_ID_EXTRA);
mentionedUsernames = intent.getStringArrayExtra(MENTIONED_USERNAMES_EXTRA);
String contentWarning = intent.getStringExtra(CONTENT_WARNING_EXTRA);
if (contentWarning != null) {
startingHideText = !contentWarning.isEmpty();
if (startingHideText) {
startingContentWarning = contentWarning;
}
}
// If come from SavedTootActivity
String savedTootText = intent.getStringExtra(SAVED_TOOT_TEXT_EXTRA);
if (!TextUtils.isEmpty(savedTootText)) {
textEditor.append(savedTootText);
}
String savedJsonUrls = intent.getStringExtra(SAVED_JSON_URLS_EXTRA);
if (!TextUtils.isEmpty(savedJsonUrls)) {
// try to redo a list of media
loadedDraftMediaUris = new Gson().fromJson(savedJsonUrls, new TypeToken<ArrayList<String>>() {
}.getType());
}
int savedTootUid = intent.getIntExtra(SAVED_TOOT_UID_EXTRA, 0);
if (savedTootUid != 0) {
this.savedTootUid = savedTootUid;
}
if (intent.hasExtra(REPLYING_STATUS_AUTHOR_USERNAME_EXTRA)) {
replyTextView.setVisibility(View.VISIBLE);
String username = intent.getStringExtra(REPLYING_STATUS_AUTHOR_USERNAME_EXTRA);
replyTextView.setText(getString(R.string.replying_to, username));
replyTextView.setOnClickListener(v -> {
if (replyContentTextView.getVisibility() != View.VISIBLE) {
replyContentTextView.setVisibility(View.VISIBLE);
} else {
replyContentTextView.setVisibility(View.GONE);
}
});
}
if (intent.hasExtra(REPLYING_STATUS_CONTENT_EXTRA)) {
replyContentTextView.setText(intent.getStringExtra(REPLYING_STATUS_CONTENT_EXTRA));
}
}
// After the starting state is finalised, the interface can be set to reflect this state.
setStatusVisibility(startingVisibility);
postProgress.setVisibility(View.INVISIBLE);
updateHideMediaToggleColor();
updateVisibleCharactersLeft();
// Setup the main text field.
// new String[] { "image/gif", "image/webp" }
setEditTextMimeTypes();
final int mentionColour = ThemeUtils.getColor(this, R.attr.compose_mention_color);
SpanUtils.highlightSpans(textEditor.getText(), mentionColour);
textEditor.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
updateVisibleCharactersLeft();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable editable) {
SpanUtils.highlightSpans(editable, mentionColour);
}
});
textEditor.setAdapter(new MentionAutoCompleteAdapter(this, R.layout.item_autocomplete, this));
textEditor.setTokenizer(new MentionTokenizer());
// Add any mentions to the text field when a reply is first composed.
if (mentionedUsernames != null) {
StringBuilder builder = new StringBuilder();
for (String name : mentionedUsernames) {
builder.append('@');
builder.append(name);
builder.append(' ');
}
textEditor.setText(builder);
textEditor.setSelection(textEditor.length());
}
// Initialise the content warning editor.
contentWarningEditor.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
updateVisibleCharactersLeft();
}
@Override
public void afterTextChanged(Editable s) {
}
});
showContentWarning(startingHideText);
if (startingContentWarning != null) {
contentWarningEditor.setText(startingContentWarning);
}
// Initialise the empty media queue state.
waitForMediaLatch = new CountUpDownLatch();
statusAlreadyInFlight = false;
// These can only be added after everything affected by the media queue is initialized.
if (!ListUtils.isEmpty(loadedDraftMediaUris)) {
for (String uriString : loadedDraftMediaUris) {
Uri uri = Uri.parse(uriString);
long mediaSize = MediaUtils.getMediaSize(getContentResolver(), uri);
pickMedia(uri, mediaSize);
}
} else if (savedMediaQueued != null) {
for (SavedQueuedMedia item : savedMediaQueued) {
Bitmap preview = MediaUtils.getImageThumbnail(getContentResolver(), item.uri, THUMBNAIL_SIZE);
addMediaToQueue(item.type, preview, item.uri, item.mediaSize, item.readyStage, item.description);
}
} else if (intent != null && savedInstanceState == null) {
/* Get incoming images being sent through a share action from another app. Only do this
* when savedInstanceState is null, otherwise both the images from the intent and the
* instance state will be re-queued. */
String type = intent.getType();
if (type != null) {
if (type.startsWith("image/")) {
List<Uri> uriList = new ArrayList<>();
if (intent.getAction() != null) {
switch(intent.getAction()) {
case Intent.ACTION_SEND:
{
Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
if (uri != null) {
uriList.add(uri);
}
break;
}
case Intent.ACTION_SEND_MULTIPLE:
{
ArrayList<Uri> list = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (list != null) {
for (Uri uri : list) {
if (uri != null) {
uriList.add(uri);
}
}
}
break;
}
}
}
for (Uri uri : uriList) {
long mediaSize = MediaUtils.getMediaSize(getContentResolver(), uri);
pickMedia(uri, mediaSize);
}
} else if (type.equals("text/plain")) {
String action = intent.getAction();
if (action != null && action.equals(Intent.ACTION_SEND)) {
String text = intent.getStringExtra(Intent.EXTRA_TEXT);
if (text != null) {
int start = Math.max(textEditor.getSelectionStart(), 0);
int end = Math.max(textEditor.getSelectionEnd(), 0);
int left = Math.min(start, end);
int right = Math.max(start, end);
textEditor.getText().replace(left, right, text, 0, text.length());
}
}
}
}
}
textEditor.requestFocus();
}
Aggregations