gracefully handle null statuses in notifications

This commit is contained in:
Conny Duck 2018-03-01 21:10:10 +01:00
parent 550235d40b
commit ed60cc3a78
4 changed files with 60 additions and 21 deletions

View File

@ -132,16 +132,25 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
case REBLOG: {
StatusNotificationViewHolder holder = (StatusNotificationViewHolder) viewHolder;
StatusViewData.Concrete statusViewData = concreteNotificaton.getStatusViewData();
holder.setDisplayName(statusViewData.getUserFullName());
holder.setUsername(statusViewData.getNickname());
holder.setCreatedAt(statusViewData.getCreatedAt());
if(statusViewData == null) {
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.setupButtons(notificationActionListener,
concreteNotificaton.getAccount().id,
concreteNotificaton.getId());
holder.setAvatars(concreteNotificaton.getStatusViewData().getAvatar(),
concreteNotificaton.getAccount().avatar);
break;
}
case FOLLOW: {
@ -284,6 +293,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
private static class StatusNotificationViewHolder extends RecyclerView.ViewHolder
implements View.OnClickListener, ToggleButton.OnCheckedChangeListener {
private final TextView message;
private final View statusNameBar;
private final TextView displayName;
private final TextView username;
private final TextView timestampInfo;
@ -303,6 +313,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
StatusNotificationViewHolder(View itemView) {
super(itemView);
message = itemView.findViewById(R.id.notification_top_text);
statusNameBar = itemView.findViewById(R.id.status_name_bar);
displayName = itemView.findViewById(R.id.status_display_name);
username = itemView.findViewById(R.id.status_username);
timestampInfo = itemView.findViewById(R.id.status_timestamp_info);
@ -324,6 +335,15 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
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) {
displayName.setText(name);
}
@ -396,9 +416,12 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
message.setText(str);
boolean hasSpoiler = !TextUtils.isEmpty(statusViewData.getSpoilerText());
contentWarningBar.setVisibility(hasSpoiler ? View.VISIBLE : View.GONE);
setupContentAndSpoiler(notificationViewData, listener);
if (statusViewData != null) {
boolean hasSpoiler = !TextUtils.isEmpty(statusViewData.getSpoilerText());
contentWarningBar.setVisibility(hasSpoiler ? View.VISIBLE : View.GONE);
setupContentAndSpoiler(notificationViewData, listener);
}
}
void setupButtons(final NotificationActionListener listener, final String accountId,

View File

@ -10,6 +10,7 @@ import android.support.v7.widget.RecyclerView;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import android.widget.ImageButton;
import android.widget.ImageView;
@ -27,6 +28,7 @@ import com.keylesspalace.tusky.util.LinkHelper;
import com.keylesspalace.tusky.util.ThemeUtils;
import com.keylesspalace.tusky.view.RoundedTransformation;
import com.keylesspalace.tusky.viewdata.StatusViewData;
import com.mikepenz.iconics.utils.Utils;
import com.squareup.picasso.Picasso;
import com.varunest.sparkbutton.SparkButton;
import com.varunest.sparkbutton.SparkEventListener;
@ -147,6 +149,15 @@ abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
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) {
if(isReply) {

View File

@ -78,19 +78,24 @@ public class StatusViewHolder extends StatusBaseViewHolder {
@Override
void setupWithStatus(StatusViewData.Concrete status, final StatusActionListener listener,
boolean mediaPreviewEnabled) {
super.setupWithStatus(status, listener, mediaPreviewEnabled);
String rebloggedByDisplayName = status.getRebloggedByUsername();
if (rebloggedByDisplayName == null) {
hideRebloggedByDisplayName();
if(status == null) {
showContent(false);
} 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.
// 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()));
String rebloggedByDisplayName = status.getRebloggedByUsername();
if (rebloggedByDisplayName == null) {
hideRebloggedByDisplayName();
} 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) {

View File

@ -14,6 +14,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginBottom="6dp"
android:layout_marginTop="8dp"
android:drawablePadding="10dp"
android:ellipsize="end"
@ -30,8 +31,7 @@
android:layout_height="wrap_content"
android:layout_below="@+id/notification_top_text"
android:layout_toEndOf="@+id/notification_status_avatar"
android:paddingBottom="4dp"
android:paddingTop="6dp">
android:paddingBottom="4dp">
<TextView
android:id="@+id/status_display_name"