Make facility actually display title and cover image

parent 34d56747
Pipeline #5124 passed with stages
in 3 minutes and 44 seconds
package srct.whatsopen
import android.annotation.SuppressLint
import android.graphics.BitmapFactory
import android.os.Bundle
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_facility_detail.*
import okhttp3.Request
import srct.whatsopen.model.Facility
import srct.whatsopen.util.WhatsOpenService
class FacilityDetailActivity : AppCompatActivity() {
private lateinit var facility: Facility
@SuppressLint("CheckResult")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_facility_detail)
setSupportActionBar(toolbar)
// ensure service is ready if we were launched by deep link or something
WhatsOpenService.init(applicationContext)
// get name
val slug = intent.getStringExtra("slug")
// get our facility object and set stuff correctly
WhatsOpenService.getData().subscribe { data ->
facility = data.find { facility -> facility.slug == slug }!!
findViewById<Toolbar>(R.id.toolbar).title = facility.name
// do the bg image
if (facility.logoBitmap == null) {
Observable.defer {
Observable.just(
WhatsOpenService.okHttpClient.newCall(
Request.Builder().url(
facility.logoUrl
).build()
).execute()
)
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe { response ->
facility.logoBitmap = BitmapFactory.decodeStream(response.body()!!.byteStream())
findViewById<ImageView>(R.id.facility_bg_image).setImageBitmap(facility.logoBitmap)
}
} else { // skip the HTTP altogether
findViewById<ImageView>(R.id.facility_bg_image).setImageBitmap(facility.logoBitmap)
}
}
supportActionBar?.setDisplayHomeAsUpEnabled(true)
}
}
......@@ -8,43 +8,23 @@ import android.view.MenuItem
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import kotlinx.android.synthetic.main.activity_main.*
import okhttp3.Cache
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import srct.whatsopen.util.MainViewAdapter
import srct.whatsopen.util.WhatsOpenService
class MainActivity : AppCompatActivity() {
private lateinit var service: WhatsOpenService
private lateinit var refreshLayout: SwipeRefreshLayout
private lateinit var cache: Cache
private lateinit var okHttpClient: OkHttpClient
private val cacheSize = (8 * 1024 * 1024).toLong() // 8 MB cache
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
setSupportActionBar(toolbar)
cache = Cache(applicationContext.cacheDir, cacheSize)
okHttpClient = OkHttpClient.Builder()
.cache(cache)
.build()
val retrofit = Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://api.srct.gmu.edu/whatsopen/v2/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build()
service = retrofit.create(WhatsOpenService::class.java)
// initialize service
WhatsOpenService.init(applicationContext)
// setup refresh listener
refreshLayout = findViewById(R.id.swipe_refresh)
refreshLayout.setOnRefreshListener {
cache.evictAll() // TODO only evict main API call?
WhatsOpenService.resetCache() // TODO only evict main API call?
this.refresh()
}
refresh()
......@@ -70,9 +50,7 @@ class MainActivity : AppCompatActivity() {
@SuppressLint("CheckResult")
private fun refresh() {
refreshLayout.isRefreshing = true
service.getData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
WhatsOpenService.getData()
.subscribe({ facilities ->
refreshLayout.isRefreshing = false
recycle_view.adapter = MainViewAdapter(facilities)
......
package srct.whatsopen.model
import android.graphics.Bitmap
import com.google.gson.annotations.SerializedName
import java.util.*
data class Facility(
......@@ -10,7 +10,9 @@ data class Facility(
@SerializedName("special_schedules") val specialSchedules: List<Schedule>,
@SerializedName("facility_location") val location: Location,
@SerializedName("slug") val slug: String,
val isFavorite: Boolean
@SerializedName("logo") val logoUrl: String,
val isFavorite: Boolean,
var logoBitmap: Bitmap?
) {
fun currentSchedule(): Schedule {
val now: Date = Calendar.getInstance(TimeZone.getTimeZone("EST5EDT")).time
......
......@@ -38,7 +38,7 @@ class MainViewAdapter(var facilities: List<Facility>) : RecyclerView.Adapter<Hol
holder.itemView.setOnClickListener {
run {
val intent = Intent(holder.itemView.context, FacilityDetailActivity::class.java)
intent.putExtra("name", "")
intent.putExtra("slug", facility.slug)
holder.itemView.context.startActivity(intent)
}
}
......@@ -46,4 +46,4 @@ class MainViewAdapter(var facilities: List<Facility>) : RecyclerView.Adapter<Hol
}
class Holder(view: View) : RecyclerView.ViewHolder(view)
class Holder(view: View) : RecyclerView.ViewHolder(view)
\ No newline at end of file
package srct.whatsopen.util
import android.content.Context
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.Cache
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import retrofit2.http.Headers
import srct.whatsopen.model.Facility
......@@ -10,4 +18,61 @@ interface WhatsOpenService {
@Headers("Cache-Control: public, max-age=43200, max-stale=2628003")
@GET("facilities")
fun getData(): Observable<List<Facility>>
companion object {
lateinit var cache: Cache
val okHttpClient: OkHttpClient by lazy {
OkHttpClient.Builder()
.cache(cache)
.build()
}
val service: WhatsOpenService by lazy {
Retrofit.Builder()
.client(okHttpClient)
.baseUrl("https://api.srct.gmu.edu/whatsopen/v2/")
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.build().create(WhatsOpenService::class.java)
}
private const val cacheSize = (8 * 1024 * 1024).toLong() // 8 MB cache
var data: List<Facility>? = null
/**
* Prepare the retrofit service for initialization if it hasn't already been.
*/
fun init(context: Context) {
cache = Cache(context.cacheDir, cacheSize)
}
/**
* Get a list of all facilities. Uses cached information to speed up the process.
*/
fun getData(): Observable<List<Facility>> {
if (data == null) {
return service.getData()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.map(fun(results): List<Facility> {
data = results
return results
})
} else {
return Observable.just(data!!)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
}
}
/**
* Clear all of the caches.
*/
fun resetCache() {
cache.evictAll()
data = null
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
......@@ -10,17 +10,17 @@
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_height="192dp"
android:layout_width="match_parent">
android:layout_width="match_parent"
android:layout_height="192dp">
<com.google.android.material.appbar.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:toolbarId="@+id/toolbar"
app:contentScrim="?attr/colorPrimary"
app:layout_scrollFlags="scroll|exitUntilCollapsed"
app:layout_scrollInterpolator="@android:anim/decelerate_interpolator"
app:contentScrim="?attr/colorPrimary">
app:toolbarId="@+id/toolbar">
<ImageView
android:id="@+id/facility_bg_image"
......@@ -33,16 +33,14 @@
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_height="?attr/actionBarSize"
android:layout_width="match_parent" />
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize" />
</com.google.android.material.appbar.CollapsingToolbarLayout>
</com.google.android.material.appbar.AppBarLayout>
<androidx.core.widget.NestedScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">
......
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