package com.gh4a.adapter;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.PopupMenu;
import android.widget.TextView;
import com.gh4a.R;
import com.gh4a.loader.NotificationHolder;
import com.gh4a.utils.StringUtils;
import com.gh4a.utils.UiUtils;
import org.eclipse.egit.github.core.Notification;
import org.eclipse.egit.github.core.NotificationSubject;
import org.eclipse.egit.github.core.Repository;
public class NotificationAdapter extends
RootAdapter<NotificationHolder, NotificationAdapter.ViewHolder> {
private static final int VIEW_TYPE_NOTIFICATION_HEADER = RootAdapter.CUSTOM_VIEW_TYPE_START + 1;
private static final String SUBJECT_ISSUE = "Issue";
private static final String SUBJECT_PULL_REQUEST = "PullRequest";
private static final String SUBJECT_COMMIT = "Commit";
private static final String SUBJECT_RELEASE = "Release";
public interface OnNotificationActionCallback {
void markAsRead(NotificationHolder notificationHolder);
void unsubscribe(NotificationHolder notificationHolder);
}
private final int mBottomMargin;
private final Context mContext;
private final OnNotificationActionCallback mActionCallback;
public NotificationAdapter(Context context, OnNotificationActionCallback actionCallback) {
super(context);
mContext = context;
mActionCallback = actionCallback;
mBottomMargin = context.getResources().getDimensionPixelSize(R.dimen.card_margin);
}
public void markAsRead(@Nullable Repository repository, @Nullable Notification notification) {
NotificationHolder previousRepoItem = null;
int unreadNotificationsInSameRepoCount = 0;
boolean isMarkingSingleNotification = repository == null && notification != null;
for (int i = 0; i < getCount(); i++) {
NotificationHolder item = getItem(i);
// Passing both repository and notification as null will mark everything as read
if ((repository == null && notification == null)
|| (repository != null && item.repository.equals(repository))
|| (item.notification != null && item.notification.equals(notification))) {
item.setIsRead(true);
}
// When marking single notification as read also mark the repository if it contained
// only 1 unread notification
if (isMarkingSingleNotification) {
if (item.notification == null) {
if (previousRepoItem != null && unreadNotificationsInSameRepoCount == 0
&& previousRepoItem.repository.equals(notification.getRepository())) {
previousRepoItem.setIsRead(true);
}
previousRepoItem = item;
unreadNotificationsInSameRepoCount = 0;
} else if (!item.isRead()) {
unreadNotificationsInSameRepoCount += 1;
}
}
}
// Additional check for the very last notification
if (isMarkingSingleNotification && previousRepoItem != null
&& unreadNotificationsInSameRepoCount == 0
&& previousRepoItem.repository.equals(notification.getRepository())) {
previousRepoItem.setIsRead(true);
}
notifyDataSetChanged();
}
@Override
protected ViewHolder onCreateViewHolder(LayoutInflater inflater, ViewGroup parent,
int viewType) {
int layoutResId = viewType == VIEW_TYPE_NOTIFICATION_HEADER
? R.layout.row_notification_header
: R.layout.row_notification;
View v = inflater.inflate(layoutResId, parent, false);
return new ViewHolder(v, mActionCallback);
}
@Override
protected int getItemViewType(NotificationHolder item) {
if (item.notification == null) {
return VIEW_TYPE_NOTIFICATION_HEADER;
}
return super.getItemViewType(item);
}
@Override
protected void onBindViewHolder(ViewHolder holder, NotificationHolder item) {
holder.ivAction.setTag(item);
float alpha = item.isRead() ? 0.5f : 1f;
holder.tvTitle.setAlpha(alpha);
if (item.notification == null) {
holder.ivAction.setVisibility(item.isRead() ? View.GONE : View.VISIBLE);
Repository repository = item.repository;
holder.tvTitle.setText(repository.getOwner().getLogin() + "/" + repository.getName());
return;
}
holder.ivIcon.setAlpha(alpha);
holder.tvTimestamp.setAlpha(alpha);
holder.mPopupMenu.getMenu().findItem(R.id.mark_as_read).setVisible(!item.isRead());
NotificationSubject subject = item.notification.getSubject();
int iconResId = getIconResId(subject.getType());
if (iconResId > 0) {
holder.ivIcon.setImageResource(iconResId);
holder.ivIcon.setVisibility(View.VISIBLE);
} else {
holder.ivIcon.setVisibility(View.INVISIBLE);
}
holder.tvTitle.setText(subject.getTitle());
holder.tvTimestamp.setText(StringUtils.formatRelativeTime(mContext,
item.notification.getUpdatedAt(), true));
ViewGroup.MarginLayoutParams layoutParams =
(ViewGroup.MarginLayoutParams) holder.vNotificationContent.getLayoutParams();
int bottomMargin = item.isLastRepositoryNotification() ? mBottomMargin : 0;
layoutParams.setMargins(0, 0, 0, bottomMargin);
holder.vNotificationContent.setLayoutParams(layoutParams);
holder.vBottomShadow.setVisibility(
item.isLastRepositoryNotification() ? View.VISIBLE : View.GONE);
}
private int getIconResId(String subjectType) {
if (SUBJECT_ISSUE.equals(subjectType)) {
return UiUtils.resolveDrawable(mContext, R.attr.issueIcon);
}
if (SUBJECT_PULL_REQUEST.equals(subjectType)) {
return UiUtils.resolveDrawable(mContext, R.attr.pullRequestIcon);
}
if (SUBJECT_COMMIT.equals(subjectType)) {
return UiUtils.resolveDrawable(mContext, R.attr.commitIcon);
}
if (SUBJECT_RELEASE.equals(subjectType)) {
return UiUtils.resolveDrawable(mContext, R.attr.releaseIcon);
}
return -1;
}
public static class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
PopupMenu.OnMenuItemClickListener {
public ViewHolder(View view, OnNotificationActionCallback actionCallback) {
super(view);
mActionCallback = actionCallback;
ivAction = (ImageView) view.findViewById(R.id.iv_action);
ivAction.setOnClickListener(this);
ivIcon = (ImageView) view.findViewById(R.id.iv_icon);
tvTitle = (TextView) view.findViewById(R.id.tv_title);
tvTimestamp = (TextView) view.findViewById(R.id.tv_timestamp);
vNotificationContent = view.findViewById(R.id.v_notification_content);
vBottomShadow = view.findViewById(R.id.v_bottom_shadow);
mPopupMenu = new PopupMenu(view.getContext(), ivAction);
mPopupMenu.getMenuInflater().inflate(R.menu.notification_menu, mPopupMenu.getMenu());
mPopupMenu.setOnMenuItemClickListener(this);
}
private final ImageView ivIcon;
private final ImageView ivAction;
private final TextView tvTitle;
private final TextView tvTimestamp;
private final View vNotificationContent;
private final View vBottomShadow;
private final PopupMenu mPopupMenu;
private final OnNotificationActionCallback mActionCallback;
@Override
public void onClick(View v) {
if (v.getId() == R.id.iv_action) {
NotificationHolder notificationHolder = (NotificationHolder) v.getTag();
if (notificationHolder.notification == null) {
mActionCallback.markAsRead(notificationHolder);
} else {
mPopupMenu.show();
}
}
}
@Override
public boolean onMenuItemClick(MenuItem item) {
NotificationHolder notificationHolder = (NotificationHolder) ivAction.getTag();
switch (item.getItemId()) {
case R.id.mark_as_read:
mActionCallback.markAsRead(notificationHolder);
return true;
case R.id.unsubscribe:
mActionCallback.unsubscribe(notificationHolder);
return true;
}
return false;
}
}
}