package com.badoo.chateau.example.data.repos.conversations;
import android.support.annotation.NonNull;
import android.util.Log;
import com.badoo.chateau.core.repos.conversations.ConversationDataSource;
import com.badoo.chateau.core.repos.conversations.ConversationQueries.CreateConversationQuery;
import com.badoo.chateau.core.repos.conversations.ConversationQueries.CreateGroupConversationQuery;
import com.badoo.chateau.core.repos.conversations.ConversationQueries.DeleteConversationsQuery;
import com.badoo.chateau.core.repos.conversations.ConversationQueries.GetConversationQuery;
import com.badoo.chateau.core.repos.conversations.ConversationQueries.LoadConversationsQuery;
import com.badoo.chateau.core.repos.conversations.ConversationQueries.LoadConversationsQuery.Type;
import com.badoo.chateau.core.repos.conversations.ConversationQueries.MarkConversationReadQuery;
import com.badoo.chateau.core.repos.conversations.ConversationQueries.SubscribeToUpdatesQuery;
import com.badoo.chateau.example.data.model.ExampleConversation;
import com.badoo.chateau.example.data.util.ParseHelper;
import com.badoo.chateau.example.data.util.ParseUtils;
import com.badoo.chateau.example.data.util.ParseUtils.ChatSubscriptionTable;
import com.badoo.chateau.example.data.util.ParseUtils.ChatTable;
import com.badoo.chateau.example.data.util.ParseUtils.CreateChatFunc;
import com.badoo.chateau.example.data.util.ParseUtils.DeleteConversationsFunc;
import com.badoo.chateau.example.data.util.ParseUtils.GetMySubscriptionsFunc;
import com.badoo.chateau.example.data.util.ParseUtils.MarkChatReadFunc;
import com.badoo.chateau.example.data.util.ParseUtils.UsersTable;
import com.parse.ParseObject;
import com.parse.ParseQuery;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import rx.Observable;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import rx.subjects.PublishSubject;
public class ParseConversationDataSource implements ConversationDataSource<ExampleConversation> {
private static final String TAG = ParseConversationDataSource.class.getSimpleName();
private final PublishSubject<Boolean> mConversationUpdatePublisher = PublishSubject.create();
private final ParseHelper mParseHelper;
public ParseConversationDataSource(@NonNull ParseHelper parseHelper) {
mParseHelper = parseHelper;
}
public void reloadConversation(@NonNull String chatId) {
Log.d(TAG, "Conversation updated: " + chatId);
load(new LoadConversationsQuery<>(Type.ALL)).subscribe();
}
@NonNull
@Override
public Observable<LoadResult<ExampleConversation>> load(LoadConversationsQuery<ExampleConversation> query) {
return mParseHelper.<List<ParseObject>>callFunction(GetMySubscriptionsFunc.NAME, Collections.emptyMap())
.flatMap(Observable::from)
.map(in -> ParseUtils.conversationFromSubscription(in, mParseHelper))
.toList()
.map(c -> new LoadResult<>(c, false, false))
.subscribeOn(Schedulers.io());
}
@NonNull
@Override
public Observable<ExampleConversation> get(GetConversationQuery query) {
return getConversation(query.getConversationId());
}
@NonNull
@Override
public Observable<Boolean> subscribe(SubscribeToUpdatesQuery query) {
return mConversationUpdatePublisher;
}
@NonNull
@Override
public Observable<ExampleConversation> create(CreateGroupConversationQuery query) {
final Map<String, Object> params = new HashMap<>();
params.put(CreateChatFunc.Fields.OTHER_USER_IDS, query.getUserIds());
params.put(CreateChatFunc.Fields.GROUP_NAME, query.getName());
return mParseHelper.<ParseObject>callFunction(CreateChatFunc.NAME, params)
.map(in -> ParseUtils.conversationFromChat(in, mParseHelper))
.subscribeOn(Schedulers.io());
}
@NonNull
@Override
public Observable<ExampleConversation> create(CreateConversationQuery query) {
final List<String> userIds = new ArrayList<>();
userIds.add(query.getUserId());
final Map<String, Object> params = new HashMap<>();
params.put(CreateChatFunc.Fields.OTHER_USER_IDS, userIds);
return mParseHelper.<ParseObject>callFunction(CreateChatFunc.NAME, params)
.map(in -> ParseUtils.conversationFromChat(in, mParseHelper))
.subscribeOn(Schedulers.io());
}
@NonNull
@Override
public Observable<Void> markRead(MarkConversationReadQuery query) {
final Map<String, Object> params = new HashMap<>();
params.put(MarkChatReadFunc.Fields.CHAT_ID, query.getConversationId());
return mParseHelper.<ParseObject>callFunction(MarkChatReadFunc.NAME, params)
.ignoreElements()
.cast(Void.class)
.subscribeOn(Schedulers.io());
}
@NonNull
@Override
public Observable<List<ExampleConversation>> delete(DeleteConversationsQuery<ExampleConversation> query) {
final Map<String, Object> params = new HashMap<>();
List<String> chatIds = new ArrayList<>();
for (ExampleConversation c : query.getConversations()) {
chatIds.add(c.getId());
}
params.put(DeleteConversationsFunc.Fields.CHAT_IDS, chatIds);
// The response contains all deleted conversations
return mParseHelper.<List<ParseObject>>callFunction(DeleteConversationsFunc.NAME, params)
.flatMap(Observable::from)
.map(in -> ParseUtils.conversationFromChat(in, mParseHelper))
.doOnNext(exampleConversation -> mConversationUpdatePublisher.onNext(true))
.toList()
.ignoreElements()
.concatWith(load(null).ignoreElements().map(i -> Collections.<ExampleConversation>emptyList()))
.subscribeOn(Schedulers.io());
}
private Observable<ExampleConversation> getConversation(@NonNull String chatId) {
final ParseQuery<ParseObject> parseQuery = new ParseQuery<>(ChatSubscriptionTable.NAME);
parseQuery.include(ChatSubscriptionTable.Fields.CHAT);
parseQuery.include(ChatSubscriptionTable.Fields.CHAT + "." + ChatTable.Fields.LAST_MESSAGE);
parseQuery.whereEqualTo(ChatSubscriptionTable.Fields.CHAT, ParseObject.createWithoutData(ChatTable.NAME, chatId));
parseQuery.whereEqualTo(ChatSubscriptionTable.Fields.USER, ParseObject.createWithoutData(UsersTable.NAME, mParseHelper.getCurrentUser().getObjectId()));
return mParseHelper.find(parseQuery)
.flatMap(Observable::from)
.map(in -> ParseUtils.conversationFromSubscription(in, mParseHelper))
.subscribeOn(Schedulers.io());
}
}