Inject repository in the Article Fragment

The Repository is now injected in the Article Fragment and the DateUtils class was modified not to rely on apiDetailsService
This commit is contained in:
davide 2022-07-21 15:19:22 +02:00
parent 9373024147
commit 7221f11f80
9 changed files with 54 additions and 39 deletions

View File

@ -48,6 +48,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActiv
import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.android.utils.persistence.toEntity
import bou.amine.apps.readerforselfossv2.android.utils.persistence.toView
import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.utils.DateUtils
import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
@ -150,6 +151,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
override val di by closestDI()
private val apiDetailsService : ApiDetailsService by instance()
private val repository : Repository by instance()
data class DrawerData(val tags: List<SelfossModel.Tag>?, val sources: List<SelfossModel.Source>?)
@ -201,7 +203,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
)
dataBase = AndroidDeviceDatabase(applicationContext)
searchService = SearchService(DateUtils(apiDetailsService))
searchService = SearchService(DateUtils(repository.apiMajorVersion))
dbService = AndroidDeviceDatabaseService(dataBase, searchService)
service = SelfossService(api, dbService, searchService)
items = ArrayList()

View File

@ -27,7 +27,7 @@ class MyApp : MultiDexApplication(), DIAware {
override val di by DI.lazy {
import(networkModule)
bind<Repository>() with singleton { RepositoryImpl(instance()) }
bind<Repository>() with singleton { RepositoryImpl(instance(), instance()) }
}
private lateinit var config: Config

View File

@ -71,7 +71,7 @@ class ItemCardAdapter(
binding.title.setLinkTextColor(appColors.colorAccent)
binding.sourceTitleAndDate.text = itm.sourceAndDateText(DateUtils(apiDetailsService))
binding.sourceTitleAndDate.text = itm.sourceAndDateText(DateUtils(repository.apiMajorVersion))
if (!fullHeightCards) {
binding.itemImage.maxHeight = imageMaxHeight

View File

@ -59,7 +59,7 @@ class ItemListAdapter(
binding.title.setLinkTextColor(appColors.colorAccent)
binding.sourceTitleAndDate.text = itm.sourceAndDateText(DateUtils(apiDetailsService))
binding.sourceTitleAndDate.text = itm.sourceAndDateText(DateUtils(repository.apiMajorVersion))
if (itm.getThumbnail(apiDetailsService.getBaseUrl()).isEmpty()) {

View File

@ -24,6 +24,7 @@ import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATIO
import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_3_4
import bou.amine.apps.readerforselfossv2.android.utils.Config
import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.rest.SelfossModel
@ -46,6 +47,7 @@ class LoadingWorker(val context: Context, params: WorkerParameters) : Worker(con
override val di by lazy { (applicationContext as MyApp).di }
private val apiDetailsService : ApiDetailsService by instance()
private val repository : Repository by instance()
override fun doWork(): Result {
val settings = Settings()
@ -59,7 +61,7 @@ override fun doWork(): Result {
apiDetailsService
)
val dateUtils = DateUtils(apiDetailsService)
val dateUtils = DateUtils(repository.apiMajorVersion)
val searchService = SearchService(dateUtils)
val service = SelfossService(api, AndroidDeviceDatabaseService(AndroidDeviceDatabase(applicationContext), searchService), searchService)

View File

@ -9,7 +9,10 @@ import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Bundle
import android.view.*
import android.webkit.*
import android.webkit.WebResourceResponse
import android.webkit.WebSettings
import android.webkit.WebView
import android.webkit.WebViewClient
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.browser.customtabs.CustomTabsIntent
@ -23,10 +26,7 @@ import bou.amine.apps.readerforselfossv2.android.api.mercury.MercuryApi
import bou.amine.apps.readerforselfossv2.android.api.mercury.ParsedContent
import bou.amine.apps.readerforselfossv2.android.databinding.FragmentArticleBinding
import bou.amine.apps.readerforselfossv2.android.model.*
import bou.amine.apps.readerforselfossv2.android.persistence.AndroidDeviceDatabase
import bou.amine.apps.readerforselfossv2.android.persistence.AndroidDeviceDatabaseService
import bou.amine.apps.readerforselfossv2.android.persistence.database.AppDatabase
import bou.amine.apps.readerforselfossv2.android.persistence.entities.AndroidItemEntity
import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_1_2
import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_2_3
import bou.amine.apps.readerforselfossv2.android.persistence.migrations.MIGRATION_3_4
@ -36,11 +36,8 @@ import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActiv
import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream
import bou.amine.apps.readerforselfossv2.android.utils.glide.loadMaybeBasicAuth
import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailable
import bou.amine.apps.readerforselfossv2.rest.SelfossApiImpl
import bou.amine.apps.readerforselfossv2.repository.Repository
import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import bou.amine.apps.readerforselfossv2.service.SearchService
import bou.amine.apps.readerforselfossv2.service.SelfossService
import bou.amine.apps.readerforselfossv2.utils.DateUtils
import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString
import com.bumptech.glide.Glide
@ -52,8 +49,10 @@ import com.russhwolf.settings.Settings
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.kodein.di.*
import org.kodein.di.DI
import org.kodein.di.DIAware
import org.kodein.di.android.x.closestDI
import org.kodein.di.instance
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
@ -63,8 +62,6 @@ import java.util.*
import java.util.concurrent.ExecutionException
class ArticleFragment : Fragment(), DIAware {
private lateinit var dbService: AndroidDeviceDatabaseService
private lateinit var service: SelfossService<AndroidItemEntity>
private var fontSize: Int = 16
private lateinit var item: SelfossModel.Item
private var mCustomTabActivityHelper: CustomTabActivityHelper? = null
@ -83,7 +80,7 @@ class ArticleFragment : Fragment(), DIAware {
private val binding get() = _binding!!
override val di : DI by closestDI()
private val apiDetailsService : ApiDetailsService by instance()
private val repository: Repository by instance()
private var settings = Settings()
@ -105,10 +102,6 @@ class ArticleFragment : Fragment(), DIAware {
super.onCreate(savedInstanceState)
dbService = AndroidDeviceDatabaseService(AndroidDeviceDatabase(requireContext()), SearchService(DateUtils(apiDetailsService)))
service = SelfossService(SelfossApiImpl(apiDetailsService), dbService, SearchService(DateUtils(apiDetailsService)))
val pi: ParecelableItem = requireArguments().getParcelable(ARG_ITEMS)!!
item = pi.toModel()
@ -130,8 +123,8 @@ class ArticleFragment : Fragment(), DIAware {
url = item.getLinkDecoded()
contentText = item.content
contentTitle = item.getTitleDecoded()
contentImage = item.getThumbnail(apiDetailsService.getBaseUrl())
contentSource = item.sourceAndDateText(DateUtils(apiDetailsService))
contentImage = item.getThumbnail(repository.baseUrl)
contentSource = item.sourceAndDateText(DateUtils(repository.apiMajorVersion))
allImages = item.getImages()
fontSize = settings.getString("reader_font_size", "16").toInt()
@ -151,14 +144,6 @@ class ArticleFragment : Fragment(), DIAware {
refreshAlignment()
val api = SelfossApiImpl(
// requireContext(),
// requireActivity(),
// settings.getBoolean("isSelfSignedCert", false),
// prefs.getString("api_timeout", "-1")!!.toLong()
apiDetailsService
)
fab = binding.fab
fab.backgroundTintList = ColorStateList.valueOf(appColors.colorAccent)
@ -185,8 +170,7 @@ class ArticleFragment : Fragment(), DIAware {
R.id.unread_action -> if (context != null) {
if (this@ArticleFragment.item.unread) {
CoroutineScope(Dispatchers.IO).launch {
api.markAsRead(this@ArticleFragment.item.id.toString())
// TODO: Update in DB
repository.markAsRead(this@ArticleFragment.item.id.toString())
}
this@ArticleFragment.item.unread = false
Toast.makeText(
@ -196,8 +180,7 @@ class ArticleFragment : Fragment(), DIAware {
).show()
} else {
CoroutineScope(Dispatchers.IO).launch {
api.unmarkAsRead(this@ArticleFragment.item.id.toString())
// TODO: Update in DB
repository.unmarkAsRead(this@ArticleFragment.item.id.toString())
}
this@ArticleFragment.item.unread = true
Toast.makeText(

View File

@ -7,8 +7,11 @@ interface Repository {
// TODO: remove the items variables in favor of storing everything in the database
var items: List<SelfossModel.Item>
var selectedItems: List<SelfossModel.Item>
var baseUrl: String
// API
var apiMajorVersion: Int
fun getMoreItems(): List<SelfossModel.Item>
fun stats(): SelfossModel.Stats
fun getTags(): List<SelfossModel.Tag>

View File

@ -2,14 +2,28 @@ package bou.amine.apps.readerforselfossv2.repository
import bou.amine.apps.readerforselfossv2.rest.SelfossApi
import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import com.russhwolf.settings.Settings
import io.github.aakira.napier.Napier
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
class RepositoryImpl(private val api: SelfossApi) : Repository {
class RepositoryImpl(private val api: SelfossApi, private val apiDetails: ApiDetailsService) : Repository {
val settings = Settings()
override lateinit var items: List<SelfossModel.Item>
override lateinit var selectedItems: List<SelfossModel.Item>
override var baseUrl = apiDetails.getBaseUrl()
override var apiMajorVersion = 0
init {
// TODO: Dispatchers.IO not available in KMM, an alternative solution should be found
CoroutineScope(Dispatchers.Main).launch {
updateApiVersion()
}
}
override fun getMoreItems(): List<SelfossModel.Item> {
TODO("Not yet implemented")
@ -92,5 +106,17 @@ class RepositoryImpl(private val api: SelfossApi) : Repository {
override fun refreshLoginInformation() {
api.refreshLoginInformation()
baseUrl = apiDetails.getBaseUrl()
}
private suspend fun updateApiVersion() {
// TODO: Handle connectivity issues
val fetchedVersion = api.version()
if (fetchedVersion != null) {
apiMajorVersion = fetchedVersion.getApiMajorVersion()
settings.putInt("apiVersionMajor", apiMajorVersion)
} else {
apiMajorVersion = settings.getInt("apiVersionMajor", 0)
}
}
}

View File

@ -2,7 +2,6 @@ package bou.amine.apps.readerforselfossv2.utils
import android.text.format.DateUtils
import bou.amine.apps.readerforselfossv2.rest.SelfossModel
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
import java.time.Instant
import java.time.LocalDateTime
import java.time.OffsetDateTime
@ -15,12 +14,12 @@ fun SelfossModel.Item.parseDate(dateUtils: bou.amine.apps.readerforselfossv2.uti
fun SelfossModel.Item.parseRelativeDate(dateUtils: bou.amine.apps.readerforselfossv2.utils.DateUtils): String =
dateUtils.parseRelativeDate(this.datetime)
class DateUtils(private val apiDetailsService: ApiDetailsService) {
class DateUtils(private val apiMajorVersion: Int) {
fun parseDate(dateString: String): Instant {
val FORMATTERV1 = "yyyy-MM-dd HH:mm:ss"
return if (apiDetailsService.getApiVersion() >= 4) {
return if (apiMajorVersion >= 4) {
OffsetDateTime.parse(dateString).toInstant()
} else {
LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern(FORMATTERV1)).toInstant(ZoneOffset.UTC)