gracefully handle null statuses in notifications
This commit is contained in:
parent
550235d40b
commit
ed60cc3a78
4 changed files with 60 additions and 21 deletions
|
@ -132,16 +132,25 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
case REBLOG: {
|
case REBLOG: {
|
||||||
StatusNotificationViewHolder holder = (StatusNotificationViewHolder) viewHolder;
|
StatusNotificationViewHolder holder = (StatusNotificationViewHolder) viewHolder;
|
||||||
StatusViewData.Concrete statusViewData = concreteNotificaton.getStatusViewData();
|
StatusViewData.Concrete statusViewData = concreteNotificaton.getStatusViewData();
|
||||||
holder.setDisplayName(statusViewData.getUserFullName());
|
|
||||||
holder.setUsername(statusViewData.getNickname());
|
if(statusViewData == null) {
|
||||||
holder.setCreatedAt(statusViewData.getCreatedAt());
|
holder.showNotificationContent(false);
|
||||||
|
} else {
|
||||||
|
holder.showNotificationContent(true);
|
||||||
|
|
||||||
|
holder.setDisplayName(statusViewData.getUserFullName());
|
||||||
|
holder.setUsername(statusViewData.getNickname());
|
||||||
|
holder.setCreatedAt(statusViewData.getCreatedAt());
|
||||||
|
|
||||||
|
holder.setAvatars(concreteNotificaton.getStatusViewData().getAvatar(),
|
||||||
|
concreteNotificaton.getAccount().avatar);
|
||||||
|
}
|
||||||
|
|
||||||
holder.setMessage(concreteNotificaton, statusListener);
|
holder.setMessage(concreteNotificaton, statusListener);
|
||||||
holder.setupButtons(notificationActionListener,
|
holder.setupButtons(notificationActionListener,
|
||||||
concreteNotificaton.getAccount().id,
|
concreteNotificaton.getAccount().id,
|
||||||
concreteNotificaton.getId());
|
concreteNotificaton.getId());
|
||||||
holder.setAvatars(concreteNotificaton.getStatusViewData().getAvatar(),
|
|
||||||
concreteNotificaton.getAccount().avatar);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FOLLOW: {
|
case FOLLOW: {
|
||||||
|
@ -284,6 +293,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
private static class StatusNotificationViewHolder extends RecyclerView.ViewHolder
|
private static class StatusNotificationViewHolder extends RecyclerView.ViewHolder
|
||||||
implements View.OnClickListener, ToggleButton.OnCheckedChangeListener {
|
implements View.OnClickListener, ToggleButton.OnCheckedChangeListener {
|
||||||
private final TextView message;
|
private final TextView message;
|
||||||
|
private final View statusNameBar;
|
||||||
private final TextView displayName;
|
private final TextView displayName;
|
||||||
private final TextView username;
|
private final TextView username;
|
||||||
private final TextView timestampInfo;
|
private final TextView timestampInfo;
|
||||||
|
@ -303,6 +313,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
StatusNotificationViewHolder(View itemView) {
|
StatusNotificationViewHolder(View itemView) {
|
||||||
super(itemView);
|
super(itemView);
|
||||||
message = itemView.findViewById(R.id.notification_top_text);
|
message = itemView.findViewById(R.id.notification_top_text);
|
||||||
|
statusNameBar = itemView.findViewById(R.id.status_name_bar);
|
||||||
displayName = itemView.findViewById(R.id.status_display_name);
|
displayName = itemView.findViewById(R.id.status_display_name);
|
||||||
username = itemView.findViewById(R.id.status_username);
|
username = itemView.findViewById(R.id.status_username);
|
||||||
timestampInfo = itemView.findViewById(R.id.status_timestamp_info);
|
timestampInfo = itemView.findViewById(R.id.status_timestamp_info);
|
||||||
|
@ -324,6 +335,15 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
contentWarningButton.setOnCheckedChangeListener(this);
|
contentWarningButton.setOnCheckedChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showNotificationContent(boolean show) {
|
||||||
|
statusNameBar.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||||
|
contentWarningBar.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||||
|
statusContent.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||||
|
statusAvatar.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||||
|
notificationAvatar.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void setDisplayName(String name) {
|
private void setDisplayName(String name) {
|
||||||
displayName.setText(name);
|
displayName.setText(name);
|
||||||
}
|
}
|
||||||
|
@ -396,9 +416,12 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
||||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
|
||||||
message.setText(str);
|
message.setText(str);
|
||||||
|
|
||||||
boolean hasSpoiler = !TextUtils.isEmpty(statusViewData.getSpoilerText());
|
if (statusViewData != null) {
|
||||||
contentWarningBar.setVisibility(hasSpoiler ? View.VISIBLE : View.GONE);
|
boolean hasSpoiler = !TextUtils.isEmpty(statusViewData.getSpoilerText());
|
||||||
setupContentAndSpoiler(notificationViewData, listener);
|
contentWarningBar.setVisibility(hasSpoiler ? View.VISIBLE : View.GONE);
|
||||||
|
setupContentAndSpoiler(notificationViewData, listener);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupButtons(final NotificationActionListener listener, final String accountId,
|
void setupButtons(final NotificationActionListener listener, final String accountId,
|
||||||
|
|
|
@ -10,6 +10,7 @@ import android.support.v7.widget.RecyclerView;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
@ -27,6 +28,7 @@ import com.keylesspalace.tusky.util.LinkHelper;
|
||||||
import com.keylesspalace.tusky.util.ThemeUtils;
|
import com.keylesspalace.tusky.util.ThemeUtils;
|
||||||
import com.keylesspalace.tusky.view.RoundedTransformation;
|
import com.keylesspalace.tusky.view.RoundedTransformation;
|
||||||
import com.keylesspalace.tusky.viewdata.StatusViewData;
|
import com.keylesspalace.tusky.viewdata.StatusViewData;
|
||||||
|
import com.mikepenz.iconics.utils.Utils;
|
||||||
import com.squareup.picasso.Picasso;
|
import com.squareup.picasso.Picasso;
|
||||||
import com.varunest.sparkbutton.SparkButton;
|
import com.varunest.sparkbutton.SparkButton;
|
||||||
import com.varunest.sparkbutton.SparkEventListener;
|
import com.varunest.sparkbutton.SparkEventListener;
|
||||||
|
@ -147,6 +149,15 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
||||||
timestampInfo.setContentDescription(readoutAloud);
|
timestampInfo.setContentDescription(readoutAloud);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void showContent(boolean show) {
|
||||||
|
if(show) {
|
||||||
|
container.setVisibility(View.VISIBLE);
|
||||||
|
container.getLayoutParams().height = ViewGroup.LayoutParams.WRAP_CONTENT;
|
||||||
|
} else {
|
||||||
|
container.setVisibility(View.INVISIBLE);
|
||||||
|
container.getLayoutParams().height = Utils.convertDpToPx(container.getContext(), 24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void setIsReply(boolean isReply) {
|
private void setIsReply(boolean isReply) {
|
||||||
if(isReply) {
|
if(isReply) {
|
||||||
|
|
|
@ -78,19 +78,24 @@ public class StatusViewHolder extends StatusBaseViewHolder {
|
||||||
@Override
|
@Override
|
||||||
void setupWithStatus(StatusViewData.Concrete status, final StatusActionListener listener,
|
void setupWithStatus(StatusViewData.Concrete status, final StatusActionListener listener,
|
||||||
boolean mediaPreviewEnabled) {
|
boolean mediaPreviewEnabled) {
|
||||||
super.setupWithStatus(status, listener, mediaPreviewEnabled);
|
if(status == null) {
|
||||||
|
showContent(false);
|
||||||
String rebloggedByDisplayName = status.getRebloggedByUsername();
|
|
||||||
if (rebloggedByDisplayName == null) {
|
|
||||||
hideRebloggedByDisplayName();
|
|
||||||
} else {
|
} else {
|
||||||
setRebloggedByDisplayName(rebloggedByDisplayName);
|
showContent(true);
|
||||||
}
|
super.setupWithStatus(status, listener, mediaPreviewEnabled);
|
||||||
|
|
||||||
// I think it's not efficient to create new object every time we bind a holder.
|
String rebloggedByDisplayName = status.getRebloggedByUsername();
|
||||||
// More efficient approach would be creating View.OnClickListener during holder creation
|
if (rebloggedByDisplayName == null) {
|
||||||
// and storing StatusActionListener in a variable after binding.
|
hideRebloggedByDisplayName();
|
||||||
rebloggedBar.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition()));
|
} else {
|
||||||
|
setRebloggedByDisplayName(rebloggedByDisplayName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// I think it's not efficient to create new object every time we bind a holder.
|
||||||
|
// More efficient approach would be creating View.OnClickListener during holder creation
|
||||||
|
// and storing StatusActionListener in a variable after binding.
|
||||||
|
rebloggedBar.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setRebloggedByDisplayName(String name) {
|
private void setRebloggedByDisplayName(String name) {
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentTop="true"
|
android:layout_alignParentTop="true"
|
||||||
|
android:layout_marginBottom="6dp"
|
||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:drawablePadding="10dp"
|
android:drawablePadding="10dp"
|
||||||
android:ellipsize="end"
|
android:ellipsize="end"
|
||||||
|
@ -30,8 +31,7 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@+id/notification_top_text"
|
android:layout_below="@+id/notification_top_text"
|
||||||
android:layout_toEndOf="@+id/notification_status_avatar"
|
android:layout_toEndOf="@+id/notification_status_avatar"
|
||||||
android:paddingBottom="4dp"
|
android:paddingBottom="4dp">
|
||||||
android:paddingTop="6dp">
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/status_display_name"
|
android:id="@+id/status_display_name"
|
||||||
|
|
Loading…
Reference in a new issue