Compare commits

..

No commits in common. "main" and "media_preview" have entirely different histories.

7 changed files with 51 additions and 204 deletions

View file

@ -13,8 +13,8 @@ android {
defaultConfig { defaultConfig {
minSdk 21 minSdk 21
targetSdk 33 targetSdk 33
versionCode 477 versionCode 476
versionName "3.17.0" versionName "3.16.4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} }
flavorDimensions "default" flavorDimensions "default"

View file

@ -1,9 +1,4 @@
[ [
{
"version": "3.17.0",
"code": "477",
"note": "Added:\n- Peertube 2FA support\n- Cache home in background (default disabled -> New settings category and per account) / change frequency\n- Auto-fetch missing messages for the Home (default disabled -> in Settings - Timelines)\n- Automatically switch between tabs when searching\n- More deep links detection\n- Allow to group mentions at the top (default: disabled)\n\n\nFixed:\n- Dynamic color for Android 12+\n- Missing media description for previews\n- Fix a crash when replying\n- Fix button size not changed\n- Forward tags in replies\n- Media cannot be downloaded or shared with Android 10\n- Some crashes"
},
{ {
"version": "3.16.4", "version": "3.16.4",
"code": "476", "code": "476",

View file

@ -318,18 +318,4 @@ public interface MastodonStatusesService {
@Header("Authorization") String token, @Header("Authorization") String token,
@Path("id") String id @Path("id") String id
); );
@POST("statuses/{id}/react/{name}")
Call<Void> addReaction(
@Header("Authorization") String app_token,
@Path("id") String id,
@Path("name") String name
);
@POST("statuses/{id}/unreact/{name}")
Call<Void> removeReaction(
@Header("Authorization") String app_token,
@Path("id") String id,
@Path("name") String name
);
} }

View file

@ -109,8 +109,6 @@ public class Status implements Serializable, Cloneable {
public boolean cached = false; public boolean cached = false;
@SerializedName("is_maths") @SerializedName("is_maths")
public Boolean isMaths; public Boolean isMaths;
@SerializedName("reactions")
public List<Reaction> reactions;
public Attachment art_attachment; public Attachment art_attachment;
public boolean isExpended = false; public boolean isExpended = false;

View file

@ -34,7 +34,6 @@ import app.fedilab.android.mastodon.client.entities.api.Reaction;
import app.fedilab.android.mastodon.helper.Helper; import app.fedilab.android.mastodon.helper.Helper;
import app.fedilab.android.mastodon.helper.ThemeHelper; import app.fedilab.android.mastodon.helper.ThemeHelper;
import app.fedilab.android.mastodon.viewmodel.mastodon.AnnouncementsVM; import app.fedilab.android.mastodon.viewmodel.mastodon.AnnouncementsVM;
import app.fedilab.android.mastodon.viewmodel.mastodon.StatusesVM;
import app.fedilab.android.mastodon.viewmodel.pleroma.ActionsVM; import app.fedilab.android.mastodon.viewmodel.pleroma.ActionsVM;
@ -47,29 +46,18 @@ public class ReactionAdapter extends RecyclerView.Adapter<ReactionAdapter.Reacti
private final List<Reaction> reactions; private final List<Reaction> reactions;
private final String announcementId; private final String announcementId;
private final boolean statusReaction; private final boolean statusReaction;
private final boolean isPleroma;
private Context context; private Context context;
ReactionAdapter(String announcementId, List<Reaction> reactions, boolean statusReaction, boolean isPleroma) {
this.reactions = reactions;
this.announcementId = announcementId;
this.statusReaction = statusReaction;
this.isPleroma = isPleroma;
}
ReactionAdapter(String announcementId, List<Reaction> reactions, boolean statusReaction) { ReactionAdapter(String announcementId, List<Reaction> reactions, boolean statusReaction) {
this.reactions = reactions; this.reactions = reactions;
this.announcementId = announcementId; this.announcementId = announcementId;
this.statusReaction = statusReaction; this.statusReaction = statusReaction;
this.isPleroma = true;
} }
ReactionAdapter(String announcementId, List<Reaction> reactions) { ReactionAdapter(String announcementId, List<Reaction> reactions) {
this.reactions = reactions; this.reactions = reactions;
this.announcementId = announcementId; this.announcementId = announcementId;
this.statusReaction = false; this.statusReaction = false;
this.isPleroma = true;
} }
@NonNull @NonNull
@ -113,7 +101,7 @@ public class ReactionAdapter extends RecyclerView.Adapter<ReactionAdapter.Reacti
} }
notifyItemChanged(position); notifyItemChanged(position);
}); });
} else if (isPleroma) { } else {
ActionsVM actionVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class); ActionsVM actionVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
holder.binding.reactionContainer.setOnClickListener(v -> { holder.binding.reactionContainer.setOnClickListener(v -> {
if (reaction.me) { if (reaction.me) {
@ -127,20 +115,6 @@ public class ReactionAdapter extends RecyclerView.Adapter<ReactionAdapter.Reacti
} }
notifyItemChanged(position); notifyItemChanged(position);
}); });
} else {
StatusesVM statusesVM = new ViewModelProvider((ViewModelStoreOwner) context).get(StatusesVM.class);
holder.binding.reactionContainer.setOnClickListener(v -> {
if (reaction.me) {
statusesVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, announcementId, reaction.name);
reaction.me = false;
reaction.count -= 1;
} else {
statusesVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, announcementId, reaction.name);
reaction.me = true;
reaction.count += 1;
}
notifyItemChanged(position);
});
} }
} }

View file

@ -50,7 +50,6 @@ import android.os.Looper;
import android.text.Html; import android.text.Html;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log;
import android.util.TypedValue; import android.util.TypedValue;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -520,7 +519,7 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
holder.binding.quotedMessage.cardviewContainer.setVisibility(View.GONE); holder.binding.quotedMessage.cardviewContainer.setVisibility(View.GONE);
} }
if (currentAccount != null && currentAccount.api == Account.API.PLEROMA || status.reactions != null) { if (currentAccount != null && currentAccount.api == Account.API.PLEROMA) {
if (status.pleroma != null && status.pleroma.emoji_reactions != null && status.pleroma.emoji_reactions.size() > 0) { if (status.pleroma != null && status.pleroma.emoji_reactions != null && status.pleroma.emoji_reactions.size() > 0) {
holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE); holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE);
ReactionAdapter reactionAdapter = new ReactionAdapter(status.id, status.pleroma.emoji_reactions, true); ReactionAdapter reactionAdapter = new ReactionAdapter(status.id, status.pleroma.emoji_reactions, true);
@ -528,13 +527,6 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
LinearLayoutManager layoutManager LinearLayoutManager layoutManager
= new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false); = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
holder.binding.layoutReactions.reactionsView.setLayoutManager(layoutManager); holder.binding.layoutReactions.reactionsView.setLayoutManager(layoutManager);
} else if (status.reactions != null && status.reactions.size() > 0) {
holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE);
ReactionAdapter reactionAdapter = new ReactionAdapter(status.id, status.reactions, true, false);
holder.binding.layoutReactions.reactionsView.setAdapter(reactionAdapter);
LinearLayoutManager layoutManager
= new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
holder.binding.layoutReactions.reactionsView.setLayoutManager(layoutManager);
} else { } else {
holder.binding.layoutReactions.getRoot().setVisibility(View.GONE); holder.binding.layoutReactions.getRoot().setVisibility(View.GONE);
holder.binding.layoutReactions.reactionsView.setAdapter(null); holder.binding.layoutReactions.reactionsView.setAdapter(null);
@ -547,57 +539,33 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
}).setOnEmojiClickListener((emoji, imageView) -> { }).setOnEmojiClickListener((emoji, imageView) -> {
String emojiStr = imageView.getUnicode(); String emojiStr = imageView.getUnicode();
boolean alreadyAdded = false; boolean alreadyAdded = false;
if (status.pleroma != null && status.pleroma.emoji_reactions != null) { if (status.pleroma == null || status.pleroma.emoji_reactions == null) {
for (Reaction reaction : status.pleroma.emoji_reactions) { return;
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) { }
alreadyAdded = true; for (Reaction reaction : status.pleroma.emoji_reactions) {
reaction.count = (reaction.count - 1); if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) {
if (reaction.count == 0) { alreadyAdded = true;
status.pleroma.emoji_reactions.remove(reaction); reaction.count = (reaction.count - 1);
} if (reaction.count == 0) {
adapter.notifyItemChanged(holder.getBindingAdapterPosition()); status.pleroma.emoji_reactions.remove(reaction);
break;
} }
}
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
status.pleroma.emoji_reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition()); adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
} }
ActionsVM actionVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class); }
if (alreadyAdded) { if (!alreadyAdded) {
actionVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr); Reaction reaction = new Reaction();
} else { reaction.me = true;
actionVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr); reaction.count = 1;
} reaction.name = emojiStr;
} else if (status.reactions != null) { status.pleroma.emoji_reactions.add(0, reaction);
for (Reaction reaction : status.reactions) { adapter.notifyItemChanged(holder.getBindingAdapterPosition());
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) { }
alreadyAdded = true; ActionsVM actionVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
reaction.count = (reaction.count - 1); if (alreadyAdded) {
if (reaction.count == 0) { actionVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
status.reactions.remove(reaction); } else {
} actionVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
}
}
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
status.reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
}
if (alreadyAdded) {
statusesVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
} else {
statusesVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
}
} }
}) })
.build(holder.binding.layoutReactions.fakeEdittext); .build(holder.binding.layoutReactions.fakeEdittext);
@ -623,61 +591,32 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
String url = emojis.get(BaseMainActivity.currentInstance).get(index).url; String url = emojis.get(BaseMainActivity.currentInstance).get(index).url;
String static_url = emojis.get(BaseMainActivity.currentInstance).get(index).static_url; String static_url = emojis.get(BaseMainActivity.currentInstance).get(index).static_url;
boolean alreadyAdded = false; boolean alreadyAdded = false;
if (status.pleroma != null && status.pleroma.emoji_reactions != null) { for (Reaction reaction : status.pleroma.emoji_reactions) {
for (Reaction reaction : status.pleroma.emoji_reactions) { if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) {
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) { alreadyAdded = true;
alreadyAdded = true; reaction.count = (reaction.count - 1);
reaction.count = (reaction.count - 1); if (reaction.count == 0) {
if (reaction.count == 0) { status.pleroma.emoji_reactions.remove(reaction);
status.pleroma.emoji_reactions.remove(reaction);
}
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
} }
}
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
reaction.url = url;
reaction.static_url = static_url;
status.pleroma.emoji_reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition()); adapter.notifyItemChanged(holder.getBindingAdapterPosition());
break;
} }
ActionsVM actionsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class); }
if (alreadyAdded) { if (!alreadyAdded) {
actionsVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr); Reaction reaction = new Reaction();
} else { reaction.me = true;
actionsVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr); reaction.count = 1;
} reaction.name = emojiStr;
} else if (status.reactions != null) { reaction.url = url;
for (Reaction reaction : status.reactions) { reaction.static_url = static_url;
if (reaction.name.compareTo(emojiStr) == 0 && reaction.me) { status.pleroma.emoji_reactions.add(0, reaction);
alreadyAdded = true; adapter.notifyItemChanged(holder.getBindingAdapterPosition());
reaction.count = (reaction.count - 1); }
if (reaction.count == 0) { ActionsVM actionsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
status.reactions.remove(reaction); if (alreadyAdded) {
} actionsVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
adapter.notifyItemChanged(holder.getBindingAdapterPosition()); } else {
break; actionsVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
}
}
if (!alreadyAdded) {
Reaction reaction = new Reaction();
reaction.me = true;
reaction.count = 1;
reaction.name = emojiStr;
reaction.url = url;
reaction.static_url = static_url;
status.reactions.add(0, reaction);
adapter.notifyItemChanged(holder.getBindingAdapterPosition());
}
if (alreadyAdded) {
statusesVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
} else {
statusesVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
}
} }
}); });
gridView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp); gridView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);

View file

@ -30,7 +30,6 @@ import java.util.List;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import app.fedilab.android.R; import app.fedilab.android.R;
import app.fedilab.android.mastodon.client.endpoints.MastodonAnnouncementsService;
import app.fedilab.android.mastodon.client.endpoints.MastodonStatusesService; import app.fedilab.android.mastodon.client.endpoints.MastodonStatusesService;
import app.fedilab.android.mastodon.client.entities.api.Account; import app.fedilab.android.mastodon.client.entities.api.Account;
import app.fedilab.android.mastodon.client.entities.api.Accounts; import app.fedilab.android.mastodon.client.entities.api.Accounts;
@ -1293,48 +1292,4 @@ public class StatusesVM extends AndroidViewModel {
}).start(); }).start();
return voidMutableLiveData; return voidMutableLiveData;
} }
/**
* React to a status with an emoji.
*
* @param instance Instance domain of the active account
* @param token Access token of the active account
* @param id Local ID of an announcement
* @param name Unicode emoji, or shortcode of custom emoji
*/
public void addReaction(@NonNull String instance, String token, @NonNull String id, @NonNull String name) {
MastodonStatusesService mastodonStatusesService = init(instance);
new Thread(() -> {
Call<Void> addReactionCall = mastodonStatusesService.addReaction(token, id, name);
if (addReactionCall != null) {
try {
addReactionCall.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
/**
* Undo a react emoji to a status.
*
* @param instance Instance domain of the active account
* @param token Access token of the active account
* @param id Local ID of an announcement
* @param name Unicode emoji, or shortcode of custom emoji
*/
public void removeReaction(@NonNull String instance, String token, @NonNull String id, @NonNull String name) {
MastodonStatusesService mastodonStatusesService = init(instance);
new Thread(() -> {
Call<Void> removeReactionCall = mastodonStatusesService.removeReaction(token, id, name);
if (removeReactionCall != null) {
try {
removeReactionCall.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
} }