From 907bbfe335d5b5e80fab4050f562e906f49741b8 Mon Sep 17 00:00:00 2001 From: stom79 Date: Tue, 15 Jan 2019 14:43:56 +0100 Subject: [PATCH] Prepare frontend 5 - Animations with cross-account actions --- .../asynctasks/PostActionAsyncTask.java | 3 +- .../mastodon/drawers/PixelfedListAdapter.java | 62 ++++++++++-- .../fragments/DisplayStatusFragment.java | 4 +- .../etalab/mastodon/helper/CrossActions.java | 99 ++++++++++++++++--- app/src/main/res/layout/drawer_pixelfed.xml | 63 +++++++----- app/src/main/res/values/colors.xml | 2 + 6 files changed, 184 insertions(+), 49 deletions(-) diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/PostActionAsyncTask.java b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/PostActionAsyncTask.java index 525a0bbb9..727da13b6 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/PostActionAsyncTask.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/asynctasks/PostActionAsyncTask.java @@ -109,14 +109,13 @@ public class PostActionAsyncTask extends AsyncTask { @Override protected Void doInBackground(Void... params) { - if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON) { + if(MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.MASTODON || MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) { //Remote action API api; if (account != null) api = new API(contextReference.get(), account.getInstance(), account.getToken()); else api = new API(contextReference.get()); - if (remoteStatus != null) { String uri; if (remoteStatus.getReblog() != null) { diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/PixelfedListAdapter.java b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/PixelfedListAdapter.java index 94d5a5ca4..f0a2e78d0 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/drawers/PixelfedListAdapter.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/drawers/PixelfedListAdapter.java @@ -30,6 +30,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; +import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; @@ -41,6 +42,7 @@ import com.bumptech.glide.load.resource.bitmap.RoundedCorners; import com.bumptech.glide.request.RequestListener; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.Target; +import com.varunest.sparkbutton.SparkButton; import java.util.ArrayList; import java.util.List; @@ -51,6 +53,7 @@ import fr.gouv.etalab.mastodon.activities.MainActivity; import fr.gouv.etalab.mastodon.activities.MediaActivity; import fr.gouv.etalab.mastodon.activities.ShowAccountActivity; import fr.gouv.etalab.mastodon.activities.ShowConversationActivity; +import fr.gouv.etalab.mastodon.asynctasks.RetrieveFeedsAsyncTask; import fr.gouv.etalab.mastodon.asynctasks.UpdateAccountInfoAsyncTask; import fr.gouv.etalab.mastodon.client.API; import fr.gouv.etalab.mastodon.client.APIResponse; @@ -84,12 +87,13 @@ public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostA private final int HIDDEN_STATUS = 0; private static final int DISPLAYED_STATUS = 1; private List timedMute; + private RetrieveFeedsAsyncTask.Type type; - - public PixelfedListAdapter(Context context, List statuses){ + public PixelfedListAdapter(Context context, RetrieveFeedsAsyncTask.Type type, List statuses){ super(); this.context = context; this.statuses = statuses; + this.type = type; layoutInflater = LayoutInflater.from(this.context); pixelfedListAdapter = this; } @@ -139,9 +143,11 @@ public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostA private class ViewHolderPixelfed extends RecyclerView.ViewHolder{ - ImageView art_media, pf_pp, pf_fav, pf_comment, pf_share; + ImageView art_media, pf_pp, pf_comment, pf_share; + SparkButton pf_fav; TextView pf_username, pf_likes, pf_description, pf_date; CardView pf_cardview; + LinearLayout pf_bottom_container; ViewHolderPixelfed(View itemView) { super(itemView); art_media = itemView.findViewById(R.id.art_media); @@ -154,6 +160,7 @@ public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostA pf_comment = itemView.findViewById(R.id.pf_comment); pf_share = itemView.findViewById(R.id.pf_share); pf_cardview = itemView.findViewById(R.id.pf_cardview); + pf_bottom_container = itemView.findViewById(R.id.pf_bottom_container); } } @@ -259,7 +266,7 @@ public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostA }); holder.pf_description.setText(status.getContentSpan(), TextView.BufferType.SPANNABLE); holder.pf_date.setText(Helper.dateToString(status.getCreated_at())); - holder.pf_description.setOnClickListener(new View.OnClickListener() { + holder.pf_comment.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (MainActivity.social != UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) { @@ -274,28 +281,69 @@ public class PixelfedListAdapter extends RecyclerView.Adapter implements OnPostA } }); + + if (status.getDisplayNameSpan() != null && status.getDisplayNameSpan().toString().trim().length() > 0) holder.pf_username.setText(status.getDisplayNameSpan(), TextView.BufferType.SPANNABLE); else holder.pf_username.setText(status.getAccount().getUsername()); int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK); + + if (theme == Helper.THEME_BLACK) { - changeDrawableColor(context, holder.pf_fav, R.color.action_black); + holder.pf_fav.setInActiveImageTint(R.color.action_black); + changeDrawableColor(context, R.drawable.ic_pixelfed_favorite_border, R.color.action_black); changeDrawableColor(context, holder.pf_comment, R.color.action_black); changeDrawableColor(context, holder.pf_share, R.color.action_black); holder.pf_cardview.setCardBackgroundColor(ContextCompat.getColor(context, R.color.black_3)); } else if (theme == Helper.THEME_DARK) { - changeDrawableColor(context, holder.pf_fav, R.color.action_dark); + holder.pf_fav.setInActiveImageTint(R.color.action_dark); changeDrawableColor(context, holder.pf_comment, R.color.action_dark); + changeDrawableColor(context, R.drawable.ic_pixelfed_favorite_border, R.color.action_dark); changeDrawableColor(context, holder.pf_share, R.color.action_dark); holder.pf_cardview.setCardBackgroundColor(ContextCompat.getColor(context, R.color.mastodonC1_)); } else { - changeDrawableColor(context, holder.pf_fav, R.color.action_light); + holder.pf_fav.setInActiveImageTint(R.color.action_light); changeDrawableColor(context, holder.pf_comment, R.color.action_light); + changeDrawableColor(context, R.drawable.ic_pixelfed_favorite_border, R.color.action_light); changeDrawableColor(context, holder.pf_share, R.color.action_light); holder.pf_cardview.setCardBackgroundColor(ContextCompat.getColor(context, R.color.white)); } + + + holder.pf_fav.pressOnTouch(false); + holder.pf_fav.setActiveImage(R.drawable.ic_pixelfed_favorite); + holder.pf_fav.setInactiveImage(R.drawable.ic_pixelfed_favorite_border); + holder.pf_fav.setDisableCircle(true); + holder.pf_fav.setActiveImageTint(R.color.pixelfed_like); + holder.pf_fav.setColors(R.color.pixelfed_like, R.color.pixelfed_like); + + if (!status.isFavAnimated()) { + if (status.isFavourited() || (status.getReblog() != null && status.getReblog().isFavourited())) { + holder.pf_fav.setChecked(true); + } else { + holder.pf_fav.setChecked(false); + } + } else { + status.setFavAnimated(false); + holder.pf_fav.setChecked(true); + holder.pf_fav.setAnimationSpeed(1.0f); + holder.pf_fav.playAnimation(); + } + boolean confirmFav = sharedpreferences.getBoolean(Helper.SET_NOTIF_VALIDATION_FAV, false); + holder.pf_fav.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + if (!status.isFavourited() && confirmFav) + status.setFavAnimated(true); + if (!status.isFavourited() && !confirmFav) { + status.setFavAnimated(true); + notifyStatusChanged(status); + } + CrossActions.doCrossAction(context, type, status, null, (status.isFavourited() || (status.getReblog() != null && status.getReblog().isFavourited())) ? API.StatusAction.UNFAVOURITE : API.StatusAction.FAVOURITE, pixelfedListAdapter, PixelfedListAdapter.this, true); + } + }); } } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java index 87740c751..3b748a07b 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/fragments/DisplayStatusFragment.java @@ -32,7 +32,6 @@ import android.support.v4.content.LocalBroadcastManager; import android.support.v4.widget.SwipeRefreshLayout; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -215,7 +214,7 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn }else if( instanceType.equals("PIXELFED")){ if( remoteInstance != null && MainActivity.social == UpdateAccountInfoAsyncTask.SOCIAL.PIXELFED) //if it's a Peertube account connected remoteInstance = account.getInstance(); - pixelfedListAdapter = new PixelfedListAdapter(context, this.statuses); + pixelfedListAdapter = new PixelfedListAdapter(context, type, this.statuses); lv_status.setAdapter(pixelfedListAdapter); }else if( instanceType.equals("ART")){ artListAdapter = new ArtListAdapter(context, this.statuses); @@ -528,7 +527,6 @@ public class DisplayStatusFragment extends Fragment implements OnRetrieveFeedsIn artListAdapter.notifyItemRangeInserted(previousPosition, statuses.size()); } }else if(instanceType.equals("PIXELFED") ) { - Log.v(Helper.TAG,"statuses: " + statuses.size()); this.statuses.addAll(statuses); pixelfedListAdapter.notifyItemRangeInserted(previousPosition, statuses.size()); } diff --git a/app/src/main/java/fr/gouv/etalab/mastodon/helper/CrossActions.java b/app/src/main/java/fr/gouv/etalab/mastodon/helper/CrossActions.java index af6d4b1c7..b9127fc06 100644 --- a/app/src/main/java/fr/gouv/etalab/mastodon/helper/CrossActions.java +++ b/app/src/main/java/fr/gouv/etalab/mastodon/helper/CrossActions.java @@ -46,6 +46,7 @@ import fr.gouv.etalab.mastodon.client.Entities.Mention; import fr.gouv.etalab.mastodon.client.Entities.Results; import fr.gouv.etalab.mastodon.client.Entities.Status; import fr.gouv.etalab.mastodon.drawers.AccountsSearchAdapter; +import fr.gouv.etalab.mastodon.drawers.PixelfedListAdapter; import fr.gouv.etalab.mastodon.drawers.StatusListAdapter; import fr.gouv.etalab.mastodon.interfaces.OnPostActionInterface; import fr.gouv.etalab.mastodon.sqlite.AccountDAO; @@ -142,22 +143,48 @@ public class CrossActions { SQLiteDatabase db = Sqlite.getInstance(context, Sqlite.DB_NAME, null, Sqlite.DB_VERSION).open(); Account currentAccount = new AccountDAO(context, db).getAccountByID(userId); if (confirmation) - displayConfirmationDialogCrossAction(context, currentAccount, doAction, status, onPostActionInterface); + displayConfirmationDialogCrossAction(context, currentAccount, doAction, status, onPostActionInterface, baseAdapter); else new PostActionAsyncTask(context, currentAccount, status, doAction, onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } else if (accounts.size() == 1 || undoAction) { - if (confirmation) displayConfirmationDialog(context, doAction, status, baseAdapter, onPostActionInterface); else { if (doAction == API.StatusAction.REBLOG || doAction == API.StatusAction.UNREBLOG) - reblogAction(context, status, baseAdapter, onPostActionInterface); + reblogAction(context, status, onPostActionInterface); else if (doAction == API.StatusAction.FAVOURITE || doAction == API.StatusAction.UNFAVOURITE) - favouriteAction(context, status, baseAdapter, onPostActionInterface); + favouriteAction(context, status, onPostActionInterface); else if (doAction == API.StatusAction.PIN || doAction == API.StatusAction.UNPIN) pinAction(context, status, baseAdapter, onPostActionInterface); + + if( doAction == API.StatusAction.FAVOURITE || doAction == API.StatusAction.UNFAVOURITE){ + if (doAction == API.StatusAction.FAVOURITE) { + status.setFavourited(true); + status.setFavAnimated(true); + }else{ + status.setFavourited(false); + status.setFavAnimated(false); + } + if(baseAdapter instanceof PixelfedListAdapter) + ((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status); + else if(baseAdapter instanceof StatusListAdapter) + ((StatusListAdapter) baseAdapter).notifyStatusChanged(status); + }else if(doAction == API.StatusAction.REBLOG || doAction == API.StatusAction.UNREBLOG){ + if (doAction == API.StatusAction.REBLOG) { + status.setReblogged(true); + status.setBoostAnimated(true); + }else{ + status.setReblogged(false); + status.setBoostAnimated(false); + } + if(baseAdapter instanceof PixelfedListAdapter) + ((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status); + else if(baseAdapter instanceof StatusListAdapter) + ((StatusListAdapter) baseAdapter).notifyStatusChanged(status); + } } } else { + AlertDialog.Builder builderSingle = new AlertDialog.Builder(context, style); builderSingle.setTitle(context.getString(R.string.choose_accounts)); final AccountsSearchAdapter accountsSearchAdapter = new AccountsSearchAdapter(context, accounts, true); @@ -702,11 +729,37 @@ public class CrossActions { @Override public void onClick(DialogInterface dialog, int which) { if( action == API.StatusAction.REBLOG || action == API.StatusAction.UNREBLOG) - reblogAction(context, status, baseAdapter, onPostActionInterface); + reblogAction(context, status, onPostActionInterface); else if( action == API.StatusAction.FAVOURITE || action == API.StatusAction.UNFAVOURITE) - favouriteAction(context, status, baseAdapter, onPostActionInterface); + favouriteAction(context, status, onPostActionInterface); else if ( action == API.StatusAction.PIN || action == API.StatusAction.UNPIN) pinAction(context, status, baseAdapter, onPostActionInterface); + + if( action == API.StatusAction.FAVOURITE || action == API.StatusAction.UNFAVOURITE){ + if (action == API.StatusAction.FAVOURITE) { + status.setFavourited(true); + status.setFavAnimated(true); + }else{ + status.setFavourited(false); + status.setFavAnimated(false); + } + if(baseAdapter instanceof PixelfedListAdapter) + ((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status); + else if(baseAdapter instanceof StatusListAdapter) + ((StatusListAdapter) baseAdapter).notifyStatusChanged(status); + }else if(action == API.StatusAction.REBLOG || action == API.StatusAction.UNREBLOG){ + if (action == API.StatusAction.REBLOG) { + status.setReblogged(true); + status.setBoostAnimated(true); + }else{ + status.setReblogged(false); + status.setBoostAnimated(false); + } + if(baseAdapter instanceof PixelfedListAdapter) + ((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status); + else if(baseAdapter instanceof StatusListAdapter) + ((StatusListAdapter) baseAdapter).notifyStatusChanged(status); + } dialog.dismiss(); } }) @@ -727,7 +780,7 @@ public class CrossActions { * @param action int * @param status Status */ - private static void displayConfirmationDialogCrossAction(final Context context,Account currentAccount, final API.StatusAction action, final Status status, final OnPostActionInterface onPostActionInterface){ + private static void displayConfirmationDialogCrossAction(final Context context,Account currentAccount, final API.StatusAction action, final Status status, final OnPostActionInterface onPostActionInterface, final RecyclerView.Adapter baseAdapter){ String title = null; if( action == API.StatusAction.FAVOURITE){ @@ -756,6 +809,31 @@ public class CrossActions { .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { + if( action == API.StatusAction.FAVOURITE || action == API.StatusAction.UNFAVOURITE){ + if (action == API.StatusAction.FAVOURITE) { + status.setFavourited(true); + status.setFavAnimated(true); + }else{ + status.setFavourited(false); + status.setFavAnimated(false); + } + if(baseAdapter instanceof PixelfedListAdapter) + ((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status); + else if(baseAdapter instanceof StatusListAdapter) + ((StatusListAdapter) baseAdapter).notifyStatusChanged(status); + }else if(action == API.StatusAction.REBLOG || action == API.StatusAction.UNREBLOG){ + if (action == API.StatusAction.REBLOG) { + status.setReblogged(true); + status.setBoostAnimated(true); + }else{ + status.setReblogged(false); + status.setBoostAnimated(false); + } + if(baseAdapter instanceof PixelfedListAdapter) + ((PixelfedListAdapter) baseAdapter).notifyStatusChanged(status); + else if(baseAdapter instanceof StatusListAdapter) + ((StatusListAdapter) baseAdapter).notifyStatusChanged(status); + } new PostActionAsyncTask(context, currentAccount, status, action, onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); dialog.dismiss(); } @@ -789,7 +867,8 @@ public class CrossActions { * Favourites/Unfavourites a status * @param status Status */ - private static void favouriteAction(Context context, Status status, RecyclerView.Adapter baseAdapter, OnPostActionInterface onPostActionInterface){ + private static void favouriteAction(Context context, Status status,OnPostActionInterface onPostActionInterface){ + if( status.isFavourited() || (status.getReblog() != null && status.getReblog().isFavourited())){ new PostActionAsyncTask(context, API.StatusAction.UNFAVOURITE, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); status.setFavourited(false); @@ -797,14 +876,13 @@ public class CrossActions { new PostActionAsyncTask(context, API.StatusAction.FAVOURITE, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); status.setFavourited(true); } - baseAdapter.notifyDataSetChanged(); } /** * Reblog/Unreblog a status * @param status Status */ - private static void reblogAction(Context context, Status status, RecyclerView.Adapter baseAdapter, OnPostActionInterface onPostActionInterface){ + private static void reblogAction(Context context, Status status, OnPostActionInterface onPostActionInterface){ if( status.isReblogged() || (status.getReblog()!= null && status.getReblog().isReblogged())){ String statusId = status.getReblog()!=null?status.getReblog().getId():status.getId(); new PostActionAsyncTask(context, API.StatusAction.UNREBLOG, statusId, onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -813,7 +891,6 @@ public class CrossActions { new PostActionAsyncTask(context, API.StatusAction.REBLOG, status.getId(), onPostActionInterface).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); status.setReblogged(true); } - baseAdapter.notifyDataSetChanged(); } /** diff --git a/app/src/main/res/layout/drawer_pixelfed.xml b/app/src/main/res/layout/drawer_pixelfed.xml index 945e6308f..cbb8dcad7 100644 --- a/app/src/main/res/layout/drawer_pixelfed.xml +++ b/app/src/main/res/layout/drawer_pixelfed.xml @@ -15,9 +15,9 @@ You should have received a copy of the GNU General Public License along with Mastalab; if not, see . --> - @@ -70,47 +70,58 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> - + android:layout_width="30dp" + android:layout_height="30dp" + app:sparkbutton_activeImage="@drawable/ic_pixelfed_favorite" + app:sparkbutton_inActiveImage="@drawable/ic_pixelfed_favorite_border" + android:contentDescription="@string/favourite" + app:sparkbutton_iconSize="30dp" + /> + android:layout_width="30dp" + android:layout_height="30dp" /> + + + + + + - - - \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 330ccb9c5..5f83e1973 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -114,4 +114,6 @@ #F1680D #c52404 + + #dc3545