Search in sources :

Example 1 with TokensChunkEvents

use of org.matrix.androidsdk.rest.model.TokensChunkEvents in project matrix-android-sdk by matrix-org.

the class DataRetriever method backPaginate.

/**
 * Trigger a back pagination for a dedicated room from Token.
 *
 * @param store           the store to use
 * @param roomId          the room Id
 * @param token           the start token.
 * @param limit           the maximum number of messages to retrieve
 * @param roomEventFilter the filter to use
 * @param callback        the callback
 */
public void backPaginate(final IMXStore store, final String roomId, final String token, final int limit, final RoomEventFilter roomEventFilter, final ApiCallback<TokensChunkEvents> callback) {
    // reach the marker end
    if (TextUtils.equals(token, Event.PAGINATE_BACK_TOKEN_END)) {
        // nothing more to provide
        final android.os.Handler handler = new android.os.Handler(Looper.getMainLooper());
        // call the callback with a delay
        // to reproduce the same behaviour as a network request.
        // except for the initial request.
        Runnable r = new Runnable() {

            @Override
            public void run() {
                handler.postDelayed(new Runnable() {

                    public void run() {
                        callback.onSuccess(new TokensChunkEvents());
                    }
                }, 0);
            }
        };
        handler.post(r);
        return;
    }
    Log.d(LOG_TAG, "## backPaginate() : starts for roomId " + roomId);
    TokensChunkEvents storageResponse = store.getEarlierMessages(roomId, token, limit);
    putPendingToken(mPendingBackwardRequestTokenByRoomId, roomId, token);
    if (storageResponse != null) {
        final android.os.Handler handler = new android.os.Handler(Looper.getMainLooper());
        final TokensChunkEvents fStorageResponse = storageResponse;
        Log.d(LOG_TAG, "## backPaginate() : some data has been retrieved into the local storage (" + fStorageResponse.chunk.size() + " events)");
        // call the callback with a delay
        // to reproduce the same behaviour as a network request.
        // except for the initial request.
        Runnable r = new Runnable() {

            @Override
            public void run() {
                handler.postDelayed(new Runnable() {

                    public void run() {
                        String expectedToken = getPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                        Log.d(LOG_TAG, "## backPaginate() : local store roomId " + roomId + " token " + token + " vs " + expectedToken);
                        if (TextUtils.equals(expectedToken, token)) {
                            clearPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                            callback.onSuccess(fStorageResponse);
                        }
                    }
                }, 0);
            }
        };
        Thread t = new Thread(r);
        t.start();
    } else {
        Log.d(LOG_TAG, "## backPaginate() : trigger a remote request");
        mRestClient.getRoomMessagesFrom(roomId, token, EventTimeline.Direction.BACKWARDS, limit, roomEventFilter, new SimpleApiCallback<TokensChunkEvents>(callback) {

            @Override
            public void onSuccess(TokensChunkEvents tokensChunkEvents) {
                String expectedToken = getPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                Log.d(LOG_TAG, "## backPaginate() succeeds : roomId " + roomId + " token " + token + " vs " + expectedToken);
                if (TextUtils.equals(expectedToken, token)) {
                    clearPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                    // Watch for the one event overlap
                    Event oldestEvent = store.getOldestEvent(roomId);
                    if (tokensChunkEvents.chunk.size() != 0) {
                        tokensChunkEvents.chunk.get(0).mToken = tokensChunkEvents.start;
                        // there is no more data on server side
                        if (null == tokensChunkEvents.end) {
                            tokensChunkEvents.end = Event.PAGINATE_BACK_TOKEN_END;
                        }
                        tokensChunkEvents.chunk.get(tokensChunkEvents.chunk.size() - 1).mToken = tokensChunkEvents.end;
                        Event firstReturnedEvent = tokensChunkEvents.chunk.get(0);
                        if ((oldestEvent != null) && (firstReturnedEvent != null) && TextUtils.equals(oldestEvent.eventId, firstReturnedEvent.eventId)) {
                            tokensChunkEvents.chunk.remove(0);
                        }
                        store.storeRoomEvents(roomId, tokensChunkEvents, EventTimeline.Direction.BACKWARDS);
                    }
                    Log.d(LOG_TAG, "## backPaginate() succeed : roomId " + roomId + " token " + token + " got " + tokensChunkEvents.chunk.size());
                    callback.onSuccess(tokensChunkEvents);
                }
            }

            private void logErrorMessage(String expectedToken, String errorMessage) {
                Log.e(LOG_TAG, "## backPaginate() failed : roomId " + roomId + " token " + token + " expected " + expectedToken + " with " + errorMessage);
            }

            @Override
            public void onNetworkError(Exception e) {
                String expectedToken = getPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                logErrorMessage(expectedToken, e.getMessage());
                // dispatch only if it is expected
                if (TextUtils.equals(token, expectedToken)) {
                    clearPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                    callback.onNetworkError(e);
                }
            }

            @Override
            public void onMatrixError(MatrixError e) {
                String expectedToken = getPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                logErrorMessage(expectedToken, e.getMessage());
                // dispatch only if it is expected
                if (TextUtils.equals(token, expectedToken)) {
                    clearPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                    callback.onMatrixError(e);
                }
            }

            @Override
            public void onUnexpectedError(Exception e) {
                String expectedToken = getPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                logErrorMessage(expectedToken, e.getMessage());
                // dispatch only if it is expected
                if (TextUtils.equals(token, expectedToken)) {
                    clearPendingToken(mPendingBackwardRequestTokenByRoomId, roomId);
                    callback.onUnexpectedError(e);
                }
            }
        });
    }
}
Also used : TokensChunkEvents(org.matrix.androidsdk.rest.model.TokensChunkEvents) Event(org.matrix.androidsdk.rest.model.Event) MatrixError(org.matrix.androidsdk.core.model.MatrixError)

Example 2 with TokensChunkEvents

use of org.matrix.androidsdk.rest.model.TokensChunkEvents in project matrix-android-sdk by matrix-org.

the class MXMemoryStore method getEarlierMessages.

@Override
public TokensChunkEvents getEarlierMessages(final String roomId, final String fromToken, final int limit) {
    // For older requests (providing a token), returning null for now
    if (null != roomId) {
        List<Event> eventsList;
        synchronized (mRoomEventsLock) {
            LinkedHashMap<String, Event> events = mRoomEvents.get(roomId);
            if ((events == null) || (events.size() == 0)) {
                return null;
            }
            // reach the end of the stored items
            if (TextUtils.equals(mRoomTokens.get(roomId), fromToken)) {
                return null;
            }
            // check if the token is known in the sublist
            eventsList = new ArrayList<>(events.values());
        }
        List<Event> subEventsList = new ArrayList<>();
        // search from the latest to the oldest events
        Collections.reverse(eventsList);
        TokensChunkEvents response = new TokensChunkEvents();
        // start the latest event and there is enough events to provide to the caller ?
        if ((null == fromToken) && (eventsList.size() <= limit)) {
            subEventsList = eventsList;
        } else {
            int index = 0;
            if (null != fromToken) {
                // search if token is one of the stored events
                for (; (index < eventsList.size()) && (!TextUtils.equals(fromToken, eventsList.get(index).mToken)); index++) ;
                index++;
            }
            // found it ?
            if (index < eventsList.size()) {
                for (; index < eventsList.size(); index++) {
                    Event event = eventsList.get(index);
                    subEventsList.add(event);
                    // loop until to find an event with a token
                    if ((subEventsList.size() >= limit) && (event.mToken != null)) {
                        break;
                    }
                }
            }
        }
        // unknown token
        if (subEventsList.size() == 0) {
            return null;
        }
        response.chunk = subEventsList;
        Event firstEvent = subEventsList.get(0);
        Event lastEvent = subEventsList.get(subEventsList.size() - 1);
        response.start = firstEvent.mToken;
        // unknown last event token, use the latest known one
        if ((null == lastEvent.mToken) && !TextUtils.isEmpty(mRoomTokens.get(roomId))) {
            lastEvent.mToken = mRoomTokens.get(roomId);
        }
        response.end = lastEvent.mToken;
        return response;
    }
    return null;
}
Also used : TokensChunkEvents(org.matrix.androidsdk.rest.model.TokensChunkEvents) ArrayList(java.util.ArrayList) Event(org.matrix.androidsdk.rest.model.Event)

Aggregations

Event (org.matrix.androidsdk.rest.model.Event)2 TokensChunkEvents (org.matrix.androidsdk.rest.model.TokensChunkEvents)2 ArrayList (java.util.ArrayList)1 MatrixError (org.matrix.androidsdk.core.model.MatrixError)1