Commit 4438355c authored by Tiago Cunha's avatar Tiago Cunha

That adapter...

parent 27d2d71b
......@@ -2,6 +2,8 @@ package chat.rocket.android.fragment.chatroom;
import android.support.annotation.NonNull;
import java.util.List;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
public interface RoomContract {
......@@ -13,6 +15,10 @@ public interface RoomContract {
void updateHistoryState(boolean hasNext, boolean isLoaded);
void onMessageSendSuccessfully();
void showUnreadCount(int count);
void showMessages(List<Message> messages);
}
interface Presenter {
......@@ -29,5 +35,9 @@ public interface RoomContract {
void resendMessage(String messageId);
void deleteMessage(String messageId);
void onUnreadCount();
void onMarkAsRead();
}
}
......@@ -20,7 +20,6 @@ import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.jakewharton.rxbinding.support.v4.widget.RxDrawerLayout;
import io.realm.Sort;
import java.lang.reflect.Field;
import java.util.ArrayList;
......@@ -31,7 +30,6 @@ import chat.rocket.android.fragment.chatroom.dialog.FileUploadProgressDialogFrag
import chat.rocket.android.fragment.chatroom.dialog.UsersOfRoomDialogFragment;
import chat.rocket.android.helper.FileUploadHelper;
import chat.rocket.android.helper.LoadMoreScrollListener;
import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.helper.OnBackPressListener;
import chat.rocket.android.helper.RecyclerViewAutoScrollManager;
import chat.rocket.android.helper.RecyclerViewScrolledToBottomListener;
......@@ -48,8 +46,8 @@ import chat.rocket.android.layouthelper.extra_action.upload.ImageUploadActionIte
import chat.rocket.android.layouthelper.extra_action.upload.VideoUploadActionItem;
import chat.rocket.android.log.RCLog;
import chat.rocket.core.SyncState;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.persistence.realm.models.ddp.RealmRoom;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.models.internal.Session;
......@@ -57,7 +55,7 @@ import chat.rocket.persistence.realm.repositories.RealmMessageRepository;
import chat.rocket.persistence.realm.repositories.RealmRoomRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
import chat.rocket.persistence.realm.RealmHelper;
import chat.rocket.persistence.realm.RealmModelListAdapter;
import chat.rocket.android.layouthelper.chatroom.ModelListAdapter;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.android.widget.internal.ExtraActionPickerDialogFragment;
......@@ -71,7 +69,7 @@ import permissions.dispatcher.RuntimePermissions;
@RuntimePermissions
public class RoomFragment extends AbstractChatRoomFragment
implements OnBackPressListener, ExtraActionPickerDialogFragment.Callback,
RealmModelListAdapter.OnItemClickListener<PairedMessage>, RoomContract.View {
ModelListAdapter.OnItemClickListener<PairedMessage>, RoomContract.View {
private static final int DIALOG_ID = 1;
private static final String HOSTNAME = "hostname";
......@@ -88,6 +86,7 @@ public class RoomFragment extends AbstractChatRoomFragment
private AbstractNewMessageIndicatorManager newMessageIndicatorManager;
private Snackbar unreadIndicator;
private boolean previousUnreadMessageExists;
private MessageListAdapter adapter;
private List<AbstractExtraActionItem> extraActionItems;
......@@ -131,6 +130,7 @@ public class RoomFragment extends AbstractChatRoomFragment
new RealmUserRepository(hostname),
new RealmRoomRepository(hostname),
new RealmMessageRepository(hostname),
new MethodCallHelper(getContext(), hostname),
ConnectivityManager.getInstance(getContext().getApplicationContext())
);
......@@ -155,12 +155,7 @@ public class RoomFragment extends AbstractChatRoomFragment
@Override
protected void onSetupView() {
RecyclerView listView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
MessageListAdapter adapter = (MessageListAdapter) realmHelper.createListAdapter(getContext(),
realm -> realm.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, roomId)
.findAllSorted(RealmMessage.TIMESTAMP, Sort.DESCENDING),
context -> new MessageListAdapter(context, hostname, userId, token)
);
adapter = new MessageListAdapter(getContext(), hostname, userId, token);
listView.setAdapter(adapter);
adapter.setOnItemClickListener(this);
......@@ -171,7 +166,7 @@ public class RoomFragment extends AbstractChatRoomFragment
@Override
protected void onAutoScrollMissed() {
if (newMessageIndicatorManager != null) {
newMessageIndicatorManager.updateNewMessageCount(getUnreadMessageCount());
presenter.onUnreadCount();
}
}
};
......@@ -233,21 +228,6 @@ public class RoomFragment extends AbstractChatRoomFragment
.setAction(R.string.dialog_view_latest_message_action, view -> scrollToLatestMessage());
}
private int getUnreadMessageCount() {
RealmRoom room = realmHelper.executeTransactionForRead(realm ->
realm.where(RealmRoom.class).equalTo(RealmRoom.ROOM_ID, roomId).findFirst());
if (room != null) {
return realmHelper.executeTransactionForReadResults(realm ->
realm.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, roomId)
.greaterThanOrEqualTo(RealmMessage.TIMESTAMP, room.getLastSeen())
.notEqualTo(RealmMessage.USER_ID, userId)
.findAll()).size();
} else {
return 0;
}
}
@Override
public void onDestroyView() {
RecyclerView listView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
......@@ -277,7 +257,7 @@ public class RoomFragment extends AbstractChatRoomFragment
View sideMenu = rootView.findViewById(R.id.room_side_menu);
sideMenu.findViewById(R.id.btn_users).setOnClickListener(view -> {
UsersOfRoomDialogFragment.create(roomId, hostname)
.show(getFragmentManager(), UsersOfRoomDialogFragment.class.getSimpleName());
.show(getFragmentManager(), "UsersOfRoomDialogFragment");
closeSideMenuIfNeeded();
});
......@@ -370,12 +350,7 @@ public class RoomFragment extends AbstractChatRoomFragment
}
private void markAsReadIfNeeded() {
RealmRoom room = realmHelper.executeTransactionForRead(realm ->
realm.where(RealmRoom.class).equalTo(RealmRoom.ROOM_ID, roomId).findFirst());
if (room != null && room.isAlert()) {
new MethodCallHelper(getContext(), hostname).readMessages(roomId)
.continueWith(new LogcatIfError());
}
presenter.onMarkAsRead();
}
@Override
......@@ -492,4 +467,14 @@ public class RoomFragment extends AbstractChatRoomFragment
scrollToLatestMessage();
messageFormManager.onMessageSend();
}
@Override
public void showUnreadCount(int count) {
newMessageIndicatorManager.updateNewMessageCount(count);
}
@Override
public void showMessages(List<Message> messages) {
adapter.updateData(messages);
}
}
package chat.rocket.android.fragment.chatroom;
import android.support.annotation.NonNull;
import android.support.v4.util.Pair;
import java.util.UUID;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.core.SyncState;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.RoomHistoryState;
......@@ -11,6 +14,7 @@ import chat.rocket.core.repositories.MessageRepository;
import chat.rocket.core.repositories.RoomRepository;
import chat.rocket.core.repositories.UserRepository;
import chat.rocket.android.service.ConnectivityManagerApi;
import rx.Single;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.subscriptions.CompositeSubscription;
......@@ -21,6 +25,7 @@ public class RoomPresenter implements RoomContract.Presenter {
private final UserRepository userRepository;
private final RoomRepository roomRepository;
private final MessageRepository messageRepository;
private final MethodCallHelper methodCallHelper;
private final ConnectivityManagerApi connectivityManagerApi;
private CompositeSubscription compositeSubscription = new CompositeSubscription();
......@@ -29,11 +34,13 @@ public class RoomPresenter implements RoomContract.Presenter {
public RoomPresenter(String roomId, UserRepository userRepository,
RoomRepository roomRepository,
MessageRepository messageRepository,
MethodCallHelper methodCallHelper,
ConnectivityManagerApi connectivityManagerApi) {
this.roomId = roomId;
this.userRepository = userRepository;
this.roomRepository = roomRepository;
this.messageRepository = messageRepository;
this.methodCallHelper = methodCallHelper;
this.connectivityManagerApi = connectivityManagerApi;
}
......@@ -43,6 +50,7 @@ public class RoomPresenter implements RoomContract.Presenter {
getRoomInfo();
getRoomHistoryStateInfo();
getMessages();
}
@Override
......@@ -151,6 +159,44 @@ public class RoomPresenter implements RoomContract.Presenter {
compositeSubscription.add(subscription);
}
@Override
public void onUnreadCount() {
final Subscription subscription = Single.zip(
userRepository.getCurrentUser()
.filter(user -> user != null)
.first()
.toSingle(),
roomRepository.getById(roomId)
.first()
.toSingle(),
(user, room) -> new Pair<>(room, user)
)
.flatMap(roomUserPair -> messageRepository
.unreadCountFor(roomUserPair.first, roomUserPair.second))
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
count -> view.showUnreadCount(count)
);
compositeSubscription.add(subscription);
}
@Override
public void onMarkAsRead() {
final Subscription subscription = roomRepository.getById(roomId)
.first()
.filter(room -> room != null && room.isAlert())
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(
room -> methodCallHelper.readMessages(room.getRoomId())
.continueWith(new LogcatIfError())
);
compositeSubscription.add(subscription);
}
private void getRoomInfo() {
final Subscription subscription = roomRepository.getById(roomId)
.distinctUntilChanged()
......@@ -180,4 +226,15 @@ public class RoomPresenter implements RoomContract.Presenter {
compositeSubscription.add(subscription);
}
private void getMessages() {
final Subscription subscription = roomRepository.getById(roomId)
.first()
.flatMap(messageRepository::getAllFrom)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(messages -> view.showMessages(messages));
compositeSubscription.add(subscription);
}
}
......@@ -3,21 +3,20 @@ package chat.rocket.android.layouthelper;
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.support.v7.util.ListUpdateCallback;
import io.realm.RealmObject;
import chat.rocket.persistence.realm.RealmModelListAdapter;
import chat.rocket.persistence.realm.RealmModelViewHolder;
import chat.rocket.android.layouthelper.chatroom.ModelListAdapter;
import chat.rocket.android.layouthelper.chatroom.ModelViewHolder;
@SuppressWarnings({"PMD.AbstractNaming", "PMD.GenericsNaming"})
/**
* RealmModelListAdapter with header and footer.
* ModelListAdapter with header and footer.
*/
public abstract class ExtRealmModelListAdapter<T extends RealmObject, VM,
VH extends RealmModelViewHolder<VM>> extends RealmModelListAdapter<T, VM, VH> {
public abstract class ExtModelListAdapter<T, VM,
VH extends ModelViewHolder<VM>> extends ModelListAdapter<T, VM, VH> {
protected static final int VIEW_TYPE_HEADER = -1;
protected static final int VIEW_TYPE_FOOTER = -2;
protected ExtRealmModelListAdapter(Context context) {
protected ExtModelListAdapter(Context context) {
super(context);
}
......
......@@ -8,10 +8,9 @@ import chat.rocket.android.R;
import chat.rocket.android.helper.DateTime;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.core.SyncState;
import chat.rocket.persistence.realm.RealmModelViewHolder;
import chat.rocket.android.widget.RocketChatAvatar;
public abstract class AbstractMessageViewHolder extends RealmModelViewHolder<PairedMessage> {
public abstract class AbstractMessageViewHolder extends ModelViewHolder<PairedMessage> {
protected final RocketChatAvatar avatar;
protected final TextView username;
protected final TextView subUsername;
......
......@@ -9,14 +9,14 @@ import java.util.Collections;
import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.ExtRealmModelListAdapter;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.android.layouthelper.ExtModelListAdapter;
import chat.rocket.core.models.Message;
/**
* target list adapter for chat room.
*/
public class MessageListAdapter
extends ExtRealmModelListAdapter<RealmMessage, PairedMessage, AbstractMessageViewHolder> {
extends ExtModelListAdapter<Message, PairedMessage, AbstractMessageViewHolder> {
private static final int VIEW_TYPE_UNKNOWN = 0;
private static final int VIEW_TYPE_NORMAL_MESSAGE = 1;
......@@ -99,7 +99,7 @@ public class MessageListAdapter
}
@Override
protected List<PairedMessage> mapResultsToViewModel(List<RealmMessage> results) {
protected List<PairedMessage> mapResultsToViewModel(List<Message> results) {
if (results.isEmpty()) {
return Collections.emptyList();
}
......
......@@ -3,7 +3,7 @@ package chat.rocket.android.layouthelper.chatroom;
import android.content.Context;
import chat.rocket.android.R;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.core.models.Message;
/**
* message type.
......@@ -11,46 +11,46 @@ import chat.rocket.persistence.realm.models.ddp.RealmMessage;
public enum MessageType {
ROOM_NAME_CHANGED("r") {
@Override
public String getString(Context context, RealmMessage message) {
public String getString(Context context, Message message) {
return context.getString(R.string.message_room_name_changed,
message.getMessage(), getUsername(message));
}
},
USER_ADDED("au") {
@Override
public String getString(Context context, RealmMessage message) {
public String getString(Context context, Message message) {
return context.getString(R.string.message_user_added_by,
message.getMessage(), getUsername(message));
}
},
USER_REMOVED("ru") {
@Override
public String getString(Context context, RealmMessage message) {
public String getString(Context context, Message message) {
return context.getString(R.string.message_user_removed_by,
message.getMessage(), getUsername(message));
}
},
USER_JOINED("uj") {
@Override
public String getString(Context context, RealmMessage message) {
public String getString(Context context, Message message) {
return context.getString(R.string.message_user_joined_channel);
}
},
USER_LEFT("ul") {
@Override
public String getString(Context context, RealmMessage message) {
public String getString(Context context, Message message) {
return context.getString(R.string.message_user_left);
}
},
WELCOME("wm") {
@Override
public String getString(Context context, RealmMessage message) {
public String getString(Context context, Message message) {
return context.getString(R.string.message_welcome, getUsername(message));
}
},
MESSAGE_REMOVED("rm") {
@Override
public String getString(Context context, RealmMessage message) {
public String getString(Context context, Message message) {
return context.getString(R.string.message_removed);
}
},
......@@ -69,16 +69,18 @@ public enum MessageType {
public static MessageType parse(String value) {
for (MessageType type : MessageType.values()) {
if (type.value.equals(value)) return type;
if (type.value.equals(value)) {
return type;
}
}
return UNSPECIFIED;
}
public String getString(Context context, RealmMessage message) {
public String getString(Context context, Message message) {
return "";
}
private static String getUsername(RealmMessage message) {
private static String getUsername(Message message) {
if (message != null && message.getUser() != null) {
return message.getUser().getUsername();
} else {
......
package chat.rocket.persistence.realm;
package chat.rocket.android.layouthelper.chatroom;
import android.content.Context;
import android.support.annotation.LayoutRes;
......@@ -8,41 +8,20 @@ import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import io.realm.RealmObject;
import java.util.List;
public abstract class RealmModelListAdapter<T extends RealmObject, VM,
VH extends RealmModelViewHolder<VM>> extends RecyclerView.Adapter<VH> {
public abstract class ModelListAdapter<T, VM, VH extends ModelViewHolder<VM>>
extends RecyclerView.Adapter<VH> {
protected final LayoutInflater inflater;
private RealmListObserver<T> realmListObserver;
private List<VM> adapterData;
private OnItemClickListener<VM> onItemClickListener;
protected RealmModelListAdapter(Context context) {
protected ModelListAdapter(Context context) {
this.inflater = LayoutInflater.from(context);
}
/*package*/ RealmModelListAdapter<T, VM, VH> initializeWith(final RealmHelper realmHelper,
RealmListObserver.Query<T> query) {
realmListObserver = new RealmListObserver<>(realmHelper, query)
.setOnUpdateListener(results -> updateData(realmHelper.copyFromRealm(results)));
return this;
}
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
realmListObserver.sub();
}
@Override
public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
realmListObserver.unsub();
super.onDetachedFromRecyclerView(recyclerView);
}
protected abstract int getRealmModelViewType(VM model);
protected abstract
......@@ -86,7 +65,7 @@ public abstract class RealmModelListAdapter<T extends RealmObject, VM,
return adapterData.get(position);
}
private void updateData(List<T> newData) {
public void updateData(List<T> newData) {
if (adapterData == null) {
adapterData = mapResultsToViewModel(newData);
notifyDataSetChanged();
......@@ -133,8 +112,8 @@ public abstract class RealmModelListAdapter<T extends RealmObject, VM,
this.onItemClickListener = onItemClickListener;
}
public interface Constructor<T extends RealmObject, VM, VH extends RealmModelViewHolder<VM>> {
RealmModelListAdapter<T, VM, VH> getNewInstance(Context context);
public interface Constructor<T, VM, VH extends ModelViewHolder<VM>> {
ModelListAdapter<T, VM, VH> getNewInstance(Context context);
}
public interface OnItemClickListener<VM> {
......
package chat.rocket.persistence.realm;
package chat.rocket.android.layouthelper.chatroom;
import android.support.v7.widget.RecyclerView;
import android.view.View;
public abstract class RealmModelViewHolder<T> extends RecyclerView.ViewHolder {
public abstract class ModelViewHolder<T> extends RecyclerView.ViewHolder {
public RealmModelViewHolder(View itemView) {
public ModelViewHolder(View itemView) {
super(itemView);
}
......
package chat.rocket.android.layouthelper.chatroom;
import chat.rocket.android.helper.DateTime;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.core.models.Message;
/**
* ViewData Model for messages in chatroom.
*/
public class PairedMessage {
public final RealmMessage target;
final RealmMessage nextSibling;
public final Message target;
final Message nextSibling;
public PairedMessage(RealmMessage target, RealmMessage nextSibling) {
public PairedMessage(Message target, Message nextSibling) {
this.target = target;
this.nextSibling = nextSibling;
}
......
......@@ -5,29 +5,31 @@ import android.support.graphics.drawable.VectorDrawableCompat;
import android.view.View;
import android.widget.TextView;
import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.helper.Avatar;
import chat.rocket.android.helper.DateTime;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.core.SyncState;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.core.models.Attachment;
import chat.rocket.core.models.Message;
import chat.rocket.android.widget.RocketChatAvatar;
import chat.rocket.android.widget.message.RocketChatMessageAttachmentsLayout;
import chat.rocket.android.widget.message.RocketChatMessageLayout;
import chat.rocket.android.widget.message.RocketChatMessageUrlsLayout;
import chat.rocket.core.models.User;
import chat.rocket.core.models.WebContent;
/**
* Renderer for RealmMessage model.
*/
public class MessageRenderer extends AbstractRenderer<RealmMessage> {
public class MessageRenderer extends AbstractRenderer<Message> {
private final UserRenderer userRenderer;
public MessageRenderer(Context context, RealmMessage message) {
public MessageRenderer(Context context, Message message) {
super(context, message);
RealmUser realmUser = message.getUser();
userRenderer = new UserRenderer(context, realmUser == null ? null : realmUser.asUser());
userRenderer = new UserRenderer(context, message.getUser());
}
/**
......@@ -40,7 +42,7 @@ public class MessageRenderer extends AbstractRenderer<RealmMessage> {
} else if (TextUtils.isEmpty(object.getAvatar())) {
userRenderer.avatarInto(rocketChatAvatar, hostname);
} else {
final RealmUser user = object.getUser();
final User user = object.getUser();
setAvatarInto(object.getAvatar(), hostname, user == null ? null : user.getUsername(),
rocketChatAvatar);
}
......@@ -104,12 +106,12 @@ public class MessageRenderer extends AbstractRenderer<RealmMessage> {
return this;
}
String urls = object.getUrls();
if (TextUtils.isEmpty(urls)) {
List<WebContent> webContents = object.getWebContents();
if (webContents == null || webContents.size() == 0) {
urlsLayout.setVisibility(View.GONE);
} else {
urlsLayout.setVisibility(View.VISIBLE);
urlsLayout.setUrls(urls);
urlsLayout.setUrls(webContents);
}
return this;
......@@ -124,8 +126,8 @@ public class MessageRenderer extends AbstractRenderer<RealmMessage> {
return this;
}
String attachments = object.getAttachments();
if (TextUtils.isEmpty(attachments)) {
List<Attachment> attachments = object.getAttachments();
if (attachments == null || attachments.size() == 0) {
attachmentsLayout.setVisibility(View.GONE);
} else {
attachmentsLayout.setVisibility(View.VISIBLE);
......
......@@ -3,7 +3,6 @@ package chat.rocket.persistence.realm;
import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Looper;
import android.support.v7.widget.RecyclerView;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmObject;
......@@ -158,12 +157,6 @@ public class RealmHelper {
return new RealmObjectObserver<T>(this, query);
}
public <T extends RealmObject, VM, VH extends RealmModelViewHolder<VM>>
RecyclerView.Adapter<VH> createListAdapter(Context context, RealmListObserver.Query<T> query,
RealmModelListAdapter.Constructor<T, VM, VH> constructor) {
return constructor.getNewInstance(context).initializeWith(this, query);
}
public <T extends RealmObject> RealmAutoCompleteAdapter<T> createAutoCompleteAdapter(
Context context,
RealmAutoCompleteAdapter.RealmFilter<T> filter,
......
......@@ -7,7 +7,9 @@ import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import chat.rocket.core.JsonConstants;
import chat.rocket.core.SyncState;
import chat.rocket.core.models.Attachment;
......@@ -16,6 +18,9 @@ import chat.rocket.core.models.AttachmentField;
import chat.rocket.core.models.AttachmentTitle;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.WebContent;
import chat.rocket.core.models.WebContentHeaders;
import chat.rocket.core.models.WebContentMeta;
import chat.rocket.core.models.WebContentParsedUrl;
/**
* RealmMessage.
......@@ -287,8 +292,80 @@ public class RealmMessage extends RealmObject {
private WebContent getWebContent(JSONObject jsonWebContent) {
return WebContent.builder()
.setUrl(jsonWebContent.optString("url"))
.setMeta(jsonWebContent.optString("meta", null))
.setHeaders(jsonWebContent.optString("headers", null))
.setMetaMap(getWebContentMetaMap(jsonWebContent.optJSONObject("meta")))
.setHeaders(getWebContentHeaders(jsonWebContent.optJSONObject("headers")))
.setParsedUrl(getWebContentParsedUrl(jsonWebContent.optJSONObject("parsedUrl")))
.build();
}
private Map<WebContentMeta.Type, WebContentMeta> getWebContentMetaMap(
JSONObject jsonWebContentMeta) {
if (jsonWebContentMeta == null) {
return null;
}
Map<WebContentMeta.Type, WebContentMeta> metaMap = new HashMap<>(3);
if (!jsonWebContentMeta.isNull("ogTitle")
|| !jsonWebContentMeta.isNull("ogDescription")
|| !jsonWebContentMeta.isNull("ogImage")) {
metaMap.put(
WebContentMeta.Type.OPEN_GRAPH,
WebContentMeta.builder()
.setType(WebContentMeta.Type.OPEN_GRAPH)
.setTitle(jsonWebContentMeta.optString("ogTitle", null))
.setDescription(jsonWebContentMeta.optString("ogDescription", null))
.setImage(jsonWebContentMeta.optString("ogImage", null))
.build()
);
}
if (!jsonWebContentMeta.isNull("twitterTitle")
|| !jsonWebContentMeta.isNull("twitterDescription")
|| !jsonWebContentMeta.isNull("twitterImage")) {
metaMap.put(
WebContentMeta.Type.TWITTER,
WebContentMeta.builder()
.setType(WebContentMeta.Type.TWITTER)
.setTitle(jsonWebContentMeta.optString("twitterTitle", null))
.setDescription(jsonWebContentMeta.optString("twitterDescription", null))
.setImage(jsonWebContentMeta.optString("twitterImage", null))
.build()
);
}
if (!jsonWebContentMeta.isNull("pageTitle")
|| !jsonWebContentMeta.isNull("description")) {
metaMap.put(
WebContentMeta.Type.OTHER,
WebContentMeta.builder()
.setType(WebContentMeta.Type.OTHER)
.setTitle(jsonWebContentMeta.optString("pageTitle", null))
.setDescription(jsonWebContentMeta.optString("description", null))
.build()
);
}
return metaMap;
}
private WebContentHeaders getWebContentHeaders(JSONObject jsonWebContentHeaders) {
if (jsonWebContentHeaders == null || jsonWebContentHeaders.isNull("contentType")) {
return null;
}
return WebContentHeaders.builder()
.setContentType(jsonWebContentHeaders.optString("contentType"))
.build();
}
private WebContentParsedUrl getWebContentParsedUrl(JSONObject jsonWebContentParsedUrl) {
if (jsonWebContentParsedUrl == null || jsonWebContentParsedUrl.isNull("host")) {
return null;
}
return WebContentParsedUrl.builder()
.setHost(jsonWebContentParsedUrl.optString("host"))
.build();
}
......
......@@ -3,11 +3,15 @@ package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import io.realm.Realm;
import io.realm.RealmResults;
import io.realm.Sort;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.User;
import chat.rocket.core.repositories.MessageRepository;
import chat.rocket.persistence.realm.RealmStore;
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
......@@ -51,7 +55,7 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
&& it.isValid())
.first()
.toSingle()
.map(it -> it.asMessage());
.map(RealmMessage::asMessage);
});
}
......@@ -151,12 +155,59 @@ public class RealmMessageRepository extends RealmRepository implements MessageRe
}
@Override
public Observable<Message> getAllFrom(Room room) {
return null;
public Observable<List<Message>> getAllFrom(Room room) {
return Observable.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null) {
return Observable.just(null);
}
return realm.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, room.getRoomId())
.findAllSorted(RealmMessage.TIMESTAMP, Sort.DESCENDING)
.asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.filter(it -> it != null
&& it.isLoaded() && it.isValid())
.map(this::toList);
});
}
@Override
public Single<Integer> unreadCountFrom(Room room) {
return null;
public Single<Integer> unreadCountFor(Room room, User user) {
return Single.defer(() -> {
final Realm realm = RealmStore.getRealm(hostname);
final Looper looper = Looper.myLooper();
if (realm == null) {
return Single.just(0);
}
return realm.where(RealmMessage.class)
.equalTo(RealmMessage.ROOM_ID, room.getId())
.greaterThanOrEqualTo(RealmMessage.TIMESTAMP, room.getLastSeen())
.notEqualTo(RealmMessage.USER_ID, user.getId())
.findAll()
.asObservable()
.unsubscribeOn(AndroidSchedulers.from(looper))
.doOnUnsubscribe(() -> close(realm, looper))
.map(RealmResults::size)
.first()
.toSingle();
});
}
private List<Message> toList(RealmResults<RealmMessage> realmMessages) {
final int total = realmMessages.size();
final List<Message> messages = new ArrayList<>(total);
for (int i = 0; i < total; i++) {
messages.add(realmMessages.get(i).asMessage());
}
return messages;
}
}
apply plugin: 'com.android.library'
buildscript {
repositories {
jcenter()
}
dependencies {
classpath rootProject.ext.androidPlugin
}
repositories {
jcenter()
}
dependencies {
classpath rootProject.ext.androidPlugin
}
}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.compileSdkVersion
versionCode 1
versionName "1"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
compileSdkVersion rootProject.ext.compileSdkVersion
buildToolsVersion rootProject.ext.buildToolsVersion
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.compileSdkVersion
versionCode 1
versionName "1"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
}
dependencies {
testCompile 'junit:junit:4.12'
compile rootProject.ext.supportAnnotations
compile rootProject.ext.supportAppCompat
compile rootProject.ext.supportV13
compile rootProject.ext.supportDesign
compile 'org.nibor.autolink:autolink:0.5.0'
compile rootProject.ext.textDrawable
compile rootProject.ext.okhttp3
compile rootProject.ext.boltsTask
compile rootProject.ext.frescoBase
compile rootProject.ext.frescoAnimatedGif
compile rootProject.ext.frescoAnimatedWebp
compile rootProject.ext.frescoWebp
compile rootProject.ext.frescoImagePipelineOkHttp3
compile 'com.caverock:androidsvg:1.2.1'
testCompile 'junit:junit:4.12'
compile rootProject.ext.supportAnnotations
compile rootProject.ext.supportAppCompat
compile rootProject.ext.supportV13
compile rootProject.ext.supportDesign
compile project(':rocket-chat-core')
compile 'org.nibor.autolink:autolink:0.5.0'
compile rootProject.ext.textDrawable
compile rootProject.ext.okhttp3
compile rootProject.ext.boltsTask
compile rootProject.ext.frescoBase
compile rootProject.ext.frescoAnimatedGif
compile rootProject.ext.frescoAnimatedWebp
compile rootProject.ext.frescoWebp
compile rootProject.ext.frescoImagePipelineOkHttp3
compile 'com.caverock:androidsvg:1.2.1'
}
......@@ -19,18 +19,20 @@ import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import chat.rocket.android.widget.R;
import chat.rocket.core.models.Attachment;
import chat.rocket.core.models.AttachmentAuthor;
import chat.rocket.core.models.AttachmentField;
import chat.rocket.core.models.AttachmentTitle;
/**
*/
public class RocketChatMessageAttachmentsLayout extends LinearLayout {
private LayoutInflater inflater;
private String hostname;
private String attachmentsString;
private List<Attachment> attachments;
public RocketChatMessageAttachmentsLayout(Context context) {
super(context);
......@@ -63,48 +65,41 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
this.hostname = hostname;
}
public void setAttachments(String attachmentsString) {
if (this.attachmentsString != null && this.attachmentsString.equals(attachmentsString)) {
public void setAttachments(List<Attachment> attachments) {
if (this.attachments != null && this.attachments.equals(attachments)) {
return;
}
this.attachmentsString = attachmentsString;
this.attachments = attachments;
removeAllViews();
try {
JSONArray attachments = new JSONArray(attachmentsString);
for (int i = 0; i < attachments.length(); i++) {
JSONObject attachment = attachments.getJSONObject(i);
appendAttachmentView(attachment);
}
} catch (JSONException exception) {
return;
for (int i = 0, size = attachments.size(); i < size; i++) {
appendAttachmentView(attachments.get(i));
}
}
private void appendAttachmentView(JSONObject attachmentObj) throws JSONException {
if (attachmentObj == null) {
private void appendAttachmentView(Attachment attachment) {
if (attachment == null) {
return;
}
View attachmentView = inflater.inflate(R.layout.message_inline_attachment, this, false);
colorizeAttachmentBar(attachmentObj, attachmentView);
showAuthorAttachment(attachmentObj, attachmentView);
showTitleAttachment(attachmentObj, attachmentView);
showReferenceAttachment(attachmentObj, attachmentView);
showImageAttachment(attachmentObj, attachmentView);
colorizeAttachmentBar(attachment, attachmentView);
showAuthorAttachment(attachment, attachmentView);
showTitleAttachment(attachment, attachmentView);
showReferenceAttachment(attachment, attachmentView);
showImageAttachment(attachment, attachmentView);
// audio
// video
showFieldsAttachment(attachmentObj, attachmentView);
showFieldsAttachment(attachment, attachmentView);
addView(attachmentView);
}
private void colorizeAttachmentBar(JSONObject attachmentObj, View attachmentView)
throws JSONException {
private void colorizeAttachmentBar(Attachment attachment, View attachmentView) {
final View attachmentStrip = attachmentView.findViewById(R.id.attachment_strip);
final String colorString = attachmentObj.optString("color");
final String colorString = attachment.getColor();
if (TextUtils.isEmpty(colorString)) {
attachmentStrip.setBackgroundResource(R.color.inline_attachment_quote_line);
return;
......@@ -117,24 +112,23 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
}
}
private void showAuthorAttachment(JSONObject attachmentObj, View attachmentView)
throws JSONException {
private void showAuthorAttachment(Attachment attachment, View attachmentView) {
final View authorBox = attachmentView.findViewById(R.id.author_box);
if (attachmentObj.isNull("author_name") || attachmentObj.isNull("author_link")
|| attachmentObj.isNull("author_icon")) {
AttachmentAuthor author = attachment.getAttachmentAuthor();
if (author == null) {
authorBox.setVisibility(GONE);
return;
}
authorBox.setVisibility(VISIBLE);
loadImage(attachmentObj.getString("author_icon"),
loadImage(author.getIconUrl(),
(SimpleDraweeView) attachmentView.findViewById(R.id.author_icon));
final TextView authorName = (TextView) attachmentView.findViewById(R.id.author_name);
authorName.setText(attachmentObj.getString("author_name"));
authorName.setText(author.getName());
final String link = absolutize(attachmentObj.getString("author_link"));
final String link = absolutize(author.getLink());
authorName.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
......@@ -147,22 +141,22 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
// timestamp and link - need to format time
}
private void showTitleAttachment(JSONObject attachmentObj, View attachmentView)
throws JSONException {
private void showTitleAttachment(Attachment attachment, View attachmentView) {
TextView titleView = (TextView) attachmentView.findViewById(R.id.title);
if (attachmentObj.isNull("title")) {
AttachmentTitle title = attachment.getAttachmentTitle();
if (title == null || title.getTitle() == null) {
titleView.setVisibility(View.GONE);
return;
}
titleView.setVisibility(View.VISIBLE);
titleView.setText(attachmentObj.getString("title"));
titleView.setText(title.getTitle());
if (attachmentObj.isNull("title_link")) {
if (title.getLink() == null) {
titleView.setOnClickListener(null);
titleView.setClickable(false);
} else {
final String link = absolutize(attachmentObj.getString("title_link"));
final String link = absolutize(title.getLink());
titleView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
......@@ -176,10 +170,9 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
}
}
private void showReferenceAttachment(JSONObject attachmentObj, View attachmentView)
throws JSONException {
private void showReferenceAttachment(Attachment attachment, View attachmentView) {
final View refBox = attachmentView.findViewById(R.id.ref_box);
if (attachmentObj.isNull("thumb_url") && attachmentObj.isNull("text")) {
if (attachment.getThumbUrl() == null && attachment.getText() == null) {
refBox.setVisibility(GONE);
return;
}
......@@ -188,7 +181,7 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
final SimpleDraweeView thumbImage = (SimpleDraweeView) refBox.findViewById(R.id.thumb);
final String thumbUrl = attachmentObj.optString("thumb_url");
final String thumbUrl = attachment.getThumbUrl();
if (TextUtils.isEmpty(thumbUrl)) {
thumbImage.setVisibility(GONE);
} else {
......@@ -198,7 +191,7 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
final TextView refText = (TextView) refBox.findViewById(R.id.text);
final String refString = attachmentObj.optString("text");
final String refString = attachment.getText();
if (TextUtils.isEmpty(refString)) {
refText.setVisibility(GONE);
} else {
......@@ -207,38 +200,37 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
}
}
private void showImageAttachment(JSONObject attachmentObj, View attachmentView)
throws JSONException {
private void showImageAttachment(Attachment attachment, View attachmentView) {
final SimpleDraweeView attachedImage =
(SimpleDraweeView) attachmentView.findViewById(R.id.image);
if (attachmentObj.isNull("image_url")) {
if (attachment.getImageUrl() == null) {
attachedImage.setVisibility(GONE);
return;
}
attachedImage.setVisibility(VISIBLE);
loadImage(attachmentObj.getString("image_url"), attachedImage);
loadImage(attachment.getImageUrl(), attachedImage);
}
private void showFieldsAttachment(JSONObject attachmentObj, View attachmentView)
throws JSONException {
if (attachmentObj.isNull("fields")) {
private void showFieldsAttachment(Attachment attachment, View attachmentView) {
List<AttachmentField> fields = attachment.getAttachmentFields();
if (fields == null || fields.size() == 0) {
return;
}
final ViewGroup attachmentContent =
(ViewGroup) attachmentView.findViewById(R.id.attachment_content);
final JSONArray fields = attachmentObj.getJSONArray("fields");
for (int i = 0, size = fields.length(); i < size; i++) {
final JSONObject fieldObject = fields.getJSONObject(i);
if (fieldObject.isNull("title") || fieldObject.isNull("value")) {
for (int i = 0, size = fields.size(); i < size; i++) {
final AttachmentField attachmentField = fields.get(i);
if (attachmentField.getTitle() == null
|| attachmentField.getText() == null) {
return;
}
MessageAttachmentFieldLayout fieldLayout = new MessageAttachmentFieldLayout(getContext());
fieldLayout.setTitle(fieldObject.getString("title"));
fieldLayout.setValue(fieldObject.getString("value"));
fieldLayout.setTitle(attachmentField.getTitle());
fieldLayout.setValue(attachmentField.getText());
attachmentContent.addView(fieldLayout);
}
......
......@@ -16,18 +16,21 @@ import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.interfaces.DraweeController;
import com.facebook.drawee.view.SimpleDraweeView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.List;
import java.util.Map;
import chat.rocket.android.widget.R;
import chat.rocket.android.widget.helper.ImageFormat;
import chat.rocket.core.models.WebContent;
import chat.rocket.core.models.WebContentHeaders;
import chat.rocket.core.models.WebContentMeta;
import chat.rocket.core.models.WebContentParsedUrl;
/**
*/
public class RocketChatMessageUrlsLayout extends LinearLayout {
private LayoutInflater inflater;
private String urlsString;
private List<WebContent> webContents;
public RocketChatMessageUrlsLayout(Context context) {
super(context);
......@@ -56,99 +59,78 @@ public class RocketChatMessageUrlsLayout extends LinearLayout {
setOrientation(VERTICAL);
}
public void setUrls(String urlsString) {
if (this.urlsString != null && this.urlsString.equals(urlsString)) {
public void setUrls(List<WebContent> webContents) {
if (this.webContents != null && this.webContents.equals(webContents)) {
return;
}
this.urlsString = urlsString;
this.webContents = webContents;
removeAllViews();
try {
JSONArray urls = new JSONArray(urlsString);
for (int i = 0; i < urls.length(); i++) {
JSONObject url = urls.getJSONObject(i);
appendUrlView(url);
}
} catch (JSONException exception) {
return;
for (int i = 0, size = webContents.size(); i < size; i++) {
appendUrlView(webContents.get(i));
}
}
private void appendUrlView(JSONObject urlObj) throws JSONException {
final String url = urlObj.getString("url");
String contentType = urlObj.getJSONObject("headers").getString("contentType");
private void appendUrlView(WebContent webContent) {
final String url = webContent.getUrl();
final WebContentHeaders webContentHeaders = webContent.getHeaders();
String contentType = webContentHeaders != null ? webContentHeaders.getContentType() : "";
if (contentType.startsWith("image/") && ImageFormat.SUPPORTED_LIST.contains(contentType)) {
if (contentType != null && contentType.startsWith("image/")
&& ImageFormat.SUPPORTED_LIST.contains(contentType)) {
View inlineImage = inflater.inflate(R.layout.message_inline_image, this, false);
loadImage(url, (SimpleDraweeView) inlineImage.findViewById(R.id.message_inline_image));
addView(inlineImage);
}
// see Rocket.Chat:packages/rocketchat-oembed/client/oembedUrlWidget.coffee
if (!urlObj.isNull("meta")) {
JSONObject meta = urlObj.getJSONObject("meta");
String title = null;
if (!meta.isNull("ogTitle")) {
title = meta.getString("ogTitle");
} else if (!meta.isNull("twitterTitle")) {
title = meta.getString("twitterTitle");
} else if (!meta.isNull("pageTitle")) {
title = meta.getString("pageTitle");
}
final Map<WebContentMeta.Type, WebContentMeta> webContentMetaMap = webContent.getMetaMap();
if (webContentMetaMap == null || webContentMetaMap.size() == 0) {
return;
}
String description = null;
if (!meta.isNull("ogDescription")) {
description = meta.getString("ogDescription");
} else if (!meta.isNull("twitterDescription")) {
description = meta.getString("twitterDescription");
} else if (!meta.isNull("description")) {
description = meta.getString("description");
}
String title = webContent.getMetaTitle();
if (description != null) {
if (description.startsWith("\"")) {
description = description.substring(1);
}
if (description.endsWith("\"")) {
description = description.substring(0, description.length() - 1);
}
String description = webContent.getMetaDescription();
if (description != null) {
if (description.startsWith("\"")) {
description = description.substring(1);
}
String imageURL = null;
if (!meta.isNull("ogImage")) {
imageURL = meta.getString("ogImage");
} else if (!meta.isNull("twitterImage")) {
imageURL = meta.getString("twitterImage");
if (description.endsWith("\"")) {
description = description.substring(0, description.length() - 1);
}
}
String host = urlObj.getJSONObject("parsedUrl").getString("host");
View embedUrl = inflater.inflate(R.layout.message_inline_embed_url, this, false);
String imageURL = webContent.getMetaImage();
((TextView) embedUrl.findViewById(R.id.hostname)).setText(host);
((TextView) embedUrl.findViewById(R.id.title)).setText(title);
((TextView) embedUrl.findViewById(R.id.description)).setText(description);
WebContentParsedUrl parsedUrl = webContent.getParsedUrl();
String host = parsedUrl != null ? parsedUrl.getHost() : null;
final SimpleDraweeView image = (SimpleDraweeView) embedUrl.findViewById(R.id.image);
if (TextUtils.isEmpty(imageURL)) {
image.setVisibility(View.GONE);
} else {
loadImage(imageURL, image);
image.setVisibility(View.VISIBLE);
}
View embedUrl = inflater.inflate(R.layout.message_inline_embed_url, this, false);
embedUrl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);
}
});
((TextView) embedUrl.findViewById(R.id.hostname)).setText(host);
((TextView) embedUrl.findViewById(R.id.title)).setText(title);
((TextView) embedUrl.findViewById(R.id.description)).setText(description);
addView(embedUrl);
final SimpleDraweeView image = (SimpleDraweeView) embedUrl.findViewById(R.id.image);
if (TextUtils.isEmpty(imageURL)) {
image.setVisibility(View.GONE);
} else {
loadImage(imageURL, image);
image.setVisibility(View.VISIBLE);
}
embedUrl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getContext().startActivity(intent);
}
});
addView(embedUrl);
}
private void loadImage(String imageUrl, SimpleDraweeView draweeView) {
......
......@@ -2,6 +2,7 @@ package chat.rocket.core.models;
import com.google.auto.value.AutoValue;
import java.util.Map;
import javax.annotation.Nullable;
@AutoValue
......@@ -10,10 +11,13 @@ public abstract class WebContent {
public abstract String getUrl();
@Nullable
public abstract String getMeta();
public abstract Map<WebContentMeta.Type, WebContentMeta> getMetaMap();
@Nullable
public abstract String getHeaders();
public abstract WebContentHeaders getHeaders();
@Nullable
public abstract WebContentParsedUrl getParsedUrl();
public static Builder builder() {
return new AutoValue_WebContent.Builder();
......@@ -24,11 +28,79 @@ public abstract class WebContent {
public abstract Builder setUrl(String url);
public abstract Builder setMeta(String meta);
public abstract Builder setMetaMap(Map<WebContentMeta.Type, WebContentMeta> webContentMetaMap);
public abstract Builder setHeaders(WebContentHeaders webContentHeaders);
public abstract Builder setHeaders(String headers);
public abstract Builder setParsedUrl(WebContentParsedUrl webContentParsedUrl);
public abstract WebContent build();
}
public String getMetaTitle() {
final Map<WebContentMeta.Type, WebContentMeta> webContentMetaMap = getMetaMap();
if (webContentMetaMap == null) {
return null;
}
WebContentMeta webContentMeta = webContentMetaMap.get(WebContentMeta.Type.OPEN_GRAPH);
if (webContentMeta != null && webContentMeta.getTitle() != null) {
return webContentMeta.getTitle();
}
webContentMeta = webContentMetaMap.get(WebContentMeta.Type.TWITTER);
if (webContentMeta != null && webContentMeta.getTitle() != null) {
return webContentMeta.getTitle();
}
webContentMeta = webContentMetaMap.get(WebContentMeta.Type.OTHER);
if (webContentMeta != null && webContentMeta.getTitle() != null) {
return webContentMeta.getTitle();
}
return null;
}
public String getMetaDescription() {
final Map<WebContentMeta.Type, WebContentMeta> webContentMetaMap = getMetaMap();
if (webContentMetaMap == null) {
return null;
}
WebContentMeta webContentMeta = webContentMetaMap.get(WebContentMeta.Type.OPEN_GRAPH);
if (webContentMeta != null && webContentMeta.getDescription() != null) {
return webContentMeta.getDescription();
}
webContentMeta = webContentMetaMap.get(WebContentMeta.Type.TWITTER);
if (webContentMeta != null && webContentMeta.getDescription() != null) {
return webContentMeta.getDescription();
}
webContentMeta = webContentMetaMap.get(WebContentMeta.Type.OTHER);
if (webContentMeta != null && webContentMeta.getDescription() != null) {
return webContentMeta.getDescription();
}
return null;
}
public String getMetaImage() {
final Map<WebContentMeta.Type, WebContentMeta> webContentMetaMap = getMetaMap();
if (webContentMetaMap == null) {
return null;
}
WebContentMeta webContentMeta = webContentMetaMap.get(WebContentMeta.Type.OPEN_GRAPH);
if (webContentMeta != null && webContentMeta.getImage() != null) {
return webContentMeta.getImage();
}
webContentMeta = webContentMetaMap.get(WebContentMeta.Type.TWITTER);
if (webContentMeta != null && webContentMeta.getImage() != null) {
return webContentMeta.getImage();
}
return null;
}
}
package chat.rocket.core.models;
import com.google.auto.value.AutoValue;
import javax.annotation.Nullable;
@AutoValue
public abstract class WebContentHeaders {
@Nullable
public abstract String getContentType();
public static Builder builder() {
return new AutoValue_WebContentHeaders.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setContentType(String contentType);
public abstract WebContentHeaders build();
}
}
package chat.rocket.core.models;
import com.google.auto.value.AutoValue;
import javax.annotation.Nullable;
@AutoValue
public abstract class WebContentMeta {
public enum Type {
OPEN_GRAPH, TWITTER, OTHER
}
public abstract Type getType();
@Nullable
public abstract String getTitle();
@Nullable
public abstract String getDescription();
@Nullable
public abstract String getImage();
public static Builder builder() {
return new AutoValue_WebContentMeta.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setType(Type type);
public abstract Builder setTitle(String title);
public abstract Builder setDescription(String description);
public abstract Builder setImage(String image);
public abstract WebContentMeta build();
}
}
package chat.rocket.core.models;
import com.google.auto.value.AutoValue;
import javax.annotation.Nullable;
@AutoValue
public abstract class WebContentParsedUrl {
@Nullable
public abstract String getHost();
public static Builder builder() {
return new AutoValue_WebContentParsedUrl.Builder();
}
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder setHost(String host);
public abstract WebContentParsedUrl build();
}
}
package chat.rocket.core.repositories;
import java.util.List;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.User;
import rx.Observable;
import rx.Single;
......@@ -15,7 +17,7 @@ public interface MessageRepository {
Single<Boolean> delete(Message message);
Observable<Message> getAllFrom(Room room);
Observable<List<Message>> getAllFrom(Room room);
Single<Integer> unreadCountFrom(Room room);
Single<Integer> unreadCountFor(Room room, User user);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment