From 81e0897a1f91a546452a07fb3f3e880e374db368 Mon Sep 17 00:00:00 2001 From: Alex Ning Date: Tue, 13 Aug 2019 14:25:16 +0800 Subject: Editing and deleting comments are now available. --- .../infinityforreddit/AppComponent.java | 1 + .../CommentAndPostRecyclerViewAdapter.java | 78 ++++++++---- .../infinityforreddit/CommentData.java | 8 ++ .../infinityforreddit/CommentsListingFragment.java | 4 +- .../CommentsListingRecyclerViewAdapter.java | 31 +++-- .../infinityforreddit/EditCommentActivity.java | 137 +++++++++++++++++++++ .../ModifyCommentBottomSheetFragment.java | 84 +++++++++++++ .../infinityforreddit/ViewPostDetailActivity.java | 31 ++++- .../infinityforreddit/ViewUserDetailActivity.java | 28 +++++ 9 files changed, 369 insertions(+), 33 deletions(-) create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/EditCommentActivity.java create mode 100644 app/src/main/java/ml/docilealligator/infinityforreddit/ModifyCommentBottomSheetFragment.java (limited to 'app/src/main/java/ml/docilealligator/infinityforreddit') diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java index d77f2397..95c16c0a 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/AppComponent.java @@ -32,4 +32,5 @@ interface AppComponent { void inject(FollowedUsersListingFragment followedUsersListingFragment); void inject(SubredditSelectionActivity subredditSelectionActivity); void inject(EditPostActivity editPostActivity); + void inject(EditCommentActivity editCommentActivity); } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAndPostRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAndPostRecyclerViewAdapter.java index 25005db0..45474c64 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAndPostRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentAndPostRecyclerViewAdapter.java @@ -6,6 +6,7 @@ import android.graphics.ColorFilter; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.net.Uri; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -19,6 +20,7 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; import androidx.browser.customtabs.CustomTabsIntent; import androidx.core.content.ContextCompat; import androidx.recyclerview.widget.RecyclerView; @@ -61,6 +63,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter mVisibleComments; private String mSubredditNamePrefixed; @@ -79,7 +82,7 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter(); mSubredditNamePrefixed = subredditNamePrefixed; @@ -425,6 +429,20 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter { + ModifyCommentBottomSheetFragment modifyCommentBottomSheetFragment = new ModifyCommentBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(ModifyCommentBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(ModifyCommentBottomSheetFragment.EXTRA_COMMENT_CONTENT, comment.getCommentContent()); + bundle.putString(ModifyCommentBottomSheetFragment.EXTRA_COMMENT_FULLNAME, comment.getFullName()); + bundle.putInt(ModifyCommentBottomSheetFragment.EXTRA_POSITION, holder.getAdapterPosition() - 1); + modifyCommentBottomSheetFragment.setArguments(bundle); + modifyCommentBottomSheetFragment.show(((AppCompatActivity) mActivity).getSupportFragmentManager(), modifyCommentBottomSheetFragment.getTag()); + }); + } + if (comment.hasReply()) { if(comment.isExpanded()) { ((CommentViewHolder) holder).expandButton.setImageResource(R.drawable.ic_expand_less_black_20dp); @@ -436,11 +454,11 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter { + upVoteButton.setOnClickListener(view -> { if(mAccessToken == null) { Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); return; @@ -915,18 +951,18 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter { + downVoteButton.setOnClickListener(view -> { if(mAccessToken == null) { Toast.makeText(mActivity, R.string.login_first, Toast.LENGTH_SHORT).show(); return; @@ -960,18 +996,18 @@ class CommentAndPostRecyclerViewAdapter extends RecyclerView.Adapter mCommentViewModel.retryLoadingMore()); + getArguments().getString(EXTRA_ACCESS_TOKEN), getArguments().getString(EXTRA_ACCOUNT_NAME), + () -> mCommentViewModel.retryLoadingMore()); String username = getArguments().getString(EXTRA_USERNAME_KEY); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentsListingRecyclerViewAdapter.java b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentsListingRecyclerViewAdapter.java index e2fd34b5..ffcf707b 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/CommentsListingRecyclerViewAdapter.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/CommentsListingRecyclerViewAdapter.java @@ -2,17 +2,18 @@ package ml.docilealligator.infinityforreddit; import android.content.Context; import android.content.Intent; +import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; -import android.widget.RelativeLayout; import android.widget.TextView; import android.widget.Toast; import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.ContextCompat; import androidx.paging.PagedListAdapter; import androidx.recyclerview.widget.DiffUtil; @@ -27,6 +28,7 @@ class CommentsListingRecyclerViewAdapter extends PagedListAdapter { + ModifyCommentBottomSheetFragment modifyCommentBottomSheetFragment = new ModifyCommentBottomSheetFragment(); + Bundle bundle = new Bundle(); + bundle.putString(ModifyCommentBottomSheetFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(ModifyCommentBottomSheetFragment.EXTRA_COMMENT_CONTENT, comment.getCommentContent()); + bundle.putString(ModifyCommentBottomSheetFragment.EXTRA_COMMENT_FULLNAME, comment.getFullName()); + bundle.putInt(ModifyCommentBottomSheetFragment.EXTRA_POSITION, holder.getAdapterPosition() - 1); + modifyCommentBottomSheetFragment.setArguments(bundle); + modifyCommentBottomSheetFragment.show(((AppCompatActivity) mContext).getSupportFragmentManager(), modifyCommentBottomSheetFragment.getTag()); + }); + } } } @@ -165,9 +182,10 @@ class CommentsListingRecyclerViewAdapter extends PagedListAdapter linearLayout.callOnClick()); - RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) shareButton.getLayoutParams(); - lp.addRule(RelativeLayout.ALIGN_PARENT_END); - lp.setMarginEnd(0); - shareButton.setLayoutParams(lp); - shareButton.setOnClickListener(view -> { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/EditCommentActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/EditCommentActivity.java new file mode 100644 index 00000000..11e30fd8 --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/EditCommentActivity.java @@ -0,0 +1,137 @@ +package ml.docilealligator.infinityforreddit; + +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.Window; +import android.widget.EditText; +import android.widget.Toast; + +import androidx.annotation.NonNull; +import androidx.appcompat.app.AppCompatActivity; +import androidx.appcompat.widget.Toolbar; +import androidx.coordinatorlayout.widget.CoordinatorLayout; +import androidx.core.content.ContextCompat; + +import com.google.android.material.snackbar.Snackbar; + +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Inject; +import javax.inject.Named; + +import butterknife.BindView; +import butterknife.ButterKnife; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; +import retrofit2.Retrofit; + +public class EditCommentActivity extends AppCompatActivity { + + static final String EXTRA_CONTENT = "EC"; + static final String EXTRA_FULLNAME = "EF"; + static final String EXTRA_ACCESS_TOKEN = "EAT"; + static final String EXTRA_POSITION = "EP"; + + static final String EXTRA_EDITED_COMMENT_CONTENT = "EECC"; + static final String EXTRA_EDITED_COMMENT_POSITION = "EECP"; + + @BindView(R.id.coordinator_layout_edit_comment_activity) CoordinatorLayout coordinatorLayout; + @BindView(R.id.toolbar_edit_comment_activity) Toolbar toolbar; + @BindView(R.id.post_text_content_edit_text_edit_comment_activity) EditText contentEditText; + + private String mFullName; + private String mAccessToken; + private boolean isSubmitting = false; + + @Inject + @Named("oauth") + Retrofit mOauthRetrofit; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_edit_comment); + + ButterKnife.bind(this); + + ((Infinity) getApplication()).getAppComponent().inject(this); + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + Window window = getWindow(); + if((getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + window.getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + window.setNavigationBarColor(ContextCompat.getColor(this, R.color.navBarColor)); + } + + setSupportActionBar(toolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + mFullName = getIntent().getExtras().getString(EXTRA_FULLNAME); + mAccessToken = getIntent().getExtras().getString(EXTRA_ACCESS_TOKEN); + contentEditText.setText(getIntent().getExtras().getString(EXTRA_CONTENT)); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.edit_comment_activity, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(@NonNull MenuItem item) { + if(item.getItemId() == R.id.action_send_edit_comment_activity) { + if(!isSubmitting) { + isSubmitting = true; + + Snackbar.make(coordinatorLayout, R.string.posting, Snackbar.LENGTH_SHORT).show(); + + String content = contentEditText.getText().toString(); + + Map params = new HashMap<>(); + params.put(RedditUtils.THING_ID_KEY, mFullName); + params.put(RedditUtils.TEXT_KEY, content); + + mOauthRetrofit.create(RedditAPI.class) + .editPostOrComment(RedditUtils.getOAuthHeader(mAccessToken), params) + .enqueue(new Callback() { + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) { + isSubmitting = false; + if(response.isSuccessful()) { + Toast.makeText(EditCommentActivity.this, R.string.edit_success, Toast.LENGTH_SHORT).show(); + + Intent returnIntent = new Intent(); + returnIntent.putExtra(EXTRA_EDITED_COMMENT_CONTENT, content); + returnIntent.putExtra(EXTRA_EDITED_COMMENT_POSITION, getIntent().getExtras().getInt(EXTRA_POSITION)); + setResult(RESULT_OK, returnIntent); + + finish(); + } else { + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(@NonNull Call call, @NonNull Throwable t) { + isSubmitting = false; + Snackbar.make(coordinatorLayout, R.string.post_failed, Snackbar.LENGTH_SHORT).show(); + } + }); + + } + return true; + } else if(item.getItemId() == android.R.id.home) { + finish(); + return true; + } + return false; + } +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ModifyCommentBottomSheetFragment.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ModifyCommentBottomSheetFragment.java new file mode 100644 index 00000000..5b19cfaf --- /dev/null +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ModifyCommentBottomSheetFragment.java @@ -0,0 +1,84 @@ +package ml.docilealligator.infinityforreddit; + + +import android.app.Activity; +import android.content.Intent; +import android.content.res.Configuration; +import android.os.Build; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import androidx.fragment.app.Fragment; + +import com.deishelon.roundedbottomsheet.RoundedBottomSheetDialogFragment; + +import butterknife.BindView; +import butterknife.ButterKnife; + + +/** + * A simple {@link Fragment} subclass. + */ +public class ModifyCommentBottomSheetFragment extends RoundedBottomSheetDialogFragment { + + static final String EXTRA_COMMENT_FULLNAME = "ECF"; + static final String EXTRA_COMMENT_CONTENT = "ECC"; + static final String EXTRA_ACCESS_TOKEN = "EAT"; + static final String EXTRA_POSITION = "EP"; + + public ModifyCommentBottomSheetFragment() { + // Required empty public constructor + } + + @BindView(R.id.edit_text_view_modify_comment_bottom_sheet_fragment) TextView editTextView; + @BindView(R.id.delete_text_view_modify_comment_bottom_sheet_fragment) TextView deleteTextView; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_modify_comment_bottom_sheet, container, false); + ButterKnife.bind(this, rootView); + + Activity activity = getActivity(); + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + && (getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK) != Configuration.UI_MODE_NIGHT_YES) { + rootView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR); + } + + Bundle bundle = getArguments(); + String fullName = bundle.getString(EXTRA_COMMENT_FULLNAME); + String content = bundle.getString(EXTRA_COMMENT_CONTENT); + String accessToken = bundle.getString(EXTRA_ACCESS_TOKEN); + + editTextView.setOnClickListener(view -> { + Intent intent = new Intent(getActivity(), EditCommentActivity.class); + intent.putExtra(EditCommentActivity.EXTRA_ACCESS_TOKEN, accessToken); + intent.putExtra(EditCommentActivity.EXTRA_FULLNAME, fullName); + intent.putExtra(EditCommentActivity.EXTRA_CONTENT, content); + intent.putExtra(EditCommentActivity.EXTRA_POSITION, bundle.getInt(EXTRA_POSITION)); + if(activity instanceof ViewPostDetailActivity) { + activity.startActivityForResult(intent, ViewPostDetailActivity.EDIT_COMMENT_REQUEST_CODE); + } else { + startActivity(intent); + } + + dismiss(); + }); + + deleteTextView.setOnClickListener(view -> { + dismiss(); + if(activity instanceof ViewPostDetailActivity) { + ((ViewPostDetailActivity) activity).deleteComment(fullName, bundle.getInt(EXTRA_POSITION)); + } else if(activity instanceof ViewUserDetailActivity) { + ((ViewUserDetailActivity) activity).deleteComment(fullName); + } + }); + + return rootView; + } + +} diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java index ad65fe4f..797c1834 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewPostDetailActivity.java @@ -59,6 +59,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { static final String EXTRA_POST_ID = "EPI"; private static final int EDIT_POST_REQUEST_CODE = 2; + static final int EDIT_COMMENT_REQUEST_CODE = 3; private RequestManager mGlide; private Locale mLocale; @@ -224,7 +225,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { mMenu.findItem(R.id.action_delete_view_post_detail_activity).setVisible(true); } mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, mRetrofit, - mOauthRetrofit, mRedditDataRoomDatabase, mGlide, mAccessToken, mPost, + mOauthRetrofit, mRedditDataRoomDatabase, mGlide, mAccessToken, mAccountName, mPost, mPost.getSubredditNamePrefixed(), mLocale, mLoadSubredditIconAsyncTask, new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { @Override @@ -290,7 +291,7 @@ public class ViewPostDetailActivity extends AppCompatActivity { } mAdapter = new CommentAndPostRecyclerViewAdapter(ViewPostDetailActivity.this, mRetrofit, - mOauthRetrofit, mRedditDataRoomDatabase, mGlide, mAccessToken, mPost, + mOauthRetrofit, mRedditDataRoomDatabase, mGlide, mAccessToken, mAccountName, mPost, mPost.getSubredditNamePrefixed(), mLocale, mLoadSubredditIconAsyncTask, new CommentAndPostRecyclerViewAdapter.CommentRecyclerViewAdapterCallback() { @Override @@ -481,6 +482,27 @@ public class ViewPostDetailActivity extends AppCompatActivity { } } + void deleteComment(String fullName, int position) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.delete_this_comment) + .setMessage(R.string.are_you_sure) + .setPositiveButton(R.string.delete, (dialogInterface, i) + -> DeleteThing.delete(mOauthRetrofit, fullName, mAccessToken, new DeleteThing.DeleteThingListener() { + @Override + public void deleteSuccess() { + Toast.makeText(ViewPostDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); + mAdapter.deleteComment(position); + } + + @Override + public void deleteFailed() { + Toast.makeText(ViewPostDetailActivity.this, R.string.delete_post_failed, Toast.LENGTH_SHORT).show(); + } + })) + .setNegativeButton(R.string.cancel, null) + .show(); + } + @Subscribe public void onPostUpdateEvent(PostUpdateEventToDetailActivity event) { if(mPost.getId().equals(event.postId)) { @@ -578,6 +600,11 @@ public class ViewPostDetailActivity extends AppCompatActivity { if(resultCode == RESULT_OK) { refresh(true); } + } else if(requestCode == EDIT_COMMENT_REQUEST_CODE) { + if(resultCode == RESULT_OK) { + mAdapter.editComment(data.getExtras().getString(EditCommentActivity.EXTRA_EDITED_COMMENT_CONTENT), + data.getExtras().getInt(EditCommentActivity.EXTRA_EDITED_COMMENT_POSITION)); + } } } diff --git a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java index 670547d9..ad007ae1 100644 --- a/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java +++ b/app/src/main/java/ml/docilealligator/infinityforreddit/ViewUserDetailActivity.java @@ -31,6 +31,7 @@ import com.bumptech.glide.request.RequestOptions; import com.google.android.material.appbar.AppBarLayout; import com.google.android.material.appbar.CollapsingToolbarLayout; import com.google.android.material.chip.Chip; +import com.google.android.material.dialog.MaterialAlertDialogBuilder; import com.google.android.material.snackbar.Snackbar; import com.google.android.material.tabs.TabLayout; @@ -385,6 +386,26 @@ public class ViewUserDetailActivity extends AppCompatActivity { } } + void deleteComment(String fullName) { + new MaterialAlertDialogBuilder(this, R.style.MaterialAlertDialogTheme) + .setTitle(R.string.delete_this_comment) + .setMessage(R.string.are_you_sure) + .setPositiveButton(R.string.delete, (dialogInterface, i) + -> DeleteThing.delete(mOauthRetrofit, fullName, mAccessToken, new DeleteThing.DeleteThingListener() { + @Override + public void deleteSuccess() { + Toast.makeText(ViewUserDetailActivity.this, R.string.delete_post_success, Toast.LENGTH_SHORT).show(); + } + + @Override + public void deleteFailed() { + Toast.makeText(ViewUserDetailActivity.this, R.string.delete_post_failed, Toast.LENGTH_SHORT).show(); + } + })) + .setNegativeButton(R.string.cancel, null) + .show(); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.view_user_detail_activity, menu); @@ -519,6 +540,7 @@ public class ViewUserDetailActivity extends AppCompatActivity { Bundle bundle = new Bundle(); bundle.putString(CommentsListingFragment.EXTRA_USERNAME_KEY, username); bundle.putString(CommentsListingFragment.EXTRA_ACCESS_TOKEN, mAccessToken); + bundle.putString(CommentsListingFragment.EXTRA_ACCOUNT_NAME, mAccountName); fragment.setArguments(bundle); return fragment; } @@ -560,5 +582,11 @@ public class ViewUserDetailActivity extends AppCompatActivity { commentsListingFragment.refresh(); } } + + public void refreshComments() { + if(commentsListingFragment != null) { + commentsListingFragment.refresh(); + } + } } } -- cgit v1.2.3