From a3367c193b2b9f6e385c155e543debd9f2bb3426 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Thu, 17 Sep 2020 11:08:06 +0800 Subject: Select user flair in subreddits. --- .../infinityforreddit/API/RedditAPI.java | 8 + .../Activity/SelectUserFlairActivity.java | 261 +++++++++++++++++++++ .../Activity/ViewSubredditDetailActivity.java | 9 + .../Adapter/UserFlairRecyclerViewAdapter.java | 88 +++++++ .../infinityforreddit/AppComponent.java | 3 + .../infinityforreddit/FetchUserFlairs.java | 122 ++++++++++ .../infinityforreddit/SelectUserFlair.java | 105 +++++++++ .../infinityforreddit/UserFlair.java | 78 ++++++ .../infinityforreddit/Utils/JSONUtils.java | 2 + 9 files changed, 676 insertions(+) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectUserFlairActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserFlairRecyclerViewAdapter.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserFlairs.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/SelectUserFlair.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/UserFlair.java (limited to 'app/src/main/java') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/API/RedditAPI.java b/app/src/main/java/ml/docilealligator/infinityforreddit/API/RedditAPI.java index 003ad955..c4589206 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/API/RedditAPI.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/API/RedditAPI.java @@ -318,4 +318,12 @@ public interface RedditAPI { @FormUrlEncoded @POST("api/block_user") Call blockUser(@HeaderMap Map headers, @FieldMap Map params); + + @GET("r/{subredditName}/api/user_flair_v2.json?raw_json=1") + Call getUserFlairs(@HeaderMap Map headers, @Path("subredditName") String subredditName); + + @FormUrlEncoded + @POST("/r/{subredditName}/api/selectflair?raw_json=1") + Call selectUserFlair(@HeaderMap Map headers, @FieldMap Map params, + @Path("subredditName") String subredditName); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectUserFlairActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectUserFlairActivity.java new file mode 100644 index 00000000..e90432f3 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/SelectUserFlairActivity.java @@ -0,0 +1,261 @@ +package ml.docilealligator.infinityforreddit.Activity; + +import android.content.Context; +import android.content.SharedPreferences; +import android.os.Build; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.recyclerview.widget.LinearLayoutManager; +import androidx.recyclerview.widget.RecyclerView; + +import com.google.android.material.appbar.AppBarLayout; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.snackbar.Snackbar; +import com.r0adkll.slidr.Slidr; + +import java.util.ArrayList; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.ActivityToolbarInterface; +import ml.docilealligator.infinityforreddit.Adapter.UserFlairRecyclerViewAdapter; +import ml.docilealligator.infinityforreddit.AsyncTask.GetCurrentAccountAsyncTask; +import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.FetchUserFlairs; +import ml.docilealligator.infinityforreddit.Infinity; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.RedditDataRoomDatabase; +import ml.docilealligator.infinityforreddit.SelectUserFlair; +import ml.docilealligator.infinityforreddit.UserFlair; +import ml.docilealligator.infinityforreddit.Utils.SharedPreferencesUtils; +import retrofit2.Retrofit; + +public class SelectUserFlairActivity extends BaseActivity implements ActivityToolbarInterface { + + public static final String EXTRA_SUBREDDIT_NAME = "ESN"; + private static final String NULL_ACCESS_TOKEN_STATE = "NATS"; + private static final String ACCESS_TOKEN_STATE = "ATS"; + private static final String ACCOUNT_NAME_STATE = "ANS"; + private static final String USER_FLAIRS_STATE = "UFS"; + + @BindView(R.id.coordinator_layout_select_user_flair_activity) + CoordinatorLayout coordinatorLayout; + @BindView(R.id.appbar_layout_select_user_flair_activity) + AppBarLayout appBarLayout; + @BindView(R.id.toolbar_select_user_flair_activity) + Toolbar toolbar; + @BindView(R.id.recycler_view_select_user_flair_activity) + RecyclerView recyclerView; + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + @Inject + RedditDataRoomDatabase mRedditDataRoomDatabase; + @Inject + @Named("default") + SharedPreferences mSharedPreferences; + @Inject + CustomThemeWrapper mCustomThemeWrapper; + private LinearLayoutManager mLinearLayoutManager; + private boolean mNullAccessToken = false; + private String mAccessToken; + private String mAccountName; + private ArrayList mUserFlairs; + private String mSubredditName; + private UserFlairRecyclerViewAdapter mAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + ((Infinity) getApplication()).getAppComponent().inject(this); + + setImmersiveModeNotApplicable(); + + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_select_user_flair); + + ButterKnife.bind(this); + + applyCustomTheme(); + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && isChangeStatusBarIconColor()) { + addOnOffsetChangedListener(appBarLayout); + } + + if (mSharedPreferences.getBoolean(SharedPreferencesUtils.SWIPE_RIGHT_TO_GO_BACK, true)) { + Slidr.attach(this); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + setToolbarGoToTop(toolbar); + + mSubredditName = getIntent().getStringExtra(EXTRA_SUBREDDIT_NAME); + setTitle(mSubredditName); + + if (savedInstanceState != null) { + mNullAccessToken = savedInstanceState.getBoolean(NULL_ACCESS_TOKEN_STATE); + mAccessToken = savedInstanceState.getString(ACCESS_TOKEN_STATE); + mAccountName = savedInstanceState.getString(ACCOUNT_NAME_STATE); + mUserFlairs = savedInstanceState.getParcelableArrayList(USER_FLAIRS_STATE); + + if (!mNullAccessToken && mAccessToken == null) { + getCurrentAccountAndBindView(); + } else { + bindView(); + } + } else { + getCurrentAccountAndBindView(); + } + } + + private void getCurrentAccountAndBindView() { + new GetCurrentAccountAsyncTask(mRedditDataRoomDatabase.accountDao(), account -> { + if (account == null) { + mNullAccessToken = true; + } else { + mAccessToken = account.getAccessToken(); + mAccountName = account.getUsername(); + } + bindView(); + }).execute(); + } + + private void bindView() { + if (mUserFlairs == null) { + FetchUserFlairs.fetchUserFlairsInSubreddit(mOauthRetrofit, mAccessToken, mSubredditName, + new FetchUserFlairs.FetchUserFlairsInSubredditListener() { + @Override + public void fetchSuccessful(ArrayList userFlairs) { + mUserFlairs = userFlairs; + instantiateRecyclerView(); + } + + @Override + public void fetchFailed() { + + } + }); + } else { + instantiateRecyclerView(); + } + } + + private void instantiateRecyclerView() { + mAdapter = new UserFlairRecyclerViewAdapter(mCustomThemeWrapper, mUserFlairs, (userFlair, editUserFlair) -> { + if (editUserFlair) { + View dialogView = getLayoutInflater().inflate(R.layout.dialog_edit_flair, null); + EditText flairEditText = dialogView.findViewById(R.id.flair_edit_text_edit_flair_dialog); + flairEditText.setText(userFlair.getText()); + flairEditText.requestFocus(); + InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE); + if (imm != null) { + imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); + } + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.edit_flair) + .setView(dialogView) + .setPositiveButton(R.string.ok, (dialogInterface, i) + -> { + if (imm != null) { + imm.hideSoftInputFromWindow(flairEditText.getWindowToken(), 0); + } + userFlair.setText(flairEditText.getText().toString()); + selectUserFlair(userFlair); + }) + .setNegativeButton(R.string.cancel, (dialogInterface, i) -> { + if (imm != null) { + imm.hideSoftInputFromWindow(flairEditText.getWindowToken(), 0); + } + }) + .setOnDismissListener(dialogInterface -> { + if (imm != null) { + imm.hideSoftInputFromWindow(flairEditText.getWindowToken(), 0); + } + }) + .show(); + } else { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.select_this_user_flair) + .setMessage(userFlair.getText()) + .setPositiveButton(R.string.yes, (dialogInterface, i) -> selectUserFlair(userFlair)) + .setNegativeButton(R.string.no, null) + .show(); + } + }); + mLinearLayoutManager = new LinearLayoutManager(SelectUserFlairActivity.this); + recyclerView.setLayoutManager(mLinearLayoutManager); + recyclerView.setAdapter(mAdapter); + } + + private void selectUserFlair(UserFlair userFlair) { + SelectUserFlair.selectUserFlair(mOauthRetrofit, mAccessToken, userFlair, mSubredditName, mAccountName, + new SelectUserFlair.SelectUserFlairListener() { + @Override + public void success() { + Toast.makeText(SelectUserFlairActivity.this, R.string.select_user_flair_success, Toast.LENGTH_SHORT).show(); + finish(); + } + + @Override + public void failed(String errorMessage) { + if (errorMessage == null || errorMessage.equals("")) { + Snackbar.make(coordinatorLayout, R.string.select_user_flair_success, Snackbar.LENGTH_SHORT).show(); + } else { + Snackbar.make(coordinatorLayout, errorMessage, Snackbar.LENGTH_SHORT).show(); + } + } + }); + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if (item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } + + @Override + protected void onSaveInstanceState(@NonNull Bundle outState) { + super.onSaveInstanceState(outState); + outState.putBoolean(NULL_ACCESS_TOKEN_STATE, mNullAccessToken); + outState.putString(ACCESS_TOKEN_STATE, mAccessToken); + outState.putString(ACCOUNT_NAME_STATE, mAccountName); + outState.putParcelableArrayList(USER_FLAIRS_STATE, mUserFlairs); + } + + @Override + protected SharedPreferences getDefaultSharedPreferences() { + return mSharedPreferences; + } + + @Override + protected CustomThemeWrapper getCustomThemeWrapper() { + return mCustomThemeWrapper; + } + + @Override + protected void applyCustomTheme() { + coordinatorLayout.setBackgroundColor(mCustomThemeWrapper.getBackgroundColor()); + applyAppBarLayoutAndToolbarTheme(appBarLayout, toolbar); + } + + @Override + public void onLongPress() { + if (mLinearLayoutManager != null) { + mLinearLayoutManager.scrollToPositionWithOffset(0, 0); + } + } +} \ No newline at end of file diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewSubredditDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewSubredditDetailActivity.java index 8b688f63..5982ee7e 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewSubredditDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Activity/ViewSubredditDetailActivity.java @@ -749,6 +749,15 @@ public class ViewSubredditDetailActivity extends BaseActivity implements SortTyp case R.id.action_change_post_layout_view_subreddit_detail_activity: postLayoutBottomSheetFragment.show(getSupportFragmentManager(), postLayoutBottomSheetFragment.getTag()); return true; + case R.id.action_select_user_flair_view_subreddit_detail_activity: + if (mAccessToken == null) { + Toast.makeText(this, R.string.login_first, Toast.LENGTH_SHORT).show(); + return true; + } + Intent selectUserFlairIntent = new Intent(this, SelectUserFlairActivity.class); + selectUserFlairIntent.putExtra(SelectUserFlairActivity.EXTRA_SUBREDDIT_NAME, subredditName); + startActivity(selectUserFlairIntent); + return true; case R.id.action_share_view_subreddit_detail_activity: Intent shareIntent = new Intent(Intent.ACTION_SEND); shareIntent.setType("text/plain"); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserFlairRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserFlairRecyclerViewAdapter.java new file mode 100644 index 00000000..e0669959 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Adapter/UserFlairRecyclerViewAdapter.java @@ -0,0 +1,88 @@ +package ml.docilealligator.infinityforreddit.Adapter; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ImageView; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.RecyclerView; + +import java.util.ArrayList; + +import butterknife.BindView; +import butterknife.ButterKnife; +import ml.docilealligator.infinityforreddit.CustomTheme.CustomThemeWrapper; +import ml.docilealligator.infinityforreddit.R; +import ml.docilealligator.infinityforreddit.UserFlair; +import ml.docilealligator.infinityforreddit.Utils.Utils; + +public class UserFlairRecyclerViewAdapter extends RecyclerView.Adapter { + private CustomThemeWrapper customThemeWrapper; + private ArrayList userFlairs; + private ItemClickListener itemClickListener; + + public UserFlairRecyclerViewAdapter(CustomThemeWrapper customThemeWrapper, ArrayList userFlairs, + ItemClickListener itemClickListener) { + this.customThemeWrapper = customThemeWrapper; + this.userFlairs = userFlairs; + this.itemClickListener = itemClickListener; + } + + public interface ItemClickListener { + void onClick(UserFlair userFlair, boolean editUserFlair); + } + + @NonNull + @Override + public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { + return new UserFlairViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_user_flair, parent, false)); + } + + @Override + public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) { + if (holder instanceof UserFlairViewHolder) { + UserFlair userFlair = userFlairs.get(holder.getAdapterPosition()); + if (userFlair.getHtmlText() == null || userFlair.getHtmlText().equals("")) { + ((UserFlairViewHolder) holder).userFlairHtmlTextView.setText(userFlair.getText()); + } else { + Utils.setHTMLWithImageToTextView(((UserFlairViewHolder) holder).userFlairHtmlTextView, userFlair.getHtmlText()); + } + if (userFlair.isEditable()) { + ((UserFlairViewHolder) holder).editUserFlairImageView.setVisibility(View.VISIBLE); + } else { + ((UserFlairViewHolder) holder).editUserFlairImageView.setVisibility(View.GONE); + } + } + } + + @Override + public int getItemCount() { + return userFlairs == null ? 0 : userFlairs.size(); + } + + class UserFlairViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.user_flair_html_text_view_item_user_flair) + TextView userFlairHtmlTextView; + @BindView(R.id.edit_user_flair_image_view_item_user_flair) + ImageView editUserFlairImageView; + + public UserFlairViewHolder(@NonNull View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + userFlairHtmlTextView.setTextColor(customThemeWrapper.getPrimaryTextColor()); + editUserFlairImageView.setColorFilter(customThemeWrapper.getPrimaryTextColor(), android.graphics.PorterDuff.Mode.SRC_IN); + + itemView.setOnClickListener(view -> { + itemClickListener.onClick(userFlairs.get(getAdapterPosition()), false); + }); + + editUserFlairImageView.setOnClickListener(view -> { + itemClickListener.onClick(userFlairs.get(getAdapterPosition()), true); + }); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index 9b40041d..328b3714 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -27,6 +27,7 @@ import ml.docilealligator.infinityforreddit.Activity.RulesActivity; import ml.docilealligator.infinityforreddit.Activity.SearchActivity; import ml.docilealligator.infinityforreddit.Activity.SearchResultActivity; import ml.docilealligator.infinityforreddit.Activity.SearchSubredditsResultActivity; +import ml.docilealligator.infinityforreddit.Activity.SelectUserFlairActivity; import ml.docilealligator.infinityforreddit.Activity.SelectedSubredditsActivity; import ml.docilealligator.infinityforreddit.Activity.SendPrivateMessageActivity; import ml.docilealligator.infinityforreddit.Activity.SettingsActivity; @@ -200,4 +201,6 @@ public interface AppComponent { void inject(SubmitCrosspostActivity submitCrosspostActivity); void inject(CommentFullMarkdownActivity commentFullMarkdownActivity); + + void inject(SelectUserFlairActivity selectUserFlairActivity); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserFlairs.java b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserFlairs.java new file mode 100644 index 00000000..5d3586bc --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/FetchUserFlairs.java @@ -0,0 +1,122 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.AsyncTask; +import android.text.Html; + +import androidx.annotation.NonNull; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.ArrayList; + +import ml.docilealligator.infinityforreddit.API.RedditAPI; +import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.Utils.JSONUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class FetchUserFlairs { + public static void fetchUserFlairsInSubreddit(Retrofit oauthRetrofit, String accessToken, String subredditName, FetchUserFlairsInSubredditListener fetchUserFlairsInSubredditListener) { + RedditAPI api = oauthRetrofit.create(RedditAPI.class); + + Call flairsCall = api.getUserFlairs(APIUtils.getOAuthHeader(accessToken), subredditName); + flairsCall.enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseUserFlairsAsyncTask(response.body(), new ParseUserFlairsAsyncTask.ParseUserFlairsAsyncTaskListener() { + @Override + public void parseSuccessful(ArrayList userFlairs) { + fetchUserFlairsInSubredditListener.fetchSuccessful(userFlairs); + } + + @Override + public void parseFailed() { + fetchUserFlairsInSubredditListener.fetchFailed(); + } + }).execute(); + } else if (response.code() == 403) { + //No flairs + fetchUserFlairsInSubredditListener.fetchSuccessful(null); + } else { + fetchUserFlairsInSubredditListener.fetchFailed(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + fetchUserFlairsInSubredditListener.fetchFailed(); + } + }); + } + + public interface FetchUserFlairsInSubredditListener { + void fetchSuccessful(ArrayList userFlairs); + + void fetchFailed(); + } + + private static class ParseUserFlairsAsyncTask extends AsyncTask, ArrayList> { + private String response; + private ParseUserFlairsAsyncTaskListener parseFlairsAsyncTaskListener; + + ParseUserFlairsAsyncTask(String response, ParseUserFlairsAsyncTaskListener parseFlairsAsyncTaskListener) { + this.response = response; + this.parseFlairsAsyncTaskListener = parseFlairsAsyncTaskListener; + } + + @Override + protected ArrayList doInBackground(Void... voids) { + try { + JSONArray jsonArray = new JSONArray(response); + ArrayList userFlairs = new ArrayList<>(); + for (int i = 0; i < jsonArray.length(); i++) { + JSONObject userFlairObject = jsonArray.getJSONObject(i); + String id = userFlairObject.getString(JSONUtils.ID_KEY); + String text = userFlairObject.getString(JSONUtils.TEXT_KEY); + boolean editable = userFlairObject.getBoolean(JSONUtils.TEXT_EDITABLE_KEY); + int maxEmojis = userFlairObject.getInt(JSONUtils.MAX_EMOJIS_KEY); + + StringBuilder authorFlairHTMLBuilder = new StringBuilder(); + if (userFlairObject.has(JSONUtils.RICHTEXT_KEY)) { + JSONArray flairArray = userFlairObject.getJSONArray(JSONUtils.RICHTEXT_KEY); + for (int j = 0; j < flairArray.length(); j++) { + JSONObject flairObject = flairArray.getJSONObject(j); + String e = flairObject.getString(JSONUtils.E_KEY); + if (e.equals("text")) { + authorFlairHTMLBuilder.append(Html.escapeHtml(flairObject.getString(JSONUtils.T_KEY))); + } else if (e.equals("emoji")) { + authorFlairHTMLBuilder.append(""); + } + } + } + + userFlairs.add(new UserFlair(id, text, authorFlairHTMLBuilder.toString(), editable, maxEmojis)); + } + return userFlairs; + } catch (JSONException e) { + e.printStackTrace(); + } + return null; + } + + @Override + protected void onPostExecute(ArrayList userFlairs) { + if (userFlairs != null) { + parseFlairsAsyncTaskListener.parseSuccessful(userFlairs); + } else { + parseFlairsAsyncTaskListener.parseFailed(); + } + } + + interface ParseUserFlairsAsyncTaskListener { + void parseSuccessful(ArrayList userFlairs); + + void parseFailed(); + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/SelectUserFlair.java b/app/src/main/java/ml/docilealligator/infinityforreddit/SelectUserFlair.java new file mode 100644 index 00000000..92761426 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/SelectUserFlair.java @@ -0,0 +1,105 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.AsyncTask; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.HashMap; +import java.util.Map; + +import ml.docilealligator.infinityforreddit.API.RedditAPI; +import ml.docilealligator.infinityforreddit.Utils.APIUtils; +import ml.docilealligator.infinityforreddit.Utils.JSONUtils; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class SelectUserFlair { + public interface SelectUserFlairListener { + void success(); + void failed(String errorMessage); + } + + public static void selectUserFlair(Retrofit oauthRetrofit, String accessToken, UserFlair userFlair, + String subredditName, String accountName, SelectUserFlairListener selectUserFlairListener) { + Map params = new HashMap<>(); + params.put(APIUtils.API_TYPE_KEY, APIUtils.API_TYPE_JSON); + params.put(APIUtils.FLAIR_TEMPLATE_ID_KEY, userFlair.getId()); + params.put(APIUtils.NAME_KEY, accountName); + params.put(APIUtils.TEXT_KEY, userFlair.getText()); + oauthRetrofit.create(RedditAPI.class).selectUserFlair(APIUtils.getOAuthHeader(accessToken), params, subredditName) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + if (response.isSuccessful()) { + new ParseErrorAsyncTask(response.body(), selectUserFlairListener).execute(); + } else { + selectUserFlairListener.failed(response.message()); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + selectUserFlairListener.failed(t.getMessage()); + } + }); + } + + private static class ParseErrorAsyncTask extends AsyncTask { + + private String response; + @Nullable + private String errorMessage; + private SelectUserFlairListener selectUserFlairListener; + + interface ParseErrorAsyncTaskListener { + void parseFinished(@Nullable String errorMessage); + } + + ParseErrorAsyncTask(String response, SelectUserFlairListener selectUserFlairListener) { + this.response = response; + this.selectUserFlairListener = selectUserFlairListener; + } + + @Override + protected Void doInBackground(Void... voids) { + try { + JSONObject responseObject = new JSONObject(response).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 errorString; + if (error.length() >= 2) { + errorString = error.getString(1); + } else { + errorString = error.getString(0); + } + errorMessage = errorString.substring(0, 1).toUpperCase() + errorString.substring(1); + } + } + } catch (JSONException e) { + e.printStackTrace(); + } + + return null; + } + + @Override + protected void onPostExecute(Void aVoid) { + super.onPostExecute(aVoid); + if (errorMessage == null) { + selectUserFlairListener.success(); + } else { + selectUserFlairListener.failed(errorMessage); + } + } + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/UserFlair.java b/app/src/main/java/ml/docilealligator/infinityforreddit/UserFlair.java new file mode 100644 index 00000000..1854ee89 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/UserFlair.java @@ -0,0 +1,78 @@ +package ml.docilealligator.infinityforreddit; + +import android.os.Parcel; +import android.os.Parcelable; + +public class UserFlair implements Parcelable { + private String id; + private String text; + private String htmlText; + private boolean editable; + private int maxEmojis; + + public UserFlair(String id, String text, String htmlText, boolean editable, int maxEmojis) { + this.id = id; + this.text = text; + this.htmlText = htmlText; + this.editable = editable; + this.maxEmojis = maxEmojis; + } + + protected UserFlair(Parcel in) { + id = in.readString(); + text = in.readString(); + htmlText = in.readString(); + editable = in.readByte() != 0; + maxEmojis = in.readInt(); + } + + public static final Creator CREATOR = new Creator() { + @Override + public UserFlair createFromParcel(Parcel in) { + return new UserFlair(in); + } + + @Override + public UserFlair[] newArray(int size) { + return new UserFlair[size]; + } + }; + + public String getId() { + return id; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public String getHtmlText() { + return htmlText; + } + + public boolean isEditable() { + return editable; + } + + public int getMaxEmojis() { + return maxEmojis; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel parcel, int i) { + parcel.writeString(id); + parcel.writeString(text); + parcel.writeString(htmlText); + parcel.writeByte((byte) (editable ? 1 : 0)); + parcel.writeInt(maxEmojis); + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java index 1d9c876f..362d4b3f 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/Utils/JSONUtils.java @@ -123,4 +123,6 @@ public class JSONUtils { public static final String Y_KEY = "y"; public static final String DEST_KEY = "dest"; public static final String GIF_KEY = "gif"; + public static final String MAX_EMOJIS_KEY = "max_emojis"; + public static final String RICHTEXT_KEY = "richtext"; } -- cgit v1.2.3