forked from mirrors/Fedilab
Add emoji reactions for Pleroma
This commit is contained in:
parent
cf1a1b3e53
commit
8a0460536c
14 changed files with 378 additions and 76 deletions
|
@ -855,7 +855,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt
|
|||
binding.toolbarSearch.setOnSearchClickListener(v -> binding.tabLayout.setVisibility(View.VISIBLE));
|
||||
//For receiving data from other activities
|
||||
LocalBroadcastManager.getInstance(BaseMainActivity.this).registerReceiver(broadcast_data, new IntentFilter(Helper.BROADCAST_DATA));
|
||||
if (emojis == null || !emojis.containsKey(BaseMainActivity.currentInstance)) {
|
||||
if (emojis == null || !emojis.containsKey(BaseMainActivity.currentInstance) || emojis.get(BaseMainActivity.currentInstance) == null) {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
emojis.put(currentInstance, new EmojiInstance(BaseMainActivity.this).getEmojiList(BaseMainActivity.currentInstance));
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package app.fedilab.android.client.endpoints;
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.http.DELETE;
|
||||
import retrofit2.http.Header;
|
||||
import retrofit2.http.PUT;
|
||||
import retrofit2.http.Path;
|
||||
|
||||
public interface PleromaAPI {
|
||||
|
||||
|
||||
@PUT("pleroma/statuses/{id}/reactions/{name}")
|
||||
Call<Void> addReaction(
|
||||
@Header("Authorization") String app_token,
|
||||
@Path("id") String id,
|
||||
@Path("name") String name
|
||||
);
|
||||
|
||||
@DELETE("pleroma/statuses/{id}/reactions/{name}")
|
||||
Call<Void> removeReaction(
|
||||
@Header("Authorization") String app_token,
|
||||
@Path("id") String id,
|
||||
@Path("name") String name
|
||||
);
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package app.fedilab.android.client.entities.api;
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
public class Pleroma implements Serializable {
|
||||
@SerializedName("emoji_reactions")
|
||||
public List<Reaction> emoji_reactions;
|
||||
}
|
|
@ -16,7 +16,9 @@ package app.fedilab.android.client.entities.api;
|
|||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Reaction {
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Reaction implements Serializable {
|
||||
@SerializedName("name")
|
||||
public String name;
|
||||
@SerializedName("count")
|
||||
|
|
|
@ -89,6 +89,8 @@ public class Status implements Serializable, Cloneable {
|
|||
public Card card;
|
||||
@SerializedName("poll")
|
||||
public Poll poll;
|
||||
@SerializedName("pleroma")
|
||||
public Pleroma pleroma;
|
||||
|
||||
|
||||
public Attachment art_attachment;
|
||||
|
|
|
@ -76,17 +76,18 @@ public class AnnouncementAdapter extends RecyclerView.Adapter<AnnouncementAdapte
|
|||
return new AnnouncementHolder(itemBinding);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull AnnouncementHolder holder, int position) {
|
||||
Announcement announcement = announcements.get(position);
|
||||
if (announcement.reactions != null && announcement.reactions.size() > 0) {
|
||||
ReactionAdapter reactionAdapter = new ReactionAdapter(announcement.id, announcement.reactions);
|
||||
holder.binding.reactionsView.setAdapter(reactionAdapter);
|
||||
holder.binding.layoutReactions.reactionsView.setAdapter(reactionAdapter);
|
||||
LinearLayoutManager layoutManager
|
||||
= new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
|
||||
holder.binding.reactionsView.setLayoutManager(layoutManager);
|
||||
holder.binding.layoutReactions.reactionsView.setLayoutManager(layoutManager);
|
||||
} else {
|
||||
holder.binding.reactionsView.setAdapter(null);
|
||||
holder.binding.layoutReactions.reactionsView.setAdapter(null);
|
||||
}
|
||||
holder.binding.content.setText(
|
||||
announcement.getSpanContent(context,
|
||||
|
@ -108,11 +109,11 @@ public class AnnouncementAdapter extends RecyclerView.Adapter<AnnouncementAdapte
|
|||
} else {
|
||||
holder.binding.dates.setVisibility(View.GONE);
|
||||
}
|
||||
holder.binding.statusEmoji.setOnClickListener(v -> {
|
||||
holder.binding.layoutReactions.statusEmoji.setOnClickListener(v -> {
|
||||
EmojiManager.install(new EmojiOneProvider());
|
||||
final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(holder.binding.statusEmoji).setOnEmojiPopupDismissListener(() -> {
|
||||
final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(holder.binding.layoutReactions.statusEmoji).setOnEmojiPopupDismissListener(() -> {
|
||||
InputMethodManager imm = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(holder.binding.statusEmoji.getWindowToken(), 0);
|
||||
imm.hideSoftInputFromWindow(holder.binding.layoutReactions.statusEmoji.getWindowToken(), 0);
|
||||
}).setOnEmojiClickListener((emoji, imageView) -> {
|
||||
String emojiStr = imageView.getUnicode();
|
||||
boolean alreadyAdded = false;
|
||||
|
@ -142,10 +143,10 @@ public class AnnouncementAdapter extends RecyclerView.Adapter<AnnouncementAdapte
|
|||
announcementsVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, announcement.id, emojiStr);
|
||||
}
|
||||
})
|
||||
.build(holder.binding.fakeEdittext);
|
||||
.build(holder.binding.layoutReactions.fakeEdittext);
|
||||
emojiPopup.toggle();
|
||||
});
|
||||
holder.binding.statusAddCustomEmoji.setOnClickListener(v -> {
|
||||
holder.binding.layoutReactions.statusAddCustomEmoji.setOnClickListener(v -> {
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context, Helper.dialogStyle());
|
||||
int paddingPixel = 15;
|
||||
float density = context.getResources().getDisplayMetrics().density;
|
||||
|
|
|
@ -42,7 +42,7 @@ public class EmojiAdapter extends BaseAdapter {
|
|||
}
|
||||
|
||||
public int getCount() {
|
||||
return emojiList.size();
|
||||
return emojiList == null ? 0 : emojiList.size();
|
||||
}
|
||||
|
||||
public Emoji getItem(int position) {
|
||||
|
|
|
@ -15,6 +15,8 @@ package app.fedilab.android.ui.drawer;
|
|||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
|
||||
import static android.content.Context.INPUT_METHOD_SERVICE;
|
||||
import static app.fedilab.android.BaseMainActivity.emojis;
|
||||
import static app.fedilab.android.BaseMainActivity.regex_home;
|
||||
import static app.fedilab.android.BaseMainActivity.regex_local;
|
||||
import static app.fedilab.android.BaseMainActivity.regex_public;
|
||||
|
@ -46,7 +48,9 @@ import android.view.LayoutInflater;
|
|||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.GridView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.RelativeLayout;
|
||||
|
@ -66,6 +70,7 @@ import androidx.lifecycle.ViewModelProvider;
|
|||
import androidx.lifecycle.ViewModelStoreOwner;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
|
@ -78,6 +83,9 @@ import com.github.stom79.mytransl.client.HttpsConnectionException;
|
|||
import com.github.stom79.mytransl.client.Results;
|
||||
import com.github.stom79.mytransl.translate.Params;
|
||||
import com.github.stom79.mytransl.translate.Translate;
|
||||
import com.vanniktech.emoji.EmojiManager;
|
||||
import com.vanniktech.emoji.EmojiPopup;
|
||||
import com.vanniktech.emoji.one.EmojiOneProvider;
|
||||
import com.varunest.sparkbutton.SparkButton;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
@ -93,6 +101,7 @@ import app.fedilab.android.R;
|
|||
import app.fedilab.android.activities.ComposeActivity;
|
||||
import app.fedilab.android.activities.ContextActivity;
|
||||
import app.fedilab.android.activities.CustomSharingActivity;
|
||||
import app.fedilab.android.activities.MainActivity;
|
||||
import app.fedilab.android.activities.MediaActivity;
|
||||
import app.fedilab.android.activities.ProfileActivity;
|
||||
import app.fedilab.android.activities.ReportActivity;
|
||||
|
@ -100,7 +109,9 @@ import app.fedilab.android.activities.StatusInfoActivity;
|
|||
import app.fedilab.android.client.entities.api.Attachment;
|
||||
import app.fedilab.android.client.entities.api.Notification;
|
||||
import app.fedilab.android.client.entities.api.Poll;
|
||||
import app.fedilab.android.client.entities.api.Reaction;
|
||||
import app.fedilab.android.client.entities.api.Status;
|
||||
import app.fedilab.android.client.entities.app.Account;
|
||||
import app.fedilab.android.client.entities.app.StatusCache;
|
||||
import app.fedilab.android.client.entities.app.StatusDraft;
|
||||
import app.fedilab.android.client.entities.app.Timeline;
|
||||
|
@ -124,6 +135,7 @@ import app.fedilab.android.ui.fragment.timeline.FragmentMastodonContext;
|
|||
import app.fedilab.android.viewmodel.mastodon.AccountsVM;
|
||||
import app.fedilab.android.viewmodel.mastodon.SearchVM;
|
||||
import app.fedilab.android.viewmodel.mastodon.StatusesVM;
|
||||
import app.fedilab.android.viewmodel.pleroma.ActionsVM;
|
||||
import es.dmoral.toasty.Toasty;
|
||||
import jp.wasabeef.glide.transformations.BlurTransformation;
|
||||
|
||||
|
@ -313,6 +325,116 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder>
|
|||
boolean fullAttachement = sharedpreferences.getBoolean(context.getString(R.string.SET_FULL_PREVIEW), false);
|
||||
boolean displayBookmark = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_BOOKMARK), false);
|
||||
|
||||
if (MainActivity.currentAccount != null && MainActivity.currentAccount.api == Account.API.PLEROMA) {
|
||||
holder.binding.layoutReactions.getRoot().setVisibility(View.VISIBLE);
|
||||
if (status.pleroma != null && status.pleroma.emoji_reactions != null && status.pleroma.emoji_reactions.size() > 0) {
|
||||
ReactionAdapter reactionAdapter = new ReactionAdapter(status.id, status.pleroma.emoji_reactions);
|
||||
holder.binding.layoutReactions.reactionsView.setAdapter(reactionAdapter);
|
||||
LinearLayoutManager layoutManager
|
||||
= new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
|
||||
holder.binding.layoutReactions.reactionsView.setLayoutManager(layoutManager);
|
||||
} else {
|
||||
holder.binding.layoutReactions.reactionsView.setAdapter(null);
|
||||
}
|
||||
holder.binding.layoutReactions.statusEmoji.setOnClickListener(v -> {
|
||||
EmojiManager.install(new EmojiOneProvider());
|
||||
final EmojiPopup emojiPopup = EmojiPopup.Builder.fromRootView(holder.binding.layoutReactions.statusEmoji).setOnEmojiPopupDismissListener(() -> {
|
||||
InputMethodManager imm = (InputMethodManager) context.getSystemService(INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(holder.binding.layoutReactions.statusEmoji.getWindowToken(), 0);
|
||||
}).setOnEmojiClickListener((emoji, imageView) -> {
|
||||
String emojiStr = imageView.getUnicode();
|
||||
boolean alreadyAdded = false;
|
||||
for (Reaction reaction : status.pleroma.emoji_reactions) {
|
||||
if (reaction.name.compareTo(emojiStr) == 0) {
|
||||
alreadyAdded = true;
|
||||
reaction.count = (reaction.count - 1);
|
||||
if (reaction.count == 0) {
|
||||
status.pleroma.emoji_reactions.remove(reaction);
|
||||
}
|
||||
adapter.notifyItemChanged(getPositionAsync(notificationList, statusList, statusToDeal));
|
||||
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(getPositionAsync(notificationList, statusList, statusToDeal));
|
||||
}
|
||||
ActionsVM actionVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
|
||||
if (alreadyAdded) {
|
||||
actionVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
|
||||
} else {
|
||||
actionVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
|
||||
}
|
||||
})
|
||||
.build(holder.binding.layoutReactions.fakeEdittext);
|
||||
emojiPopup.toggle();
|
||||
});
|
||||
holder.binding.layoutReactions.statusAddCustomEmoji.setOnClickListener(v -> {
|
||||
|
||||
final AlertDialog.Builder builder = new AlertDialog.Builder(context, Helper.dialogStyle());
|
||||
int paddingPixel = 15;
|
||||
float density = context.getResources().getDisplayMetrics().density;
|
||||
int paddingDp = (int) (paddingPixel * density);
|
||||
builder.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss());
|
||||
builder.setTitle(R.string.insert_emoji);
|
||||
AlertDialog alertDialogEmoji = null;
|
||||
if (emojis != null && emojis.size() > 0 && emojis.get(BaseMainActivity.currentInstance) != null) {
|
||||
GridView gridView = new GridView(context);
|
||||
gridView.setAdapter(new EmojiAdapter(emojis.get(BaseMainActivity.currentInstance)));
|
||||
gridView.setNumColumns(5);
|
||||
AlertDialog finalAlertDialogEmoji = alertDialogEmoji;
|
||||
gridView.setOnItemClickListener((parent, view, index, id) -> {
|
||||
String emojiStr = emojis.get(BaseMainActivity.currentInstance).get(index).shortcode;
|
||||
String url = emojis.get(BaseMainActivity.currentInstance).get(index).url;
|
||||
String static_url = emojis.get(BaseMainActivity.currentInstance).get(index).static_url;
|
||||
boolean alreadyAdded = false;
|
||||
for (Reaction reaction : status.pleroma.emoji_reactions) {
|
||||
if (reaction.name.compareTo(emojiStr) == 0) {
|
||||
alreadyAdded = true;
|
||||
reaction.count = (reaction.count - 1);
|
||||
if (reaction.count == 0) {
|
||||
status.pleroma.emoji_reactions.remove(reaction);
|
||||
}
|
||||
adapter.notifyItemChanged(getPositionAsync(notificationList, statusList, statusToDeal));
|
||||
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(getPositionAsync(notificationList, statusList, statusToDeal));
|
||||
}
|
||||
ActionsVM actionsVM = new ViewModelProvider((ViewModelStoreOwner) context).get(ActionsVM.class);
|
||||
if (alreadyAdded) {
|
||||
actionsVM.removeReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
|
||||
} else {
|
||||
actionsVM.addReaction(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, statusToDeal.id, emojiStr);
|
||||
}
|
||||
if (finalAlertDialogEmoji != null) {
|
||||
finalAlertDialogEmoji.dismiss();
|
||||
}
|
||||
});
|
||||
gridView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);
|
||||
builder.setView(gridView);
|
||||
} else {
|
||||
TextView textView = new TextView(context);
|
||||
textView.setText(context.getString(R.string.no_emoji));
|
||||
textView.setPadding(paddingDp, paddingDp, paddingDp, paddingDp);
|
||||
builder.setView(textView);
|
||||
}
|
||||
alertDialogEmoji = builder.show();
|
||||
});
|
||||
}
|
||||
|
||||
int truncate_toots_size = sharedpreferences.getInt(context.getString(R.string.SET_TRUNCATE_TOOTS_SIZE), 0);
|
||||
// boolean display_video_preview = sharedpreferences.getBoolean(context.getString(R.string.SET_DISPLAY_VIDEO_PREVIEWS), true);
|
||||
// boolean isModerator = sharedpreferences.getBoolean(Helper.PREF_IS_MODERATOR, false);
|
||||
|
|
|
@ -174,10 +174,12 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter.
|
|||
}
|
||||
|
||||
public void scrollToTop() {
|
||||
if (binding != null) {
|
||||
binding.swipeContainer.setRefreshing(true);
|
||||
flagLoading = false;
|
||||
route(DIRECTION.SCROLL_TOP, true);
|
||||
}
|
||||
}
|
||||
|
||||
public View onCreateView(@NonNull LayoutInflater inflater,
|
||||
ViewGroup container, Bundle savedInstanceState) {
|
||||
|
|
|
@ -23,9 +23,6 @@ import androidx.lifecycle.AndroidViewModel;
|
|||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -54,7 +51,6 @@ public class AnnouncementsVM extends AndroidViewModel {
|
|||
}
|
||||
|
||||
private MastodonAnnouncementsService init(@NonNull String instance) {
|
||||
Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create();
|
||||
Retrofit retrofit = new Retrofit.Builder()
|
||||
.baseUrl("https://" + instance + "/api/v1/")
|
||||
.addConverterFactory(GsonConverterFactory.create(Helper.getDateBuilder()))
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
package app.fedilab.android.viewmodel.pleroma;
|
||||
/* Copyright 2022 Thomas Schneider
|
||||
*
|
||||
* This file is a part of Fedilab
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* Fedilab is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||
* Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with Fedilab; if not,
|
||||
* see <http://www.gnu.org/licenses>. */
|
||||
|
||||
import android.app.Application;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.AndroidViewModel;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import app.fedilab.android.client.endpoints.PleromaAPI;
|
||||
import app.fedilab.android.client.entities.api.Announcement;
|
||||
import app.fedilab.android.helper.Helper;
|
||||
import okhttp3.OkHttpClient;
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
|
||||
public class ActionsVM extends AndroidViewModel {
|
||||
|
||||
final OkHttpClient okHttpClient = new OkHttpClient.Builder()
|
||||
.readTimeout(60, TimeUnit.SECONDS)
|
||||
.connectTimeout(60, TimeUnit.SECONDS)
|
||||
.callTimeout(60, TimeUnit.SECONDS)
|
||||
.proxy(Helper.getProxy(getApplication().getApplicationContext()))
|
||||
.build();
|
||||
private MutableLiveData<Announcement> announcementMutableLiveData;
|
||||
private MutableLiveData<List<Announcement>> announcementListMutableLiveData;
|
||||
|
||||
public ActionsVM(@NonNull Application application) {
|
||||
super(application);
|
||||
}
|
||||
|
||||
private PleromaAPI init(@NonNull String instance) {
|
||||
Retrofit retrofit = new Retrofit.Builder()
|
||||
.baseUrl("https://" + instance + "/api/v1/")
|
||||
.addConverterFactory(GsonConverterFactory.create(Helper.getDateBuilder()))
|
||||
.client(okHttpClient)
|
||||
.build();
|
||||
return retrofit.create(PleromaAPI.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* React to an announcement 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) {
|
||||
PleromaAPI pleromaAPI = init(instance);
|
||||
new Thread(() -> {
|
||||
Call<Void> addReactionCall = pleromaAPI.addReaction(token, id, name);
|
||||
if (addReactionCall != null) {
|
||||
try {
|
||||
addReactionCall.execute();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Undo a react emoji to an announcement.
|
||||
*
|
||||
* @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) {
|
||||
PleromaAPI pleromaAPI = init(instance);
|
||||
new Thread(() -> {
|
||||
Call<Void> removeReactionCall = pleromaAPI.removeReaction(token, id, name);
|
||||
if (removeReactionCall != null) {
|
||||
try {
|
||||
removeReactionCall.execute();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
|
@ -59,64 +59,9 @@
|
|||
tools:maxLines="10"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/status_reactions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/content">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/reactions_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/status_add_custom_emoji"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:contentDescription="@string/add_reaction"
|
||||
android:src="@drawable/ic_baseline_emoji_emotions_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?attr/iconColor" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/status_emoji"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:contentDescription="@string/add_reaction"
|
||||
android:src="@drawable/ic_baseline_add_reaction_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?attr/iconColor" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
|
||||
<app.fedilab.android.helper.FedilabAutoCompleteTextView
|
||||
android:id="@+id/fake_edittext"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:importantForAutofill="noExcludeDescendants"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
<include
|
||||
android:id="@+id/layout_reactions"
|
||||
layout="@layout/layout_reactions" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</com.google.android.material.card.MaterialCardView>
|
|
@ -601,6 +601,12 @@
|
|||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<include
|
||||
android:id="@+id/layout_reactions"
|
||||
layout="@layout/layout_reactions"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
|
60
app/src/main/res/layout/layout_reactions.xml
Normal file
60
app/src/main/res/layout/layout_reactions.xml
Normal file
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/status_reactions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp"
|
||||
android:orientation="horizontal"
|
||||
android:paddingBottom="10dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/content">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/reactions_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/status_add_custom_emoji"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:contentDescription="@string/add_reaction"
|
||||
android:src="@drawable/ic_baseline_emoji_emotions_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?attr/iconColor" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/status_emoji"
|
||||
android:layout_width="30dp"
|
||||
android:layout_height="30dp"
|
||||
android:layout_marginStart="10dp"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:contentDescription="@string/add_reaction"
|
||||
android:src="@drawable/ic_baseline_add_reaction_24"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:tint="?attr/iconColor" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone">
|
||||
|
||||
<app.fedilab.android.helper.FedilabAutoCompleteTextView
|
||||
android:id="@+id/fake_edittext"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:importantForAutofill="noExcludeDescendants"
|
||||
android:inputType="text" />
|
||||
</LinearLayout>
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
Loading…
Reference in a new issue