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());
}
}
}
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);
}
}
}
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);
}
}
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));
}
}
}
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);
}
}
Aggregations