Commit 978b39bd authored by Tiago Cunha's avatar Tiago Cunha Committed by GitHub

Merge pull request #236 from RocketChat/fix/remote-image

The image url is dynamic according to the server
parents f030df31 02dc8ed5
package chat.rocket.android.fragment.chatroom;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.core.models.ServerInfo;
import chat.rocket.core.models.Session;
import chat.rocket.core.models.User;
public class RocketChatAbsoluteUrl implements AbsoluteUrl {
private final String baseUrl;
private final String userId;
private final String token;
public RocketChatAbsoluteUrl(ServerInfo info, User user, Session session) {
baseUrl = (info.isSecure() ? "https://" : "http://") + info.getHostname();
userId = user.getId();
token = session.getToken();
}
@Override
public String getAbsolute(String url) {
return url.startsWith("/") ? baseUrl + url + "?rc_uid=" + userId + "&rc_token=" + token : url;
}
}
......@@ -11,6 +11,8 @@ public interface RoomContract {
interface View extends BaseContract.View {
void setupWith(RocketChatAbsoluteUrl rocketChatAbsoluteUrl);
void render(Room room);
void updateHistoryState(boolean hasNext, boolean isLoaded);
......@@ -34,6 +36,8 @@ public interface RoomContract {
void loadMoreMessages();
void onViewSetup();
void onMessageSelected(@Nullable Message message);
void sendMessage(String messageText);
......
......@@ -29,6 +29,7 @@ import chat.rocket.android.R;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.fragment.chatroom.dialog.FileUploadProgressDialogFragment;
import chat.rocket.android.fragment.chatroom.dialog.UsersOfRoomDialogFragment;
import chat.rocket.android.helper.AbsoluteUrlHelper;
import chat.rocket.android.helper.FileUploadHelper;
import chat.rocket.android.helper.LoadMoreScrollListener;
import chat.rocket.android.helper.OnBackPressListener;
......@@ -47,10 +48,13 @@ import chat.rocket.android.layouthelper.extra_action.upload.ImageUploadActionIte
import chat.rocket.android.layouthelper.extra_action.upload.VideoUploadActionItem;
import chat.rocket.android.log.RCLog;
import chat.rocket.core.interactors.MessageInteractor;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.core.models.Message;
import chat.rocket.core.models.Room;
import chat.rocket.persistence.realm.repositories.RealmMessageRepository;
import chat.rocket.persistence.realm.repositories.RealmRoomRepository;
import chat.rocket.persistence.realm.repositories.RealmServerInfoRepository;
import chat.rocket.persistence.realm.repositories.RealmSessionRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
import chat.rocket.android.layouthelper.chatroom.ModelListAdapter;
import chat.rocket.persistence.realm.RealmStore;
......@@ -111,16 +115,28 @@ public class RoomFragment extends AbstractChatRoomFragment
hostname = args.getString(HOSTNAME);
roomId = args.getString(ROOM_ID);
RealmRoomRepository roomRepository = new RealmRoomRepository(hostname);
MessageInteractor messageInteractor = new MessageInteractor(
new RealmMessageRepository(hostname),
new RealmRoomRepository(hostname)
roomRepository
);
RealmUserRepository userRepository = new RealmUserRepository(hostname);
AbsoluteUrlHelper absoluteUrlHelper = new AbsoluteUrlHelper(
hostname,
new RealmServerInfoRepository(),
userRepository,
new SessionInteractor(new RealmSessionRepository(hostname))
);
presenter = new RoomPresenter(
roomId,
new RealmUserRepository(hostname),
userRepository,
messageInteractor,
new RealmRoomRepository(hostname),
roomRepository,
absoluteUrlHelper,
new MethodCallHelper(getContext(), hostname),
ConnectivityManager.getInstance(getContext())
);
......@@ -138,7 +154,7 @@ public class RoomFragment extends AbstractChatRoomFragment
@Override
protected void onSetupView() {
RecyclerView listView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
adapter = new MessageListAdapter(getContext(), hostname);
adapter = new MessageListAdapter(getContext());
listView.setAdapter(adapter);
adapter.setOnItemClickListener(this);
......@@ -186,6 +202,8 @@ public class RoomFragment extends AbstractChatRoomFragment
setupSideMenu();
setupMessageComposer();
setupMessageActions();
presenter.onViewSetup();
}
private void setupMessageActions() {
......@@ -214,7 +232,12 @@ public class RoomFragment extends AbstractChatRoomFragment
@Override
public void onDestroyView() {
RecyclerView listView = (RecyclerView) rootView.findViewById(R.id.recyclerview);
listView.getAdapter().unregisterAdapterDataObserver(autoScrollManager);
if (listView != null) {
RecyclerView.Adapter adapter = listView.getAdapter();
if (adapter != null) {
adapter.unregisterAdapterDataObserver(autoScrollManager);
}
}
super.onDestroyView();
}
......@@ -385,6 +408,11 @@ public class RoomFragment extends AbstractChatRoomFragment
presenter.sendMessage(messageText);
}
@Override
public void setupWith(RocketChatAbsoluteUrl rocketChatAbsoluteUrl) {
adapter.setAbsoluteUrl(rocketChatAbsoluteUrl);
}
@Override
public void render(Room room) {
String type = room.getType();
......@@ -433,6 +461,9 @@ public class RoomFragment extends AbstractChatRoomFragment
@Override
public void showMessages(List<Message> messages) {
if (adapter == null) {
return;
}
adapter.updateData(messages);
}
......
......@@ -11,6 +11,7 @@ import io.reactivex.disposables.Disposable;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.AbsoluteUrlHelper;
import chat.rocket.android.helper.LogIfError;
import chat.rocket.android.shared.BasePresenter;
import chat.rocket.core.SyncState;
......@@ -30,6 +31,7 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
private final MessageInteractor messageInteractor;
private final UserRepository userRepository;
private final RoomRepository roomRepository;
private final AbsoluteUrlHelper absoluteUrlHelper;
private final MethodCallHelper methodCallHelper;
private final ConnectivityManagerApi connectivityManagerApi;
......@@ -37,12 +39,14 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
UserRepository userRepository,
MessageInteractor messageInteractor,
RoomRepository roomRepository,
AbsoluteUrlHelper absoluteUrlHelper,
MethodCallHelper methodCallHelper,
ConnectivityManagerApi connectivityManagerApi) {
this.roomId = roomId;
this.userRepository = userRepository;
this.messageInteractor = messageInteractor;
this.roomRepository = roomRepository;
this.absoluteUrlHelper = absoluteUrlHelper;
this.methodCallHelper = methodCallHelper;
this.connectivityManagerApi = connectivityManagerApi;
}
......@@ -72,6 +76,16 @@ public class RoomPresenter extends BasePresenter<RoomContract.View>
addSubscription(subscription);
}
@Override
public void onViewSetup() {
final Disposable subscription = absoluteUrlHelper.getRocketChatAbsoluteUrl()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(it -> view.setupWith(it.orNull()));
addSubscription(subscription);
}
@Override
public void loadMoreMessages() {
......
......@@ -15,9 +15,8 @@ abstract class AbstractChatRoomDialogFragment extends BottomSheetDialogFragment
protected RealmHelper realmHelper;
protected String roomId;
protected
@LayoutRes
abstract int getLayout();
protected abstract int getLayout();
protected abstract void onSetupDialog();
......
......@@ -7,20 +7,30 @@ import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.TextView;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.R;
import chat.rocket.android.fragment.chatroom.RocketChatAbsoluteUrl;
import chat.rocket.android.helper.AbsoluteUrlHelper;
import chat.rocket.android.helper.LogIfError;
import chat.rocket.android.layouthelper.chatroom.dialog.RoomUserAdapter;
import chat.rocket.android.log.RCLog;
import chat.rocket.core.SyncState;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.persistence.realm.models.internal.GetUsersOfRoomsProcedure;
import chat.rocket.persistence.realm.RealmObjectObserver;
import chat.rocket.android.service.ConnectivityManager;
import chat.rocket.persistence.realm.repositories.RealmServerInfoRepository;
import chat.rocket.persistence.realm.repositories.RealmSessionRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
/**
* Dialog to show members in a room.
......@@ -31,6 +41,8 @@ public class UsersOfRoomDialogFragment extends AbstractChatRoomDialogFragment {
private RealmObjectObserver<GetUsersOfRoomsProcedure> procedureObserver;
private int previousSyncState;
private CompositeDisposable compositeDisposable = new CompositeDisposable();
public UsersOfRoomDialogFragment() {
}
......@@ -76,9 +88,32 @@ public class UsersOfRoomDialogFragment extends AbstractChatRoomDialogFragment {
@Override
protected void onSetupDialog() {
AbsoluteUrlHelper absoluteUrlHelper = new AbsoluteUrlHelper(
hostname,
new RealmServerInfoRepository(),
new RealmUserRepository(hostname),
new SessionInteractor(new RealmSessionRepository(hostname))
);
compositeDisposable.add(
absoluteUrlHelper.getRocketChatAbsoluteUrl()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::setupView)
);
}
private void setupView(Optional<RocketChatAbsoluteUrl> rocketChatAbsoluteUrlOptional) {
compositeDisposable.clear();
if (!rocketChatAbsoluteUrlOptional.isPresent()) {
return;
}
RecyclerView recyclerView = (RecyclerView) getDialog().findViewById(R.id.recyclerview);
recyclerView.setLayoutManager(new GridLayoutManager(getContext(), 2));
recyclerView.setAdapter(new RoomUserAdapter(getContext(), realmHelper, hostname));
recyclerView.setAdapter(
new RoomUserAdapter(getContext(), realmHelper, rocketChatAbsoluteUrlOptional.get()));
}
private void requestGetUsersOfRoom() {
......
......@@ -3,6 +3,7 @@ package chat.rocket.android.fragment.sidebar;
import android.support.annotation.NonNull;
import java.util.List;
import chat.rocket.android.fragment.chatroom.RocketChatAbsoluteUrl;
import chat.rocket.android.shared.BaseContract;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.User;
......@@ -17,7 +18,7 @@ public interface SidebarMainContract {
void showRoomList(@NonNull List<Room> roomList);
void showUser(User user);
void show(User user, RocketChatAbsoluteUrl absoluteUrl);
}
interface Presenter extends BaseContract.Presenter<View> {
......
......@@ -20,8 +20,10 @@ import chat.rocket.android.R;
import chat.rocket.android.RocketChatCache;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.fragment.AbstractFragment;
import chat.rocket.android.fragment.chatroom.RocketChatAbsoluteUrl;
import chat.rocket.android.fragment.sidebar.dialog.AddChannelDialogFragment;
import chat.rocket.android.fragment.sidebar.dialog.AddDirectMessageDialogFragment;
import chat.rocket.android.helper.AbsoluteUrlHelper;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.chatroom.roomlist.ChannelRoomListHeader;
import chat.rocket.android.layouthelper.chatroom.roomlist.DirectMessageRoomListHeader;
......@@ -29,10 +31,13 @@ import chat.rocket.android.layouthelper.chatroom.roomlist.RoomListAdapter;
import chat.rocket.android.layouthelper.chatroom.roomlist.RoomListHeader;
import chat.rocket.android.layouthelper.chatroom.roomlist.UnreadRoomListHeader;
import chat.rocket.core.interactors.RoomInteractor;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.core.models.Room;
import chat.rocket.core.models.User;
import chat.rocket.android.renderer.UserRenderer;
import chat.rocket.persistence.realm.repositories.RealmRoomRepository;
import chat.rocket.persistence.realm.repositories.RealmServerInfoRepository;
import chat.rocket.persistence.realm.repositories.RealmSessionRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
import chat.rocket.android.widget.RocketChatAvatar;
......@@ -69,11 +74,21 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
Bundle args = getArguments();
hostname = args == null ? null : args.getString(HOSTNAME);
RealmUserRepository userRepository = new RealmUserRepository(hostname);
AbsoluteUrlHelper absoluteUrlHelper = new AbsoluteUrlHelper(
hostname,
new RealmServerInfoRepository(),
userRepository,
new SessionInteractor(new RealmSessionRepository(hostname))
);
presenter = new SidebarMainPresenter(
hostname,
new RoomInteractor(new RealmRoomRepository(hostname)),
new RealmUserRepository(hostname),
userRepository,
new RocketChatCache(getContext()),
absoluteUrlHelper,
TextUtils.isEmpty(hostname) ? null : new MethodCallHelper(getContext(), hostname)
);
}
......@@ -144,10 +159,11 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
});
}
private void onRenderCurrentUser(User user) {
if (user != null && !TextUtils.isEmpty(hostname)) {
private void onRenderCurrentUser(User user, RocketChatAbsoluteUrl absoluteUrl) {
if (user != null && absoluteUrl != null) {
new UserRenderer(getContext(), user)
.avatarInto((RocketChatAvatar) rootView.findViewById(R.id.current_user_avatar), hostname)
.avatarInto((RocketChatAvatar) rootView.findViewById(R.id.current_user_avatar),
absoluteUrl)
.usernameInto((TextView) rootView.findViewById(R.id.current_user_name))
.statusColorInto((ImageView) rootView.findViewById(R.id.current_user_status));
}
......@@ -215,8 +231,8 @@ public class SidebarMainFragment extends AbstractFragment implements SidebarMain
}
@Override
public void showUser(User user) {
onRenderCurrentUser(user);
public void show(User user, RocketChatAbsoluteUrl absoluteUrl) {
onRenderCurrentUser(user, absoluteUrl);
updateRoomListMode(user);
}
}
package chat.rocket.android.fragment.sidebar;
import android.support.annotation.NonNull;
import android.support.v4.util.Pair;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.RocketChatCache;
import chat.rocket.android.api.MethodCallHelper;
import chat.rocket.android.helper.AbsoluteUrlHelper;
import chat.rocket.android.helper.LogIfError;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.shared.BasePresenter;
......@@ -23,15 +26,19 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
private final RoomInteractor roomInteractor;
private final UserRepository userRepository;
private final RocketChatCache rocketChatCache;
private final AbsoluteUrlHelper absoluteUrlHelper;
private final MethodCallHelper methodCallHelper;
public SidebarMainPresenter(String hostname, RoomInteractor roomInteractor,
UserRepository userRepository, RocketChatCache rocketChatCache,
UserRepository userRepository,
RocketChatCache rocketChatCache,
AbsoluteUrlHelper absoluteUrlHelper,
MethodCallHelper methodCallHelper) {
this.hostname = hostname;
this.roomInteractor = roomInteractor;
this.userRepository = userRepository;
this.rocketChatCache = rocketChatCache;
this.absoluteUrlHelper = absoluteUrlHelper;
this.methodCallHelper = methodCallHelper;
}
......@@ -47,7 +54,17 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
view.showScreen();
subscribeToRooms();
subscribeToUser();
final Disposable subscription = Flowable.combineLatest(
userRepository.getCurrent().distinctUntilChanged(),
absoluteUrlHelper.getRocketChatAbsoluteUrl().toFlowable(),
Pair::new
)
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(pair -> view.show(pair.first.orNull(), pair.second.orNull()));
addSubscription(subscription);
}
@Override
......@@ -94,16 +111,6 @@ public class SidebarMainPresenter extends BasePresenter<SidebarMainContract.View
addSubscription(subscription);
}
private void subscribeToUser() {
final Disposable subscription = userRepository.getCurrent()
.distinctUntilChanged()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(userOptional -> view.showUser(userOptional.orNull()));
addSubscription(subscription);
}
private void updateCurrentUserStatus(String status) {
if (methodCallHelper != null) {
methodCallHelper.setUserStatus(status).continueWith(new LogIfError());
......
......@@ -4,20 +4,33 @@ import android.os.Bundle;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.TextView;
import com.fernandocejas.arrow.optional.Optional;
import com.jakewharton.rxbinding2.widget.RxTextView;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.realm.Case;
import bolts.Task;
import chat.rocket.android.BackgroundLooper;
import chat.rocket.android.R;
import chat.rocket.android.fragment.chatroom.RocketChatAbsoluteUrl;
import chat.rocket.android.helper.AbsoluteUrlHelper;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.sidebar.dialog.SuggestUserAdapter;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.RealmAutoCompleteAdapter;
import chat.rocket.persistence.realm.repositories.RealmServerInfoRepository;
import chat.rocket.persistence.realm.repositories.RealmSessionRepository;
import chat.rocket.persistence.realm.repositories.RealmUserRepository;
/**
* add Direct RealmMessage.
*/
public class AddDirectMessageDialogFragment extends AbstractAddRoomDialogFragment {
private CompositeDisposable compositeDisposable = new CompositeDisposable();
public static AddDirectMessageDialogFragment create(String hostname) {
Bundle args = new Bundle();
args.putString("hostname", hostname);
......@@ -38,13 +51,19 @@ public class AddDirectMessageDialogFragment extends AbstractAddRoomDialogFragmen
AutoCompleteTextView autoCompleteTextView =
(AutoCompleteTextView) getDialog().findViewById(R.id.editor_username);
RealmAutoCompleteAdapter<RealmUser> adapter =
realmHelper.createAutoCompleteAdapter(getContext(),
(realm, text) -> realm.where(RealmUser.class)
.contains(RealmUser.USERNAME, text, Case.INSENSITIVE)
.findAllSorted(RealmUser.USERNAME),
context -> new SuggestUserAdapter(context, hostname));
autoCompleteTextView.setAdapter(adapter);
AbsoluteUrlHelper absoluteUrlHelper = new AbsoluteUrlHelper(
hostname,
new RealmServerInfoRepository(),
new RealmUserRepository(hostname),
new SessionInteractor(new RealmSessionRepository(hostname))
);
compositeDisposable.add(
absoluteUrlHelper.getRocketChatAbsoluteUrl()
.subscribeOn(AndroidSchedulers.from(BackgroundLooper.get()))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::setupView)
);
RxTextView.textChanges(autoCompleteTextView)
.map(text -> !TextUtils.isEmpty(text))
......@@ -54,6 +73,25 @@ public class AddDirectMessageDialogFragment extends AbstractAddRoomDialogFragmen
buttonAddDirectMessage.setOnClickListener(view -> createRoom());
}
private void setupView(Optional<RocketChatAbsoluteUrl> rocketChatAbsoluteUrlOptional) {
compositeDisposable.clear();
if (!rocketChatAbsoluteUrlOptional.isPresent()) {
return;
}
AutoCompleteTextView autoCompleteTextView =
(AutoCompleteTextView) getDialog().findViewById(R.id.editor_username);
RealmAutoCompleteAdapter<RealmUser> adapter =
realmHelper.createAutoCompleteAdapter(getContext(),
(realm, text) -> realm.where(RealmUser.class)
.contains(RealmUser.USERNAME, text, Case.INSENSITIVE)
.findAllSorted(RealmUser.USERNAME),
context -> new SuggestUserAdapter(context, rocketChatAbsoluteUrlOptional.get()));
autoCompleteTextView.setAdapter(adapter);
}
@Override
protected Task<Void> getMethodCallForSubmitAction() {
String username =
......
package chat.rocket.android.helper;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.Single;
import chat.rocket.android.fragment.chatroom.RocketChatAbsoluteUrl;
import chat.rocket.core.interactors.SessionInteractor;
import chat.rocket.core.repositories.ServerInfoRepository;
import chat.rocket.core.repositories.UserRepository;
public class AbsoluteUrlHelper {
private final String hostname;
private final ServerInfoRepository serverInfoRepository;
private final UserRepository userRepository;
private final SessionInteractor sessionInteractor;
public AbsoluteUrlHelper(String hostname,
ServerInfoRepository serverInfoRepository,
UserRepository userRepository,
SessionInteractor sessionInteractor) {
this.hostname = hostname;
this.serverInfoRepository = serverInfoRepository;
this.userRepository = userRepository;
this.sessionInteractor = sessionInteractor;
}
public Single<Optional<RocketChatAbsoluteUrl>> getRocketChatAbsoluteUrl() {
return Flowable.zip(
serverInfoRepository.getByHostname(hostname)
.filter(Optional::isPresent)
.map(Optional::get),
userRepository.getCurrent()
.filter(Optional::isPresent)
.map(Optional::get),
sessionInteractor.getDefault()
.filter(Optional::isPresent)
.map(Optional::get),
(info, user, session) -> Optional.of(new RocketChatAbsoluteUrl(
info, user,
session
))
)
.first(Optional.absent());
}
}
......@@ -11,6 +11,7 @@ import com.amulyakhare.textdrawable.TextDrawable;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import chat.rocket.android.log.RCLog;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.android.widget.RocketChatAvatar;
/**
......@@ -22,11 +23,11 @@ public class Avatar {
0xFF03A9F4, 0xFF00BCD4, 0xFF009688, 0xFF4CAF50, 0xFF8BC34A, 0xFFCDDC39,
0xFFFFC107, 0xFFFF9800, 0xFFFF5722, 0xFF795548, 0xFF9E9E9E, 0xFF607D8B
};
private final String hostname;
private final AbsoluteUrl absoluteUrl;
private final String username;
public Avatar(String hostname, String username) {
this.hostname = hostname;
public Avatar(AbsoluteUrl absoluteUrl, String username) {
this.absoluteUrl = absoluteUrl;
this.username = username;
}
......@@ -71,7 +72,7 @@ public class Avatar {
//from Rocket.Chat:packages/rocketchat-ui/lib/avatar.coffee
//REMARK! this is often SVG image! (see: Rocket.Chat:server/startup/avatar.coffee)
try {
return "https://" + hostname + "/avatar/" + URLEncoder.encode(username, "UTF-8") + ".jpg";
return absoluteUrl.getAbsolute("/avatar/" + URLEncoder.encode(username, "UTF-8") + ".jpg");
} catch (UnsupportedEncodingException exception) {
RCLog.e(exception, "failed to get URL for user: %s", username);
return null;
......
......@@ -7,6 +7,7 @@ import android.widget.TextView;
import chat.rocket.android.R;
import chat.rocket.android.helper.DateTime;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.core.SyncState;
import chat.rocket.android.widget.RocketChatAvatar;
......@@ -16,14 +17,14 @@ public abstract class AbstractMessageViewHolder extends ModelViewHolder<PairedMe
protected final TextView subUsername;
protected final TextView timestamp;
protected final View userAndTimeContainer;
protected final String hostname;
protected final AbsoluteUrl absoluteUrl;
protected final View newDayContainer;
protected final TextView newDayText;
/**
* constructor WITH hostname.
*/
public AbstractMessageViewHolder(View itemView, String hostname) {
public AbstractMessageViewHolder(View itemView, AbsoluteUrl absoluteUrl) {
super(itemView);
avatar = (RocketChatAvatar) itemView.findViewById(R.id.user_avatar);
username = (TextView) itemView.findViewById(R.id.username);
......@@ -32,7 +33,7 @@ public abstract class AbstractMessageViewHolder extends ModelViewHolder<PairedMe
userAndTimeContainer = itemView.findViewById(R.id.user_and_timestamp_container);
newDayContainer = itemView.findViewById(R.id.newday_container);
newDayText = (TextView) itemView.findViewById(R.id.newday_text);
this.hostname = hostname;
this.absoluteUrl = absoluteUrl;
}
/**
......
......@@ -10,6 +10,7 @@ import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.layouthelper.ExtModelListAdapter;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.core.models.Message;
/**
......@@ -22,15 +23,19 @@ public class MessageListAdapter
private static final int VIEW_TYPE_NORMAL_MESSAGE = 1;
private static final int VIEW_TYPE_SYSTEM_MESSAGE = 2;
private final String hostname;
private AbsoluteUrl absoluteUrl;
private boolean autoloadImages = false;
private boolean hasNext;
private boolean isLoaded;
public MessageListAdapter(Context context, String hostname) {
public MessageListAdapter(Context context) {
super(context);
this.hostname = hostname;
}
public void setAbsoluteUrl(AbsoluteUrl absoluteUrl) {
this.absoluteUrl = absoluteUrl;
notifyDataSetChanged();
}
public void setAutoloadImages(boolean autoloadImages) {
......@@ -88,11 +93,11 @@ public class MessageListAdapter
protected AbstractMessageViewHolder onCreateRealmModelViewHolder(int viewType, View itemView) {
switch (viewType) {
case VIEW_TYPE_NORMAL_MESSAGE:
return new MessageNormalViewHolder(itemView, hostname);
return new MessageNormalViewHolder(itemView, absoluteUrl);
case VIEW_TYPE_SYSTEM_MESSAGE:
return new MessageSystemViewHolder(itemView, hostname);
return new MessageSystemViewHolder(itemView, absoluteUrl);
default:
return new AbstractMessageViewHolder(itemView, hostname) {
return new AbstractMessageViewHolder(itemView, absoluteUrl) {
@Override
protected void bindMessage(PairedMessage pairedMessage, boolean autoloadImages) {
}
......
......@@ -4,6 +4,7 @@ import android.view.View;
import chat.rocket.android.R;
import chat.rocket.android.renderer.MessageRenderer;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.android.widget.message.RocketChatMessageAttachmentsLayout;
import chat.rocket.android.widget.message.RocketChatMessageLayout;
import chat.rocket.android.widget.message.RocketChatMessageUrlsLayout;
......@@ -19,8 +20,8 @@ public class MessageNormalViewHolder extends AbstractMessageViewHolder {
/**
* constructor WITH hostname.
*/
public MessageNormalViewHolder(View itemView, String hostname) {
super(itemView, hostname);
public MessageNormalViewHolder(View itemView, AbsoluteUrl absoluteUrl) {
super(itemView, absoluteUrl);
body = (RocketChatMessageLayout) itemView.findViewById(R.id.message_body);
urls = (RocketChatMessageUrlsLayout) itemView.findViewById(R.id.message_urls);
attachments =
......@@ -30,11 +31,11 @@ public class MessageNormalViewHolder extends AbstractMessageViewHolder {
@Override
protected void bindMessage(PairedMessage pairedMessage, boolean autoloadImages) {
new MessageRenderer(itemView.getContext(), pairedMessage.target, autoloadImages)
.avatarInto(avatar, hostname)
.avatarInto(avatar, absoluteUrl)
.usernameInto(username, subUsername)
.timestampInto(timestamp)
.bodyInto(body)
.urlsInto(urls)
.attachmentsInto(attachments, hostname);
.attachmentsInto(attachments, absoluteUrl);
}
}
......@@ -5,6 +5,7 @@ import android.widget.TextView;
import chat.rocket.android.R;
import chat.rocket.android.renderer.MessageRenderer;
import chat.rocket.android.widget.AbsoluteUrl;
/**
* ViewData holder of NORMAL chat message.
......@@ -15,15 +16,15 @@ public class MessageSystemViewHolder extends AbstractMessageViewHolder {
/**
* constructor WITH hostname.
*/
public MessageSystemViewHolder(View itemView, String hostname) {
super(itemView, hostname);
public MessageSystemViewHolder(View itemView, AbsoluteUrl absoluteUrl) {
super(itemView, absoluteUrl);
body = (TextView) itemView.findViewById(R.id.message_body);
}
@Override
protected void bindMessage(PairedMessage pairedMessage, boolean autoloadImages) {
new MessageRenderer(itemView.getContext(), pairedMessage.target, autoloadImages)
.avatarInto(avatar, hostname)
.avatarInto(avatar, absoluteUrl)
.usernameInto(username, subUsername)
.timestampInto(timestamp);
......
......@@ -9,6 +9,7 @@ import android.view.ViewGroup;
import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.core.models.User;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.RealmHelper;
......@@ -22,17 +23,17 @@ public class RoomUserAdapter extends RecyclerView.Adapter<RoomUserViewHolder> {
private final Context context;
private final LayoutInflater inflater;
private final RealmHelper realmHelper;
private final String hostname;
private final AbsoluteUrl absoluteUrl;
private List<String> usernames;
/**
* Constructor with required parameters.
*/
public RoomUserAdapter(Context context, RealmHelper realmHelper, String hostname) {
public RoomUserAdapter(Context context, RealmHelper realmHelper, AbsoluteUrl absoluteUrl) {
this.context = context;
this.inflater = LayoutInflater.from(context);
this.realmHelper = realmHelper;
this.hostname = hostname;
this.absoluteUrl = absoluteUrl;
}
@Override
......@@ -57,12 +58,12 @@ public class RoomUserAdapter extends RecyclerView.Adapter<RoomUserViewHolder> {
.setUtcOffset(0)
.build();
new UserRenderer(context, user)
.avatarInto(holder.avatar, hostname)
.avatarInto(holder.avatar, absoluteUrl)
.usernameInto(holder.username);
} else {
new UserRenderer(context, realmUser.asUser())
.statusColorInto(holder.status)
.avatarInto(holder.avatar, hostname)
.avatarInto(holder.avatar, absoluteUrl)
.usernameInto(holder.username);
}
}
......
......@@ -7,6 +7,7 @@ import android.widget.ImageView;
import java.util.Iterator;
import java.util.List;
import chat.rocket.android.R;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.persistence.realm.models.ddp.RealmUser;
import chat.rocket.persistence.realm.RealmAutoCompleteAdapter;
import chat.rocket.android.renderer.UserRenderer;
......@@ -16,18 +17,18 @@ import chat.rocket.android.widget.RocketChatAvatar;
* adapter to suggest user names.
*/
public class SuggestUserAdapter extends RealmAutoCompleteAdapter<RealmUser> {
private final String hostname;
private final AbsoluteUrl absoluteUrl;
public SuggestUserAdapter(Context context, String hostname) {
public SuggestUserAdapter(Context context, AbsoluteUrl absoluteUrl) {
super(context, R.layout.listitem_room_user, R.id.room_user_name);
this.hostname = hostname;
this.absoluteUrl = absoluteUrl;
}
@Override
protected void onBindItemView(View itemView, RealmUser user) {
new UserRenderer(itemView.getContext(), user.asUser())
.statusColorInto((ImageView) itemView.findViewById(R.id.room_user_status))
.avatarInto((RocketChatAvatar) itemView.findViewById(R.id.room_user_avatar), hostname);
.avatarInto((RocketChatAvatar) itemView.findViewById(R.id.room_user_avatar), absoluteUrl);
}
@Override
......
......@@ -10,6 +10,7 @@ import chat.rocket.android.R;
import chat.rocket.android.helper.Avatar;
import chat.rocket.android.helper.DateTime;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.core.SyncState;
import chat.rocket.core.models.Attachment;
import chat.rocket.core.models.Message;
......@@ -37,15 +38,15 @@ public class MessageRenderer extends AbstractRenderer<Message> {
/**
* show Avatar image.
*/
public MessageRenderer avatarInto(RocketChatAvatar rocketChatAvatar, String hostname) {
public MessageRenderer avatarInto(RocketChatAvatar rocketChatAvatar, AbsoluteUrl absoluteUrl) {
if (object.getSyncState() == SyncState.FAILED) {
rocketChatAvatar.loadImage(VectorDrawableCompat
.create(context.getResources(), R.drawable.ic_error_outline_black_24dp, null));
} else if (TextUtils.isEmpty(object.getAvatar())) {
userRenderer.avatarInto(rocketChatAvatar, hostname);
userRenderer.avatarInto(rocketChatAvatar, absoluteUrl);
} else {
final User user = object.getUser();
setAvatarInto(object.getAvatar(), hostname, user == null ? null : user.getUsername(),
setAvatarInto(object.getAvatar(), absoluteUrl, user == null ? null : user.getUsername(),
rocketChatAvatar);
}
return this;
......@@ -123,7 +124,7 @@ public class MessageRenderer extends AbstractRenderer<Message> {
* show urls in RocketChatMessageUrlsLayout.
*/
public MessageRenderer attachmentsInto(RocketChatMessageAttachmentsLayout attachmentsLayout,
String hostname) {
AbsoluteUrl absoluteUrl) {
if (!shouldHandle(attachmentsLayout)) {
return this;
}
......@@ -133,16 +134,16 @@ public class MessageRenderer extends AbstractRenderer<Message> {
attachmentsLayout.setVisibility(View.GONE);
} else {
attachmentsLayout.setVisibility(View.VISIBLE);
attachmentsLayout.setHostname(hostname);
attachmentsLayout.setAbsoluteUrl(absoluteUrl);
attachmentsLayout.setAttachments(attachments, autoloadImages);
}
return this;
}
private void setAvatarInto(String avatar, String hostname, String username,
private void setAvatarInto(String avatar, AbsoluteUrl absoluteUrl, String username,
RocketChatAvatar imageView) {
imageView.loadImage(avatar, new Avatar(hostname, username).getTextDrawable(context));
imageView.loadImage(avatar, new Avatar(absoluteUrl, username).getTextDrawable(context));
}
private void aliasAndUsernameInto(TextView aliasTextView, TextView usernameTextView) {
......
......@@ -7,6 +7,7 @@ import android.widget.TextView;
import chat.rocket.android.R;
import chat.rocket.android.helper.Avatar;
import chat.rocket.android.helper.TextUtils;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.core.models.User;
import chat.rocket.android.widget.RocketChatAvatar;
......@@ -22,13 +23,13 @@ public class UserRenderer extends AbstractRenderer<User> {
/**
* show Avatar image
*/
public UserRenderer avatarInto(RocketChatAvatar rocketChatAvatar, String hostname) {
public UserRenderer avatarInto(RocketChatAvatar rocketChatAvatar, AbsoluteUrl absoluteUrl) {
if (!shouldHandle(rocketChatAvatar)) {
return this;
}
if (!TextUtils.isEmpty(object.getUsername())) {
new Avatar(hostname, object.getUsername()).into(rocketChatAvatar);
new Avatar(absoluteUrl, object.getUsername()).into(rocketChatAvatar);
}
return this;
}
......
......@@ -21,7 +21,7 @@
<exclude name="AbstractNaming" />
<exclude name="LongVariable" />
<!--exclude name="ShortMethodName" /-->
<!--exclude name="ShortVariable" /-->
<exclude name="ShortVariable" />
<exclude name="ShortClassName" />
<!--<exclude name="VariableNamingConventions" />-->
</rule>
......
......@@ -2,6 +2,7 @@ package chat.rocket.persistence.realm.models;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
......@@ -24,14 +25,14 @@ public class RealmBasedServerInfo extends RealmObject {
private String session;
private boolean insecure;
interface ColumnName {
public interface ColumnName {
String HOSTNAME = "hostname";
String NAME = "name";
String SESSION = "session";
String INSECURE = "insecure";
}
ServerInfo getServerInfo() {
public ServerInfo getServerInfo() {
return ServerInfo.builder()
.setHostname(hostname)
.setName(name)
......@@ -40,12 +41,16 @@ public class RealmBasedServerInfo extends RealmObject {
.build();
}
public static RealmHelper getRealm() {
public static Realm getRealm() {
return RealmStore.getRealm(DB_NAME);
}
public static RealmHelper getRealmHelper() {
return RealmStore.getOrCreateForServerScope(DB_NAME);
}
public static void addOrUpdate(String hostname, String name, boolean insecure) {
getRealm().executeTransaction(realm ->
getRealmHelper().executeTransaction(realm ->
realm.createOrUpdateObjectFromJson(RealmBasedServerInfo.class, new JSONObject()
.put(ColumnName.HOSTNAME, hostname)
.put(ColumnName.NAME, TextUtils.isEmpty(name) ? JSONObject.NULL : name)
......@@ -53,7 +58,7 @@ public class RealmBasedServerInfo extends RealmObject {
}
public static void remove(String hostname) {
getRealm().executeTransaction(realm -> {
getRealmHelper().executeTransaction(realm -> {
realm.where(RealmBasedServerInfo.class).equalTo(ColumnName.HOSTNAME, hostname)
.findAll()
.deleteAllFromRealm();
......@@ -62,12 +67,12 @@ public class RealmBasedServerInfo extends RealmObject {
}
public static void updateSession(String hostname, String session) {
RealmBasedServerInfo impl = getRealm().executeTransactionForRead(realm ->
RealmBasedServerInfo impl = getRealmHelper().executeTransactionForRead(realm ->
realm.where(RealmBasedServerInfo.class).equalTo(ColumnName.HOSTNAME, hostname).findFirst());
if (impl != null) {
impl.session = session;
getRealm().executeTransaction(realm -> {
getRealmHelper().executeTransaction(realm -> {
realm.copyToRealmOrUpdate(impl);
return null;
});
......@@ -76,13 +81,13 @@ public class RealmBasedServerInfo extends RealmObject {
@Nullable
public static ServerInfo getServerInfoForHost(String hostname) {
RealmBasedServerInfo impl = getRealm().executeTransactionForRead(realm ->
RealmBasedServerInfo impl = getRealmHelper().executeTransactionForRead(realm ->
realm.where(RealmBasedServerInfo.class).equalTo(ColumnName.HOSTNAME, hostname).findFirst());
return impl == null ? null : impl.getServerInfo();
}
public static List<ServerInfo> getServerInfoList() {
List<RealmBasedServerInfo> results = getRealm().executeTransactionForReadResults(realm ->
List<RealmBasedServerInfo> results = getRealmHelper().executeTransactionForReadResults(realm ->
realm.where(RealmBasedServerInfo.class).findAll());
ArrayList<ServerInfo> list = new ArrayList<>();
for (RealmBasedServerInfo impl : results) {
......
package chat.rocket.persistence.realm.repositories;
import android.os.Looper;
import android.support.v4.util.Pair;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import chat.rocket.core.models.ServerInfo;
import chat.rocket.core.repositories.ServerInfoRepository;
import chat.rocket.persistence.realm.models.RealmBasedServerInfo;
import hu.akarnokd.rxjava.interop.RxJavaInterop;
public class RealmServerInfoRepository extends RealmRepository implements ServerInfoRepository {
@Override
public Flowable<Optional<ServerInfo>> getByHostname(String hostname) {
return Flowable.defer(() -> Flowable.using(
() -> new Pair<>(RealmBasedServerInfo.getRealm(), Looper.myLooper()),
pair -> {
RealmBasedServerInfo info = pair.first.where(RealmBasedServerInfo.class)
.equalTo(RealmBasedServerInfo.ColumnName.HOSTNAME, hostname)
.findFirst();
if (info == null) {
return Flowable.just(Optional.<RealmBasedServerInfo>absent());
}
return RxJavaInterop.toV2Flowable(info
.<RealmBasedServerInfo>asObservable()
.filter(it -> it.isLoaded() && it.isValid())
.map(Optional::of));
},
pair -> close(pair.first, pair.second)
)
.unsubscribeOn(AndroidSchedulers.from(Looper.myLooper()))
.map(optional -> {
if (optional.isPresent()) {
return Optional.of(optional.get().getServerInfo());
}
return Optional.absent();
}));
}
}
package chat.rocket.android.widget;
public interface AbsoluteUrl {
String getAbsolute(String url);
}
......@@ -17,6 +17,7 @@ import android.widget.TextView;
import com.facebook.drawee.view.SimpleDraweeView;
import java.util.List;
import chat.rocket.android.widget.AbsoluteUrl;
import chat.rocket.android.widget.R;
import chat.rocket.android.widget.helper.FrescoHelper;
import chat.rocket.core.models.Attachment;
......@@ -28,7 +29,7 @@ import chat.rocket.core.models.AttachmentTitle;
*/
public class RocketChatMessageAttachmentsLayout extends LinearLayout {
private LayoutInflater inflater;
private String hostname;
private AbsoluteUrl absoluteUrl;
private List<Attachment> attachments;
public RocketChatMessageAttachmentsLayout(Context context) {
......@@ -58,8 +59,8 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
setOrientation(VERTICAL);
}
public void setHostname(String hostname) {
this.hostname = hostname;
public void setAbsoluteUrl(AbsoluteUrl absoluteUrl) {
this.absoluteUrl = absoluteUrl;
}
public void setAttachments(List<Attachment> attachments, boolean autoloadImages) {
......@@ -238,7 +239,7 @@ public class RocketChatMessageAttachmentsLayout extends LinearLayout {
}
private String absolutize(String url) {
return url.startsWith("/") ? "https://" + hostname + url : url;
return absoluteUrl.getAbsolute(url);
}
private void loadImage(final String url, final SimpleDraweeView drawee, final View load,
......
......@@ -2,6 +2,8 @@ package chat.rocket.core.models;
import com.google.auto.value.AutoValue;
import javax.annotation.Nullable;
@AutoValue
public abstract class LoginServiceConfiguration {
......@@ -9,6 +11,7 @@ public abstract class LoginServiceConfiguration {
public abstract String getService();
@Nullable
public abstract String getKey();
public static Builder builder() {
......
package chat.rocket.core.repositories;
import com.fernandocejas.arrow.optional.Optional;
import io.reactivex.Flowable;
import chat.rocket.core.models.ServerInfo;
public interface ServerInfoRepository {
Flowable<Optional<ServerInfo>> getByHostname(String hostname);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment