Search in sources :

Example 1 with PostStatusModelImpl

use of com.github.moko256.twitlatte.model.impl.PostStatusModelImpl in project twicalico by moko256.

the class PostActivity method onCreate.

@SuppressLint("SetTextI18n")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_post);
    TypedValue value = new TypedValue();
    getTheme().resolveAttribute(android.R.attr.textColorTertiary, value, true);
    COLOR_STABLE = ContextCompat.getColor(this, value.resourceId);
    getTheme().resolveAttribute(R.attr.colorError, value, true);
    COLOR_ERROR = ContextCompat.getColor(this, value.resourceId);
    RequestManager requestManager = Glide.with(this);
    client = GlobalApplicationKt.getClient(this);
    model = new PostStatusModelImpl(getContentResolver(), client.getApiClient());
    disposable = new CompositeDisposable();
    rootViewGroup = findViewById(android.R.id.content);
    actionBar = Objects.requireNonNull(getSupportActionBar());
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setHomeAsUpIndicator(R.drawable.ic_clear_white_24dp);
    actionBar.setDisplayShowCustomEnabled(true);
    userIcon = new ImageView(this);
    final int dp36 = DpToPxKt.dpToPx(this, 36);
    ActionBar.LayoutParams userIconParams = new ActionBar.LayoutParams(dp36, dp36);
    userIconParams.setMarginStart(dp36 / 3 * 2);
    actionBar.setCustomView(userIcon, userIconParams);
    disposable.add(Single.create(new VerifyCredentialOnSubscribe(client)).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(user -> requestManager.load(client.getMediaUrlConverter().convertProfileIconUriBySize(user, dp36)).circleCrop().into(userIcon), Throwable::printStackTrace));
    counterTextView = findViewById(R.id.tweet_text_edit_counter);
    editText = findViewById(R.id.tweet_text_edit);
    editText.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) {
            model.getUpdateStatus().setContext(s.toString());
            updateCounter();
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });
    editText.setFilters(NoSpanInputFilterKt.getNoSpanInputFilter());
    editText.setImageAddedListener(imageUri -> {
        if (model.getUriList().size() < model.getUriListSizeLimit()) {
            addedImagesAdapter.addImageAndUpdateView(imageUri);
            model.getUriList().add(imageUri);
            updateCounter();
            isPossiblySensitive.setEnabled(true);
            return true;
        } else {
            return false;
        }
    });
    editText.setOnKeyListener((v, keyCode, event) -> {
        if (!isPosting && event.getAction() == KeyEvent.ACTION_DOWN && event.isCtrlPressed() && keyCode == KeyEvent.KEYCODE_ENTER) {
            postOrConfirmIfValid();
            return true;
        }
        return false;
    });
    imagesRecyclerView = findViewById(R.id.activity_tweet_send_images_recycler_view);
    addedImagesAdapter = new AddedImagesAdapter(this, requestManager);
    imagesRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
    imagesRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {

        @Override
        public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
            outRect.right = DpToPxKt.oneDpToPx(getResources().getDisplayMetrics().density);
        }
    });
    addedImagesAdapter.limit = model.getUriListSizeLimit();
    addedImagesAdapter.onAddButtonClickListener = v -> startActivityForResult(Intent.createChooser(new Intent(Intent.ACTION_GET_CONTENT).addCategory(Intent.CATEGORY_OPENABLE).putExtra(Intent.EXTRA_MIME_TYPES, new String[] { "image/*", "video/*" }).putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true).setType("*/*"), getString(R.string.add_media)), REQUEST_GET_IMAGE);
    addedImagesAdapter.onDeleteButtonListener = position -> {
        addedImagesAdapter.removeImageAndUpdateView(position);
        model.getUriList().remove(position);
        boolean enabled = model.getUriList().size() > 0;
        updateCounter();
        isPossiblySensitive.setEnabled(enabled);
        isPossiblySensitive.setChecked(isPossiblySensitive.isChecked() && enabled);
    };
    addedImagesAdapter.onImageClickListener = position -> {
        try {
            Intent open = new Intent(Intent.ACTION_VIEW).setData(model.getUriList().get(position)).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            startActivity(Intent.createChooser(open, getString(R.string.open_media)));
        } catch (Throwable e) {
            e.printStackTrace();
        }
    };
    imagesRecyclerView.setAdapter(addedImagesAdapter);
    emojiInputRecyclerView = findViewById(R.id.suggestions_of_emoji);
    isPossiblySensitive = findViewById(R.id.activity_tweet_is_possibly_sensitive);
    isPossiblySensitive.setEnabled(addedImagesAdapter.getImagesList().size() > 0);
    isPossiblySensitive.setOnCheckedChangeListener((buttonView, isChecked) -> model.getUpdateStatus().setPossiblySensitive(isChecked));
    postVisibility = findViewById(R.id.activity_tweet_visibility_spinner);
    contentWarningText = findViewById(R.id.tweet_text_warning);
    contentWarningEnabled = findViewById(R.id.activity_tweet_add_content_warning);
    pollsText = new EditText[] { findViewById(R.id.edit_poll_0), findViewById(R.id.edit_poll_1), findViewById(R.id.edit_poll_2), findViewById(R.id.edit_poll_3) };
    pollsExpiredAt = findViewById(R.id.edit_poll_expired_at);
    pollsExpireAtLabel = findViewById(R.id.edit_poll_expired_at_description);
    pollsMultiple = findViewById(R.id.poll_multiple);
    pollsHideTotals = findViewById(R.id.hide_totals);
    addPoll = findViewById(R.id.activity_add_poll);
    ArraysKt.forEach(pollsText, editText -> {
        editText.setVisibility(View.GONE);
        return Unit.INSTANCE;
    });
    pollsExpiredAt.setVisibility(View.GONE);
    pollsMultiple.setVisibility(View.GONE);
    pollsHideTotals.setVisibility(View.GONE);
    pollsExpireAtLabel.setVisibility(View.GONE);
    if (client.getAccessToken().getClientType() == CLIENT_TYPE_MASTODON) {
        emojiAdapter = new EmojiAdapter(emojiList, this, requestManager, emoji -> {
            int selectionEnd = editText.getSelectionEnd();
            String shortCode = emoji.getShortCode();
            Editable text = editText.getText();
            if (text != null) {
                text.insert(selectionEnd, ":").insert(selectionEnd + 1, shortCode).insert(selectionEnd + 1 + shortCode.length(), ": ");
            } else {
                editText.setText(":" + shortCode + ": ");
            }
            editText.setSelection(selectionEnd + shortCode.length() + 3);
            return Unit.INSTANCE;
        }, () -> {
            disposable.add(model.requestCustomEmojis().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(emojis -> {
                emojiList.clear();
                emojiList.addAll(emojis);
                emojiAdapter.notifyDataSetChanged();
            }, this::errorNotify));
            return Unit.INSTANCE;
        });
        contentWarningText.setFilters(NoSpanInputFilterKt.getNoSpanInputFilter());
        emojiInputRecyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.HORIZONTAL, false));
        emojiInputRecyclerView.setAdapter(emojiAdapter);
        contentWarningText.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) {
                model.getUpdateStatus().setContentWarning(s.toString());
                updateCounter();
            }

            @Override
            public void afterTextChanged(Editable s) {
            }
        });
        contentWarningEnabled.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (isChecked) {
                contentWarningText.setVisibility(View.VISIBLE);
                contentWarningText.requestFocus();
            } else {
                contentWarningText.setVisibility(View.GONE);
                model.getUpdateStatus().setContentWarning("");
            }
        });
        postVisibility.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                model.getUpdateStatus().setVisibility(POST_VISIBILITY[position]);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        ArrayList<String> options = new ArrayList<>(4);
        ArraysKt.forEachIndexed(pollsText, (i, editText) -> {
            if (i < 2) {
                editText.setHint(getString(R.string.poll_n, i + 1));
            } else {
                editText.setHint(getString(R.string.poll_n_optional, i + 1));
            }
            options.add("");
            editText.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) {
                    options.set(i, s.toString());
                    model.getUpdateStatus().setPollList(options);
                }

                @Override
                public void afterTextChanged(Editable s) {
                }
            });
            return Unit.INSTANCE;
        });
        pollsExpiredAt.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {

            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                model.getUpdateStatus().setPollExpiredSecond(POLL_EXPIRED_AT[position]);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
        pollsMultiple.setOnCheckedChangeListener((buttonView, isChecked) -> model.getUpdateStatus().setPollSelectableMultiple(isChecked));
        pollsHideTotals.setOnCheckedChangeListener((buttonView, isChecked) -> model.getUpdateStatus().setPollHideTotalsUntilExpired(isChecked));
        addPoll.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (isChecked) {
                ArraysKt.forEach(pollsText, editText -> {
                    editText.setVisibility(View.VISIBLE);
                    return Unit.INSTANCE;
                });
                pollsExpiredAt.setVisibility(View.VISIBLE);
                pollsMultiple.setVisibility(View.VISIBLE);
                pollsHideTotals.setVisibility(View.VISIBLE);
                pollsExpireAtLabel.setVisibility(View.VISIBLE);
            } else {
                model.getUpdateStatus().setPollList(null);
                ArraysKt.forEach(pollsText, editText -> {
                    editText.setVisibility(View.GONE);
                    editText.setText("");
                    return Unit.INSTANCE;
                });
                pollsExpiredAt.setVisibility(View.GONE);
                pollsMultiple.setVisibility(View.GONE);
                pollsHideTotals.setVisibility(View.GONE);
                pollsExpireAtLabel.setVisibility(View.GONE);
            }
        });
    } else {
        emojiInputRecyclerView.setVisibility(View.GONE);
        contentWarningEnabled.setVisibility(View.GONE);
        postVisibility.setVisibility(View.GONE);
        findViewById(R.id.activity_tweet_visibility_description).setVisibility(View.GONE);
        addPoll.setVisibility(View.GONE);
    }
    addLocation = findViewById(R.id.activity_tweet_add_location);
    if (client.getAccessToken().getClientType() == CLIENT_TYPE_TWITTER) {
        addLocation.setVisibility(View.VISIBLE);
        addLocation.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if (isChecked) {
                locationText.setVisibility(View.VISIBLE);
                if (PermissionChecker.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PermissionChecker.PERMISSION_GRANTED) {
                    updateLocation();
                } else {
                    ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, REQUEST_CODE_PERMISSION_LOCATION);
                }
            } else {
                model.getUpdateStatus().setLocation(null);
                locationText.setVisibility(View.GONE);
                locationText.setText("");
            }
        });
    } else {
        addLocation.setVisibility(View.GONE);
    }
    locationText = findViewById(R.id.activity_tweet_location_result);
    locationText.setVisibility(View.GONE);
    if (getIntent() != null) {
        model.getUpdateStatus().setInReplyToStatusId(getIntent().getLongExtra(INTENT_EXTRA_IN_REPLY_TO_STATUS_ID, -1));
        if (savedInstanceState == null) {
            String text = getIntent().getStringExtra(INTENT_EXTRA_TWEET_TEXT);
            if (text != null) {
                editText.setText(text);
                editText.setSelection(text.length());
            } else {
                editText.setText("");
            }
            ArrayList<Uri> uris = getIntent().getParcelableArrayListExtra(INTENT_EXTRA_IMAGE_URI);
            if (uris != null) {
                addedImagesAdapter.getImagesList().addAll(uris);
                model.getUriList().addAll(uris);
                updateCounter();
                isPossiblySensitive.setEnabled(true);
            }
        }
    }
    editText.setHint(model.isReply() ? R.string.reply : R.string.post);
}
Also used : Rect(android.graphics.Rect) Bundle(android.os.Bundle) NonNull(androidx.annotation.NonNull) Pair(kotlin.Pair) Uri(android.net.Uri) ImageView(android.widget.ImageView) AppCompatActivity(androidx.appcompat.app.AppCompatActivity) AndroidSchedulers(io.reactivex.android.schedulers.AndroidSchedulers) ActionBar(androidx.appcompat.app.ActionBar) Manifest(android.Manifest) CheckBox(android.widget.CheckBox) RequestManager(com.bumptech.glide.RequestManager) LocationSingleBuilder(com.github.moko256.twitlatte.rx.LocationSingleBuilder) View(android.view.View) Schedulers(io.reactivex.schedulers.Schedulers) AdapterView(android.widget.AdapterView) RecyclerView(androidx.recyclerview.widget.RecyclerView) ContextCompat(androidx.core.content.ContextCompat) PostStatusModelImpl(com.github.moko256.twitlatte.model.impl.PostStatusModelImpl) NoSpanInputFilterKt(com.github.moko256.twitlatte.text.NoSpanInputFilterKt) Objects(java.util.Objects) DpToPxKt(com.github.moko256.twitlatte.view.DpToPxKt) List(java.util.List) CompositeDisposable(io.reactivex.disposables.CompositeDisposable) Unit(kotlin.Unit) TextView(android.widget.TextView) PostStatusModel(com.github.moko256.twitlatte.model.base.PostStatusModel) ImageKeyboardEditText(com.github.moko256.twitlatte.widget.ImageKeyboardEditText) Emoji(com.github.moko256.latte.client.base.entity.Emoji) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) LocationManager(android.location.LocationManager) Snackbar(com.google.android.material.snackbar.Snackbar) TextWatcher(android.text.TextWatcher) Context(android.content.Context) KeyEvent(android.view.KeyEvent) AlertDialog(androidx.appcompat.app.AlertDialog) ArraysKt(kotlin.collections.ArraysKt) Intent(android.content.Intent) CLIENT_TYPE_TWITTER(com.github.moko256.latte.client.twitter.TwitterApiClientImplKt.CLIENT_TYPE_TWITTER) Single(io.reactivex.Single) Editable(android.text.Editable) MenuItem(android.view.MenuItem) ArrayList(java.util.ArrayList) ClipData(android.content.ClipData) PermissionChecker(androidx.core.content.PermissionChecker) SuppressLint(android.annotation.SuppressLint) Menu(android.view.Menu) Parcelable(android.os.Parcelable) ActivityCompat(androidx.core.app.ActivityCompat) Client(com.github.moko256.twitlatte.entity.Client) VerifyCredentialOnSubscribe(com.github.moko256.twitlatte.rx.VerifyCredentialOnSubscribe) Spinner(android.widget.Spinner) Glide(com.bumptech.glide.Glide) TypedValue(android.util.TypedValue) EditText(android.widget.EditText) CLIENT_TYPE_MASTODON(com.github.moko256.latte.client.mastodon.MastodonApiClientImplKt.CLIENT_TYPE_MASTODON) ArrayList(java.util.ArrayList) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) Uri(android.net.Uri) RequestManager(com.bumptech.glide.RequestManager) TextWatcher(android.text.TextWatcher) Editable(android.text.Editable) ImageView(android.widget.ImageView) ActionBar(androidx.appcompat.app.ActionBar) TypedValue(android.util.TypedValue) Rect(android.graphics.Rect) Intent(android.content.Intent) VerifyCredentialOnSubscribe(com.github.moko256.twitlatte.rx.VerifyCredentialOnSubscribe) ImageView(android.widget.ImageView) View(android.view.View) AdapterView(android.widget.AdapterView) RecyclerView(androidx.recyclerview.widget.RecyclerView) TextView(android.widget.TextView) SuppressLint(android.annotation.SuppressLint) PostStatusModelImpl(com.github.moko256.twitlatte.model.impl.PostStatusModelImpl) RecyclerView(androidx.recyclerview.widget.RecyclerView) AdapterView(android.widget.AdapterView) CompositeDisposable(io.reactivex.disposables.CompositeDisposable) SuppressLint(android.annotation.SuppressLint)

Aggregations

Manifest (android.Manifest)1 SuppressLint (android.annotation.SuppressLint)1 ClipData (android.content.ClipData)1 Context (android.content.Context)1 Intent (android.content.Intent)1 Rect (android.graphics.Rect)1 LocationManager (android.location.LocationManager)1 Uri (android.net.Uri)1 Bundle (android.os.Bundle)1 Parcelable (android.os.Parcelable)1 Editable (android.text.Editable)1 TextWatcher (android.text.TextWatcher)1 TypedValue (android.util.TypedValue)1 KeyEvent (android.view.KeyEvent)1 Menu (android.view.Menu)1 MenuItem (android.view.MenuItem)1 View (android.view.View)1 AdapterView (android.widget.AdapterView)1 CheckBox (android.widget.CheckBox)1 EditText (android.widget.EditText)1