Răsfoiți Sursa

Moved sorting and grouping logic to separate organizer class

Vadik Sirekanyan 7 ani în urmă
părinte
comite
d92a29b15a

+ 6 - 57
app/src/main/java/me/vadik/knigopis/BookRepository.kt

@@ -5,9 +5,8 @@ import io.reactivex.Single
 import io.reactivex.rxkotlin.Singles
 import me.vadik.knigopis.api.Endpoint
 import me.vadik.knigopis.auth.KAuth
-import me.vadik.knigopis.common.ResourceProvider
+import me.vadik.knigopis.data.BookOrganizer
 import me.vadik.knigopis.model.*
-import java.util.*
 
 interface BookRepository {
 
@@ -22,28 +21,18 @@ interface BookRepository {
 class BookRepositoryImpl(
     private val api: Endpoint,
     private val auth: KAuth,
-    private val resources: ResourceProvider,
-    private val config: Configuration
+    private val plannedBookOrganizer: BookOrganizer<PlannedBook>,
+    private val finishedBookPrepare: BookOrganizer<FinishedBook>
 ) : BookRepository {
 
     override fun loadBooks(): Single<List<Pair<Book, BookHeader>>> =
         Singles.zip(
-            api.getPlannedBooks(auth.getAccessToken())
-                .map {
-                    if (config.sortingMode == 0) {
-                        it.sortedByDescending(PlannedBook::priority)
-                    } else {
-                        it.sortedByDescending(PlannedBook::updatedAt)
-                    }
-                }
-                .map { groupPlannedBooks(it) },
+            api.getPlannedBooks(auth.getAccessToken()),
             api.getFinishedBooks(auth.getAccessToken())
-                .map { it.sortedByDescending(FinishedBook::order) }
-                .map { groupFinishedBooks(it) }
         ).map { (planned, finished) ->
             mutableListOf<Pair<Book, BookHeader>>().apply {
-                addAll(planned)
-                addAll(finished)
+                addAll(plannedBookOrganizer.organize(planned))
+                addAll(finishedBookPrepare.organize(finished))
             }
         }
 
@@ -69,44 +58,4 @@ class BookRepositoryImpl(
             }
         }
 
-    private fun groupPlannedBooks(books: List<PlannedBook>): List<Pair<Book, BookHeader>> {
-        val result = mutableListOf<Pair<Book, BookHeader>>()
-        val doingBooks = books.filterNot { it.priority == 0 }
-        if (doingBooks.isNotEmpty()) {
-            val todoHeaderTitle = resources.getString(R.string.books_header_doing)
-            val doingHeader = BookHeader(todoHeaderTitle, doingBooks.size)
-            result.add(doingHeader to doingHeader)
-            result.addAll(doingBooks.map { it to doingHeader })
-        }
-        val todoBooks = books.filter { it.priority == 0 }
-        if (todoBooks.isNotEmpty()) {
-            val todoHeaderTitle = resources.getString(R.string.books_header_todo)
-            val todoHeader = BookHeader(todoHeaderTitle, todoBooks.size)
-            result.add(todoHeader to todoHeader)
-            result.addAll(todoBooks.map { it to todoHeader })
-        }
-        return result
-    }
-
-    private fun groupFinishedBooks(books: List<FinishedBook>): List<Pair<Book, BookHeader>> {
-        var first = true
-        return books.groupBy { it.readYear }
-            .toSortedMap(Comparator { year1, year2 ->
-                year2.compareTo(year1)
-            })
-            .flatMap { (year, books) ->
-                val headerTitle = when {
-                    year.isEmpty() -> resources.getString(R.string.books_header_done_other)
-                    first -> {
-                        first = false
-                        resources.getString(R.string.books_header_done_first, year)
-                    }
-                    else -> resources.getString(R.string.books_header_done, year)
-                }
-                val header = BookHeader(headerTitle, books.size)
-                val items = books.map { it to header }
-                listOf(header to header, *items.toTypedArray())
-            }
-    }
-
 }

+ 83 - 0
app/src/main/java/me/vadik/knigopis/data/BookOrganizer.kt

@@ -0,0 +1,83 @@
+package me.vadik.knigopis.data
+
+import me.vadik.knigopis.Configuration
+import me.vadik.knigopis.R
+import me.vadik.knigopis.common.ResourceProvider
+import me.vadik.knigopis.model.Book
+import me.vadik.knigopis.model.BookHeader
+import me.vadik.knigopis.model.FinishedBook
+import me.vadik.knigopis.model.PlannedBook
+
+interface BookOrganizer<T : Book> {
+
+    fun sort(books: List<T>): List<T>
+
+    fun group(books: List<T>): List<Pair<Book, BookHeader>>
+
+    fun organize(books: List<T>): List<Pair<Book, BookHeader>> =
+        group(sort(books))
+
+}
+
+class PlannedBookOrganizerImpl(
+    private val resources: ResourceProvider,
+    private val config: Configuration
+) : BookOrganizer<PlannedBook> {
+
+    override fun sort(books: List<PlannedBook>): List<PlannedBook> =
+        if (config.sortingMode == 0) {
+            books.sortedByDescending(PlannedBook::priority)
+        } else {
+            books.sortedByDescending(PlannedBook::updatedAt)
+        }
+
+    override fun group(books: List<PlannedBook>): List<Pair<Book, BookHeader>> {
+        val result = mutableListOf<Pair<Book, BookHeader>>()
+        val doingBooks = books.filterNot { it.priority == 0 }
+        if (doingBooks.isNotEmpty()) {
+            val todoHeaderTitle = resources.getString(R.string.books_header_doing)
+            val doingHeader = BookHeader(todoHeaderTitle, doingBooks.size)
+            result.add(doingHeader to doingHeader)
+            result.addAll(doingBooks.map { it to doingHeader })
+        }
+        val todoBooks = books.filter { it.priority == 0 }
+        if (todoBooks.isNotEmpty()) {
+            val todoHeaderTitle = resources.getString(R.string.books_header_todo)
+            val todoHeader = BookHeader(todoHeaderTitle, todoBooks.size)
+            result.add(todoHeader to todoHeader)
+            result.addAll(todoBooks.map { it to todoHeader })
+        }
+        return result
+    }
+
+}
+
+class FinishedBookPrepareImpl(
+    private val resources: ResourceProvider
+) : BookOrganizer<FinishedBook> {
+
+    override fun sort(books: List<FinishedBook>): List<FinishedBook> =
+        books.sortedByDescending(FinishedBook::order)
+
+    override fun group(books: List<FinishedBook>): List<Pair<Book, BookHeader>> {
+        var first = true
+        return books.groupBy { it.readYear }
+            .toSortedMap(Comparator { year1, year2 ->
+                year2.compareTo(year1)
+            })
+            .flatMap { (year, books) ->
+                val headerTitle = when {
+                    year.isEmpty() -> resources.getString(R.string.books_header_done_other)
+                    first -> {
+                        first = false
+                        resources.getString(R.string.books_header_done_first, year)
+                    }
+                    else -> resources.getString(R.string.books_header_done, year)
+                }
+                val header = BookHeader(headerTitle, books.size)
+                val items = books.map { it to header }
+                listOf(header to header, *items.toTypedArray())
+            }
+    }
+
+}

+ 8 - 1
app/src/main/java/me/vadik/knigopis/dependency/modules.kt

@@ -11,9 +11,14 @@ import me.vadik.knigopis.auth.KAuth
 import me.vadik.knigopis.auth.KAuthImpl
 import me.vadik.knigopis.common.ResourceProvider
 import me.vadik.knigopis.common.ResourceProviderImpl
+import me.vadik.knigopis.data.BookOrganizer
+import me.vadik.knigopis.data.FinishedBookPrepareImpl
+import me.vadik.knigopis.data.PlannedBookOrganizerImpl
 import me.vadik.knigopis.dialog.BottomSheetDialogFactory
 import me.vadik.knigopis.dialog.DialogFactory
+import me.vadik.knigopis.model.FinishedBook
 import me.vadik.knigopis.model.ImageThumbnail
+import me.vadik.knigopis.model.PlannedBook
 import me.vadik.knigopis.user.UserInteractor
 import me.vadik.knigopis.user.UserInteractorImpl
 import okhttp3.OkHttpClient
@@ -29,11 +34,13 @@ private const val IMAGE_API_URL = "https://api.qwant.com/api/"
 private const val DATE_FORMAT = "yyyy-MM-dd HH:mm:ss"
 
 val appModule = applicationContext {
-    bean { BookRepositoryImpl(get(), get(), get(), get()) as BookRepository }
+    bean { BookRepositoryImpl(get(), get(), get("planned"), get("finished")) as BookRepository }
     bean { BookCoverSearchImpl(get(), BookCoverCacheImpl(get())) as BookCoverSearch }
     bean { KAuthImpl(get(), get()) as KAuth }
     bean { createMainEndpoint() }
     bean { createImageEndpoint() }
+    bean("planned") { PlannedBookOrganizerImpl(get(), get()) as BookOrganizer<PlannedBook> }
+    bean("finished") { FinishedBookPrepareImpl(get()) as BookOrganizer<FinishedBook> }
     bean { ConfigurationImpl(get()) as Configuration }
     bean { ResourceProviderImpl(get()) as ResourceProvider }
     factory { BottomSheetDialogFactory(it["activity"]) as DialogFactory }