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:
Konrad Pozniak 2022-04-21 18:46:55 +02:00 committed by GitHub
parent 43709532d6
commit db7eac0a8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 55 additions and 13 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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,10 +102,10 @@ class StatusDetailedViewHolder extends StatusBaseViewHolder {
}
@Override
public void setupWithStatus(final StatusViewData.Concrete status,
final StatusActionListener listener,
StatusDisplayOptions statusDisplayOptions,
@Nullable Object payloads) {
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
if (payloads == null) {

View File

@ -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);
}
}