mirror of
https://github.com/nuclearfog/Shitter.git
synced 2025-01-01 04:17:21 +01:00
added announcement reaction view
This commit is contained in:
parent
725ceb6248
commit
3a95cacfa2
@ -7,7 +7,7 @@ import java.io.Serializable;
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public interface Reaction extends Serializable {
|
||||
public interface Reaction extends Serializable, Comparable<Reaction> {
|
||||
|
||||
/**
|
||||
* @return title, emoji unicode or custom emoji shortcode of the reaction
|
||||
@ -28,4 +28,10 @@ public interface Reaction extends Serializable {
|
||||
* @return true if selected by current user
|
||||
*/
|
||||
boolean isSelected();
|
||||
|
||||
|
||||
@Override
|
||||
default int compareTo(Reaction reaction) {
|
||||
return Integer.compare(reaction.getCount(), getCount());
|
||||
}
|
||||
}
|
@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView.Adapter;
|
||||
|
||||
import org.nuclearfog.twidda.model.Announcement;
|
||||
import org.nuclearfog.twidda.model.Reaction;
|
||||
import org.nuclearfog.twidda.model.lists.Announcements;
|
||||
import org.nuclearfog.twidda.ui.adapter.recyclerview.holder.AnnouncementHolder;
|
||||
import org.nuclearfog.twidda.ui.adapter.recyclerview.holder.OnHolderClickListener;
|
||||
@ -49,10 +50,20 @@ public class AnnouncementAdapter extends Adapter<AnnouncementHolder> implements
|
||||
|
||||
@Override
|
||||
public void onItemClick(int position, int type, int... extras) {
|
||||
if (type == ANNOUNCEMENT_DISMISS) {
|
||||
listener.onAnnouncementDismiss(items.get(position));
|
||||
} else if (type == ANNOUNCEMENT_CLICK) {
|
||||
listener.onAnnouncementClick(items.get(position));
|
||||
|
||||
switch(type) {
|
||||
case ANNOUNCEMENT_DISMISS:
|
||||
listener.onAnnouncementDismiss(items.get(position));
|
||||
break;
|
||||
|
||||
case ANNOUNCEMENT_CLICK:
|
||||
listener.onAnnouncementClick(items.get(position));
|
||||
break;
|
||||
|
||||
case ANNOUNCEMENT_REACTION:
|
||||
int reactionIndex = extras[0];
|
||||
listener.onReactionClick(items.get(position).getReactions()[reactionIndex]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,5 +136,12 @@ public class AnnouncementAdapter extends Adapter<AnnouncementHolder> implements
|
||||
* @param announcement clicked item
|
||||
*/
|
||||
void onAnnouncementDismiss(Announcement announcement);
|
||||
|
||||
/**
|
||||
* called to select reaction
|
||||
*
|
||||
* @param reaction selected reaction
|
||||
*/
|
||||
void onReactionClick(Reaction reaction);
|
||||
}
|
||||
}
|
@ -0,0 +1,83 @@
|
||||
package org.nuclearfog.twidda.ui.adapter.recyclerview;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.recyclerview.widget.RecyclerView.Adapter;
|
||||
|
||||
import org.nuclearfog.twidda.model.Reaction;
|
||||
import org.nuclearfog.twidda.ui.adapter.recyclerview.holder.OnHolderClickListener;
|
||||
import org.nuclearfog.twidda.ui.adapter.recyclerview.holder.ReactionHolder;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class ReactionAdapter extends Adapter<ReactionHolder> implements OnHolderClickListener {
|
||||
|
||||
private OnReactionSelected listener;
|
||||
private List<Reaction> items = new LinkedList<>();
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public ReactionAdapter(OnReactionSelected listener) {
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ReactionHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
return new ReactionHolder(parent, this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ReactionHolder holder, int position) {
|
||||
holder.setContent(items.get(position));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return items.size();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onItemClick(int position, int type, int... extras) {
|
||||
if (type == ANNOUNCEMENT_REACTION) {
|
||||
listener.onReactionClick(position);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean onPlaceholderClick(int index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* add adapter items
|
||||
*/
|
||||
public void setItems(Reaction[] reactions) {
|
||||
items.clear();
|
||||
Arrays.sort(reactions);
|
||||
items.addAll(Arrays.asList(reactions));
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public interface OnReactionSelected {
|
||||
|
||||
void onReactionClick(int index);
|
||||
}
|
||||
}
|
@ -10,6 +10,7 @@ import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.cardview.widget.CardView;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
|
||||
@ -22,19 +23,22 @@ import org.nuclearfog.twidda.backend.utils.StringUtils;
|
||||
import org.nuclearfog.twidda.backend.utils.Tagger;
|
||||
import org.nuclearfog.twidda.config.GlobalSettings;
|
||||
import org.nuclearfog.twidda.model.Announcement;
|
||||
import org.nuclearfog.twidda.ui.adapter.recyclerview.ReactionAdapter;
|
||||
import org.nuclearfog.twidda.ui.adapter.recyclerview.ReactionAdapter.OnReactionSelected;
|
||||
|
||||
/**
|
||||
* Viewholder for {@link org.nuclearfog.twidda.ui.adapter.recyclerview.AnnouncementAdapter}
|
||||
*
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class AnnouncementHolder extends ViewHolder implements OnClickListener {
|
||||
public class AnnouncementHolder extends ViewHolder implements OnClickListener, OnReactionSelected {
|
||||
|
||||
private TextView time, content;
|
||||
|
||||
private OnHolderClickListener listener;
|
||||
private GlobalSettings settings;
|
||||
private TextEmojiLoader emojiLoader;
|
||||
private ReactionAdapter adapter;
|
||||
|
||||
private AsyncExecutor.AsyncCallback<TextEmojiLoader.Result> textResult = this::setTextEmojis;
|
||||
private int iconSize;
|
||||
@ -48,13 +52,17 @@ public class AnnouncementHolder extends ViewHolder implements OnClickListener {
|
||||
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_announcement, parent, false));
|
||||
settings = GlobalSettings.get(parent.getContext());
|
||||
emojiLoader = new TextEmojiLoader(parent.getContext());
|
||||
adapter = new ReactionAdapter(this);
|
||||
CardView card = (CardView) itemView;
|
||||
ViewGroup container = itemView.findViewById(R.id.item_announcement_container);
|
||||
View dismiss = itemView.findViewById(R.id.item_announcement_dismiss);
|
||||
RecyclerView reactionList = itemView.findViewById(R.id.item_announcement_list_reactions);
|
||||
time = itemView.findViewById(R.id.item_announcement_timestamp);
|
||||
content = itemView.findViewById(R.id.item_announcement_content);
|
||||
iconSize = parent.getResources().getDimensionPixelSize(R.dimen.item_announcement_icon_size);
|
||||
|
||||
reactionList.setLayoutManager(new LinearLayoutManager(parent.getContext(), LinearLayoutManager.HORIZONTAL, false));
|
||||
reactionList.setAdapter(adapter);
|
||||
card.setCardBackgroundColor(settings.getCardColor());
|
||||
AppStyles.setTheme(container, Color.TRANSPARENT);
|
||||
|
||||
@ -76,6 +84,15 @@ public class AnnouncementHolder extends ViewHolder implements OnClickListener {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onReactionClick(int index) {
|
||||
int position = getLayoutPosition();
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
listener.onItemClick(position, OnHolderClickListener.ANNOUNCEMENT_REACTION, index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
@ -88,6 +105,7 @@ public class AnnouncementHolder extends ViewHolder implements OnClickListener {
|
||||
}
|
||||
content.setText(textSpan);
|
||||
time.setText(StringUtils.formatCreationTime(time.getResources(), announcement.getTimestamp()));
|
||||
adapter.setItems(announcement.getReactions());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,6 +61,8 @@ public interface OnHolderClickListener {
|
||||
|
||||
int ANNOUNCEMENT_DISMISS = 29;
|
||||
|
||||
int ANNOUNCEMENT_REACTION = 30;
|
||||
|
||||
/**
|
||||
* called when an item was clicked
|
||||
*
|
||||
|
@ -0,0 +1,71 @@
|
||||
package org.nuclearfog.twidda.ui.adapter.recyclerview.holder;
|
||||
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
|
||||
|
||||
import com.squareup.picasso.Picasso;
|
||||
|
||||
import org.nuclearfog.twidda.R;
|
||||
import org.nuclearfog.twidda.backend.image.PicassoBuilder;
|
||||
import org.nuclearfog.twidda.config.GlobalSettings;
|
||||
import org.nuclearfog.twidda.model.Reaction;
|
||||
|
||||
/**
|
||||
* @author nuclearfog
|
||||
*/
|
||||
public class ReactionHolder extends ViewHolder implements OnClickListener {
|
||||
|
||||
private ImageView icon;
|
||||
private TextView description;
|
||||
|
||||
private OnHolderClickListener listener;
|
||||
private GlobalSettings settings;
|
||||
private Picasso picasso;
|
||||
|
||||
public ReactionHolder(ViewGroup parent, OnHolderClickListener listener) {
|
||||
super(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_reaction, parent, false));
|
||||
icon = itemView.findViewById(R.id.item_reaction_icon);
|
||||
description = itemView.findViewById(R.id.item_reaction_text);
|
||||
picasso = PicassoBuilder.get(parent.getContext());
|
||||
settings = GlobalSettings.get(parent.getContext());
|
||||
this.listener = listener;
|
||||
|
||||
description.setTextColor(settings.getTextColor());
|
||||
|
||||
itemView.setOnClickListener(this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.getId() == R.id.item_reaction_root) {
|
||||
int position = getLayoutPosition();
|
||||
if (position != RecyclerView.NO_POSITION) {
|
||||
listener.onItemClick(position, OnHolderClickListener.ANNOUNCEMENT_REACTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void setContent(Reaction reaction) {
|
||||
if (!reaction.getImageUrl().isEmpty() && settings.imagesEnabled()) {
|
||||
icon.setVisibility(View.VISIBLE);
|
||||
picasso.load(reaction.getImageUrl()).into(icon);
|
||||
description.setText("");
|
||||
} else {
|
||||
icon.setVisibility(View.GONE);
|
||||
icon.setImageResource(0);
|
||||
description.setText(reaction.getName() + " ");
|
||||
}
|
||||
description.append(Integer.toString(reaction.getCount()));
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@ import org.nuclearfog.twidda.backend.async.AnnouncementLoader;
|
||||
import org.nuclearfog.twidda.backend.async.AsyncExecutor.AsyncCallback;
|
||||
import org.nuclearfog.twidda.backend.utils.ErrorUtils;
|
||||
import org.nuclearfog.twidda.model.Announcement;
|
||||
import org.nuclearfog.twidda.model.Reaction;
|
||||
import org.nuclearfog.twidda.model.lists.Announcements;
|
||||
import org.nuclearfog.twidda.ui.adapter.recyclerview.AnnouncementAdapter;
|
||||
import org.nuclearfog.twidda.ui.adapter.recyclerview.AnnouncementAdapter.OnAnnouncementClickListener;
|
||||
@ -123,6 +124,12 @@ public class AnnouncementFragment extends ListFragment implements OnAnnouncement
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onReactionClick(Reaction reaction) {
|
||||
// todo implement this
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.cardview.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/CardView">
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_announcement_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxLines="15"
|
||||
android:textSize="@dimen/item_announcement_textsize_content"
|
||||
@ -50,8 +50,8 @@
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/item_announcement_list_reactions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/item_announcement_list_reaction_height"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/item_announcement_content"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
25
app/src/main/res/layout/item_reaction.xml
Normal file
25
app/src/main/res/layout/item_reaction.xml
Normal file
@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/item_reaction_root"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_margin="@dimen/item_reaction_margin_layout"
|
||||
android:background="@drawable/button"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/item_reaction_icon"
|
||||
android:layout_width="@dimen/item_reaction_size_icon"
|
||||
android:layout_height="@dimen/item_reaction_size_icon"
|
||||
android:layout_margin="@dimen/item_reaction_margin_layout"
|
||||
android:contentDescription="@string/description_announcement_reaction" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_reaction_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="@dimen/item_reaction_size_text"
|
||||
android:layout_margin="@dimen/item_reaction_margin_layout" />
|
||||
|
||||
</LinearLayout>
|
@ -391,6 +391,11 @@
|
||||
<!--dimens of item_media_field.xml-->
|
||||
<dimen name="dialog_media_field_layout_margin">5dp</dimen>
|
||||
|
||||
<!--dimens of item_reaction.xml-->
|
||||
<dimen name="item_reaction_size_icon">20dp</dimen>
|
||||
<dimen name="item_reaction_size_text">14sp</dimen>
|
||||
<dimen name="item_reaction_margin_layout">5dp</dimen>
|
||||
|
||||
<!--dimens of navigation_header-xml-->
|
||||
<dimen name="navigation_header_layout_padding">10dp</dimen>
|
||||
<dimen name="navigation_header_layout_margin">8dp</dimen>
|
||||
|
@ -329,6 +329,7 @@
|
||||
<string name="status_media_preview_button">Video preview button</string>
|
||||
<string name="poll_finished">Vote finished</string>
|
||||
<string name="description_poll_vote_icon">voted</string>
|
||||
<string name="description_announcement_reaction">reaction of an announcement</string>
|
||||
<string name="description_attachment_icon">Status/Message attachment</string>
|
||||
<string name="notification_status_poll">vote finished</string>
|
||||
<string name="login_network_selector_label">select network</string>
|
||||
|
Loading…
Reference in New Issue
Block a user