Search in sources :

Example 1 with MessageRow

use of org.matrix.androidsdk.adapters.MessageRow in project matrix-android-sdk by matrix-org.

the class MatrixMessageListFragment method onSearchResponse.

/**
 * Manage the search response.
 *
 * @param searchResponse         the search response
 * @param onSearchResultListener the search result listener
 */
protected void onSearchResponse(final SearchResponse searchResponse, final OnSearchResultListener onSearchResultListener) {
    List<SearchResult> searchResults = searchResponse.searchCategories.roomEvents.results;
    ArrayList<MessageRow> messageRows = new ArrayList<>(searchResults.size());
    for (SearchResult searchResult : searchResults) {
        RoomState roomState = null;
        if (null != mRoom) {
            roomState = mRoom.getState();
        }
        if (null == roomState) {
            Room room = mSession.getDataHandler().getStore().getRoom(searchResult.result.roomId);
            if (null != room) {
                roomState = room.getState();
            }
        }
        boolean isValidMessage = false;
        if ((null != searchResult.result) && (null != searchResult.result.getContent())) {
            JsonObject object = searchResult.result.getContentAsJsonObject();
            if (null != object) {
                isValidMessage = (0 != object.entrySet().size());
            }
        }
        if (isValidMessage) {
            messageRows.add(new MessageRow(searchResult.result, roomState));
        }
    }
    Collections.reverse(messageRows);
    mAdapter.clear();
    mAdapter.addAll(messageRows);
    mNextBatch = searchResponse.searchCategories.roomEvents.nextBatch;
    if (null != onSearchResultListener) {
        try {
            onSearchResultListener.onSearchSucceed(messageRows.size());
        } catch (Exception e) {
            Log.e(LOG_TAG, "onSearchResponse failed with " + e.getMessage());
        }
    }
}
Also used : MessageRow(org.matrix.androidsdk.adapters.MessageRow) ArrayList(java.util.ArrayList) JsonObject(com.google.gson.JsonObject) SearchResult(org.matrix.androidsdk.rest.model.search.SearchResult) Room(org.matrix.androidsdk.data.Room) RoomState(org.matrix.androidsdk.data.RoomState)

Example 2 with MessageRow

use of org.matrix.androidsdk.adapters.MessageRow in project matrix-android-sdk by matrix-org.

the class MatrixMessageListFragment method onEventSent.

@Override
public void onEventSent(final Event event, final String prevEventId) {
    // onEvent is not called because the server event echo manages an event sent by itself
    if ((null == mAdapter.getMessageRow(event.eventId)) && canAddEvent(event)) {
        if (null != mAdapter.getMessageRow(prevEventId)) {
            mAdapter.updateEventById(event, prevEventId);
        } else {
            // refresh the listView only when it is a live timeline or a search
            mAdapter.add(new MessageRow(event, mRoom.getLiveState()), true);
        }
        if (mFutureReadMarkerEventId != null && prevEventId.equals(mFutureReadMarkerEventId)) {
            mFutureReadMarkerEventId = null;
            // Move read marker to the newly sent message
            mRoom.setReadMakerEventId(event.eventId);
            RoomSummary summary = mRoom.getDataHandler().getStore().getSummary(mRoom.getRoomId());
            if (summary != null) {
                String readReceiptEventId = summary.getReadReceiptEventId();
                // Inform adapter of the new read marker position
                mAdapter.updateReadMarker(event.eventId, readReceiptEventId);
            }
        }
    } else {
        MessageRow row = mAdapter.getMessageRow(prevEventId);
        if (null != row) {
            mAdapter.remove(row);
        }
    }
}
Also used : MessageRow(org.matrix.androidsdk.adapters.MessageRow) RoomSummary(org.matrix.androidsdk.data.RoomSummary)

Example 3 with MessageRow

use of org.matrix.androidsdk.adapters.MessageRow in project matrix-android-sdk by matrix-org.

the class MatrixMessageListFragment method add.

/**
 * Add a media item in the room.
 */
private void add(final RoomMediaMessage roomMediaMessage) {
    MessageRow messageRow = addMessageRow(roomMediaMessage);
    // add sanity check
    if (null == messageRow) {
        return;
    }
    final Event event = messageRow.getEvent();
    if (!event.isUndeliverable()) {
        ApiCallback<Void> callback = new ApiCallback<Void>() {

            @Override
            public void onSuccess(Void info) {
                getUiHandler().post(new Runnable() {

                    @Override
                    public void run() {
                        onMessageSendingSucceeded(event);
                    }
                });
            }

            private void commonFailure(final Event event) {
                getUiHandler().post(new Runnable() {

                    @Override
                    public void run() {
                        Activity activity = getActivity();
                        if (null != activity) {
                            // display the error message only if the message cannot be resent
                            if ((null != event.unsentException) && (event.isUndeliverable())) {
                                if ((event.unsentException instanceof RetrofitError) && ((RetrofitError) event.unsentException).isNetworkError()) {
                                    Toast.makeText(activity, activity.getString(R.string.unable_to_send_message) + " : " + getActivity().getString(R.string.network_error), Toast.LENGTH_LONG).show();
                                } else {
                                    Toast.makeText(activity, activity.getString(R.string.unable_to_send_message) + " : " + event.unsentException.getLocalizedMessage(), Toast.LENGTH_LONG).show();
                                }
                            } else if (null != event.unsentMatrixError) {
                                String localised = (event.unsentMatrixError instanceof MXCryptoError) ? ((MXCryptoError) event.unsentMatrixError).getDetailedErrorDescription() : event.unsentMatrixError.getLocalizedMessage();
                                Toast.makeText(activity, activity.getString(R.string.unable_to_send_message) + " : " + localised, Toast.LENGTH_LONG).show();
                            }
                            mAdapter.notifyDataSetChanged();
                            onMessageSendingFailed(event);
                        }
                    }
                });
            }

            @Override
            public void onNetworkError(final Exception e) {
                commonFailure(event);
            }

            @Override
            public void onMatrixError(final MatrixError e) {
                // do not display toast if the sending failed because of unknown deviced (e2e issue)
                if (event.mSentState == Event.SentState.FAILED_UNKNOWN_DEVICES) {
                    getUiHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            mAdapter.notifyDataSetChanged();
                            onUnknownDevices(event, (MXCryptoError) e);
                        }
                    });
                } else {
                    commonFailure(event);
                }
            }

            @Override
            public void onUnexpectedError(final Exception e) {
                commonFailure(event);
            }
        };
        roomMediaMessage.setEventSendingCallback(callback);
    }
}
Also used : ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) Activity(android.app.Activity) MessageRow(org.matrix.androidsdk.adapters.MessageRow) MotionEvent(android.view.MotionEvent) Event(org.matrix.androidsdk.rest.model.Event) MatrixError(org.matrix.androidsdk.rest.model.MatrixError) RetrofitError(retrofit.RetrofitError) MXCryptoError(org.matrix.androidsdk.crypto.MXCryptoError)

Example 4 with MessageRow

use of org.matrix.androidsdk.adapters.MessageRow in project matrix-android-sdk by matrix-org.

the class MatrixMessageListFragment method onEvent.

// ==============================================================================================================
// MatrixMessagesFragment methods
// ==============================================================================================================
@Override
public void onEvent(final Event event, final EventTimeline.Direction direction, final RoomState roomState) {
    if (null == event) {
        Log.e(LOG_TAG, "## onEvent() : null event");
        return;
    }
    if (TextUtils.equals(event.eventId, mEventId)) {
        // Save timestamp in case this event will not be added in adapter
        mEventOriginServerTs = event.getOriginServerTs();
    }
    if (direction == EventTimeline.Direction.FORWARDS) {
        if (Event.EVENT_TYPE_REDACTION.equals(event.getType())) {
            MessageRow messageRow = mAdapter.getMessageRow(event.getRedacts());
            if (null != messageRow) {
                Event prunedEvent = mSession.getDataHandler().getStore().getEvent(event.getRedacts(), event.roomId);
                if (null == prunedEvent) {
                    mAdapter.removeEventById(event.getRedacts());
                } else {
                    messageRow.updateEvent(prunedEvent);
                    JsonObject content = messageRow.getEvent().getContentAsJsonObject();
                    boolean hasToRemoved = (null == content) || (null == content.entrySet()) || (0 == content.entrySet().size());
                    // GA issue : the activity can be null
                    if (!hasToRemoved && (null != getActivity())) {
                        EventDisplay eventDisplay = new EventDisplay(getActivity(), prunedEvent, roomState);
                        hasToRemoved = TextUtils.isEmpty(eventDisplay.getTextualDisplay());
                    }
                    // event is removed if it has no more content.
                    if (hasToRemoved) {
                        mAdapter.removeEventById(prunedEvent.eventId);
                    }
                }
                mAdapter.notifyDataSetChanged();
            }
        } else {
            if (canAddEvent(event)) {
                // refresh the listView only when it is a live timeline or a search
                MessageRow newMessageRow = new MessageRow(event, roomState);
                mAdapter.add(newMessageRow, (null == mEventTimeLine) || mEventTimeLine.isLiveTimeline());
                // Move read marker if necessary
                if (isResumed() && mEventTimeLine != null && mEventTimeLine.isLiveTimeline()) {
                    MessageRow currentReadMarkerRow = getReadMarkerMessageRow(newMessageRow);
                    if (canUpdateReadMarker(newMessageRow, currentReadMarkerRow)) {
                        if (0 == mMessageListView.getChildCount()) {
                            mMessageListView.post(new Runnable() {

                                @Override
                                public void run() {
                                    // check if the previous one was displayed
                                    View childView = mMessageListView.getChildAt(mMessageListView.getChildCount() - 2);
                                    // Previous message was the last read
                                    if ((null != childView) && (childView.getTop() >= 0)) {
                                        // Move read marker to the newly sent message
                                        mRoom.setReadMakerEventId(event.eventId);
                                        mAdapter.resetReadMarker();
                                    }
                                }
                            });
                        } else {
                            View childView = mMessageListView.getChildAt(mMessageListView.getChildCount() - 1);
                            // Previous message was the last read
                            if ((null != childView) && (childView.getTop() >= 0)) {
                                // Move read marker to the newly sent message
                                mRoom.setReadMakerEventId(event.eventId);
                                mAdapter.resetReadMarker();
                            }
                        }
                    }
                }
            }
        }
    } else {
        if (canAddEvent(event)) {
            mAdapter.addToFront(new MessageRow(event, roomState));
        }
    }
}
Also used : MessageRow(org.matrix.androidsdk.adapters.MessageRow) MotionEvent(android.view.MotionEvent) Event(org.matrix.androidsdk.rest.model.Event) JsonObject(com.google.gson.JsonObject) EventDisplay(org.matrix.androidsdk.util.EventDisplay) View(android.view.View) AbsListView(android.widget.AbsListView) AutoScrollDownListView(org.matrix.androidsdk.view.AutoScrollDownListView)

Example 5 with MessageRow

use of org.matrix.androidsdk.adapters.MessageRow in project matrix-android-sdk by matrix-org.

the class MatrixMessageListFragment method requestSearchHistory.

/**
 * Search the pattern on a pagination server side.
 */
public void requestSearchHistory() {
    // there is no more server message
    if (TextUtils.isEmpty(mNextBatch)) {
        mIsBackPaginating = false;
        return;
    }
    mIsBackPaginating = true;
    final int firstPos = mMessageListView.getFirstVisiblePosition();
    final String fPattern = mPattern;
    final int countBeforeUpdate = mAdapter.getCount();
    showLoadingBackProgress();
    List<String> roomIds = null;
    if (null != mRoom) {
        roomIds = Arrays.asList(mRoom.getRoomId());
    }
    ApiCallback<SearchResponse> callback = new ApiCallback<SearchResponse>() {

        @Override
        public void onSuccess(final SearchResponse searchResponse) {
            // check that the pattern was not modified before the end of the search
            if (TextUtils.equals(mPattern, fPattern)) {
                List<SearchResult> searchResults = searchResponse.searchCategories.roomEvents.results;
                // is there any result to display
                if (0 != searchResults.size()) {
                    mAdapter.setNotifyOnChange(false);
                    for (SearchResult searchResult : searchResults) {
                        MessageRow row = new MessageRow(searchResult.result, (null == mRoom) ? null : mRoom.getState());
                        mAdapter.insert(row, 0);
                    }
                    mNextBatch = searchResponse.searchCategories.roomEvents.nextBatch;
                    // Scroll the list down to where it was before adding rows to the top
                    getUiHandler().post(new Runnable() {

                        @Override
                        public void run() {
                            final int expectedFirstPos = firstPos + (mAdapter.getCount() - countBeforeUpdate);
                            // trick to avoid that the list jump to the latest item.
                            mMessageListView.lockSelectionOnResize();
                            mAdapter.notifyDataSetChanged();
                            // do not use count because some messages are not displayed
                            // so we compute the new pos
                            mMessageListView.setSelection(expectedFirstPos);
                            mMessageListView.post(new Runnable() {

                                @Override
                                public void run() {
                                    mIsBackPaginating = false;
                                    // fill the history
                                    if (mMessageListView.getFirstVisiblePosition() <= 2) {
                                        requestSearchHistory();
                                    }
                                }
                            });
                        }
                    });
                } else {
                    mIsBackPaginating = false;
                }
                hideLoadingBackProgress();
            }
        }

        private void onError() {
            mIsBackPaginating = false;
            hideLoadingBackProgress();
        }

        // the request will be auto restarted when a valid network will be found
        @Override
        public void onNetworkError(Exception e) {
            Log.e(LOG_TAG, "Network error: " + e.getMessage());
            onError();
        }

        @Override
        public void onMatrixError(MatrixError e) {
            Log.e(LOG_TAG, "Matrix error" + " : " + e.errcode + " - " + e.getMessage());
            onError();
        }

        @Override
        public void onUnexpectedError(Exception e) {
            Log.e(LOG_TAG, "onUnexpectedError error" + e.getMessage());
            onError();
        }
    };
    if (mIsMediaSearch) {
        mSession.searchMediasByName(mPattern, roomIds, mNextBatch, callback);
    } else {
        mSession.searchMessagesByText(mPattern, roomIds, mNextBatch, callback);
    }
}
Also used : ApiCallback(org.matrix.androidsdk.rest.callback.ApiCallback) SimpleApiCallback(org.matrix.androidsdk.rest.callback.SimpleApiCallback) SearchResult(org.matrix.androidsdk.rest.model.search.SearchResult) SearchResponse(org.matrix.androidsdk.rest.model.search.SearchResponse) MessageRow(org.matrix.androidsdk.adapters.MessageRow) MatrixError(org.matrix.androidsdk.rest.model.MatrixError)

Aggregations

MessageRow (org.matrix.androidsdk.adapters.MessageRow)7 MotionEvent (android.view.MotionEvent)4 Event (org.matrix.androidsdk.rest.model.Event)4 View (android.view.View)2 AbsListView (android.widget.AbsListView)2 JsonObject (com.google.gson.JsonObject)2 ApiCallback (org.matrix.androidsdk.rest.callback.ApiCallback)2 SimpleApiCallback (org.matrix.androidsdk.rest.callback.SimpleApiCallback)2 MatrixError (org.matrix.androidsdk.rest.model.MatrixError)2 SearchResult (org.matrix.androidsdk.rest.model.search.SearchResult)2 AutoScrollDownListView (org.matrix.androidsdk.view.AutoScrollDownListView)2 Activity (android.app.Activity)1 ArrayList (java.util.ArrayList)1 MXCryptoError (org.matrix.androidsdk.crypto.MXCryptoError)1 Room (org.matrix.androidsdk.data.Room)1 RoomState (org.matrix.androidsdk.data.RoomState)1 RoomSummary (org.matrix.androidsdk.data.RoomSummary)1 SearchResponse (org.matrix.androidsdk.rest.model.search.SearchResponse)1 EventDisplay (org.matrix.androidsdk.util.EventDisplay)1 RetrofitError (retrofit.RetrofitError)1