From 0431e1d7a8e85f35b7e146256583708908e2c687 Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Fri, 2 Sep 2016 14:24:11 -0400 Subject: [PATCH] Fix version checker, add unused topic functionality, bump version to 0.2.0.5 (#4) Fix version checker, add unused topic functionality, bump version to 0.2.0.5 --- app/build.gradle | 12 +- app/src/main/AndroidManifest.xml | 5 + app/src/main/assets/neu_topics.json | 173 ++++++++++++++++++ .../tonyjhuang/cheddar/CheddarActivity.java | 12 +- .../tonyjhuang/cheddar/api/CheddarApi.java | 12 +- .../cheddar/api/cache/CacheApi.java | 2 +- .../cheddar/api/message/MessageApi.java | 2 +- .../models/value/ValueTypeAdapterFactory.java | 33 +--- .../cheddar/api/network/ParseApi.java | 4 +- .../network/request/JoinChatRoomRequest.java | 4 +- .../cheddar/ui/chat/ChatActivity.java | 6 +- .../cheddar/ui/joinchat/JoinChatActivity.java | 120 ++++++++++++ .../tonyjhuang/cheddar/ui/joinchat/Topic.java | 28 +++ .../cheddar/ui/joinchat/TopicAdapter.java | 65 +++++++ .../ui/joinchat/TopicListFragment.java | 44 +++++ .../cheddar/ui/joinchat/TopicTree.java | 22 +++ .../cheddar/ui/list/ChatRoomListActivity.java | 7 +- .../cheddar/utils/VersionChecker.java | 25 +++ .../main/res/layout/activity_join_chat.xml | 31 ++++ .../main/res/layout/fragment_topic_list.xml | 18 ++ app/src/main/res/layout/row_topic.xml | 40 ++++ app/src/main/res/values/strings.xml | 4 + 22 files changed, 608 insertions(+), 61 deletions(-) create mode 100644 app/src/main/assets/neu_topics.json create mode 100644 app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/JoinChatActivity.java create mode 100644 app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/Topic.java create mode 100644 app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicAdapter.java create mode 100644 app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicListFragment.java create mode 100644 app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicTree.java create mode 100644 app/src/main/java/com/tonyjhuang/cheddar/utils/VersionChecker.java create mode 100644 app/src/main/res/layout/activity_join_chat.xml create mode 100644 app/src/main/res/layout/fragment_topic_list.xml create mode 100644 app/src/main/res/layout/row_topic.xml diff --git a/app/build.gradle b/app/build.gradle index 629165a..30ea542 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -85,8 +85,8 @@ android { applicationId "com.tonyjhuang.cheddar" minSdkVersion 15 targetSdkVersion 23 - versionCode 10 - versionName "0.2.0.4" + versionCode 11 + versionName "0.2.0.5" multiDexEnabled true } @@ -212,9 +212,11 @@ dependencies { compile "com.google.auto.value:auto-value:1.2" apt "com.google.auto.value:auto-value:1.2" - apt 'com.ryanharter.auto.value:auto-value-gson:0.2.5' - apt 'com.ryanharter.auto.value:auto-value-parcel:0.2.1' - apt 'com.gabrielittner.auto.value:auto-value-with:0.1.3' + apt 'com.ryanharter.auto.value:auto-value-gson:0.4.2' + provided 'com.ryanharter.auto.value:auto-value-gson:0.4.2' + apt 'com.ryanharter.auto.value:auto-value-parcel:0.2.4-rc2' + compile 'com.ryanharter.auto.value:auto-value-parcel-adapter:0.2.4-rc2' + apt 'com.gabrielittner.auto.value:auto-value-with:1.0.0-rc1' } apply plugin: 'com.google.gms.google-services' \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 45ea2b3..89d4214 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -64,6 +64,11 @@ android:launchMode="singleTop" android:screenOrientation="portrait" /> + + diff --git a/app/src/main/assets/neu_topics.json b/app/src/main/assets/neu_topics.json new file mode 100644 index 0000000..d83d72d --- /dev/null +++ b/app/src/main/assets/neu_topics.json @@ -0,0 +1,173 @@ +{ + "topics": [ + { + "name": "Random", + "slug": "random", + "drawable": "" + }, + { + "name": "Dorms", + "slug": "dorm", + "drawable": "", + "subtopics": [ + { + "name": "West Village", + "slug": "wv", + "drawable": "", + "subtopics": [ + { + "name": "West Village A", + "slug": "a", + "drawable": "" + }, + { + "name": "West Village B", + "slug": "b", + "drawable": "" + }, + { + "name": "West Village C", + "slug": "c", + "drawable": "" + }, + { + "name": "West Village E", + "slug": "e", + "drawable": "" + }, + { + "name": "West Village F", + "slug": "f", + "drawable": "" + }, + { + "name": "West Village G", + "slug": "g", + "drawable": "" + }, + { + "name": "West Village H", + "slug": "h", + "drawable": "" + } + ] + }, + { + "name": "Huntington Ave Apts", + "slug": "huntington", + "drawable": "" + }, + { + "name": "Mission Hill Apts", + "slug": "mission_hill", + "drawable": "" + }, + { + "name": "St. Stephen Street Apts", + "slug": "st_stephen", + "drawable": "" + }, + { + "name": "10 Coventry", + "slug": "10_coventry", + "drawable": "" + }, + { + "name": "153 Hemenway Street", + "slug": "153_hemenway", + "drawable": "" + }, + { + "name": "780 Columbus Ave", + "slug": "780_columbus ", + "drawable": "" + }, + { + "name": "Burstein Hall", + "slug": "burnstein", + "drawable": "" + }, + { + "name": "Davenport Commons", + "slug": "davenport", + "drawable": "" + }, + { + "name": "East Village", + "slug": "east_village", + "drawable": "" + }, + { + "name": "Hastings Hall", + "slug": "hastings", + "drawable": "" + }, + { + "name": "International Village", + "slug": "international_village", + "drawable": "" + }, + { + "name": "Kennedy Hall", + "slug": "kennedy", + "drawable": "" + }, + { + "name": "Kerr Hall", + "slug": "kerr", + "drawable": "" + }, + { + "name": "Light Hall", + "slug": "light", + "drawable": "" + }, + { + "name": "Loftman Hall", + "slug": "loftman", + "drawable": "" + }, + { + "name": "Melvin Hall", + "slug": "melven", + "drawable": "" + }, + { + "name": "Rubenstein Hall", + "slug": "rubenstein", + "drawable": "" + }, + { + "name": "Smith Hall", + "slug": "smith", + "drawable": "" + }, + { + "name": "Speare Hall", + "slug": "speare", + "drawable": "" + }, + { + "name": "Stetson East Hall", + "slug": "stetson_east", + "drawable": "" + }, + { + "name": "Stetson West Hall", + "slug": "steson_west", + "drawable": "" + }, + { + "name": "White Hall", + "slug": "white", + "drawable": "" + }, + { + "name": "Willis Hall", + "slug": "willis", + "drawable": "" + } + ] + } + ] +} \ No newline at end of file diff --git a/app/src/main/java/com/tonyjhuang/cheddar/CheddarActivity.java b/app/src/main/java/com/tonyjhuang/cheddar/CheddarActivity.java index 4f56ad8..cdfeb80 100644 --- a/app/src/main/java/com/tonyjhuang/cheddar/CheddarActivity.java +++ b/app/src/main/java/com/tonyjhuang/cheddar/CheddarActivity.java @@ -4,23 +4,19 @@ import android.support.v7.app.AppCompatActivity; import android.widget.Toast; -import com.tonyjhuang.cheddar.api.CheddarApi; import com.tonyjhuang.cheddar.ui.dialog.ChangelogDialog; import com.tonyjhuang.cheddar.ui.dialog.ForceVersionUpdateDialog; import com.tonyjhuang.cheddar.utils.Scheduler; +import com.tonyjhuang.cheddar.utils.VersionChecker; -import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.EActivity; import timber.log.Timber; import uk.co.chrisjenx.calligraphy.CalligraphyContextWrapper; -@EActivity(R.layout.activity_welcome) +@EActivity public abstract class CheddarActivity extends AppCompatActivity { - @Bean - public CheddarApi api; - @Override protected void attachBaseContext(Context newBase) { super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase)); @@ -34,8 +30,8 @@ protected void showChangeLog(CheddarPrefs_ prefs) { } } - protected void checkUpdate() { - api.checkVersionUpgrade().compose(Scheduler.defaultSchedulers()) + protected void checkForUpdate(VersionChecker versionChecker) { + versionChecker.check().compose(Scheduler.defaultSchedulers()) .subscribe(shouldUpgrade -> { if (shouldUpgrade) { ForceVersionUpdateDialog.show(this); diff --git a/app/src/main/java/com/tonyjhuang/cheddar/api/CheddarApi.java b/app/src/main/java/com/tonyjhuang/cheddar/api/CheddarApi.java index d290afc..5e2ecf3 100644 --- a/app/src/main/java/com/tonyjhuang/cheddar/api/CheddarApi.java +++ b/app/src/main/java/com/tonyjhuang/cheddar/api/CheddarApi.java @@ -3,7 +3,6 @@ import android.content.Context; import com.crashlytics.android.Crashlytics; -import com.tonyjhuang.cheddar.BuildConfig; import com.tonyjhuang.cheddar.CheddarPrefs_; import com.tonyjhuang.cheddar.api.cache.CacheApi; import com.tonyjhuang.cheddar.api.message.MessageApi; @@ -195,7 +194,7 @@ public Observable getChatRoom(String chatRoomId) { public Observable joinGroupChatRoom() { Observable observable = getCurrentUser().map(User::objectId) - .flatMap(parseApi::joinGroupChatRoom) + .flatMap(currentUserId -> parseApi.joinGroupChatRoom(currentUserId, null)) .flatMap(cacheApi::persist) .flatMap(alias -> Observable.defer(() -> // Cache ChatRoom after joining. @@ -366,15 +365,6 @@ public Observable sendFeedback(String feedback) { // Miscellaneous //****************************************************** - /** - * Do we need to force an upgrade? - */ - public Observable checkVersionUpgrade() { - return parseApi.getMinimumBuildNumber() - .map(minBuildNumber -> BuildConfig.VERSION_CODE < minBuildNumber) - .doOnError(Crashlytics::logException); - } - /** * Send feedback that a user has requested their school to be supported. */ diff --git a/app/src/main/java/com/tonyjhuang/cheddar/api/cache/CacheApi.java b/app/src/main/java/com/tonyjhuang/cheddar/api/cache/CacheApi.java index 41ec90d..b606fa0 100644 --- a/app/src/main/java/com/tonyjhuang/cheddar/api/cache/CacheApi.java +++ b/app/src/main/java/com/tonyjhuang/cheddar/api/cache/CacheApi.java @@ -44,7 +44,7 @@ public class CacheApi { (src, typeOfSrc, context) -> new JsonPrimitive(src.getTime()); private final Gson gson = new GsonBuilder() - .registerTypeAdapterFactory(new ValueTypeAdapterFactory()) + .registerTypeAdapterFactory(ValueTypeAdapterFactory.create()) .registerTypeAdapter(Date.class, dateJsonSerializer) .create(); diff --git a/app/src/main/java/com/tonyjhuang/cheddar/api/message/MessageApi.java b/app/src/main/java/com/tonyjhuang/cheddar/api/message/MessageApi.java index 41758fa..5aa261a 100644 --- a/app/src/main/java/com/tonyjhuang/cheddar/api/message/MessageApi.java +++ b/app/src/main/java/com/tonyjhuang/cheddar/api/message/MessageApi.java @@ -127,7 +127,7 @@ public void errorCallback(String channel, PubnubError error) { private static class PubnubObservableCallback extends Callback { private Gson gson = new GsonBuilder() - .registerTypeAdapterFactory(new ValueTypeAdapterFactory()) + .registerTypeAdapterFactory(ValueTypeAdapterFactory.create()) .registerTypeAdapter(MessageApiObjectHolder.class, new MessageApiDeserializer()) .registerTypeAdapter(ChatEvent.ChatEventType.class, ChatEvent.ChatEventType.DESERIALIZER) .create(); diff --git a/app/src/main/java/com/tonyjhuang/cheddar/api/models/value/ValueTypeAdapterFactory.java b/app/src/main/java/com/tonyjhuang/cheddar/api/models/value/ValueTypeAdapterFactory.java index 4606ee0..34fe77a 100644 --- a/app/src/main/java/com/tonyjhuang/cheddar/api/models/value/ValueTypeAdapterFactory.java +++ b/app/src/main/java/com/tonyjhuang/cheddar/api/models/value/ValueTypeAdapterFactory.java @@ -1,35 +1,12 @@ package com.tonyjhuang.cheddar.api.models.value; -import com.google.gson.Gson; -import com.google.gson.TypeAdapter; import com.google.gson.TypeAdapterFactory; -import com.google.gson.reflect.TypeToken; +import com.ryanharter.auto.value.gson.GsonTypeAdapterFactory; -import java.lang.reflect.Method; +@GsonTypeAdapterFactory +public abstract class ValueTypeAdapterFactory implements TypeAdapterFactory { -/** - * Created by tonyjhuang on 4/27/16. - */ -public class ValueTypeAdapterFactory implements TypeAdapterFactory { - - @SuppressWarnings("unchecked") - public TypeAdapter create(Gson gson, final TypeToken type) { - Class rawType = type.getRawType(); - try { - if(rawType.equals(AutoValue_User.class)) { - return (TypeAdapter) AutoValue_User.typeAdapter(gson); - } else if (rawType.equals(AutoValue_Alias.class)) { - return (TypeAdapter) AutoValue_Alias.typeAdapter(gson); - } else if (rawType.equals(AutoValue_ChatEvent.class)) { - return (TypeAdapter) AutoValue_ChatEvent.typeAdapter(gson); - } - // Call static typeAdapter method on class if it exists, otherwise - // return the default type adapter. - Method typeAdapterMethod = rawType.getDeclaredMethod("typeAdapter", Gson.class); - return (TypeAdapter) typeAdapterMethod.invoke(null, gson); - } catch (Exception e) { - //Timber.v("couldn't invoke static typeAdapter method on " + rawType + ": " + e); - return gson.getDelegateAdapter(this, type).nullSafe(); - } + public static TypeAdapterFactory create() { + return new AutoValueGson_ValueTypeAdapterFactory(); } } diff --git a/app/src/main/java/com/tonyjhuang/cheddar/api/network/ParseApi.java b/app/src/main/java/com/tonyjhuang/cheddar/api/network/ParseApi.java index 2ea8a50..c0966c9 100644 --- a/app/src/main/java/com/tonyjhuang/cheddar/api/network/ParseApi.java +++ b/app/src/main/java/com/tonyjhuang/cheddar/api/network/ParseApi.java @@ -284,9 +284,9 @@ public Observable findChatRoom(String chatRoomId) { /** * Places the User into a new group ChatRoom. */ - public Observable joinGroupChatRoom(String userId) { + public Observable joinGroupChatRoom(String userId, @Nullable String topic) { JoinChatRoomRequest request = - new JoinChatRoomRequest(userId, GROUP_OCCUPANCY, SUBKEY, PUBKEY); + new JoinChatRoomRequest(userId, GROUP_OCCUPANCY, topic, SUBKEY, PUBKEY); return service.joinChatRoom(request); } diff --git a/app/src/main/java/com/tonyjhuang/cheddar/api/network/request/JoinChatRoomRequest.java b/app/src/main/java/com/tonyjhuang/cheddar/api/network/request/JoinChatRoomRequest.java index 81d3088..a61347b 100644 --- a/app/src/main/java/com/tonyjhuang/cheddar/api/network/request/JoinChatRoomRequest.java +++ b/app/src/main/java/com/tonyjhuang/cheddar/api/network/request/JoinChatRoomRequest.java @@ -6,12 +6,14 @@ public class JoinChatRoomRequest { public String userId; public int maxOccupancy; + public String topic; public String subkey; public String pubkey; - public JoinChatRoomRequest(String userId, int maxOccupancy, String subkey, String pubkey) { + public JoinChatRoomRequest(String userId, int maxOccupancy, String topic, String subkey, String pubkey) { this.userId = userId; this.maxOccupancy = maxOccupancy; + this.topic = topic; this.subkey = subkey; this.pubkey = pubkey; } diff --git a/app/src/main/java/com/tonyjhuang/cheddar/ui/chat/ChatActivity.java b/app/src/main/java/com/tonyjhuang/cheddar/ui/chat/ChatActivity.java index 29ec573..17160c3 100644 --- a/app/src/main/java/com/tonyjhuang/cheddar/ui/chat/ChatActivity.java +++ b/app/src/main/java/com/tonyjhuang/cheddar/ui/chat/ChatActivity.java @@ -21,7 +21,6 @@ import com.tonyjhuang.cheddar.CheddarActivity; import com.tonyjhuang.cheddar.CheddarPrefs_; import com.tonyjhuang.cheddar.R; -import com.tonyjhuang.cheddar.api.CheddarApi; import com.tonyjhuang.cheddar.api.CheddarMetrics; import com.tonyjhuang.cheddar.api.models.value.Alias; import com.tonyjhuang.cheddar.api.models.value.ChatEvent; @@ -30,6 +29,7 @@ import com.tonyjhuang.cheddar.ui.customviews.PreserveScrollStateListView; import com.tonyjhuang.cheddar.ui.dialog.FeedbackDialog; import com.tonyjhuang.cheddar.ui.dialog.LoadingDialog; +import com.tonyjhuang.cheddar.utils.VersionChecker; import org.androidannotations.annotations.AfterInject; import org.androidannotations.annotations.AfterTextChange; @@ -87,7 +87,7 @@ public class ChatActivity extends CheddarActivity implements ChatRoomView { @Extra String aliasId; @Bean - CheddarApi api; + VersionChecker versionChecker; @Pref CheddarPrefs_ prefs; @SystemService @@ -377,7 +377,7 @@ public void onNewMessagesClick() { @Override protected void onResume() { super.onResume(); - checkUpdate(); + checkForUpdate(versionChecker); presenter.onResume(); showChangeLog(prefs); if (chatEventListView != null && diff --git a/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/JoinChatActivity.java b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/JoinChatActivity.java new file mode 100644 index 0000000..94b4802 --- /dev/null +++ b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/JoinChatActivity.java @@ -0,0 +1,120 @@ +package com.tonyjhuang.cheddar.ui.joinchat; + +import android.content.res.AssetManager; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; + +import com.crashlytics.android.Crashlytics; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.tonyjhuang.cheddar.CheddarActivity; +import com.tonyjhuang.cheddar.R; +import com.tonyjhuang.cheddar.api.models.value.ValueTypeAdapterFactory; +import com.tonyjhuang.cheddar.utils.Scheduler; +import com.tonyjhuang.cheddar.utils.VersionChecker; + +import org.androidannotations.annotations.AfterInject; +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EActivity; +import org.androidannotations.annotations.Extra; +import org.androidannotations.annotations.ViewById; + +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.util.ArrayList; + +import rx.Observable; +import rx.Subscription; +import rx.subjects.AsyncSubject; +import timber.log.Timber; + +@EActivity(R.layout.activity_join_chat) +public class JoinChatActivity extends CheddarActivity { + + @ViewById + Toolbar toolbar; + @ViewById(R.id.topic_view) + RecyclerView topicView; + + @Bean + VersionChecker versionChecker; + + @Extra + TopicTree topicTree; + + /** + * Subject that emits the list of topics. + */ + private AsyncSubject topicSubject = AsyncSubject.create(); + private Subscription topicSubscription; // For sending topics to UI. + private boolean firstLoad = true; + + @AfterInject + public void afterInject() { + if (topicTree != null) { + topicSubject.onNext(TopicTree.create(new ArrayList<>())); + topicSubject.onCompleted(); + } else { + loadTopics().compose(Scheduler.defaultSchedulers()) + .subscribe(topicSubject); + } + } + + @AfterViews + public void afterViews() { + setSupportActionBar(toolbar); + assert getSupportActionBar() != null; + getSupportActionBar().setTitle(R.string.join_chat_title); + + topicView.setLayoutManager(new LinearLayoutManager(this)); + topicView.setItemAnimator(new DefaultItemAnimator()); + } + + /** + * Load topics from disk and emit through topicSubject. + */ + private Observable loadTopics() { + return Observable.defer(() -> { + Gson gson = new GsonBuilder() + .registerTypeAdapterFactory(ValueTypeAdapterFactory.create()) + .create(); + AssetManager assetManager = getAssets(); + try { + // Unhardcode pls + InputStream ims = assetManager.open("neu_topics.json"); + Reader reader = new InputStreamReader(ims); + return Observable.just(gson.fromJson(reader, TopicTree.class)); + } catch (IOException e) { + return Observable.error(e); + } + }).doOnError(Crashlytics::logException); + } + + @Override + protected void onResume() { + super.onResume(); + checkForUpdate(versionChecker); + if (firstLoad) { + topicSubscription = topicSubject.subscribe( + // TODO: better error handling + this::displayTopics, e -> Timber.e(e, "couldn't get topics")); + } + } + + private void displayTopics(TopicTree topicTree) { + firstLoad = false; + TopicAdapter adapter = new TopicAdapter(topicTree); + topicView.setAdapter(adapter); + } + + @Override + protected void onPause() { + super.onPause(); + if (topicSubscription != null) topicSubscription.unsubscribe(); + } +} diff --git a/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/Topic.java b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/Topic.java new file mode 100644 index 0000000..cab18b2 --- /dev/null +++ b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/Topic.java @@ -0,0 +1,28 @@ +package com.tonyjhuang.cheddar.ui.joinchat; + + +import android.os.Parcelable; +import android.support.annotation.Nullable; + +import com.google.auto.value.AutoValue; +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; + +import java.util.List; + +@AutoValue +public abstract class Topic implements Parcelable { + + public static TypeAdapter typeAdapter(Gson gson) { + return new AutoValue_Topic.GsonTypeAdapter(gson); + } + + public abstract String name(); + + public abstract String slug(); + + public abstract String drawable(); + + @Nullable + public abstract List subtopics(); +} diff --git a/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicAdapter.java b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicAdapter.java new file mode 100644 index 0000000..6363496 --- /dev/null +++ b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicAdapter.java @@ -0,0 +1,65 @@ +package com.tonyjhuang.cheddar.ui.joinchat; + +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; + +import com.tonyjhuang.cheddar.R; + +import rx.Observable; +import rx.subjects.PublishSubject; + +/** + * Data adapter for a list of chat room topics + */ +public class TopicAdapter extends RecyclerView.Adapter { + + // See http://stackoverflow.com/a/24933117 + private final PublishSubject onClickSubject = PublishSubject.create(); + + /** + * TopicTree that we're displaying. + */ + private TopicTree topicTree; + + public TopicAdapter(TopicTree topicTree) { + this.topicTree = topicTree; + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_topic, parent, false); + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + Topic topic = topicTree.topics().get(position); + holder.nameView.setText(topic.name()); + holder.container.setOnClickListener(view -> onClickSubject.onNext(topic)); + } + + @Override + public int getItemCount() { + return topicTree.topics().size(); + } + + public Observable getOnClickObservable() { + return onClickSubject.asObservable(); + } + + public static class ViewHolder extends RecyclerView.ViewHolder { + public ViewGroup container; + public TextView nameView; + public TextView selectorView; + + public ViewHolder(View itemView) { + super(itemView); + nameView = (TextView) itemView.findViewById(R.id.name); + selectorView = (TextView) itemView.findViewById(R.id.selector); + container = (ViewGroup) itemView.findViewById(R.id.container); + } + } +} diff --git a/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicListFragment.java b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicListFragment.java new file mode 100644 index 0000000..9a49e83 --- /dev/null +++ b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicListFragment.java @@ -0,0 +1,44 @@ +package com.tonyjhuang.cheddar.ui.joinchat; + +import android.support.v4.app.Fragment; +import android.support.v7.widget.DefaultItemAnimator; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; + +import com.tonyjhuang.cheddar.R; + +import org.androidannotations.annotations.AfterViews; +import org.androidannotations.annotations.EFragment; +import org.androidannotations.annotations.FragmentArg; +import org.androidannotations.annotations.ViewById; +import org.greenrobot.eventbus.EventBus; + +import timber.log.Timber; + +@EFragment(R.layout.fragment_topic_list) +public class TopicListFragment extends Fragment{ + @ViewById(R.id.topic_view) + RecyclerView topicView; + + @FragmentArg + TopicTree topicTree; + + @AfterViews + public void afterViews() { + topicView.setLayoutManager(new LinearLayoutManager(getContext())); + topicView.setItemAnimator(new DefaultItemAnimator()); + TopicAdapter adapter = new TopicAdapter(topicTree); + topicView.setAdapter(adapter); + adapter.getOnClickObservable().subscribe( + topic -> EventBus.getDefault().post(new OnTopicClickedEvent(topic)), + error -> Timber.e(error, "???")); + } + + public static class OnTopicClickedEvent { + public Topic topic; + + public OnTopicClickedEvent(Topic topic) { + this.topic = topic; + } + } +} diff --git a/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicTree.java b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicTree.java new file mode 100644 index 0000000..765a7a4 --- /dev/null +++ b/app/src/main/java/com/tonyjhuang/cheddar/ui/joinchat/TopicTree.java @@ -0,0 +1,22 @@ +package com.tonyjhuang.cheddar.ui.joinchat; + +import android.os.Parcelable; + +import com.google.auto.value.AutoValue; +import com.google.gson.Gson; +import com.google.gson.TypeAdapter; + +import java.util.List; + +@AutoValue +public abstract class TopicTree implements Parcelable{ + public abstract List topics(); + + public static TopicTree create(List topics) { + return new AutoValue_TopicTree(topics); + } + + public static TypeAdapter typeAdapter(Gson gson) { + return new AutoValue_TopicTree.GsonTypeAdapter(gson); + } +} diff --git a/app/src/main/java/com/tonyjhuang/cheddar/ui/list/ChatRoomListActivity.java b/app/src/main/java/com/tonyjhuang/cheddar/ui/list/ChatRoomListActivity.java index 3682ddb..fc4e769 100644 --- a/app/src/main/java/com/tonyjhuang/cheddar/ui/list/ChatRoomListActivity.java +++ b/app/src/main/java/com/tonyjhuang/cheddar/ui/list/ChatRoomListActivity.java @@ -19,6 +19,7 @@ import com.tonyjhuang.cheddar.ui.dialog.LoadingDialog; import com.tonyjhuang.cheddar.ui.welcome.WelcomeActivity_; import com.tonyjhuang.cheddar.utils.Scheduler; +import com.tonyjhuang.cheddar.utils.VersionChecker; import org.androidannotations.annotations.AfterInject; import org.androidannotations.annotations.AfterViews; @@ -52,6 +53,9 @@ public class ChatRoomListActivity extends CheddarActivity implements ChatRoomLis @Bean ChatRoomListAdapter adapter; + @Bean + VersionChecker versionChecker; + @Pref CheddarPrefs_ prefs; @@ -138,7 +142,7 @@ private void dismissLoadingDialog() { @Override protected void onResume() { super.onResume(); - checkUpdate(); + checkForUpdate(versionChecker); presenter.onResume(); showChangeLog(prefs); } @@ -178,6 +182,7 @@ public boolean onCreateOptionsMenu(Menu menu) { } private void joinNewChatRoom() { + //JoinChatActivity_.intent(this).start(); loadingDialog = LoadingDialog.show(this, R.string.chat_join_chat); presenter.onJoinChatRoomClicked(); } diff --git a/app/src/main/java/com/tonyjhuang/cheddar/utils/VersionChecker.java b/app/src/main/java/com/tonyjhuang/cheddar/utils/VersionChecker.java new file mode 100644 index 0000000..a93b932 --- /dev/null +++ b/app/src/main/java/com/tonyjhuang/cheddar/utils/VersionChecker.java @@ -0,0 +1,25 @@ +package com.tonyjhuang.cheddar.utils; + +import com.crashlytics.android.Crashlytics; +import com.tonyjhuang.cheddar.BuildConfig; +import com.tonyjhuang.cheddar.api.network.ParseApi; + +import org.androidannotations.annotations.Bean; +import org.androidannotations.annotations.EBean; + +import rx.Observable; + +/** + * Helper for checking if we need an app update. + */ +@EBean +public class VersionChecker { + @Bean + ParseApi parseApi; + + public Observable check() { + return parseApi.getMinimumBuildNumber() + .map(minBuildNumber -> BuildConfig.VERSION_CODE < minBuildNumber) + .doOnError(Crashlytics::logException); + } +} diff --git a/app/src/main/res/layout/activity_join_chat.xml b/app/src/main/res/layout/activity_join_chat.xml new file mode 100644 index 0000000..36844e1 --- /dev/null +++ b/app/src/main/res/layout/activity_join_chat.xml @@ -0,0 +1,31 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_topic_list.xml b/app/src/main/res/layout/fragment_topic_list.xml new file mode 100644 index 0000000..9da3717 --- /dev/null +++ b/app/src/main/res/layout/fragment_topic_list.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/row_topic.xml b/app/src/main/res/layout/row_topic.xml new file mode 100644 index 0000000..7cd7b86 --- /dev/null +++ b/app/src/main/res/layout/row_topic.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ac4bfa0..6ebfa37 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -103,6 +103,10 @@ Couldn\'t join new chat. You can only be in 5 chat rooms at once Couldn\'t load messages. + + + Join new chat + Couldn\'t register for push notifications.