Commit 980212f8 authored by Yusuke Iwaki's avatar Yusuke Iwaki

implement message view stub.

parent 54872cab
package chat.rocket.android.activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import chat.rocket.android.LaunchUtil;
import chat.rocket.android.RocketChatCache;
import chat.rocket.android.model.ServerConfig;
import chat.rocket.android.realm_helper.RealmListObserver;
import chat.rocket.android.realm_helper.RealmStore;
import chat.rocket.android.service.RocketChatService;
import icepick.State;
abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
private RealmListObserver<ServerConfig> unconfiguredServersObserver =
......@@ -19,8 +21,8 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
}
});
protected String serverConfigId;
protected String roomId;
@State protected String serverConfigId;
@State protected String roomId;
SharedPreferences.OnSharedPreferenceChangeListener preferenceChangeListener =
(sharedPreferences, key) -> {
......@@ -67,11 +69,7 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
onRoomIdUpdated();
}
protected void onServerConfigIdUpdated() {
RocketChatCache.get(this).edit()
.remove(RocketChatCache.KEY_SELECTED_ROOM_ID)
.apply();
}
protected void onServerConfigIdUpdated() {}
protected void onRoomIdUpdated() {}
......@@ -93,4 +91,8 @@ abstract class AbstractAuthedActivity extends AbstractFragmentActivity {
unconfiguredServersObserver.unsub();
super.onPause();
}
@Override protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
}
......@@ -29,7 +29,9 @@ public class MainActivity extends AbstractAuthedActivity {
setContentView(R.layout.activity_main);
setupSidebar();
showFragment(new HomeFragment());
if (roomId == null) {
showFragment(new HomeFragment());
}
}
private void setupSidebar() {
......
......@@ -2,14 +2,22 @@ package chat.rocket.android.fragment.chatroom;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import chat.rocket.android.R;
import chat.rocket.android.helper.LogcatIfError;
import chat.rocket.android.layouthelper.chatroom.MessageListAdapter;
import chat.rocket.android.model.SyncState;
import chat.rocket.android.model.ddp.Message;
import chat.rocket.android.model.ddp.RoomSubscription;
import chat.rocket.android.model.internal.LoadMessageProcedure;
import chat.rocket.android.realm_helper.RealmHelper;
import chat.rocket.android.realm_helper.RealmModelListView;
import chat.rocket.android.realm_helper.RealmObjectObserver;
import chat.rocket.android.realm_helper.RealmStore;
import io.realm.Realm;
import io.realm.RealmResults;
import io.realm.Sort;
import org.json.JSONObject;
/**
......@@ -45,6 +53,8 @@ public class RoomFragment extends AbstractChatRoomFragment {
roomObserver = realmHelper
.createObjectObserver(realm -> realm.where(RoomSubscription.class).equalTo("rid", roomId))
.setOnUpdateListener(this::onRenderRoom);
initialRequest();
}
@Override protected int getLayout() {
......@@ -52,8 +62,24 @@ public class RoomFragment extends AbstractChatRoomFragment {
}
@Override protected void onSetupView() {
RealmModelListView listView = (RealmModelListView) rootView.findViewById(R.id.listview);
realmHelper.bindListView(listView,
realm -> realm.where(Message.class)
.equalTo("rid", roomId)
.findAllSorted("ts", Sort.DESCENDING),
MessageListAdapter::new);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext(),
LinearLayoutManager.VERTICAL, true);
listView.setLayoutManager(layoutManager);
}
private void onRenderRoom(RoomSubscription roomSubscription) {
activityToolbar.setTitle(roomSubscription.getName());
}
// TODO: just a sample!!
private void initialRequest() {
realmHelper.executeTransaction(realm -> {
realm.createOrUpdateObjectFromJson(LoadMessageProcedure.class, new JSONObject()
.put("roomId", roomId)
......@@ -64,8 +90,8 @@ public class RoomFragment extends AbstractChatRoomFragment {
}).continueWith(new LogcatIfError());
}
private void onRenderRoom(RoomSubscription roomSubscription) {
activityToolbar.setTitle(roomSubscription.getName());
private RealmResults<Message> queryItems(Realm realm) {
return realm.where(Message.class).equalTo("rid", roomId).findAllSorted("ts");
}
@Override public void onResume() {
......
package chat.rocket.android.layouthelper.chatroom;
import android.content.Context;
import android.view.View;
import chat.rocket.android.model.ddp.Message;
import chat.rocket.android.realm_adapter.RealmModelListAdapter;
/**
* message list adapter for chat room.
*/
public class MessageListAdapter extends RealmModelListAdapter<Message, MessageViewHolder> {
public MessageListAdapter(Context context) {
super(context);
}
@Override protected int getItemViewType(Message model) {
return 0;
}
@Override protected int getLayout(int viewType) {
return android.R.layout.simple_list_item_1;
}
@Override protected MessageViewHolder onCreateRealmModelViewHolder(int viewType, View itemView) {
return new MessageViewHolder(itemView);
}
}
package chat.rocket.android.layouthelper.chatroom;
import android.graphics.Color;
import android.view.View;
import android.widget.TextView;
import chat.rocket.android.model.ddp.Message;
import chat.rocket.android.realm_adapter.RealmModelViewHolder;
/**
*/
public class MessageViewHolder extends RealmModelViewHolder<Message> {
private TextView text;
public MessageViewHolder(View itemView) {
super(itemView);
text = (TextView) itemView.findViewById(android.R.id.text1);
}
public void bind(Message message) {
text.setText(message.getMsg());
text.setTextColor(Color.BLACK);
}
}
......@@ -64,8 +64,7 @@ public class LoadMessageProcedureObserver extends AbstractModelObserver<LoadMess
.put("roomId", roomId)
.put("syncstate", SyncState.SYNCED)
.put("timestamp", lastTs)
.put("hasNext", lastTs > 0))
);
.put("hasNext", lastTs > 0)));
})
).continueWithTask(task -> {
if (task.isFaulted()) {
......
......@@ -3,8 +3,8 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
<chat.rocket.android.realm_helper.RealmModelListView
android:id="@+id/listview"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
......
......@@ -36,4 +36,5 @@ dependencies {
compile rootProject.ext.supportAnnotations
compile rootProject.ext.supportAppCompat
compile rootProject.ext.supportDesign
compile 'io.realm:android-adapters:1.4.0'
}
package chat.rocket.android.realm_adapter;
import android.content.Context;
import android.support.annotation.LayoutRes;
import android.view.View;
import android.view.ViewGroup;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.RealmRecyclerViewAdapter;
import io.realm.RealmResults;
public abstract class RealmModelListAdapter<T extends RealmObject,
VH extends RealmModelViewHolder<T>> extends RealmRecyclerViewAdapter<T, VH> {
public interface Query<T extends RealmObject> {
RealmResults<T> queryItems(Realm realm);
}
public interface Constructor<T extends RealmObject, VH extends RealmModelViewHolder<T>> {
RealmModelListAdapter<T, VH> getNewInstance(Context context);
}
public RealmModelListAdapter(Context context) {
super(context, null, true);
}
protected abstract int getItemViewType(T model);
protected abstract @LayoutRes int getLayout(int viewType);
protected abstract VH onCreateRealmModelViewHolder(int viewType, View itemView);
@Override public final int getItemViewType(int position) {
return getItemViewType(getItem(position));
}
@Override public VH onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = inflater.inflate(getLayout(viewType), parent, false);
return onCreateRealmModelViewHolder(viewType, itemView);
}
@Override public void onBindViewHolder(VH holder, int position) {
holder.bind(getItem(position));
}
}
package chat.rocket.android.realm_adapter;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import io.realm.RealmObject;
public abstract class RealmModelViewHolder<T extends RealmObject> extends RecyclerView.ViewHolder {
public RealmModelViewHolder(View itemView) {
super(itemView);
}
public abstract void bind(T model);
}
......@@ -32,7 +32,7 @@ abstract class AbstractRealmResultsObserver<T extends RealmObject> {
}
public void keepalive() {
if (realm == null || realm.isClosed()) {
if (realm == null || realm.isClosed() || !results.isValid()) {
unsub();
sub();
}
......@@ -41,7 +41,9 @@ abstract class AbstractRealmResultsObserver<T extends RealmObject> {
public void unsub() {
try {
if (results != null) {
results.removeChangeListener(listener);
if (results.isValid()) {
results.removeChangeListener(listener);
}
results = null;
}
if (realm != null && !realm.isClosed()) {
......
......@@ -3,6 +3,8 @@ package chat.rocket.android.realm_helper;
import android.os.Looper;
import bolts.Task;
import bolts.TaskCompletionSource;
import chat.rocket.android.realm_adapter.RealmModelListAdapter;
import chat.rocket.android.realm_adapter.RealmModelViewHolder;
import io.realm.Realm;
import io.realm.RealmConfiguration;
import io.realm.RealmObject;
......@@ -168,4 +170,13 @@ public class RealmHelper {
RealmObjectObserver.Query<T> query) {
return new RealmObjectObserver<T>(this, query);
}
public <T extends RealmObject, VH extends RealmModelViewHolder<T>> void bindListView(
RealmModelListView listView,
RealmModelListAdapter.Query<T> query,
RealmModelListAdapter.Constructor<T, VH> constructor) {
if (listView != null) {
listView.setup(this, query, constructor);
}
}
}
package chat.rocket.android.realm_helper;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import android.view.View;
import chat.rocket.android.realm_adapter.RealmModelListAdapter;
import chat.rocket.android.realm_adapter.RealmModelViewHolder;
import io.realm.Realm;
import io.realm.RealmObject;
import io.realm.RealmResults;
public class RealmModelListView extends RecyclerView {
private Realm realm;
public RealmModelListView(Context context) {
super(context);
}
public RealmModelListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RealmModelListView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/*package*/ <T extends RealmObject, VH extends RealmModelViewHolder<T>> void setup(
final RealmHelper realmHelper,
final RealmModelListAdapter.Query<T> query,
final RealmModelListAdapter.Constructor<T, VH> constructor) {
addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override public void onViewAttachedToWindow(View view) {
realm = realmHelper.instance();
RealmResults<T> results = query.queryItems(realm);
RealmModelListAdapter<T, VH> adapter = constructor.getNewInstance(view.getContext());
adapter.updateData(results);
setAdapter(adapter);
}
@Override public void onViewDetachedFromWindow(View view) {
setAdapter(null);
if (realm != null && !realm.isClosed()) {
realm.close();
}
}
});
}
// just for preventing from unexpected overriding.
@Override public final void setAdapter(Adapter adapter) {
super.setAdapter(adapter);
}
}
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