LoadMessageProcedureObserver.java 3.77 KB
Newer Older
1 2 3
package chat.rocket.android.service.observer;

import android.content.Context;
Yusuke Iwaki's avatar
Yusuke Iwaki committed
4
import chat.rocket.android.api.MethodCallHelper;
Yusuke Iwaki's avatar
Yusuke Iwaki committed
5
import chat.rocket.android.log.RCLog;
6
import chat.rocket.android.service.DDPClientRef;
Tiago Cunha's avatar
Tiago Cunha committed
7
import chat.rocket.core.SyncState;
8
import chat.rocket.persistence.realm.RealmHelper;
Tiago Cunha's avatar
Tiago Cunha committed
9 10
import chat.rocket.persistence.realm.models.ddp.RealmMessage;
import chat.rocket.persistence.realm.models.internal.LoadMessageProcedure;
11 12 13 14 15
import io.realm.Realm;
import io.realm.RealmResults;
import io.realm.Sort;
import java.util.List;
import org.json.JSONObject;
16 17 18 19 20 21 22 23

/**
 * Background process for loading messages.
 */
public class LoadMessageProcedureObserver extends AbstractModelObserver<LoadMessageProcedure> {

  private final MethodCallHelper methodCall;

24
  public LoadMessageProcedureObserver(Context context, String hostname,
25 26 27
                                      RealmHelper realmHelper, DDPClientRef ddpClientRef) {
    super(context, hostname, realmHelper, ddpClientRef);
    methodCall = new MethodCallHelper(realmHelper, ddpClientRef);
28 29
  }

Yusuke Iwaki's avatar
Yusuke Iwaki committed
30 31
  @Override
  public RealmResults<LoadMessageProcedure> queryItems(Realm realm) {
32
    return realm.where(LoadMessageProcedure.class)
Tiago Cunha's avatar
Tiago Cunha committed
33
        .equalTo(LoadMessageProcedure.SYNC_STATE, SyncState.NOT_SYNCED)
34 35 36
        .findAll();
  }

Yusuke Iwaki's avatar
Yusuke Iwaki committed
37 38
  @Override
  public void onUpdateResults(List<LoadMessageProcedure> results) {
39
    if (results == null || results.isEmpty()) {
40 41 42
      return;
    }

43
    LoadMessageProcedure procedure = results.get(0);
44 45 46 47 48 49
    final String roomId = procedure.getRoomId();
    final boolean isReset = procedure.isReset();
    final long timestamp = procedure.getTimestamp();
    final int count = procedure.getCount();
    final long lastSeen = 0; // TODO: Not implemented yet.

50
    realmHelper.executeTransaction(realm ->
51
        realm.createOrUpdateObjectFromJson(LoadMessageProcedure.class, new JSONObject()
Tiago Cunha's avatar
Tiago Cunha committed
52 53
            .put(LoadMessageProcedure.ID, roomId)
            .put(LoadMessageProcedure.SYNC_STATE, SyncState.SYNCING))
54 55
    ).onSuccessTask(task ->
        methodCall.loadHistory(roomId, isReset ? 0 : timestamp, count, lastSeen)
56
            .onSuccessTask(_task -> {
Tiago Cunha's avatar
Tiago Cunha committed
57 58 59 60 61
              RealmMessage lastMessage = realmHelper.executeTransactionForRead(realm ->
                  realm.where(RealmMessage.class)
                      .equalTo(RealmMessage.ROOM_ID, roomId)
                      .equalTo(RealmMessage.SYNC_STATE, SyncState.SYNCED)
                      .findAllSorted(RealmMessage.TIMESTAMP, Sort.ASCENDING).first(null));
62
              long lastTs = lastMessage != null ? lastMessage.getTimestamp() : 0;
63
              int messageCount = _task.getResult().length();
64
              return realmHelper.executeTransaction(realm ->
65
                  realm.createOrUpdateObjectFromJson(LoadMessageProcedure.class, new JSONObject()
Tiago Cunha's avatar
Tiago Cunha committed
66 67 68 69 70
                      .put(LoadMessageProcedure.ID, roomId)
                      .put(LoadMessageProcedure.SYNC_STATE, SyncState.SYNCED)
                      .put(LoadMessageProcedure.TIMESTAMP, lastTs)
                      .put(LoadMessageProcedure.RESET, false)
                      .put(LoadMessageProcedure.HAS_NEXT, messageCount == count)));
71
            })
72 73
    ).continueWithTask(task -> {
      if (task.isFaulted()) {
Yusuke Iwaki's avatar
Yusuke Iwaki committed
74
        RCLog.w(task.getError());
75
        realmHelper.executeTransaction(realm ->
76
            realm.createOrUpdateObjectFromJson(LoadMessageProcedure.class, new JSONObject()
Tiago Cunha's avatar
Tiago Cunha committed
77 78
                .put(LoadMessageProcedure.ID, roomId)
                .put(LoadMessageProcedure.SYNC_STATE, SyncState.FAILED)));
79
      } else {
80 81 82 83
        realmHelper.executeTransaction(realm ->
            realm.createOrUpdateObjectFromJson(LoadMessageProcedure.class, new JSONObject()
                .put(LoadMessageProcedure.ID, roomId)
                .put(LoadMessageProcedure.SYNC_STATE, SyncState.SYNCED)));
84
      }
85
      return null;
86 87
    });
  }
88
}