guard against the status of a notification being null in rare cases (#2449)
* guard against the status of a notification being null in rare cases * improve code, fix bug when payloads is not null * remove findViewById * add comments in NotificationsAdapter
This commit is contained in:
parent
43709532d6
commit
db7eac0a8d
4 changed files with 55 additions and 13 deletions
|
@ -180,8 +180,16 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
|||
case VIEW_TYPE_STATUS: {
|
||||
StatusViewHolder holder = (StatusViewHolder) viewHolder;
|
||||
StatusViewData.Concrete status = concreteNotificaton.getStatusViewData();
|
||||
holder.setupWithStatus(status,
|
||||
statusListener, statusDisplayOptions, payloadForHolder);
|
||||
if (status == null) {
|
||||
/* in some very rare cases servers sends null status even though they should not,
|
||||
* we have to handle it somehow */
|
||||
holder.showStatusContent(false);
|
||||
} else {
|
||||
if (payloads == null) {
|
||||
holder.showStatusContent(true);
|
||||
}
|
||||
holder.setupWithStatus(status, statusListener, statusDisplayOptions, payloadForHolder);
|
||||
}
|
||||
if (concreteNotificaton.getType() == Notification.Type.POLL) {
|
||||
holder.setPollInfo(accountId.equals(concreteNotificaton.getAccount().getId()));
|
||||
} else {
|
||||
|
@ -194,6 +202,8 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
|
|||
StatusViewData.Concrete statusViewData = concreteNotificaton.getStatusViewData();
|
||||
if (payloadForHolder == null) {
|
||||
if (statusViewData == null) {
|
||||
/* in some very rare cases servers sends null status even though they should not,
|
||||
* we have to handle it somehow */
|
||||
holder.showNotificationContent(false);
|
||||
} else {
|
||||
holder.showNotificationContent(true);
|
||||
|
|
|
@ -20,6 +20,7 @@ import androidx.annotation.DrawableRes;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
|
@ -76,6 +77,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
|||
private SparkButton favouriteButton;
|
||||
private SparkButton bookmarkButton;
|
||||
private ImageButton moreButton;
|
||||
private ConstraintLayout mediaContainer;
|
||||
protected MediaPreviewImageView[] mediaPreviews;
|
||||
private ImageView[] mediaOverlays;
|
||||
private TextView sensitiveMediaWarning;
|
||||
|
@ -124,7 +126,8 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
|||
bookmarkButton = itemView.findViewById(R.id.status_bookmark);
|
||||
moreButton = itemView.findViewById(R.id.status_more);
|
||||
|
||||
itemView.findViewById(R.id.status_media_preview_container).setClipToOutline(true);
|
||||
mediaContainer = itemView.findViewById(R.id.status_media_preview_container);
|
||||
mediaContainer.setClipToOutline(true);
|
||||
|
||||
mediaPreviews = new MediaPreviewImageView[]{
|
||||
itemView.findViewById(R.id.status_media_preview_0),
|
||||
|
@ -719,9 +722,9 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
|||
this.setupWithStatus(status, listener, statusDisplayOptions, null);
|
||||
}
|
||||
|
||||
public void setupWithStatus(StatusViewData.Concrete status,
|
||||
final StatusActionListener listener,
|
||||
StatusDisplayOptions statusDisplayOptions,
|
||||
public void setupWithStatus(@NonNull StatusViewData.Concrete status,
|
||||
@NonNull final StatusActionListener listener,
|
||||
@NonNull StatusDisplayOptions statusDisplayOptions,
|
||||
@Nullable Object payloads) {
|
||||
if (payloads == null) {
|
||||
Status actionable = status.getActionable();
|
||||
|
@ -1133,6 +1136,28 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
|
|||
}
|
||||
}
|
||||
|
||||
public void showStatusContent(boolean show) {
|
||||
int visibility = show ? View.VISIBLE : View.GONE;
|
||||
avatar.setVisibility(visibility);
|
||||
avatarInset.setVisibility(visibility);
|
||||
displayName.setVisibility(visibility);
|
||||
username.setVisibility(visibility);
|
||||
timestampInfo.setVisibility(visibility);
|
||||
contentWarningDescription.setVisibility(visibility);
|
||||
contentWarningButton.setVisibility(visibility);
|
||||
content.setVisibility(visibility);
|
||||
cardView.setVisibility(visibility);
|
||||
mediaContainer.setVisibility(visibility);
|
||||
pollOptions.setVisibility(visibility);
|
||||
pollButton.setVisibility(visibility);
|
||||
pollDescription.setVisibility(visibility);
|
||||
replyButton.setVisibility(visibility);
|
||||
reblogButton.setVisibility(visibility);
|
||||
favouriteButton.setVisibility(visibility);
|
||||
bookmarkButton.setVisibility(visibility);
|
||||
moreButton.setVisibility(visibility);
|
||||
}
|
||||
|
||||
private static String formatDuration(double durationInSeconds) {
|
||||
int seconds = (int) Math.round(durationInSeconds) % 60;
|
||||
int minutes = (int) durationInSeconds % 3600 / 60;
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.view.View;
|
|||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
|
@ -101,9 +102,9 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setupWithStatus(final StatusViewData.Concrete status,
|
||||
final StatusActionListener listener,
|
||||
StatusDisplayOptions statusDisplayOptions,
|
||||
public void setupWithStatus(@NonNull final StatusViewData.Concrete status,
|
||||
@NonNull final StatusActionListener listener,
|
||||
@NonNull StatusDisplayOptions statusDisplayOptions,
|
||||
@Nullable Object payloads) {
|
||||
super.setupWithStatus(status, listener, statusDisplayOptions, payloads);
|
||||
setupCard(status, CardViewMode.FULL_WIDTH, statusDisplayOptions, listener); // Always show card for detailed status
|
||||
|
|
|
@ -22,6 +22,7 @@ import android.view.View;
|
|||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
|
@ -58,9 +59,9 @@ public class StatusViewHolder extends StatusBaseViewHolder {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setupWithStatus(StatusViewData.Concrete status,
|
||||
final StatusActionListener listener,
|
||||
StatusDisplayOptions statusDisplayOptions,
|
||||
public void setupWithStatus(@NonNull StatusViewData.Concrete status,
|
||||
@NonNull final StatusActionListener listener,
|
||||
@NonNull StatusDisplayOptions statusDisplayOptions,
|
||||
@Nullable Object payloads) {
|
||||
if (payloads == null) {
|
||||
|
||||
|
@ -129,4 +130,9 @@ public class StatusViewHolder extends StatusBaseViewHolder {
|
|||
content.setFilters(NO_INPUT_FILTER);
|
||||
}
|
||||
}
|
||||
|
||||
public void showStatusContent(boolean show) {
|
||||
super.showStatusContent(show);
|
||||
contentCollapseButton.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue