mirror of
https://github.com/oxen-io/session-android.git
synced 2025-12-30 17:26:17 +00:00
Support for a "new messages" divider in conversations
// FREEBIE
This commit is contained in:
@@ -18,6 +18,8 @@ package org.thoughtcrime.securesms;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Rect;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
@@ -104,15 +106,15 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
|
||||
|
||||
protected static class HeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
protected TextView textView;
|
||||
static class HeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView textView;
|
||||
|
||||
public HeaderViewHolder(View itemView) {
|
||||
HeaderViewHolder(View itemView) {
|
||||
super(itemView);
|
||||
textView = ViewUtil.findById(itemView, R.id.text);
|
||||
}
|
||||
|
||||
public HeaderViewHolder(TextView textView) {
|
||||
HeaderViewHolder(TextView textView) {
|
||||
super(textView);
|
||||
this.textView = textView;
|
||||
}
|
||||
@@ -263,6 +265,24 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
getCursor().close();
|
||||
}
|
||||
|
||||
public int findLastSeenPosition(long lastSeen) {
|
||||
if (lastSeen <= 0) return -1;
|
||||
if (!isActiveCursor()) return -1;
|
||||
|
||||
int count = getItemCount();
|
||||
|
||||
for (int i=0;i<count;i++) {
|
||||
Cursor cursor = getCursorAtPositionOrThrow(i);
|
||||
MessageRecord messageRecord = getMessageRecord(cursor);
|
||||
|
||||
if (messageRecord.getTimestamp() < lastSeen) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void toggleSelection(MessageRecord messageRecord) {
|
||||
if (!batchSelected.remove(messageRecord)) {
|
||||
batchSelected.add(messageRecord);
|
||||
@@ -301,15 +321,82 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
return Util.hashCode(calendar.get(Calendar.YEAR), calendar.get(Calendar.DAY_OF_YEAR));
|
||||
}
|
||||
|
||||
public long getTimestamp(int position) {
|
||||
if (!isActiveCursor()) return 0;
|
||||
if (isHeaderPosition(position)) return 0;
|
||||
if (isFooterPosition(position)) return 0;
|
||||
if (position >= getItemCount()) return 0;
|
||||
if (position < 0) return 0;
|
||||
|
||||
Cursor cursor = getCursorAtPositionOrThrow(position);
|
||||
MessageRecord messageRecord = getMessageRecord(cursor);
|
||||
|
||||
return messageRecord.getTimestamp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
|
||||
return new HeaderViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.conversation_item_header, parent, false));
|
||||
}
|
||||
|
||||
public HeaderViewHolder onCreateLastSeenViewHolder(ViewGroup parent) {
|
||||
return new HeaderViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.conversation_item_last_seen, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindHeaderViewHolder(HeaderViewHolder viewHolder, int position) {
|
||||
Cursor cursor = getCursorAtPositionOrThrow(position);
|
||||
viewHolder.setText(DateUtils.getRelativeDate(getContext(), locale, getMessageRecord(cursor).getDateReceived()));
|
||||
}
|
||||
|
||||
public void onBindLastSeenViewHolder(HeaderViewHolder viewHolder, int position) {
|
||||
viewHolder.setText(getContext().getResources().getQuantityString(R.plurals.ConversationAdapter_n_unread_messages, (position + 1), (position + 1)));
|
||||
}
|
||||
|
||||
public static class LastSeenHeader extends StickyHeaderDecoration {
|
||||
|
||||
private final ConversationAdapter adapter;
|
||||
private final long lastSeenTimestamp;
|
||||
|
||||
public LastSeenHeader(ConversationAdapter adapter, long lastSeenTimestamp) {
|
||||
super(adapter, false, false);
|
||||
this.adapter = adapter;
|
||||
this.lastSeenTimestamp = lastSeenTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasHeader(RecyclerView parent, StickyHeaderAdapter stickyAdapter, int position) {
|
||||
if (!adapter.isActiveCursor()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lastSeenTimestamp <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long currentRecordTimestamp = adapter.getTimestamp(position);
|
||||
long previousRecordTimestamp = adapter.getTimestamp(position + 1);
|
||||
|
||||
return currentRecordTimestamp > lastSeenTimestamp && previousRecordTimestamp < lastSeenTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected HeaderViewHolder getHeader(RecyclerView parent, StickyHeaderAdapter stickyAdapter, int position) {
|
||||
HeaderViewHolder viewHolder = adapter.onCreateLastSeenViewHolder(parent);
|
||||
adapter.onBindLastSeenViewHolder(viewHolder, position);
|
||||
|
||||
int widthSpec = View.MeasureSpec.makeMeasureSpec(parent.getWidth(), View.MeasureSpec.EXACTLY);
|
||||
int heightSpec = View.MeasureSpec.makeMeasureSpec(parent.getHeight(), View.MeasureSpec.UNSPECIFIED);
|
||||
|
||||
int childWidth = ViewGroup.getChildMeasureSpec(widthSpec, parent.getPaddingLeft() + parent.getPaddingRight(), viewHolder.itemView.getLayoutParams().width);
|
||||
int childHeight = ViewGroup.getChildMeasureSpec(heightSpec, parent.getPaddingTop() + parent.getPaddingBottom(), viewHolder.itemView.getLayoutParams().height);
|
||||
|
||||
viewHolder.itemView.measure(childWidth, childHeight);
|
||||
viewHolder.itemView.layout(0, 0, viewHolder.itemView.getMeasuredWidth(), viewHolder.itemView.getMeasuredHeight());
|
||||
|
||||
return viewHolder;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user