diff options
author | Docile-Alligator <chineseperson5@gmail.com> | 2022-02-21 14:52:22 +0000 |
---|---|---|
committer | Docile-Alligator <chineseperson5@gmail.com> | 2022-02-21 14:52:22 +0000 |
commit | 679820b96ebae991b667c0bfd845eae6d6e27e48 (patch) | |
tree | bd5e6c3f66593ca416742421cdc8fc4e8aa9570c /app/src/main/java | |
parent | 3a69e028673181f014630bb68205166dc39ded0a (diff) | |
download | infinity-for-reddit-679820b96ebae991b667c0bfd845eae6d6e27e48.tar infinity-for-reddit-679820b96ebae991b667c0bfd845eae6d6e27e48.tar.gz infinity-for-reddit-679820b96ebae991b667c0bfd845eae6d6e27e48.tar.bz2 infinity-for-reddit-679820b96ebae991b667c0bfd845eae6d6e27e48.tar.lz infinity-for-reddit-679820b96ebae991b667c0bfd845eae6d6e27e48.tar.xz infinity-for-reddit-679820b96ebae991b667c0bfd845eae6d6e27e48.tar.zst infinity-for-reddit-679820b96ebae991b667c0bfd845eae6d6e27e48.zip |
Submitting poll posts is available.
Diffstat (limited to 'app/src/main/java')
12 files changed, 826 insertions, 3 deletions
diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index a3f45e59..969d4411 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -30,6 +30,7 @@ import ml.docilealligator.infinityforreddit.activities.PostFilterUsageListingAct import ml.docilealligator.infinityforreddit.activities.PostGalleryActivity; import ml.docilealligator.infinityforreddit.activities.PostImageActivity; import ml.docilealligator.infinityforreddit.activities.PostLinkActivity; +import ml.docilealligator.infinityforreddit.activities.PostPollActivity; import ml.docilealligator.infinityforreddit.activities.PostTextActivity; import ml.docilealligator.infinityforreddit.activities.PostVideoActivity; import ml.docilealligator.infinityforreddit.activities.RPANActivity; @@ -295,4 +296,6 @@ public interface AppComponent { void inject(FontPreferenceFragment fontPreferenceFragment); void inject(CommentPreferenceFragment commentPreferenceFragment); + + void inject(PostPollActivity postPollActivity); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/PollPayload.java b/app/src/main/java/ml/docilealligator/infinityforreddit/PollPayload.java new file mode 100644 index 00000000..0e33d3ed --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/PollPayload.java @@ -0,0 +1,48 @@ +package ml.docilealligator.infinityforreddit; + +import com.google.gson.annotations.SerializedName; + +public class PollPayload { + @SerializedName("api_type") + public String apiType = "json"; + @SerializedName("duration") + public int duration; + @SerializedName("nsfw") + public boolean isNsfw; + public String[] options; + @SerializedName("flair_id") + public String flairId; + @SerializedName("flair_text") + public String flairText; + @SerializedName("post_to_twitter") + public boolean postToTwitter = false; + @SerializedName("sendreplies") + public boolean sendReplies; + @SerializedName("show_error_list") + public boolean showErrorList = true; + @SerializedName("spoiler") + public boolean isSpoiler; + @SerializedName("sr") + public String subredditName; + @SerializedName("submit_type") + public String submitType; + public String title; + @SerializedName("validate_on_submit") + public boolean validateOnSubmit = true; + + public PollPayload(String subredditName, String title, String[] options, int duration, boolean isNsfw, + boolean isSpoiler, Flair flair, boolean sendReplies, String submitType) { + this.subredditName = subredditName; + this.title = title; + this.options = options; + this.duration = duration; + this.isNsfw = isNsfw; + this.isSpoiler = isSpoiler; + if (flair != null) { + flairId = flair.getId(); + flairText = flair.getText(); + } + this.sendReplies = sendReplies; + this.submitType = submitType; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditGalleryPayload.java b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditGalleryPayload.java index d8763ff0..bd3365c3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/RedditGalleryPayload.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/RedditGalleryPayload.java @@ -26,6 +26,7 @@ public class RedditGalleryPayload { public boolean originalContent = false; @SerializedName("post_to_twitter") public boolean postToTwitter = false; + @SerializedName("sendreplies") public boolean sendReplies; @SerializedName("validate_on_submit") public boolean validateOnSubmit = true; diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java index 2e253dfe..d8ef9165 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/MainActivity.java @@ -1161,6 +1161,10 @@ public class MainActivity extends BaseActivity implements SortTypeSelectionCallb case PostTypeBottomSheetFragment.TYPE_GALLERY: intent = new Intent(MainActivity.this, PostGalleryActivity.class); startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_POLL: + intent = new Intent(MainActivity.this, PostPollActivity.class); + startActivity(intent); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostPollActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostPollActivity.java new file mode 100644 index 00000000..05eb71c1 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/PostPollActivity.java @@ -0,0 +1,689 @@ +package ml.docilealligator.infinityforreddit.activities; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.ColorStateList; +import android.content.res.Resources; +import android.graphics.PorterDuff; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.EditText; +import android.widget.LinearLayout; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.content.ContextCompat; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.RequestManager; +import com.bumptech.glide.request.RequestOptions; +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.button.MaterialButton; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.divider.MaterialDivider; +import com.google.android.material.slider.Slider; +import com.google.android.material.snackbar.Snackbar; +import com.google.android.material.switchmaterial.SwitchMaterial; +import com.google.android.material.textfield.TextInputEditText; +import com.google.android.material.textfield.TextInputLayout; +import com.google.gson.Gson; +import com.libRG.CustomTextView; + +import org.greenrobot.eventbus.EventBus; +import org.greenrobot.eventbus.Subscribe; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.concurrent.Executor; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import jp.wasabeef.glide.transformations.RoundedCornersTransformation; +import ml.docilealligator.infinityforreddit.Flair; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.PollPayload; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.asynctasks.LoadSubredditIcon; +import ml.docilealligator.infinityforreddit.bottomsheetfragments.FlairBottomSheetFragment; +import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.events.SubmitPollPostEvent; +import ml.docilealligator.infinityforreddit.events.SwitchAccountEvent; +import ml.docilealligator.infinityforreddit.services.SubmitPostService; +import ml.docilealligator.infinityforreddit.utils.SharedPreferencesUtils; +import ml.docilealligator.infinityforreddit.utils.Utils; +import pl.droidsonroids.gif.GifImageView; +import retrofit2.Retrofit; + +public class PostPollActivity extends BaseActivity implements FlairBottomSheetFragment.FlairSelectionCallback { + + static final String EXTRA_SUBREDDIT_NAME = "ESN"; + + private static final String SUBREDDIT_NAME_STATE = "SNS"; + private static final String SUBREDDIT_ICON_STATE = "SIS"; + private static final String SUBREDDIT_SELECTED_STATE = "SSS"; + private static final String SUBREDDIT_IS_USER_STATE = "SIUS"; + private static final String LOAD_SUBREDDIT_ICON_STATE = "LSIS"; + private static final String IS_POSTING_STATE = "IPS"; + private static final String FLAIR_STATE = "FS"; + private static final String IS_SPOILER_STATE = "ISS"; + private static final String IS_NSFW_STATE = "INS"; + + private static final int SUBREDDIT_SELECTION_REQUEST_CODE = 0; + + @BindView(R.id.coordinator_layout_post_poll_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_post_poll_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_post_poll_activity) + Toolbar toolbar; + @BindView(R.id.subreddit_icon_gif_image_view_post_poll_activity) + GifImageView iconGifImageView; + @BindView(R.id.subreddit_name_text_view_post_poll_activity) + TextView subredditNameTextView; + @BindView(R.id.rules_button_post_poll_activity) + MaterialButton rulesButton; + @BindView(R.id.divider_1_post_poll_activity) + MaterialDivider divider1; + @BindView(R.id.flair_custom_text_view_post_poll_activity) + CustomTextView flairTextView; + @BindView(R.id.spoiler_custom_text_view_post_poll_activity) + CustomTextView spoilerTextView; + @BindView(R.id.nsfw_custom_text_view_post_poll_activity) + CustomTextView nsfwTextView; + @BindView(R.id.receive_post_reply_notifications_linear_layout_post_poll_activity) + LinearLayout receivePostReplyNotificationsLinearLayout; + @BindView(R.id.receive_post_reply_notifications_text_view_post_poll_activity) + TextView receivePostReplyNotificationsTextView; + @BindView(R.id.receive_post_reply_notifications_switch_material_post_poll_activity) + SwitchMaterial receivePostReplyNotificationsSwitchMaterial; + @BindView(R.id.divider_2_post_poll_activity) + MaterialDivider divider2; + @BindView(R.id.post_title_edit_text_post_poll_activity) + EditText titleEditText; + @BindView(R.id.divider_3_post_poll_activity) + MaterialDivider divider3; + @BindView(R.id.voting_length_text_view_post_poll_activity) + TextView votingLengthTextView; + @BindView(R.id.voting_length_seek_bar_post_poll_activity) + Slider votingLengthSlider; + @BindView(R.id.option_1_text_input_layout_post_poll_activity) + TextInputLayout option1TextInputLayout; + @BindView(R.id.option_1_text_input_layout_edit_text_post_poll_activity) + TextInputEditText option1TextInputEditText; + @BindView(R.id.option_2_text_input_layout_post_poll_activity) + TextInputLayout option2TextInputLayout; + @BindView(R.id.option_2_text_input_layout_edit_text_post_poll_activity) + TextInputEditText option2TextInputEditText; + @BindView(R.id.option_3_text_input_layout_post_poll_activity) + TextInputLayout option3TextInputLayout; + @BindView(R.id.option_3_text_input_layout_edit_text_post_poll_activity) + TextInputEditText option3TextInputEditText; + @BindView(R.id.option_4_text_input_layout_post_poll_activity) + TextInputLayout option4TextInputLayout; + @BindView(R.id.option_4_text_input_layout_edit_text_post_poll_activity) + TextInputEditText option4TextInputEditText; + @BindView(R.id.option_5_text_input_layout_post_poll_activity) + TextInputLayout option5TextInputLayout; + @BindView(R.id.option_5_text_input_layout_edit_text_post_poll_activity) + TextInputEditText option5TextInputEditText; + @BindView(R.id.option_6_text_input_layout_post_poll_activity) + TextInputLayout option6TextInputLayout; + @BindView(R.id.option_6_text_input_layout_edit_text_post_poll_activity) + TextInputEditText option6TextInputEditText; + @Inject + @Named("no_oauth") + Retrofit mRetrofit; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + @Named("current_account") + SharedPreferences mCurrentAccountSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + @Inject + Executor mExecutor; + private String mAccessToken; + private String mAccountName; + private String iconUrl; + private String subredditName; + private boolean subredditSelected = false; + private boolean subredditIsUser; + private boolean loadSubredditIconSuccessful = true; + private boolean isPosting; + private int primaryTextColor; + private int flairBackgroundColor; + private int flairTextColor; + private int spoilerBackgroundColor; + private int spoilerTextColor; + private int nsfwBackgroundColor; + private int nsfwTextColor; + private Flair flair; + private boolean isSpoiler = false; + private boolean isNSFW = false; + private Resources resources; + private Menu mMemu; + private RequestManager mGlide; + private FlairBottomSheetFragment flairSelectionBottomSheetFragment; + private Snackbar mPostingSnackbar; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_post_poll); + + ButterKnife.bind(this); + + EventBus.getDefault().register(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mGlide = Glide.with(this); + + mPostingSnackbar = Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_INDEFINITE); + + resources = getResources(); + + mAccessToken = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCESS_TOKEN, null); + mAccountName = mCurrentAccountSharedPreferences.getString(SharedPreferencesUtils.ACCOUNT_NAME, null); + + Resources resources = getResources(); + + if (savedInstanceState != null) { + subredditName = savedInstanceState.getString(SUBREDDIT_NAME_STATE); + iconUrl = savedInstanceState.getString(SUBREDDIT_ICON_STATE); + subredditSelected = savedInstanceState.getBoolean(SUBREDDIT_SELECTED_STATE); + subredditIsUser = savedInstanceState.getBoolean(SUBREDDIT_IS_USER_STATE); + loadSubredditIconSuccessful = savedInstanceState.getBoolean(LOAD_SUBREDDIT_ICON_STATE); + isPosting = savedInstanceState.getBoolean(IS_POSTING_STATE); + flair = savedInstanceState.getParcelable(FLAIR_STATE); + isSpoiler = savedInstanceState.getBoolean(IS_SPOILER_STATE); + isNSFW = savedInstanceState.getBoolean(IS_NSFW_STATE); + + if (subredditName != null) { + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + if (!loadSubredditIconSuccessful) { + loadSubredditIcon(); + } + } + displaySubredditIcon(); + + if (isPosting) { + mPostingSnackbar.show(); + } + + if (flair != null) { + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + if (isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + } + if (isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + } + } else { + isPosting = false; + + if (getIntent().hasExtra(EXTRA_SUBREDDIT_NAME)) { + loadSubredditIconSuccessful = false; + subredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + subredditSelected = true; + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + flairTextView.setVisibility(View.VISIBLE); + loadSubredditIcon(); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + } + + iconGifImageView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + subredditNameTextView.setOnClickListener(view -> { + Intent intent = new Intent(this, SubredditSelectionActivity.class); + startActivityForResult(intent, SUBREDDIT_SELECTION_REQUEST_CODE); + }); + + rulesButton.setOnClickListener(view -> { + if (subredditName == null) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + } else { + Intent intent = new Intent(this, RulesActivity.class); + if (subredditIsUser) { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, "u_" + subredditName); + } else { + intent.putExtra(RulesActivity.EXTRA_SUBREDDIT_NAME, subredditName); + } + startActivity(intent); + } + }); + + flairTextView.setOnClickListener(view -> { + if (flair == null) { + flairSelectionBottomSheetFragment = new FlairBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(FlairBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(FlairBottomSheetFragment.EXTRA_SUBREDDIT_NAME, subredditName); + flairSelectionBottomSheetFragment.setArguments(bundle); + flairSelectionBottomSheetFragment.show(getSupportFragmentManager(), flairSelectionBottomSheetFragment.getTag()); + } else { + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + }); + + spoilerTextView.setOnClickListener(view -> { + if (!isSpoiler) { + spoilerTextView.setBackgroundColor(spoilerBackgroundColor); + spoilerTextView.setBorderColor(spoilerBackgroundColor); + spoilerTextView.setTextColor(spoilerTextColor); + isSpoiler = true; + } else { + spoilerTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + spoilerTextView.setTextColor(primaryTextColor); + isSpoiler = false; + } + }); + + nsfwTextView.setOnClickListener(view -> { + if (!isNSFW) { + nsfwTextView.setBackgroundColor(nsfwBackgroundColor); + nsfwTextView.setBorderColor(nsfwBackgroundColor); + nsfwTextView.setTextColor(nsfwTextColor); + isNSFW = true; + } else { + nsfwTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + nsfwTextView.setTextColor(primaryTextColor); + isNSFW = false; + } + }); + + receivePostReplyNotificationsLinearLayout.setOnClickListener(view -> { + receivePostReplyNotificationsSwitchMaterial.performClick(); + }); + + votingLengthTextView.setText(getString(R.string.voting_length, (int) votingLengthSlider.getValue())); + votingLengthSlider.addOnChangeListener((slider, value, fromUser) -> votingLengthTextView.setText(getString(R.string.voting_length, (int) value))); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndCollapsingToolbarLayoutAndToolbarTheme(appBarLayout, null, toolbar); + int secondaryTextColor = mCustomThemeWrapper.getSecondaryTextColor(); + subredditNameTextView.setTextColor(secondaryTextColor); + rulesButton.setTextColor(mCustomThemeWrapper.getButtonTextColor()); + rulesButton.setBackgroundColor(mCustomThemeWrapper.getColorPrimaryLightTheme()); + primaryTextColor = mCustomThemeWrapper.getPrimaryTextColor(); + receivePostReplyNotificationsTextView.setTextColor(primaryTextColor); + int dividerColor = mCustomThemeWrapper.getDividerColor(); + divider1.setDividerColor(dividerColor); + divider2.setDividerColor(dividerColor); + divider3.setDividerColor(dividerColor); + flairBackgroundColor = mCustomThemeWrapper.getFlairBackgroundColor(); + flairTextColor = mCustomThemeWrapper.getFlairTextColor(); + spoilerBackgroundColor = mCustomThemeWrapper.getSpoilerBackgroundColor(); + spoilerTextColor = mCustomThemeWrapper.getSpoilerTextColor(); + nsfwBackgroundColor = mCustomThemeWrapper.getNsfwBackgroundColor(); + nsfwTextColor = mCustomThemeWrapper.getNsfwTextColor(); + flairTextView.setTextColor(primaryTextColor); + spoilerTextView.setTextColor(primaryTextColor); + nsfwTextView.setTextColor(primaryTextColor); + titleEditText.setTextColor(primaryTextColor); + titleEditText.setHintTextColor(secondaryTextColor); + option1TextInputLayout.setBoxStrokeColor(primaryTextColor); + option1TextInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + option1TextInputEditText.setTextColor(primaryTextColor); + + option2TextInputLayout.setBoxStrokeColor(primaryTextColor); + option2TextInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + option2TextInputEditText.setTextColor(primaryTextColor); + + option3TextInputLayout.setBoxStrokeColor(primaryTextColor); + option3TextInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + option3TextInputEditText.setTextColor(primaryTextColor); + + option4TextInputLayout.setBoxStrokeColor(primaryTextColor); + option4TextInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + option4TextInputEditText.setTextColor(primaryTextColor); + + option5TextInputLayout.setBoxStrokeColor(primaryTextColor); + option5TextInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + option5TextInputEditText.setTextColor(primaryTextColor); + + option6TextInputLayout.setBoxStrokeColor(primaryTextColor); + option6TextInputLayout.setDefaultHintTextColor(ColorStateList.valueOf(primaryTextColor)); + option6TextInputEditText.setTextColor(primaryTextColor); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + Drawable cursorDrawable = Utils.getTintedDrawable(this, R.drawable.edit_text_cursor, primaryTextColor); + option1TextInputEditText.setTextCursorDrawable(cursorDrawable); + option2TextInputEditText.setTextCursorDrawable(cursorDrawable); + option3TextInputEditText.setTextCursorDrawable(cursorDrawable); + option4TextInputEditText.setTextCursorDrawable(cursorDrawable); + option5TextInputEditText.setTextCursorDrawable(cursorDrawable); + option6TextInputEditText.setTextCursorDrawable(cursorDrawable); + } else { + setCursorDrawableColor(option1TextInputEditText, primaryTextColor); + setCursorDrawableColor(option2TextInputEditText, primaryTextColor); + setCursorDrawableColor(option3TextInputEditText, primaryTextColor); + setCursorDrawableColor(option4TextInputEditText, primaryTextColor); + setCursorDrawableColor(option5TextInputEditText, primaryTextColor); + setCursorDrawableColor(option6TextInputEditText, primaryTextColor); + } + + if (typeface != null) { + subredditNameTextView.setTypeface(typeface); + rulesButton.setTypeface(typeface); + receivePostReplyNotificationsTextView.setTypeface(typeface); + flairTextView.setTypeface(typeface); + spoilerTextView.setTypeface(typeface); + nsfwTextView.setTypeface(typeface); + titleEditText.setTypeface(typeface); + option1TextInputEditText.setTypeface(typeface); + option2TextInputEditText.setTypeface(typeface); + option3TextInputEditText.setTypeface(typeface); + option4TextInputEditText.setTypeface(typeface); + option5TextInputEditText.setTypeface(typeface); + option6TextInputEditText.setTypeface(typeface); + } + } + + public void setCursorDrawableColor(EditText editText, int color) { + try { + Field fCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes"); + fCursorDrawableRes.setAccessible(true); + int mCursorDrawableRes = fCursorDrawableRes.getInt(editText); + Field fEditor = TextView.class.getDeclaredField("mEditor"); + fEditor.setAccessible(true); + Object editor = fEditor.get(editText); + Class<?> clazz = editor.getClass(); + Field fCursorDrawable = clazz.getDeclaredField("mCursorDrawable"); + fCursorDrawable.setAccessible(true); + Drawable[] drawables = new Drawable[2]; + drawables[0] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); + drawables[1] = editText.getContext().getResources().getDrawable(mCursorDrawableRes); + drawables[0].setColorFilter(color, PorterDuff.Mode.SRC_IN); + drawables[1].setColorFilter(color, PorterDuff.Mode.SRC_IN); + fCursorDrawable.set(editor, drawables); + } catch (Throwable ignored) { } + } + + private void displaySubredditIcon() { + if (iconUrl != null && !iconUrl.equals("")) { + mGlide.load(iconUrl) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .error(mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0)))) + .into(iconGifImageView); + } else { + mGlide.load(R.drawable.subreddit_default_icon) + .apply(RequestOptions.bitmapTransform(new RoundedCornersTransformation(72, 0))) + .into(iconGifImageView); + } + } + + private void loadSubredditIcon() { + LoadSubredditIcon.loadSubredditIcon(mExecutor, new Handler(), mRedditDataRoomDatabase, subredditName, mAccessToken, mOauthRetrofit, mRetrofit, iconImageUrl -> { + iconUrl = iconImageUrl; + displaySubredditIcon(); + loadSubredditIconSuccessful = true; + }); + } + + private void promptAlertDialog(int titleResId, int messageResId) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(titleResId) + .setMessage(messageResId) + .setPositiveButton(R.string.discard_dialog_button, (dialogInterface, i) + -> finish()) + .setNegativeButton(R.string.no, null) + .show(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.post_poll_activity, menu); + applyMenuItemTheme(menu); + mMemu = menu; + if (isPosting) { + mMemu.findItem(R.id.action_send_post_poll_activity).setEnabled(false); + mMemu.findItem(R.id.action_send_post_poll_activity).getIcon().setAlpha(130); + } + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + int itemId = item.getItemId(); + if (itemId == android.R.id.home) { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + return true; + } else { + if (!titleEditText.getText().toString().equals("") + || !option1TextInputEditText.getText().toString().equals("") + || !option2TextInputEditText.getText().toString().equals("") + || !option3TextInputEditText.getText().toString().equals("") + || !option4TextInputEditText.getText().toString().equals("") + || !option5TextInputEditText.getText().toString().equals("") + || !option6TextInputEditText.getText().toString().equals("")) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + return true; + } + } + finish(); + return true; + } else if (itemId == R.id.action_send_post_poll_activity) { + if (!subredditSelected) { + Snackbar.make(coordinatorLayout, R.string.select_a_subreddit, Snackbar.LENGTH_SHORT).show(); + return true; + } + + if (titleEditText.getText() == null) { + Snackbar.make(coordinatorLayout, R.string.title_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + String subredditName; + if (subredditIsUser) { + subredditName = "u_" + subredditNameTextView.getText().toString(); + } else { + subredditName = subredditNameTextView.getText().toString(); + } + + ArrayList<String> optionList = new ArrayList<>(); + if (!option1TextInputEditText.getText().toString().equals("")) { + optionList.add(option1TextInputEditText.getText().toString()); + } + if (!option2TextInputEditText.getText().toString().equals("")) { + optionList.add(option2TextInputEditText.getText().toString()); + } + if (!option3TextInputEditText.getText().toString().equals("")) { + optionList.add(option3TextInputEditText.getText().toString()); + } + if (!option4TextInputEditText.getText().toString().equals("")) { + optionList.add(option4TextInputEditText.getText().toString()); + } + if (!option5TextInputEditText.getText().toString().equals("")) { + optionList.add(option5TextInputEditText.getText().toString()); + } + if (!option6TextInputEditText.getText().toString().equals("")) { + optionList.add(option6TextInputEditText.getText().toString()); + } + + if (optionList.size() < 2) { + Snackbar.make(coordinatorLayout, R.string.two_options_required, Snackbar.LENGTH_SHORT).show(); + return true; + } + + isPosting = true; + + item.setEnabled(false); + item.getIcon().setAlpha(130); + + mPostingSnackbar.show(); + + Intent intent = new Intent(this, SubmitPostService.class); + intent.putExtra(SubmitPostService.EXTRA_ACCESS_TOKEN, mAccessToken); + intent.putExtra(SubmitPostService.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(SubmitPostService.EXTRA_POST_TYPE, SubmitPostService.EXTRA_POST_TYPE_POLL); + PollPayload payload = new PollPayload(subredditName, titleEditText.getText().toString(), + optionList.toArray(new String[0]), (int) votingLengthSlider.getValue(), isNSFW, isSpoiler, flair, receivePostReplyNotificationsSwitchMaterial.isChecked(), + subredditIsUser ? "profile" : "subreddit"); + intent.putExtra(SubmitPostService.EXTRA_POLL_PAYLOAD, new Gson().toJson(payload)); + + ContextCompat.startForegroundService(this, intent); + + return true; + } + + return false; + } + + @Override + public void onBackPressed() { + if (isPosting) { + promptAlertDialog(R.string.exit_when_submit, R.string.exit_when_submit_post_detail); + } else { + if (!titleEditText.getText().toString().equals("") + || !option1TextInputEditText.getText().toString().equals("") + || !option2TextInputEditText.getText().toString().equals("") + || !option3TextInputEditText.getText().toString().equals("") + || !option4TextInputEditText.getText().toString().equals("") + || !option5TextInputEditText.getText().toString().equals("") + || !option6TextInputEditText.getText().toString().equals("")) { + promptAlertDialog(R.string.discard, R.string.discard_detail); + } else { + finish(); + } + } + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString(SUBREDDIT_NAME_STATE, subredditName); + outState.putString(SUBREDDIT_ICON_STATE, iconUrl); + outState.putBoolean(SUBREDDIT_SELECTED_STATE, subredditSelected); + outState.putBoolean(SUBREDDIT_IS_USER_STATE, subredditIsUser); + outState.putBoolean(LOAD_SUBREDDIT_ICON_STATE, loadSubredditIconSuccessful); + outState.putBoolean(IS_POSTING_STATE, isPosting); + outState.putParcelable(FLAIR_STATE, flair); + outState.putBoolean(IS_SPOILER_STATE, isSpoiler); + outState.putBoolean(IS_NSFW_STATE, isNSFW); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == SUBREDDIT_SELECTION_REQUEST_CODE) { + if (resultCode == RESULT_OK) { + subredditName = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_NAME); + iconUrl = data.getExtras().getString(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_ICON_URL); + subredditSelected = true; + subredditIsUser = data.getExtras().getBoolean(SubredditSelectionActivity.EXTRA_RETURN_SUBREDDIT_IS_USER); + + subredditNameTextView.setTextColor(primaryTextColor); + subredditNameTextView.setText(subredditName); + displaySubredditIcon(); + + flairTextView.setVisibility(View.VISIBLE); + flairTextView.setBackgroundColor(resources.getColor(android.R.color.transparent)); + flairTextView.setTextColor(primaryTextColor); + flairTextView.setText(getString(R.string.flair)); + flair = null; + } + } + } + + @Override + public void flairSelected(Flair flair) { + this.flair = flair; + flairTextView.setText(flair.getText()); + flairTextView.setBackgroundColor(flairBackgroundColor); + flairTextView.setBorderColor(flairBackgroundColor); + flairTextView.setTextColor(flairTextColor); + } + + @Subscribe + public void onAccountSwitchEvent(SwitchAccountEvent event) { + finish(); + } + + @Subscribe + public void onSubmitPollPostEvent(SubmitPollPostEvent submitPollPostEvent) { + isPosting = false; + mPostingSnackbar.dismiss(); + if (submitPollPostEvent.postSuccess) { + Intent intent = new Intent(this, LinkResolverActivity.class); + intent.setData(Uri.parse(submitPollPostEvent.postUrl)); + startActivity(intent); + finish(); + } else { + mMemu.findItem(R.id.action_send_post_poll_activity).setEnabled(true); + mMemu.findItem(R.id.action_send_post_poll_activity).getIcon().setAlpha(255); + if (submitPollPostEvent.errorMessage == null || submitPollPostEvent.errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, submitPollPostEvent.errorMessage.substring(0, 1).toUpperCase() + + submitPollPostEvent.errorMessage.substring(1), Snackbar.LENGTH_SHORT).show(); + } + } + } +}
\ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java index 2d928ac5..ab60515e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/SearchResultActivity.java @@ -741,6 +741,10 @@ public class SearchResultActivity extends BaseActivity implements SortTypeSelect case PostTypeBottomSheetFragment.TYPE_GALLERY: intent = new Intent(this, PostGalleryActivity.class); startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_POLL: + intent = new Intent(this, PostPollActivity.class); + startActivity(intent); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java index b2b82fa6..f63c1cd3 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewSubredditDetailActivity.java @@ -1277,7 +1277,12 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp break; case PostTypeBottomSheetFragment.TYPE_GALLERY: intent = new Intent(this, PostGalleryActivity.class); - intent.putExtra(PostVideoActivity.EXTRA_SUBREDDIT_NAME, subredditName); + intent.putExtra(PostGalleryActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_POLL: + intent = new Intent(this, PostPollActivity.class); + intent.putExtra(PostPollActivity.EXTRA_SUBREDDIT_NAME, subredditName); startActivity(intent); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java index 731c6aa9..78625af4 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/activities/ViewUserDetailActivity.java @@ -1570,6 +1570,10 @@ public class ViewUserDetailActivity extends BaseActivity implements SortTypeSele case PostTypeBottomSheetFragment.TYPE_GALLERY: intent = new Intent(this, PostGalleryActivity.class); startActivity(intent); + break; + case PostTypeBottomSheetFragment.TYPE_POLL: + intent = new Intent(this, PostPollActivity.class); + startActivity(intent); } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java index fa672901..f4120d14 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/apis/RedditAPI.java @@ -294,6 +294,9 @@ public interface RedditAPI { @POST("/api/submit_gallery_post.json?resubmit=true&raw_json=1") Call<String> submitGalleryPost(@HeaderMap Map<String, String> headers, @Body String body); + @POST("/api/submit_poll_post.json?resubmit=true&raw_json=1&gilding_detail=1") + Call<String> submitPollPost(@HeaderMap Map<String, String> headers, @Body String body); + @GET("/api/trending_searches_v1.json?withAds=0&raw_json=1&gilding_detail=1") Call<String> getTrendingSearches(); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java index fd6fc650..bc410123 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/bottomsheetfragments/PostTypeBottomSheetFragment.java @@ -31,6 +31,7 @@ public class PostTypeBottomSheetFragment extends LandscapeExpandedRoundedBottomS public static final int TYPE_IMAGE = 2; public static final int TYPE_VIDEO = 3; public static final int TYPE_GALLERY = 4; + public static final int TYPE_POLL = 5; @BindView(R.id.text_type_linear_layout_post_type_bottom_sheet_fragment) TextView textTypeTextView; @BindView(R.id.link_type_linear_layout_post_type_bottom_sheet_fragment) @@ -41,6 +42,8 @@ public class PostTypeBottomSheetFragment extends LandscapeExpandedRoundedBottomS TextView videoTypeTextView; @BindView(R.id.gallery_type_linear_layout_post_type_bottom_sheet_fragment) TextView galleryTypeTextView; + @BindView(R.id.poll_type_linear_layout_post_type_bottom_sheet_fragment) + TextView pollTypeTextView; private BaseActivity activity; public PostTypeBottomSheetFragment() { @@ -83,6 +86,11 @@ public class PostTypeBottomSheetFragment extends LandscapeExpandedRoundedBottomS dismiss(); }); + pollTypeTextView.setOnClickListener(view -> { + ((PostTypeSelectionCallback) activity).postTypeSelected(TYPE_POLL); + dismiss(); + }); + if (activity.typeface != null) { Utils.setFontToAllTextViews(rootView, activity.typeface); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitPollPostEvent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitPollPostEvent.java new file mode 100644 index 00000000..63b4c9cf --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/events/SubmitPollPostEvent.java @@ -0,0 +1,13 @@ +package ml.docilealligator.infinityforreddit.events; + +public class SubmitPollPostEvent { + public boolean postSuccess; + public String postUrl; + public String errorMessage; + + public SubmitPollPostEvent(boolean postSuccess, String postUrl, String errorMessage) { + this.postSuccess = postSuccess; + this.postUrl = postUrl; + this.errorMessage = errorMessage; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java b/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java index f1ba75f3..0882e491 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/services/SubmitPostService.java @@ -47,6 +47,7 @@ import ml.docilealligator.infinityforreddit.customtheme.CustomThemeWrapper; import ml.docilealligator.infinityforreddit.events.SubmitCrosspostEvent; import ml.docilealligator.infinityforreddit.events.SubmitGalleryPostEvent; import ml.docilealligator.infinityforreddit.events.SubmitImagePostEvent; +import ml.docilealligator.infinityforreddit.events.SubmitPollPostEvent; import ml.docilealligator.infinityforreddit.events.SubmitTextOrLinkPostEvent; import ml.docilealligator.infinityforreddit.events.SubmitVideoOrGifPostEvent; import ml.docilealligator.infinityforreddit.post.Post; @@ -63,6 +64,7 @@ public class SubmitPostService extends Service { public static final String EXTRA_TITLE = "ET"; public static final String EXTRA_CONTENT = "EC"; public static final String EXTRA_REDDIT_GALLERY_PAYLOAD = "ERGP"; + public static final String EXTRA_POLL_PAYLOAD = "EPP"; public static final String EXTRA_KIND = "EK"; public static final String EXTRA_FLAIR = "EF"; public static final String EXTRA_IS_SPOILER = "EIS"; @@ -73,7 +75,8 @@ public class SubmitPostService extends Service { public static final int EXTRA_POST_TYPE_IMAGE = 1; public static final int EXTRA_POST_TYPE_VIDEO = 2; public static final int EXTRA_POST_TYPE_GALLERY = 3; - public static final int EXTRA_POST_TYPE_CROSSPOST = 4; + public static final int EXTRA_POST_TYPE_POLL = 4; + public static final int EXTRA_POST_TYPE_CROSSPOST = 5; private static final String EXTRA_MEDIA_URI = "EU"; @Inject @@ -136,8 +139,10 @@ public class SubmitPostService extends Service { Uri mediaUri = Uri.parse(bundle.getString(EXTRA_MEDIA_URI)); submitVideoPost(accessToken, mediaUri, subredditName, title, flair, isSpoiler, isNSFW, receivePostReplyNotifications); - } else { + } else if (postType == EXTRA_POST_TYPE_GALLERY) { submitGalleryPost(accessToken, bundle.getString(EXTRA_REDDIT_GALLERY_PAYLOAD)); + } else { + submitPollPost(accessToken, bundle.getString(EXTRA_POLL_PAYLOAD)); } } } @@ -373,6 +378,42 @@ public class SubmitPostService extends Service { } } + private void submitPollPost(String accessToken, String payload) { + try { + Response<String> response = mOauthRetrofit.create(RedditAPI.class).submitPollPost(APIUtils.getOAuthHeader(accessToken), payload).execute(); + if (response.isSuccessful()) { + JSONObject responseObject = new JSONObject(response.body()).getJSONObject(JSONUtils.JSON_KEY); + if (responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() != 0) { + JSONArray error = responseObject.getJSONArray(JSONUtils.ERRORS_KEY) + .getJSONArray(responseObject.getJSONArray(JSONUtils.ERRORS_KEY).length() - 1); + if (error.length() != 0) { + String errorMessage; + if (error.length() >= 2) { + errorMessage = error.getString(1); + } else { + errorMessage = error.getString(0); + } + handler.post(() -> EventBus.getDefault().post(new SubmitPollPostEvent(false, null, errorMessage))); + } else { + handler.post(() -> EventBus.getDefault().post(new SubmitPollPostEvent(false, null, null))); + } + } else { + String postUrl = responseObject.getJSONObject(JSONUtils.DATA_KEY).getString(JSONUtils.URL_KEY); + handler.post(() -> { + EventBus.getDefault().post(new SubmitPollPostEvent(true, postUrl, null)); + }); + } + } else { + handler.post(() -> EventBus.getDefault().post(new SubmitPollPostEvent(false, null, response.message()))); + } + } catch (IOException | JSONException e) { + e.printStackTrace(); + handler.post(() -> EventBus.getDefault().post(new SubmitPollPostEvent(false, null, e.getMessage()))); + } finally { + stopService(); + } + } + private static void copyFileToCache(InputStream fileInputStream, String destinationFilePath) throws IOException { OutputStream out = new FileOutputStream(destinationFilePath); byte[] buf = new byte[2048]; |