mirror of
https://github.com/deltachat/deltachat-android.git
synced 2025-10-05 10:39:24 +02:00
show new message marker #447
This commit is contained in:
parent
b74c654451
commit
96814700cb
8 changed files with 711 additions and 768 deletions
|
@ -151,7 +151,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
public static final String CHAT_ID_EXTRA = "chat_id";
|
||||
public static final String IS_ARCHIVED_EXTRA = "is_archived";
|
||||
public static final String TEXT_EXTRA = "draft_text";
|
||||
public static final String LAST_SEEN_EXTRA = "last_seen";
|
||||
public static final String STARTING_POSITION_EXTRA = "starting_position";
|
||||
|
||||
private static final int PICK_GALLERY = 1;
|
||||
|
@ -310,9 +309,6 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
if (isFinishing()) overridePendingTransition(R.anim.fade_scale_in, R.anim.slide_to_right);
|
||||
quickAttachmentDrawer.onPause();
|
||||
inputPanel.onPause();
|
||||
|
||||
fragment.setLastSeen(System.currentTimeMillis());
|
||||
|
||||
AudioSlidePlayer.stopAll();
|
||||
}
|
||||
|
||||
|
@ -1163,7 +1159,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
|
|||
return;
|
||||
}
|
||||
|
||||
fragment.setLastSeen(0);
|
||||
fragment.setLastSeen(-1);
|
||||
|
||||
if (refreshFragment) {
|
||||
fragment.reload(recipient, chatId);
|
||||
|
|
|
@ -91,6 +91,8 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
|||
private @NonNull DcChat dcChat;
|
||||
private @NonNull int[] dcMsgList = new int[0];
|
||||
private int positionToPulseHighlight = -1;
|
||||
private int lastSeenPosition = -1;
|
||||
private long lastSeen = -1;
|
||||
|
||||
protected static class ViewHolder extends RecyclerView.ViewHolder {
|
||||
public <V extends View & BindableConversationItem> ViewHolder(final @NonNull V itemView) {
|
||||
|
@ -120,6 +122,19 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
|||
return dcChat.getName();
|
||||
}
|
||||
|
||||
public void setLastSeen(long timestamp) {
|
||||
lastSeen = timestamp;
|
||||
}
|
||||
|
||||
public void updateLastSeenPosition() {
|
||||
this.lastSeenPosition = findLastSeenPosition(lastSeen);
|
||||
|
||||
}
|
||||
|
||||
public int getLastSeenPosition() {
|
||||
return lastSeenPosition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dcMsgList.length;
|
||||
|
@ -261,24 +276,6 @@ 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;
|
||||
|
||||
int count = getItemCount();
|
||||
|
||||
for (int i = 0;i<count;i++) {
|
||||
DcMsg msg = getMsg(i);
|
||||
if (msg.isOutgoing() || msg.getTimestamp() <= lastSeen) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void toggleSelection(DcMsg messageRecord) {
|
||||
if (!batchSelected.remove(messageRecord)) {
|
||||
batchSelected.add(messageRecord);
|
||||
|
@ -314,6 +311,59 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
|||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getHeaderId(int position) {
|
||||
if (position >= getItemCount()) return -1;
|
||||
if (position < 0) return -1;
|
||||
|
||||
calendar.setTime(new Date(getSortTimestamp(position)));
|
||||
return Util.hashCode(calendar.get(Calendar.YEAR), calendar.get(Calendar.DAY_OF_YEAR));
|
||||
}
|
||||
|
||||
@Override
|
||||
public HeaderViewHolder onCreateHeaderViewHolder(ViewGroup parent) {
|
||||
return new HeaderViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.conversation_item_header, parent, false));
|
||||
}
|
||||
|
||||
/**
|
||||
* date header view
|
||||
*/
|
||||
@Override
|
||||
public void onBindHeaderViewHolder(HeaderViewHolder viewHolder, int position) {
|
||||
viewHolder.setText(DateUtils.getRelativeDate(getContext(), locale, getSortTimestamp(position)));
|
||||
}
|
||||
|
||||
|
||||
public void changeData(@Nullable int[] dcMsgList) {
|
||||
// should be called when there are new messages
|
||||
this.dcMsgList = dcMsgList == null ? new int[0] : dcMsgList;
|
||||
reloadData();
|
||||
}
|
||||
|
||||
private void reloadData() {
|
||||
// should be called when some items in a message are changed, eg. seen-state
|
||||
recordCache.clear();
|
||||
updateLastSeenPosition();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private int findLastSeenPosition(long lastSeen) {
|
||||
if (lastSeen <= 0) return -1;
|
||||
if (!isActive()) return -1;
|
||||
|
||||
int count = getItemCount();
|
||||
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
DcMsg msg = getMsg(i);
|
||||
if (msg.isOutgoing() || msg.getTimestamp() <= lastSeen) {
|
||||
return i - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
public HeaderViewHolder onCreateLastSeenViewHolder(ViewGroup parent) {
|
||||
return new HeaderViewHolder(LayoutInflater.from(getContext()).inflate(R.layout.conversation_item_last_seen, parent, false));
|
||||
}
|
||||
|
@ -323,30 +373,16 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
|||
}
|
||||
|
||||
static class LastSeenHeader extends StickyHeaderDecoration {
|
||||
|
||||
private final ConversationAdapter adapter;
|
||||
private final long lastSeenTimestamp;
|
||||
|
||||
LastSeenHeader(ConversationAdapter adapter, long lastSeenTimestamp) {
|
||||
LastSeenHeader(ConversationAdapter adapter) {
|
||||
super(adapter, false, false);
|
||||
this.adapter = adapter;
|
||||
this.lastSeenTimestamp = lastSeenTimestamp;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasHeader(RecyclerView parent, StickyHeaderAdapter stickyAdapter, int position) {
|
||||
if (!adapter.isActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lastSeenTimestamp <= 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
long currentRecordTimestamp = adapter.getSortTimestamp(position);
|
||||
long previousRecordTimestamp = adapter.getSortTimestamp(position + 1);
|
||||
|
||||
return currentRecordTimestamp > lastSeenTimestamp && previousRecordTimestamp < lastSeenTimestamp;
|
||||
return adapter.isActive() && position == adapter.getLastSeenPosition();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -371,41 +407,5 @@ public class ConversationAdapter <V extends View & BindableConversationItem>
|
|||
return viewHolder;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public long getHeaderId(int position) {
|
||||
if (position >= getItemCount()) return -1;
|
||||
if (position < 0) return -1;
|
||||
|
||||
DcMsg dcMsg = getMsg(position);
|
||||
|
||||
calendar.setTime(new Date(getSortTimestamp(position)));
|
||||
return Util.hashCode(calendar.get(Calendar.YEAR), calendar.get(Calendar.DAY_OF_YEAR));
|
||||
}
|
||||
|
||||
@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, getSortTimestamp(position)));
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
recordCache.clear();
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -41,7 +41,6 @@ import org.thoughtcrime.securesms.util.DynamicTheme;
|
|||
import org.thoughtcrime.securesms.util.Prefs;
|
||||
|
||||
import static org.thoughtcrime.securesms.ConversationActivity.CHAT_ID_EXTRA;
|
||||
import static org.thoughtcrime.securesms.ConversationActivity.LAST_SEEN_EXTRA;
|
||||
import static org.thoughtcrime.securesms.ConversationActivity.STARTING_POSITION_EXTRA;
|
||||
import static org.thoughtcrime.securesms.map.MapDataManager.ALL_CHATS_GLOBAL_MAP;
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.REQUEST_RELAY;
|
||||
|
@ -217,16 +216,15 @@ public class ConversationListActivity extends PassphraseRequiredActionBarActivit
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onCreateConversation(int chatId, long lastSeen) {
|
||||
openConversation(chatId, lastSeen, -1);
|
||||
public void onCreateConversation(int chatId) {
|
||||
openConversation(chatId, -1);
|
||||
}
|
||||
|
||||
public void openConversation(int chatId, long lastSeen, int startingPosition) {
|
||||
public void openConversation(int chatId, int startingPosition) {
|
||||
searchToolbar.clearFocus();
|
||||
|
||||
Intent intent = new Intent(this, ConversationActivity.class);
|
||||
intent.putExtra(CHAT_ID_EXTRA, chatId);
|
||||
intent.putExtra(LAST_SEEN_EXTRA, lastSeen);
|
||||
intent.putExtra(STARTING_POSITION_EXTRA, startingPosition);
|
||||
if (isRelayingMessageContent(this)) {
|
||||
acquireRelayMessageContent(this, intent);
|
||||
|
|
|
@ -9,7 +9,6 @@ import org.thoughtcrime.securesms.util.DynamicTheme;
|
|||
|
||||
import static org.thoughtcrime.securesms.ConversationActivity.CHAT_ID_EXTRA;
|
||||
import static org.thoughtcrime.securesms.ConversationActivity.IS_ARCHIVED_EXTRA;
|
||||
import static org.thoughtcrime.securesms.ConversationActivity.LAST_SEEN_EXTRA;
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.REQUEST_RELAY;
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.acquireRelayMessageContent;
|
||||
import static org.thoughtcrime.securesms.util.RelayUtil.isRelayingMessageContent;
|
||||
|
@ -63,11 +62,10 @@ public class ConversationListArchiveActivity extends PassphraseRequiredActionBar
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onCreateConversation(int chatId, long lastSeenTime) {
|
||||
public void onCreateConversation(int chatId) {
|
||||
Intent intent = new Intent(this, ConversationActivity.class);
|
||||
intent.putExtra(CHAT_ID_EXTRA, chatId);
|
||||
intent.putExtra(IS_ARCHIVED_EXTRA, true);
|
||||
intent.putExtra(LAST_SEEN_EXTRA, lastSeenTime);
|
||||
if (isRelayingMessageContent(this)) {
|
||||
acquireRelayMessageContent(this, intent);
|
||||
startActivityForResult(intent, REQUEST_RELAY);
|
||||
|
|
|
@ -341,8 +341,8 @@ public class ConversationListFragment extends Fragment
|
|||
actionMode.setTitle(String.valueOf(getListAdapter().getBatchSelections().size()));
|
||||
}
|
||||
|
||||
private void handleCreateConversation(int threadId, long lastSeen) {
|
||||
((ConversationSelectedListener)getActivity()).onCreateConversation(threadId, lastSeen);
|
||||
private void handleCreateConversation(int chatId) {
|
||||
((ConversationSelectedListener)getActivity()).onCreateConversation(chatId);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -413,7 +413,7 @@ public class ConversationListFragment extends Fragment
|
|||
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||
int belongingChatId = dcContext.createChatByMsgId(msgId);
|
||||
if( belongingChatId != 0 ) {
|
||||
handleCreateConversation(belongingChatId, 0);
|
||||
handleCreateConversation(belongingChatId);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(R.string.not_now, null)
|
||||
|
@ -424,7 +424,7 @@ public class ConversationListFragment extends Fragment
|
|||
return;
|
||||
}
|
||||
|
||||
handleCreateConversation(chatId, 0);
|
||||
handleCreateConversation(chatId);
|
||||
} else {
|
||||
ConversationListAdapter adapter = (ConversationListAdapter)list.getAdapter();
|
||||
adapter.toggleThreadInBatchSet(item.getChatId());
|
||||
|
@ -454,7 +454,7 @@ public class ConversationListFragment extends Fragment
|
|||
}
|
||||
|
||||
public interface ConversationSelectedListener {
|
||||
void onCreateConversation(int threadId, long lastSeen);
|
||||
void onCreateConversation(int chatId);
|
||||
void onSwitchToArchive();
|
||||
}
|
||||
|
||||
|
|
|
@ -297,7 +297,6 @@ public class MapActivity extends BaseActivity implements Observer, TimeRangeSlid
|
|||
|
||||
Intent intent = new Intent(MapActivity.this, ConversationActivity.class);
|
||||
intent.putExtra(ConversationActivity.CHAT_ID_EXTRA, dcMsgChatId);
|
||||
intent.putExtra(ConversationActivity.LAST_SEEN_EXTRA, 0);
|
||||
intent.putExtra(ConversationActivity.STARTING_POSITION_EXTRA, startingPosition);
|
||||
startActivity(intent);
|
||||
return true;
|
||||
|
|
|
@ -133,7 +133,7 @@ public class SearchFragment extends Fragment implements SearchListAdapter.EventL
|
|||
public void onConversationClicked(@NonNull DcChatlist.Item chatlistItem) {
|
||||
ConversationListActivity conversationList = (ConversationListActivity) getActivity();
|
||||
if (conversationList != null) {
|
||||
conversationList.onCreateConversation(chatlistItem.chatId,0);
|
||||
conversationList.onCreateConversation(chatlistItem.chatId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -150,11 +150,11 @@ public class SearchFragment extends Fragment implements SearchListAdapter.EventL
|
|||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.setPositiveButton(android.R.string.ok, (dialog, which) -> {
|
||||
int chatId1 = dcContext.createChatByContactId(contact.getId());
|
||||
conversationList.onCreateConversation(chatId1,0);
|
||||
conversationList.onCreateConversation(chatId1);
|
||||
}).show();
|
||||
}
|
||||
else {
|
||||
conversationList.onCreateConversation(chatId,0);
|
||||
conversationList.onCreateConversation(chatId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ public class SearchFragment extends Fragment implements SearchListAdapter.EventL
|
|||
break;
|
||||
}
|
||||
}
|
||||
conversationList.openConversation(chatId, 0, startingPosition);
|
||||
conversationList.openConversation(chatId, startingPosition);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue