mirror of
https://github.com/ArcaneChat/android.git
synced 2026-07-03 14:05:24 +02:00
show day in non-scrolling headers, tackles #29
This commit is contained in:
@@ -20,7 +20,6 @@ import android.content.Context;
|
||||
import android.support.annotation.LayoutRes;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.VisibleForTesting;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -39,14 +38,14 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
||||
import org.thoughtcrime.securesms.util.DateUtils;
|
||||
import org.thoughtcrime.securesms.util.LRUCache;
|
||||
import org.thoughtcrime.securesms.util.StickyHeaderDecoration;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.ViewUtil;
|
||||
import org.whispersystems.libsignal.util.guava.Optional;
|
||||
|
||||
import java.lang.ref.SoftReference;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Calendar;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -89,7 +88,6 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
private final @NonNull LayoutInflater inflater;
|
||||
private final @NonNull Context context;
|
||||
private final @NonNull Calendar calendar;
|
||||
private final @NonNull MessageDigest digest;
|
||||
|
||||
private ApplicationDcContext dcContext;
|
||||
private @NonNull int[] dcMsgList = new int[0];
|
||||
@@ -110,6 +108,11 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive() {
|
||||
return dcMsgList.length > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dcMsgList.length;
|
||||
@@ -122,6 +125,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
return new DcMsg(0);
|
||||
}
|
||||
|
||||
|
||||
static class HeaderViewHolder extends RecyclerView.ViewHolder {
|
||||
TextView textView;
|
||||
|
||||
@@ -146,44 +150,21 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
void onItemLongClick(DcMsg item);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@VisibleForTesting
|
||||
ConversationAdapter(Context context) {
|
||||
try {
|
||||
this.glideRequests = null;
|
||||
this.locale = null;
|
||||
this.clickListener = null;
|
||||
this.recipient = null;
|
||||
this.inflater = null;
|
||||
this.calendar = null;
|
||||
this.context = context;
|
||||
this.digest = MessageDigest.getInstance("SHA1");
|
||||
this.dcContext = DcHelper.getContext(context);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new AssertionError("SHA1 isn't supported!");
|
||||
}
|
||||
}
|
||||
|
||||
public ConversationAdapter(@NonNull Context context,
|
||||
@NonNull GlideRequests glideRequests,
|
||||
@NonNull Locale locale,
|
||||
@Nullable ItemClickListener clickListener,
|
||||
@NonNull Recipient recipient) {
|
||||
try {
|
||||
this.glideRequests = glideRequests;
|
||||
this.locale = locale;
|
||||
this.clickListener = clickListener;
|
||||
this.recipient = recipient;
|
||||
this.context = context;
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
this.calendar = Calendar.getInstance();
|
||||
this.digest = MessageDigest.getInstance("SHA1");
|
||||
this.dcContext = DcHelper.getContext(context);
|
||||
this.glideRequests = glideRequests;
|
||||
this.locale = locale;
|
||||
this.clickListener = clickListener;
|
||||
this.recipient = recipient;
|
||||
this.context = context;
|
||||
this.inflater = LayoutInflater.from(context);
|
||||
this.calendar = Calendar.getInstance();
|
||||
this.dcContext = DcHelper.getContext(context);
|
||||
|
||||
setHasStableIds(true);
|
||||
} catch (NoSuchAlgorithmException nsae) {
|
||||
throw new AssertionError("SHA1 isn't supported!");
|
||||
}
|
||||
setHasStableIds(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -255,7 +236,7 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
public int findLastSeenPosition(long lastSeen) {
|
||||
/* TODO -- we shoud do this without loading all messages in the chat
|
||||
if (lastSeen <= 0) return -1;
|
||||
if (isActive()) return -1;
|
||||
if (!isActive()) return -1;
|
||||
|
||||
int count = getItemCount();
|
||||
|
||||
@@ -291,39 +272,8 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isFooterPosition(int position) {
|
||||
// return hasFooterView() && position == getItemCount() - 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected boolean isHeaderPosition(int position) {
|
||||
// return hasHeaderView() && position == 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getHeaderId(int position) {
|
||||
return -1; // no header Id.
|
||||
// if (isActive()) return -1;
|
||||
// if (isHeaderPosition(position)) return -1;
|
||||
// if (isFooterPosition(position)) return -1;
|
||||
// if (position >= getItemCount()) return -1;
|
||||
// if (position < 0) return -1;
|
||||
//
|
||||
// MessageRecord record = getRecordForPositionOrThrow(position);
|
||||
//
|
||||
// calendar.setTime(new Date(record.getDateSent()));
|
||||
// return Util.hashCode(calendar.get(Calendar.YEAR), calendar.get(Calendar.DAY_OF_YEAR));
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return dcMsgList.length > 0;
|
||||
}
|
||||
|
||||
public long getReceivedTimestamp(int position) {
|
||||
if (isActive()) return 0;
|
||||
if (isHeaderPosition(position)) return 0;
|
||||
if (isFooterPosition(position)) return 0;
|
||||
if (!isActive()) return 0;
|
||||
if (position >= getItemCount()) return 0;
|
||||
if (position < 0) return 0;
|
||||
|
||||
@@ -336,21 +286,10 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
return context;
|
||||
}
|
||||
|
||||
@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) {
|
||||
DcMsg msg = getMsg(position);
|
||||
viewHolder.setText(DateUtils.getRelativeDate(getContext(), locale, msg.getTimestamp()));
|
||||
}
|
||||
|
||||
public void onBindLastSeenViewHolder(HeaderViewHolder viewHolder, int position) {
|
||||
viewHolder.setText(getContext().getResources().getQuantityString(R.plurals.ConversationAdapter_n_unread_messages, (position + 1), (position + 1)));
|
||||
}
|
||||
@@ -405,14 +344,40 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
||||
}
|
||||
}
|
||||
|
||||
public void changeData(@Nullable int[] dcMsgList) {
|
||||
this.dcMsgList = dcMsgList==null? new int[0] : dcMsgList;
|
||||
messageRecordCache.clear();
|
||||
notifyDataSetChanged();
|
||||
|
||||
@Override
|
||||
public long getHeaderId(int position) {
|
||||
if (position >= getItemCount()) return -1;
|
||||
if (position < 0) return -1;
|
||||
|
||||
DcMsg dcMsg = getMsg(position);
|
||||
|
||||
calendar.setTime(new Date(dcMsg.getTimestamp()));
|
||||
return Util.hashCode(calendar.get(Calendar.YEAR), calendar.get(Calendar.DAY_OF_YEAR));
|
||||
}
|
||||
|
||||
public void setHeaderView(@Nullable View headerView) {
|
||||
// TODO: must not be implemented, remove calls to this function
|
||||
@Override
|
||||
public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
|
||||
return new HeaderViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.conversation_item_header, parent, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindHeaderViewHolder(HeaderViewHolder viewHolder, int position) {
|
||||
DcMsg msg = getMsg(position);
|
||||
viewHolder.setText(DateUtils.getRelativeDate(getContext(), locale, msg.getTimestamp()));
|
||||
}
|
||||
|
||||
|
||||
public void changeData(@Nullable int[] dcMsgList) {
|
||||
// should be called when there are new messages
|
||||
this.dcMsgList = dcMsgList==null? new int[0] : dcMsgList;
|
||||
reloadData();
|
||||
}
|
||||
|
||||
public void reloadData() {
|
||||
// should be called when some items in a message are changed, eg. seen-state
|
||||
messageRecordCache.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
public void addFastRecord(@NonNull MessageRecord record) {
|
||||
|
||||
@@ -549,7 +549,7 @@ public class ConversationFragment extends Fragment
|
||||
MessageRecord messageRecord = DatabaseFactory.getMmsDatabase(getContext()).readerFor(message, threadId).getCurrent();
|
||||
|
||||
if (getListAdapter() != null) {
|
||||
getListAdapter().setHeaderView(null);
|
||||
//getListAdapter().setHeaderView(null);
|
||||
setLastSeen(0);
|
||||
getListAdapter().addFastRecord(messageRecord);
|
||||
}
|
||||
@@ -561,7 +561,7 @@ public class ConversationFragment extends Fragment
|
||||
MessageRecord messageRecord = DatabaseFactory.getSmsDatabase(getContext()).readerFor(message, threadId).getCurrent();
|
||||
|
||||
if (getListAdapter() != null) {
|
||||
getListAdapter().setHeaderView(null);
|
||||
//getListAdapter().setHeaderView(null);
|
||||
setLastSeen(0);
|
||||
getListAdapter().addFastRecord(messageRecord);
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ public class ConversationItemFooter extends LinearLayout {
|
||||
if (messageRecord.isFailed()) {
|
||||
dateView.setText(R.string.ConversationItem_error_not_delivered);
|
||||
} else {
|
||||
dateView.setText(DateUtils.getExtendedRelativeTimeSpanString(getContext(), locale, messageRecord.getTimestamp()));
|
||||
dateView.setText(DateUtils.getTimeOfDayTimeSpanString(getContext(), locale, messageRecord.getTimestamp()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -91,6 +91,21 @@ public class DateUtils extends android.text.format.DateUtils {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getTimeOfDayTimeSpanString(final Context c, final Locale locale, final long timestamp) {
|
||||
if (isWithin(timestamp, 1, TimeUnit.MINUTES)) {
|
||||
return c.getString(R.string.DateUtils_just_now);
|
||||
} else if (isWithin(timestamp, 1, TimeUnit.HOURS)) {
|
||||
int mins = (int)TimeUnit.MINUTES.convert(System.currentTimeMillis() - timestamp, TimeUnit.MILLISECONDS);
|
||||
return c.getResources().getString(R.string.DateUtils_minutes_ago, mins);
|
||||
} else {
|
||||
StringBuilder format = new StringBuilder();
|
||||
if (DateFormat.is24HourFormat(c)) format.append("HH:mm");
|
||||
else format.append("hh:mm a");
|
||||
|
||||
return getFormattedDateTime(timestamp, format.toString(), locale);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getDayPrecisionTimeSpanString(Context context, Locale locale, long timestamp) {
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user