Przeglądaj źródła

Added caching thumbnail images

sirekanyan 8 lat temu
rodzic
commit
48e6b0a5e0

+ 10 - 5
app/src/main/java/me/vadik/knigopis/MainActivity.kt

@@ -15,22 +15,27 @@ import me.vadik.knigopis.adapters.UsersAdapter
 import me.vadik.knigopis.auth.KAuth
 import me.vadik.knigopis.auth.KAuthImpl
 import me.vadik.knigopis.model.FinishedBook
-import me.vadik.knigopis.model.User
 import me.vadik.knigopis.model.PlannedBook
+import me.vadik.knigopis.model.User
 
 private const val ULOGIN_REQUEST_CODE = 0
 
 class MainActivity : AppCompatActivity() {
 
   private val api by lazy { app().baseApi.create(Endpoint::class.java) }
-  private val imageApi by lazy { app().imageApi.create(ImageEndpoint::class.java) }
   private val auth by lazy { KAuthImpl(applicationContext, api) as KAuth }
   private val users = mutableListOf<User>()
   private val finishedBooks = mutableListOf<FinishedBook>()
   private val plannedBooks = mutableListOf<PlannedBook>()
   private val usersAdapter = UsersAdapter.create(users)
-  private val finishedBooksAdapter by lazy { BooksAdapter(imageApi).create(finishedBooks) }
-  private val plannedBooksAdapter by lazy { BooksAdapter(imageApi).create(plannedBooks) }
+  private val booksAdapter by lazy {
+    BooksAdapter(
+        app().imageApi.create(ImageEndpoint::class.java),
+        getSharedPreferences("knigopis", MODE_PRIVATE)
+    )
+  }
+  private val finishedBooksAdapter by lazy { booksAdapter.create(finishedBooks) }
+  private val plannedBooksAdapter by lazy { booksAdapter.create(plannedBooks) }
   private lateinit var usersView: RecyclerView
   private lateinit var finishedBooksView: RecyclerView
   private lateinit var plannedBooksView: RecyclerView
@@ -157,7 +162,7 @@ class MainActivity : AppCompatActivity() {
         .io2main()
         .subscribe({
           plannedBooks.clear()
-          plannedBooks.addAll(it)
+          plannedBooks.addAll(it.sortedBy { -it.priority })
           plannedBooksAdapter.notifyDataSetChanged()
         }, {
           logError("cannot load planned books", it)

+ 22 - 6
app/src/main/java/me/vadik/knigopis/adapters/BooksAdapter.kt

@@ -1,10 +1,12 @@
 package me.vadik.knigopis.adapters
 
+import android.content.SharedPreferences
 import android.view.View
 import android.widget.ImageView
 import android.widget.TextView
 import com.bumptech.glide.Glide
 import com.bumptech.glide.request.RequestOptions
+import io.reactivex.Single
 import me.vadik.knigopis.ImageEndpoint
 import me.vadik.knigopis.R
 import me.vadik.knigopis.io2main
@@ -12,18 +14,32 @@ import me.vadik.knigopis.logError
 import me.vadik.knigopis.model.Book
 import java.util.concurrent.TimeUnit
 
-class BooksAdapter(private val imageEndpoint: ImageEndpoint) {
+class BooksAdapter(
+    private val imageEndpoint: ImageEndpoint,
+    private val preferences: SharedPreferences
+) {
 
   fun create(books: List<Book>) = createAdapter<Book, View>(
       books,
       R.layout.book,
       Adapter(R.id.book_image) { book ->
-        imageEndpoint.searchImage("${book.title} ${book.author}")
-            .delay((Math.random() * 3000).toLong(), TimeUnit.MICROSECONDS)
-            .io2main()
-            .subscribe({ thumbnail ->
+        val cachedUrl = preferences.getString("book${book.id}", null)
+        Single.defer {
+          if (cachedUrl == null) {
+            imageEndpoint.searchImage("${book.title} ${book.author}")
+                .delay((Math.random() * 3000).toLong(), TimeUnit.MICROSECONDS)
+                .map { thumbnail ->
+                  ("https:" + thumbnail.url).also {
+                    preferences.edit().putString("book${book.id}", it).apply()
+                  }
+                }
+          } else {
+            Single.just(cachedUrl)
+          }
+        }.io2main()
+            .subscribe({ thumbnailUrl ->
               Glide.with(context)
-                  .load("https:" + thumbnail.url)
+                  .load(thumbnailUrl)
                   .apply(RequestOptions.circleCropTransform())
                   .into(this as ImageView)
             }, {

+ 1 - 3
app/src/main/java/me/vadik/knigopis/adapters/adapter.kt

@@ -11,7 +11,7 @@ class Adapter<in T, in V : View>(@IdRes val id: Int, val bind: V.(T) -> Unit)
 
 class ViewHolder(rootView: View, val views: List<*>) : RecyclerView.ViewHolder(rootView)
 
-fun <T, V : View> createAdapter(
+inline fun <T, reified V : View> createAdapter(
     items: List<T>,
     @LayoutRes itemLayout: Int,
     vararg adapters: Adapter<T, V>
@@ -20,14 +20,12 @@ fun <T, V : View> createAdapter(
       override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
           parent.inflate(itemLayout).let { rootView ->
             ViewHolder(rootView, adapters.map {
-              @Suppress("UNCHECKED_CAST")
               rootView.findViewById<View>(it.id) as V
             })
           }
 
       override fun onBindViewHolder(holder: ViewHolder, position: Int) =
           adapters.forEachIndexed { index, adapter ->
-            @Suppress("UNCHECKED_CAST")
             adapter.bind.invoke(holder.views[index] as V, items[position])
           }
 

+ 1 - 0
app/src/main/java/me/vadik/knigopis/model/Book.kt

@@ -1,6 +1,7 @@
 package me.vadik.knigopis.model
 
 interface Book {
+  val id: String
   val title: String
   val author: String
 }

+ 1 - 1
app/src/main/java/me/vadik/knigopis/model/FinishedBook.kt

@@ -1,7 +1,7 @@
 package me.vadik.knigopis.model
 
 class FinishedBook(
-    val id: String,
+    override val id: String,
     override val title: String,
     override val author: String,
     val notes: String,

+ 1 - 1
app/src/main/java/me/vadik/knigopis/model/PlannedBook.kt

@@ -1,7 +1,7 @@
 package me.vadik.knigopis.model
 
 class PlannedBook(
-    val id: String,
+    override val id: String,
     val userId: String,
     val createdAt: String,
     val updatedAt: String,

+ 1 - 1
app/src/main/res/values-ru/strings.xml

@@ -2,7 +2,7 @@
     <string name="app_name">Книгопись</string>
     <string name="title_home">Читают</string>
     <string name="title_done">Прочитано</string>
-    <string name="title_todo">Читать</string>
+    <string name="title_todo">К прочтению</string>
     <string name="option_login">Войти</string>
     <string name="option_logout">Выйти</string>
 </resources>