blob: 86140fc2bd329afdcf638c5dc3fd86c1599f44c0 [file] [log] [blame]
/*
* Copyright 2017 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.wearable.wear.messaging.chat;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.percent.PercentRelativeLayout;
import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.RoundedBitmapDrawable;
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory;
import android.support.v7.util.SortedList;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.util.SortedListAdapterCallback;
import android.support.wearable.view.WearableRecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.animation.GlideAnimation;
import com.bumptech.glide.request.target.SimpleTarget;
import com.example.android.wearable.wear.messaging.R;
import com.example.android.wearable.wear.messaging.model.Chat;
import com.example.android.wearable.wear.messaging.model.Message;
import com.example.android.wearable.wear.messaging.model.Profile;
import java.util.Calendar;
import java.util.Collection;
import java.util.Locale;
/**
* Adapter for chat view. Uses a SortedList of Messages by sent time. Determines if the senderId is
* the current user and chooses the corresponding senderId layout.
*
* <p>The adapter will tint the background of a message so that there is an alternating visual
* difference to make reading messages easier by providing better visual clues
*/
class ChatAdapter extends WearableRecyclerView.Adapter<ChatAdapter.MessageViewHolder> {
private final Context mContext;
private final Chat mChat;
private final Profile mUser;
private final SortedList<Message> mMessages;
private final int mBlue30;
private final int mBlue15;
ChatAdapter(Context context, Chat chat, Profile user) {
this.mContext = context;
this.mChat = chat;
this.mUser = user;
mBlue15 = ContextCompat.getColor(mContext, R.color.blue_15);
mBlue30 = ContextCompat.getColor(mContext, R.color.blue_30);
mMessages =
new SortedList<>(
Message.class,
new SortedListAdapterCallback<Message>(this) {
@Override
public int compare(Message m1, Message m2) {
return (int) (m1.getSentTime() - m2.getSentTime());
}
@Override
public boolean areContentsTheSame(Message oldItem, Message newItem) {
return oldItem.equals(newItem);
}
@Override
public boolean areItemsTheSame(Message item1, Message item2) {
return item1.getId().equals(item2.getId());
}
});
}
@Override
public MessageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MessageViewHolder(
LayoutInflater.from(mContext).inflate(R.layout.chat_message, parent, false));
}
@Override
public void onBindViewHolder(final MessageViewHolder holder, int position) {
Message message = mMessages.get(position);
Profile sender = mChat.getParticipants().get(mMessages.get(position).getSenderId());
if (sender == null) {
sender = mUser;
}
Glide.with(mContext)
.load(sender.getProfileImageSource())
.asBitmap()
.placeholder(R.drawable.ic_face_white_24dp)
.into(
new SimpleTarget<Bitmap>(100, 100) {
@Override
public void onResourceReady(
Bitmap resource,
GlideAnimation<? super Bitmap> glideAnimation) {
RoundedBitmapDrawable circularBitmapDrawable =
RoundedBitmapDrawableFactory.create(
mContext.getResources(), resource);
circularBitmapDrawable.setCircular(true);
holder.profileImage.setImageDrawable(circularBitmapDrawable);
}
});
// Convert to just the first name of the sender or short hand it if the sender is you.
String name;
if (isUser(sender.getId())) {
name = "You";
} else {
name = sender.getName().split("\\s")[0];
}
holder.textName.setText(name);
// Odd messages have a darker background.
if (position % 2 == 0) {
holder.parentLayout.setBackgroundColor(mBlue15);
} else {
holder.parentLayout.setBackgroundColor(mBlue30);
}
holder.textContent.setText(message.getText());
holder.textTime.setText(millisToDateTime(message.getSentTime()));
}
@Override
public int getItemCount() {
return mMessages.size();
}
public void addMessage(Message message) {
mMessages.add(message);
}
public void addMessages(Collection<Message> messages) {
// There is a bug with {@link SortedList#addAll} that will add new items to the end
// of the list allowing duplications in the view which is unexpected behavior
// https://code.google.com/p/android/issues/detail?id=201618
// so we will mimic the add all operation (add individually but execute in one batch)
mMessages.beginBatchedUpdates();
for (Message message : messages) {
mMessages.add(message);
}
mMessages.endBatchedUpdates();
}
/**
* Converts time since epoch to Month Date Time.
*
* @param time since epoch
* @return String formatted in Month Date HH:MM
*/
private String millisToDateTime(long time) {
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time);
String month = cal.getDisplayName(Calendar.MONTH, Calendar.SHORT, Locale.US);
int date = cal.get(Calendar.DAY_OF_MONTH);
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
return month + " " + date + " " + hour + ":" + String.format(Locale.US, "%02d", minute);
}
private boolean isUser(String id) {
return id.equals(mUser.getId());
}
/** View holder to encapsulate the details of a chat message. */
class MessageViewHolder extends RecyclerView.ViewHolder {
final ViewGroup parentLayout;
final TextView textContent;
final TextView textName;
final ImageView profileImage;
final TextView textTime;
public MessageViewHolder(View itemView) {
super(itemView);
parentLayout = (PercentRelativeLayout) itemView.findViewById(R.id.layout_container);
textContent = (TextView) itemView.findViewById(R.id.text_content);
textName = (TextView) itemView.findViewById(R.id.text_name);
textTime = (TextView) itemView.findViewById(R.id.text_time);
profileImage = (ImageView) itemView.findViewById(R.id.profile_img);
}
}
}