diff --git a/androidApp/src/main/AndroidManifest.xml b/androidApp/src/main/AndroidManifest.xml index f2e3130..5ef39dd 100644 --- a/androidApp/src/main/AndroidManifest.xml +++ b/androidApp/src/main/AndroidManifest.xml @@ -68,10 +68,6 @@ android:name=".ImageActivity"> - - diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt index fc9acb5..0c7093c 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/AddSourceActivity.kt @@ -12,7 +12,7 @@ import bou.amine.apps.readerforselfossv2.android.themes.Toppings import bou.amine.apps.readerforselfossv2.android.utils.isBaseUrlValid import bou.amine.apps.readerforselfossv2.model.NetworkUnavailableException import bou.amine.apps.readerforselfossv2.repository.Repository -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.ftinc.scoop.Scoop import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -31,7 +31,7 @@ class AddSourceActivity : AppCompatActivity(), DIAware { override val di by closestDI() private val repository : Repository by instance() - private val apiDetailsService : ApiDetailsService by instance() + private val appSettingsService : AppSettingsService by instance() override fun onCreate(savedInstanceState: Bundle?) { appColors = AppColors(this@AddSourceActivity) @@ -83,7 +83,7 @@ class AddSourceActivity : AppCompatActivity(), DIAware { override fun onResume() { super.onResume() - val baseUrl = apiDetailsService.getBaseUrl() + val baseUrl = appSettingsService.getBaseUrl() if (baseUrl.isEmpty() || !baseUrl.isBaseUrlValid(this@AddSourceActivity)) { mustLoginToAddSource() } else { diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt index 51e32ca..8d35cdd 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/HomeActivity.kt @@ -35,7 +35,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.bottombar.removeBadge import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActivityHelper import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.* import com.ashokvarma.bottomnavigation.BottomNavigationBar import com.ashokvarma.bottomnavigation.BottomNavigationItem @@ -69,7 +69,6 @@ import kotlin.concurrent.thread class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAware { - private val MENU_PREFERENCES = 12302 private val DRAWER_ID_TAGS = 100101L private val DRAWER_ID_HIDDEN_TAGS = 101100L private val DRAWER_ID_SOURCES = 100110L @@ -77,21 +76,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar private var items: ArrayList = ArrayList() - private var internalBrowser = false - private var articleViewer = false - private var shouldBeCardView = false - private var displayUnreadCount = false - private var displayAllCount = false - private var fullHeightCards: Boolean = false private var elementsShown: ItemType = ItemType.UNREAD private var lastFetchDone: Boolean = false - private var updateSources: Boolean = true - private var markOnScroll: Boolean = false - private var hiddenTags: List = emptyList() - - private var periodicRefresh = false - private var refreshMinutes: Long = 360L - private var refreshWhenChargingOnly = false private lateinit var tabNewBadge: TextBadgeItem private lateinit var tabArchiveBadge: TextBadgeItem @@ -101,7 +87,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar private var offset: Int = 0 private var firstVisible: Int = 0 private lateinit var recyclerViewScrollListener: RecyclerView.OnScrollListener - private var settings = Settings() private lateinit var binding: ActivityHomeBinding private var recyclerAdapter: RecyclerView.Adapter<*>? = null @@ -112,6 +97,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar override val di by closestDI() private val repository : Repository by instance() + private val appSettingsService : AppSettingsService by instance() data class DrawerData(val tags: List?, val sources: List?) @@ -121,6 +107,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } override fun onCreate(savedInstanceState: Bundle?) { + + // Add appcolors to DI appColors = AppColors(this@HomeActivity) super.onCreate(savedInstanceState) @@ -152,8 +140,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar handleSwipeRefreshLayout() - handleSettings() - getElementsAccordingToTab() @@ -292,7 +278,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar override fun onResume() { super.onResume() - // TODO: Make this the only appcolors init appColors = AppColors(this@HomeActivity) handleDrawerItems() @@ -301,10 +286,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar reloadLayoutManager() - if (!settings.getBoolean("infinite_loading", false)) { - binding.recyclerView.setHasFixedSize(true) - } else { + if (appSettingsService.isInfiniteLoadingEnabled()) { handleInfiniteScroll() + } else { + binding.recyclerView.setHasFixedSize(true) } handleBottomBarActions() @@ -323,31 +308,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar customTabActivityHelper.unbindCustomTabsService(this) } - private fun handleSettings() { - // TODO : clean this - internalBrowser = settings.getBoolean("prefer_internal_browser", true) - articleViewer = settings.getBoolean("prefer_article_viewer", true) - shouldBeCardView = settings.getBoolean("card_view_active", false) - displayUnreadCount = settings.getBoolean("display_unread_count", true) - displayAllCount = settings.getBoolean("display_other_count", false) - fullHeightCards = settings.getBoolean("full_height_cards", false) - - updateSources = settings.getBoolean("update_sources", true) - markOnScroll = settings.getBoolean("mark_on_scroll", false) - hiddenTags = if (settings.getString("hidden_tags", "").isNotEmpty()) { - settings.getString("hidden_tags", "").replace("\\s".toRegex(), "").split(",") - } else { - emptyList() - } - periodicRefresh = settings.getBoolean("periodic_refresh", false) - refreshWhenChargingOnly = settings.getBoolean("refresh_when_charging", false) - refreshMinutes = settings.getString("periodic_refresh_minutes", "360").toLong() - - if (refreshMinutes <= 15) { - refreshMinutes = 15 - } - } - private fun handleThemeBinding() { val scoop = Scoop.getInstance() scoop.bind(this, Toppings.PRIMARY.value, binding.toolBar) @@ -401,16 +361,13 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar binding.drawerContainer.addDrawerListener(drawerListener) - val displayAccountHeader = - settings.getBoolean("account_header_displaying", false) - binding.mainDrawer.addStickyFooterItem( PrimaryDrawerItem().apply { nameRes = R.string.drawer_report_bug iconRes = R.drawable.ic_bug_report_black_24dp isIconTinted = true onDrawerItemClickListener = { _, _, _ -> - val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(ApiDetailsService.trackerUrl)) + val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(AppSettingsService.trackerUrl)) startActivity(browserIntent) false } @@ -427,12 +384,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } }) - if (displayAccountHeader) { + if (appSettingsService.isDisplayAccountHeaderEnabled()) { AccountHeaderView(this).apply { attachToSliderView(binding.mainDrawer) addProfiles( ProfileDrawerItem().apply { - nameText = settings.getString("url", "") + nameText = appSettingsService.getBaseUrl() setBackgroundResource(R.drawable.bg) iconRes = R.mipmap.ic_launcher selectionListEnabledForSingleProfile = false @@ -496,7 +453,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } } else { val filteredTags = maybeTags - .filterNot { hiddenTags.contains(it.tag) } + .filterNot { appSettingsService.getHiddenTags().contains(it.tag) } .sortedBy { it.unread == 0 } tagsBadge = filteredTags.map { createDrawerItem(it) @@ -518,7 +475,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } } else { val filteredHiddenTags: List = - maybeTags.filter { hiddenTags.contains(it.tag) } + maybeTags.filter { appSettingsService.getHiddenTags().contains(it.tag) } tagsBadge = filteredHiddenTags.map { createDrawerItem(it) @@ -574,7 +531,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } } ) - if (hiddenTags.isNotEmpty()) { + if (appSettingsService.getHiddenTags().isNotEmpty()) { binding.mainDrawer.itemAdapter.add( DividerDrawerItem(), SecondaryDrawerItem().apply { @@ -707,7 +664,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar // This will only update the layout manager if settings changed when (currentManager) { is StaggeredGridLayoutManager -> - if (!shouldBeCardView) { + if (!appSettingsService.isCardViewEnabled()) { layoutManager = GridLayoutManager( this, calculateNoOfColumns() @@ -715,7 +672,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar binding.recyclerView.layoutManager = layoutManager } is GridLayoutManager -> - if (shouldBeCardView) { + if (appSettingsService.isCardViewEnabled()) { layoutManager = StaggeredGridLayoutManager( calculateNoOfColumns(), StaggeredGridLayoutManager.VERTICAL @@ -726,7 +683,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } else -> if (currentManager == null) { - if (!shouldBeCardView) { + if (!appSettingsService.isCardViewEnabled()) { layoutManager = GridLayoutManager( this, calculateNoOfColumns() @@ -862,15 +819,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } if (recyclerAdapter == null) { - if (shouldBeCardView) { + if (appSettingsService.isCardViewEnabled()) { recyclerAdapter = ItemCardAdapter( this, items, customTabActivityHelper, - internalBrowser, // TODO remove and use from apidetailsservice - articleViewer, // TODO remove and use from apidetailsservice - fullHeightCards, // TODO remove and use from apidetailsservice appColors, ) { updateItems(it) @@ -881,8 +835,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar this, items, customTabActivityHelper, - internalBrowser, // TODO remove and use from apidetailsservice - articleViewer, // TODO remove and use from apidetailsservice appColors, ) { updateItems(it) @@ -905,7 +857,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } private fun reloadBadges() { - if (displayUnreadCount || displayAllCount) { + if (appSettingsService.isDisplayUnreadCountEnabled() || appSettingsService.isDisplayAllCountEnabled()) { CoroutineScope(Dispatchers.Main).launch { repository.reloadBadges() reloadBadgeContent() @@ -914,12 +866,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } private fun reloadBadgeContent() { - if (displayUnreadCount) { + if (appSettingsService.isDisplayUnreadCountEnabled()) { tabNewBadge .setText(repository.badgeUnread.toString()) .maybeShow() } - if (displayAllCount) { + if (appSettingsService.isDisplayAllCountEnabled()) { tabArchiveBadge .setText(repository.badgeAll.toString()) .maybeShow() @@ -1038,8 +990,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar return true } R.id.action_disconnect -> { - val settings = Settings() - settings.clear() + appSettingsService.clearAll() val intent = Intent(this, LoginActivity::class.java) this.startActivity(intent) this@HomeActivity.finish() @@ -1062,15 +1013,15 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar } private fun handleRecurringTask() { - if (periodicRefresh) { + if (appSettingsService.isPeriodicRefreshEnabled()) { val myConstraints = Constraints.Builder() .setRequiresBatteryNotLow(true) - .setRequiresCharging(refreshWhenChargingOnly) + .setRequiresCharging(appSettingsService.isRefreshWhenChargingOnlyEnabled()) .setRequiresStorageNotLow(true) .build() val backgroundWork = - PeriodicWorkRequestBuilder(refreshMinutes, TimeUnit.MINUTES) + PeriodicWorkRequestBuilder(appSettingsService.getRefreshMinutes(), TimeUnit.MINUTES) .setConstraints(myConstraints) .addTag("selfoss-loading") .build() @@ -1078,9 +1029,5 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar WorkManager.getInstance(baseContext).enqueueUniquePeriodicWork("selfoss-loading", ExistingPeriodicWorkPolicy.KEEP, backgroundWork) } } - - private fun handleOfflineActions() { - - } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt index 544325f..9edfc96 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/LoginActivity.kt @@ -16,8 +16,8 @@ import bou.amine.apps.readerforselfossv2.android.databinding.ActivityLoginBindin import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.utils.isBaseUrlValid import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.mikepenz.aboutlibraries.LibsBuilder -import com.russhwolf.settings.Settings import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -25,19 +25,19 @@ import org.kodein.di.DIAware import org.kodein.di.android.closestDI import org.kodein.di.instance -class LoginActivity() : AppCompatActivity(), DIAware { +class LoginActivity : AppCompatActivity(), DIAware { private var inValidCount: Int = 0 private var isWithSelfSignedCert = false private var isWithLogin = false private var isWithHTTPLogin = false - private val settings = Settings() private lateinit var appColors: AppColors private lateinit var binding: ActivityLoginBinding override val di by closestDI() private val repository : Repository by instance() + private val appSettingsService : AppSettingsService by instance() override fun onCreate(savedInstanceState: Bundle?) { appColors = AppColors(this@LoginActivity) @@ -52,7 +52,7 @@ class LoginActivity() : AppCompatActivity(), DIAware { handleBaseUrlFail() - if (settings.getString("url", "").isNotEmpty()) { + if (appSettingsService.getBaseUrl().isNotEmpty()) { goToMain() } @@ -117,11 +117,8 @@ class LoginActivity() : AppCompatActivity(), DIAware { } private fun preferenceError(t: Throwable) { - settings.remove("url") - settings.remove("login") - settings.remove("httpUserName") - settings.remove("password") - settings.remove("httpPassword") + appSettingsService.resetLoginInformation() + binding.urlView.error = getString(R.string.wrong_infos) binding.loginView.error = getString(R.string.wrong_infos) binding.passwordView.error = getString(R.string.wrong_infos) @@ -199,7 +196,7 @@ class LoginActivity() : AppCompatActivity(), DIAware { } else { showProgress(true) - repository.refreshLoginInformation(url, login, password, httpLogin, httpPassword, isWithSelfSignedCert) + repository.refreshLoginInformation(url, login, password, isWithSelfSignedCert) CoroutineScope(Dispatchers.IO).launch { val result = repository.login() diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt index 9ad4e7e..8acb314 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/MyApp.kt @@ -18,7 +18,7 @@ import bou.amine.apps.readerforselfossv2.android.viewmodel.AppViewModel import bou.amine.apps.readerforselfossv2.dao.DriverFactory import bou.amine.apps.readerforselfossv2.dao.ReaderForSelfossDB import bou.amine.apps.readerforselfossv2.repository.Repository -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.bumptech.glide.Glide import com.bumptech.glide.request.RequestOptions import com.ftinc.scoop.Scoop @@ -48,12 +48,10 @@ class MyApp : MultiDexApplication(), DIAware { private val viewModel: AppViewModel by instance() private val connectivityStatus: ConnectivityStatus by instance() private val driverFactory: DriverFactory by instance() - private lateinit var settings : Settings override fun onCreate() { super.onCreate() Napier.base(DebugAntilog()) - settings = Settings() initDrawerImageLoader() @@ -90,11 +88,11 @@ class MyApp : MultiDexApplication(), DIAware { val name = getString(R.string.notification_channel_sync) val importance = NotificationManager.IMPORTANCE_LOW - val mChannel = NotificationChannel(ApiDetailsService.syncChannelId, name, importance) + val mChannel = NotificationChannel(AppSettingsService.syncChannelId, name, importance) val newItemsChannelname = getString(R.string.new_items_channel_sync) val newItemsChannelimportance = NotificationManager.IMPORTANCE_DEFAULT - val newItemsChannelmChannel = NotificationChannel(ApiDetailsService.newItemsChannelId, newItemsChannelname, newItemsChannelimportance) + val newItemsChannelmChannel = NotificationChannel(AppSettingsService.newItemsChannelId, newItemsChannelname, newItemsChannelimportance) notificationManager.createNotificationChannel(mChannel) notificationManager.createNotificationChannel(newItemsChannelmChannel) diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt index 125940e..e87aa44 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/ReaderActivity.kt @@ -16,8 +16,8 @@ import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.Toppings import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.ftinc.scoop.Scoop -import com.russhwolf.settings.Settings import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -27,7 +27,6 @@ import org.kodein.di.instance class ReaderActivity : AppCompatActivity(), DIAware { - private var markOnScroll: Boolean = false private var currentItem: Int = 0 private lateinit var appColors: AppColors @@ -35,12 +34,9 @@ class ReaderActivity : AppCompatActivity(), DIAware { private lateinit var binding: ActivityReaderBinding - private var activeAlignment: Int = 1 - private val JUSTIFY = 1 - private val ALIGN_LEFT = 2 - override val di by closestDI() private val repository: Repository by instance() + private val appSettingsService: AppSettingsService by instance() private fun showMenuItem(willAddToFavorite: Boolean) { if (willAddToFavorite) { @@ -58,8 +54,6 @@ class ReaderActivity : AppCompatActivity(), DIAware { showMenuItem(false) } - private var settings = Settings() - override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) appColors = AppColors(this) @@ -76,9 +70,6 @@ class ReaderActivity : AppCompatActivity(), DIAware { supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setDisplayShowHomeEnabled(true) - markOnScroll = settings.getBoolean("mark_on_scroll", false) - activeAlignment = settings.getInt("text_align", JUSTIFY) - if (allItems.isEmpty()) { finish() } @@ -98,10 +89,9 @@ class ReaderActivity : AppCompatActivity(), DIAware { } private fun readItem(item: SelfossModel.Item) { - if (markOnScroll) { + if (appSettingsService.isMarkOnScrollEnabled()) { CoroutineScope(Dispatchers.IO).launch { repository.markAsRead(item) - // TODO: Handle failure } } } @@ -142,7 +132,7 @@ class ReaderActivity : AppCompatActivity(), DIAware { } private fun alignmentMenu() { - val showJustify = activeAlignment == ALIGN_LEFT + val showJustify = appSettingsService.getActiveAllignment() == AppSettingsService.ALIGN_LEFT toolbarMenu.findItem(R.id.align_left).isVisible = !showJustify toolbarMenu.findItem(R.id.align_justify).isVisible = showJustify } @@ -211,21 +201,19 @@ class ReaderActivity : AppCompatActivity(), DIAware { } } R.id.align_left -> { - activeAlignment = ALIGN_LEFT - switchAlignmentSetting() + switchAlignmentSetting(AppSettingsService.ALIGN_LEFT) refreshFragment() } R.id.align_justify -> { - activeAlignment = JUSTIFY - switchAlignmentSetting() + switchAlignmentSetting(AppSettingsService.JUSTIFY) refreshFragment() } } return super.onOptionsItemSelected(item) } - private fun switchAlignmentSetting() { - settings.putInt("text_align", activeAlignment) + private fun switchAlignmentSetting(allignment: Int) { + appSettingsService.changeAllignment(allignment) alignmentMenu() } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt index 36ef496..94f004c 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemCardAdapter.kt @@ -17,6 +17,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getIcon import bou.amine.apps.readerforselfossv2.utils.getThumbnail @@ -34,9 +35,6 @@ class ItemCardAdapter( override val app: Activity, override var items: ArrayList, private val helper: CustomTabActivityHelper, - private val internalBrowser: Boolean, - private val articleViewer: Boolean, - private val fullHeightCards: Boolean, override val appColors: AppColors, override val updateItems: (ArrayList) -> Unit ) : ItemsAdapter() { @@ -47,6 +45,7 @@ class ItemCardAdapter( override val di: DI by closestDI(app) override val repository : Repository by instance() + override val appSettingsService : AppSettingsService by instance() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = CardItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) @@ -66,7 +65,7 @@ class ItemCardAdapter( binding.sourceTitleAndDate.text = itm.sourceAndDateText(repository.dateUtils) - if (!fullHeightCards) { + if (!appSettingsService.isFullHeightCardsEnabled()) { binding.itemImage.maxHeight = imageMaxHeight binding.itemImage.scaleType = ScaleType.CENTER_CROP } @@ -146,8 +145,8 @@ class ItemCardAdapter( bindingAdapterPosition, items[bindingAdapterPosition].getLinkDecoded(), customTabsIntent, - internalBrowser, - articleViewer, + appSettingsService.isInternalBrowserEnabled(), + appSettingsService.isArticleViewerEnabled(), app ) } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt index 6a9f30a..1cee1ff 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemListAdapter.kt @@ -14,6 +14,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapCenterCrop import bou.amine.apps.readerforselfossv2.android.utils.glide.circularBitmapDrawable import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getIcon import bou.amine.apps.readerforselfossv2.utils.getThumbnail @@ -27,8 +28,6 @@ class ItemListAdapter( override val app: Activity, override var items: ArrayList, private val helper: CustomTabActivityHelper, - private val internalBrowser: Boolean, - private val articleViewer: Boolean, override val appColors: AppColors, override val updateItems: (ArrayList) -> Unit ) : ItemsAdapter() { @@ -37,6 +36,7 @@ class ItemListAdapter( override val di: DI by closestDI(app) override val repository : Repository by instance() + override val appSettingsService : AppSettingsService by instance() override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { val binding = ListItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) @@ -94,8 +94,8 @@ class ItemListAdapter( bindingAdapterPosition, items[bindingAdapterPosition].getLinkDecoded(), customTabsIntent, - internalBrowser, - articleViewer, + appSettingsService.isInternalBrowserEnabled(), + appSettingsService.isArticleViewerEnabled(), app ) } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt index 99b8002..e72c9b8 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/adapters/ItemsAdapter.kt @@ -8,6 +8,7 @@ import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.ItemType import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.CoroutineScope @@ -18,6 +19,7 @@ import org.kodein.di.DIAware abstract class ItemsAdapter : RecyclerView.Adapter(), DIAware { abstract var items: ArrayList abstract val repository: Repository + abstract val appSettingsService: AppSettingsService abstract val app: Activity abstract val appColors: AppColors abstract val updateItems: (ArrayList) -> Unit @@ -92,8 +94,6 @@ abstract class ItemsAdapter : RecyclerView.Adapte private fun unreadItemAtIndex(position: Int, showSnackbar: Boolean = true) { CoroutineScope(Dispatchers.IO).launch { repository.unmarkAsRead(items[position]) - // Todo: SharedItems.unreadItem(app, api, db, items[position]) - // TODO: update db } notifyItemChanged(position) diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt index c86de60..82c4476 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/background/background.kt @@ -17,7 +17,7 @@ import bou.amine.apps.readerforselfossv2.android.model.preloadImages import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAccessible import bou.amine.apps.readerforselfossv2.model.SelfossModel import bou.amine.apps.readerforselfossv2.repository.Repository -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.russhwolf.settings.Settings import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -31,33 +31,32 @@ class LoadingWorker(val context: Context, params: WorkerParameters) : Worker(con override val di by lazy { (applicationContext as MyApp).di } private val repository : Repository by instance() + private val appSettingsService : AppSettingsService by instance() override fun doWork(): Result { - val settings = Settings() - val periodicRefresh = settings.getBoolean("periodic_refresh", false) - if (periodicRefresh && isNetworkAccessible(context)) { + if (appSettingsService.isPeriodicRefreshEnabled() && isNetworkAccessible(context)) { CoroutineScope(Dispatchers.IO).launch { val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager val notification = - NotificationCompat.Builder(applicationContext, ApiDetailsService.syncChannelId) + NotificationCompat.Builder(applicationContext, AppSettingsService.syncChannelId) .setContentTitle(context.getString(R.string.loading_notification_title)) .setContentText(context.getString(R.string.loading_notification_text)) .setOngoing(true) .setPriority(PRIORITY_LOW) - .setChannelId(ApiDetailsService.syncChannelId) + .setChannelId(AppSettingsService.syncChannelId) .setSmallIcon(R.drawable.ic_stat_cloud_download_black_24dp) notificationManager.notify(1, notification.build()) - val notifyNewItems = settings.getBoolean("notify_new_items", false) - repository.handleDBActions() - launch { - handleNewItemsNotification(repository.tryToCacheItemsAndGetNewOnes(), notifyNewItems, notificationManager) + if (appSettingsService.isNotifyNewItemsEnabled()) { + launch { + handleNewItemsNotification(repository.tryToCacheItemsAndGetNewOnes(), notificationManager) + } } } } @@ -66,7 +65,6 @@ override fun doWork(): Result { private fun handleNewItemsNotification( newItems: List?, - notifyNewItems: Boolean, notificationManager: NotificationManager ) { CoroutineScope(Dispatchers.IO).launch { @@ -74,7 +72,7 @@ override fun doWork(): Result { val newSize = apiItems.filter { it.unread }.size - if (notifyNewItems && newSize > 0) { + if (newSize > 0) { val intent = Intent(context, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK @@ -87,7 +85,7 @@ override fun doWork(): Result { val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, pflags) val newItemsNotification = - NotificationCompat.Builder(applicationContext, ApiDetailsService.newItemsChannelId) + NotificationCompat.Builder(applicationContext, AppSettingsService.newItemsChannelId) .setContentTitle(context.getString(R.string.new_items_notification_title)) .setContentText( context.getString( @@ -96,7 +94,7 @@ override fun doWork(): Result { ) ) .setPriority(PRIORITY_DEFAULT) - .setChannelId(ApiDetailsService.newItemsChannelId) + .setChannelId(AppSettingsService.newItemsChannelId) .setContentIntent(pendingIntent) .setAutoCancel(true) .setSmallIcon(R.drawable.ic_tab_fiber_new_black_24dp) diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt index c893954..2eee8b1 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt @@ -31,6 +31,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.customtabs.CustomTabActiv import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream import bou.amine.apps.readerforselfossv2.repository.Repository import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getImages import bou.amine.apps.readerforselfossv2.utils.getThumbnail @@ -74,8 +75,7 @@ class ArticleFragment : Fragment(), DIAware { override val di : DI by closestDI() private val repository: Repository by instance() - - private var settings = Settings() + private val appSettingsService: AppSettingsService by instance() private var typeface: Typeface? = null private var resId: Int = 0 @@ -114,10 +114,10 @@ class ArticleFragment : Fragment(), DIAware { contentSource = item.sourceAndDateText(repository.dateUtils) allImages = item.getImages() - fontSize = settings.getString("reader_font_size", "16").toInt() - staticBar = settings.getBoolean("reader_static_bar", false) + fontSize = appSettingsService.getFontSize() + staticBar = appSettingsService.isStaticBarEnabled() + font = appSettingsService.getFont() - font = settings.getString("reader_font", "") if (font.isNotEmpty()) { resId = requireContext().resources.getIdentifier(font, "font", requireContext().packageName) typeface = try { @@ -239,7 +239,7 @@ class ArticleFragment : Fragment(), DIAware { .setTitle(requireContext().getString(R.string.webview_dialog_issue_title)) .setPositiveButton(android.R.string.ok ) { _, _ -> - settings.putBoolean("prefer_article_viewer", false) + appSettingsService.disableArticleViewer() requireActivity().finish() } .create() @@ -255,7 +255,7 @@ class ArticleFragment : Fragment(), DIAware { } private fun refreshAlignment() { - textAlignment = when (settings.getInt("text_align", 1)) { + textAlignment = when (appSettingsService.getActiveAllignment()) { 1 -> "justify" 2 -> "left" else -> "justify" diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/settings/SettingsActivity.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/settings/SettingsActivity.kt index 050e6a8..3014dfe 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/settings/SettingsActivity.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/settings/SettingsActivity.kt @@ -14,8 +14,9 @@ import androidx.preference.Preference import androidx.preference.PreferenceFragmentCompat import bou.amine.apps.readerforselfossv2.android.R import bou.amine.apps.readerforselfossv2.android.databinding.ActivitySettingsBinding +import bou.amine.apps.readerforselfossv2.android.themes.AppColors import bou.amine.apps.readerforselfossv2.android.themes.Toppings -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import com.ftinc.scoop.Scoop import com.russhwolf.settings.Settings import java.lang.NumberFormatException @@ -174,12 +175,7 @@ class SettingsActivity : AppCompatActivity(), override fun onOptionsItemSelected(item: MenuItem): Boolean { val id = item.itemId if (id == R.id.clear) { - val settings = Settings() - settings.remove("color_primary") - settings.remove("color_primary_dark") - settings.remove("color_accent") - settings.remove("color_accent_dark") - settings.remove("dark_theme") + AppColors.resetColors() requireActivity().recreate() } return super.onOptionsItemSelected(item) @@ -196,17 +192,17 @@ class SettingsActivity : AppCompatActivity(), setPreferencesFromResource(R.xml.pref_links, rootKey) preferenceManager.findPreference("trackerLink")?.onPreferenceClickListener = Preference.OnPreferenceClickListener { - openUrl(Uri.parse(ApiDetailsService.trackerUrl)) + openUrl(Uri.parse(AppSettingsService.trackerUrl)) true } preferenceManager.findPreference("sourceLink")?.onPreferenceClickListener = Preference.OnPreferenceClickListener { - openUrl(Uri.parse(ApiDetailsService.sourceUrl)) + openUrl(Uri.parse(AppSettingsService.sourceUrl)) false } preferenceManager.findPreference("translation")?.onPreferenceClickListener = Preference.OnPreferenceClickListener { - openUrl(Uri.parse(ApiDetailsService.translationUrl)) + openUrl(Uri.parse(AppSettingsService.translationUrl)) false } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/themes/AppColors.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/themes/AppColors.kt index 78db5a6..bd01677 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/themes/AppColors.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/themes/AppColors.kt @@ -58,4 +58,15 @@ class AppColors(a: Activity) { a.resources.getColor(R.color.grey_900) } } + + companion object { + fun resetColors() { + val settings = Settings() + settings.remove("color_primary") + settings.remove("color_primary_dark") + settings.remove("color_accent") + settings.remove("color_accent_dark") + settings.remove("dark_theme") + } + } } diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/SelfSignedGlideModule.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/SelfSignedGlideModule.kt deleted file mode 100644 index 999a130..0000000 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/utils/glide/SelfSignedGlideModule.kt +++ /dev/null @@ -1,33 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android.utils.glide - -import android.content.Context -import bou.amine.apps.readerforselfossv2.android.utils.getUnsafeHttpClient -import com.bumptech.glide.Glide -import com.bumptech.glide.GlideBuilder -import com.bumptech.glide.Registry -import com.bumptech.glide.load.model.GlideUrl -import com.bumptech.glide.module.GlideModule -import com.russhwolf.settings.Settings -import java.io.InputStream - -class SelfSignedGlideModule : GlideModule { - - override fun applyOptions(context: Context?, builder: GlideBuilder?) { - } - - override fun registerComponents(context: Context?, glide: Glide?, registry: Registry?) { - - if (context != null) { - val settings = Settings() - if (settings.getBoolean("isSelfSignedCert", false)) { - val client = getUnsafeHttpClient().build() - - registry?.append( - GlideUrl::class.java, - InputStream::class.java, - com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader.Factory(client) - ) - } - } - } -} \ No newline at end of file diff --git a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index 7eee3b2..15cfb94 100644 --- a/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/androidMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -1,15 +1,15 @@ package bou.amine.apps.readerforselfossv2.utils import android.text.format.DateUtils -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import java.time.Instant import java.time.LocalDateTime import java.time.OffsetDateTime import java.time.ZoneOffset import java.time.format.DateTimeFormatter -actual class DateUtils actual constructor(apiDetailsService: ApiDetailsService) { - val ads: ApiDetailsService = apiDetailsService // TODO: why is this needed now ? +actual class DateUtils actual constructor(appSettingsService: AppSettingsService) { + val ads: AppSettingsService = appSettingsService // TODO: why is this needed now ? actual fun parseDate(dateString: String): Long { diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/DI/modules.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/DI/modules.kt index ebcb8f1..7888376 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/DI/modules.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/DI/modules.kt @@ -1,13 +1,13 @@ package bou.amine.apps.readerforselfossv2.DI import bou.amine.apps.readerforselfossv2.rest.SelfossApi -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import org.kodein.di.DI import org.kodein.di.bind import org.kodein.di.instance import org.kodein.di.singleton val networkModule by DI.Module { - bind() with singleton { ApiDetailsService() } + bind() with singleton { AppSettingsService() } bind() with singleton { SelfossApi(instance()) } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt index d9e4254..052783d 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt @@ -4,7 +4,7 @@ import bou.amine.apps.readerforselfossv2.dao.* import bou.amine.apps.readerforselfossv2.model.NetworkUnavailableException import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.model.SelfossModel -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.* import com.github.ln_12.library.ConnectivityStatus import com.russhwolf.settings.Settings @@ -13,14 +13,13 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -class Repository(private val api: SelfossApi, private val apiDetails: ApiDetailsService, private val connectivityStatus: ConnectivityStatus, private val db: ReaderForSelfossDB) { - val settings = Settings() +class Repository(private val api: SelfossApi, private val appSettingsService: AppSettingsService, connectivityStatus: ConnectivityStatus, private val db: ReaderForSelfossDB) { var items = ArrayList() val isConnectionAvailable = connectivityStatus.isNetworkConnected var connectionMonitored = false - var baseUrl = apiDetails.getBaseUrl() + var baseUrl = appSettingsService.getBaseUrl() lateinit var dateUtils: DateUtils var displayedItems = ItemType.UNREAD @@ -29,7 +28,6 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails var sourceFilter: SelfossModel.Source? = null var searchFilter: String? = null - var itemsCaching = settings.getBoolean("items_caching", false) var offlineOverride = false var badgeUnread = 0 @@ -43,7 +41,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails // TODO: Dispatchers.IO not available in KMM, an alternative solution should be found CoroutineScope(Dispatchers.Main).launch { updateApiVersion() - dateUtils = DateUtils(apiDetails) + dateUtils = DateUtils(appSettingsService) reloadBadges() } } @@ -61,7 +59,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails null ) } else { - if (itemsCaching) { + if (appSettingsService.isItemCachingEnabled()) { fetchedItems = getDBItems().filter { displayedItems == ItemType.ALL || (it.unread && displayedItems == ItemType.UNREAD) || @@ -98,7 +96,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails return items } - suspend fun getMaxItemsForBackground(itemType: ItemType): List? { + private suspend fun getMaxItemsForBackground(itemType: ItemType): List? { return if (isNetworkAvailable()) { api.getItems( itemType.type, @@ -172,7 +170,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails return success } - suspend fun markAsReadById(id: Int): Boolean { + private suspend fun markAsReadById(id: Int): Boolean { return if (isNetworkAvailable()) { api.markAsRead(id.toString())?.isSuccess == true } else { @@ -191,7 +189,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails return success } - suspend fun unmarkAsReadById(id: Int): Boolean { + private suspend fun unmarkAsReadById(id: Int): Boolean { return if (isNetworkAvailable()) { api.unmarkAsRead(id.toString())?.isSuccess == true } else { @@ -209,7 +207,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails return success } - suspend fun starrById(id: Int): Boolean { + private suspend fun starrById(id: Int): Boolean { return if (isNetworkAvailable()) { api.starr(id.toString())?.isSuccess == true } else { @@ -227,7 +225,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails return success } - suspend fun unstarrById(id: Int): Boolean { + private suspend fun unstarrById(id: Int): Boolean { return if (isNetworkAvailable()) { api.unstarr(id.toString())?.isSuccess == true } else { @@ -307,7 +305,7 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails spout, tags, filter, - apiDetails.getApiVersion() + appSettingsService.getApiVersion() )?.isSuccess == true } @@ -350,27 +348,19 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails return result } - fun refreshLoginInformation(url: String, login: String, password: String, - httpLogin: String, httpPassword: String, - isSelfSignedCert: Boolean) { - settings.putString("url", url) - settings.putString("login", login) - settings.putString("httpUserName", httpLogin) - settings.putString("password", password) - settings.putString("httpPassword", httpPassword) - settings.putBoolean("isSelfSignedCert", isSelfSignedCert) + fun refreshLoginInformation(url: String, login: String, password: String, isSelfSignedCert: Boolean) { + appSettingsService.refreshLoginInformation(url, login, password, isSelfSignedCert) baseUrl = url api.refreshLoginInformation() } private suspend fun updateApiVersion() { - val apiMajorVersion = apiDetails.getApiVersion() + val apiMajorVersion = appSettingsService.getApiVersion() if (isNetworkAvailable()) { val fetchedVersion = api.version() if (fetchedVersion != null && fetchedVersion.getApiMajorVersion() != apiMajorVersion) { - settings.putInt("apiVersionMajor", fetchedVersion.getApiMajorVersion()) - apiDetails.refreshApiVersion() + appSettingsService.updateApiVersion(fetchedVersion.getApiMajorVersion()) } } dateUtils = DateUtils(apiMajorVersion) @@ -378,10 +368,10 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails fun isNetworkAvailable() = isConnectionAvailable.value && !offlineOverride - fun getDBActions(): List = + private fun getDBActions(): List = db.actionsQueries.actions().executeAsList() - fun deleteDBAction(action: ACTION) = + private fun deleteDBAction(action: ACTION) = db.actionsQueries.deleteAction(action.id) fun getDBTags(): List = db.tagsQueries.tags().executeAsList() @@ -432,7 +422,9 @@ class Repository(private val api: SelfossApi, private val apiDetails: ApiDetails val starredItems = getMaxItemsForBackground(ItemType.STARRED) insertDBItems(newItems.orEmpty() + allItems.orEmpty() + starredItems.orEmpty()) return newItems - } catch (e: Throwable) {} + } catch (e: Throwable) { + // We do nothing + } return emptyList() } diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt index 1a2c56e..160f2d8 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt @@ -1,7 +1,7 @@ package bou.amine.apps.readerforselfossv2.rest import bou.amine.apps.readerforselfossv2.model.SelfossModel -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService import io.ktor.client.* import io.ktor.client.call.* import io.ktor.client.plugins.* @@ -14,7 +14,7 @@ import io.ktor.client.plugins.logging.* import io.ktor.serialization.kotlinx.json.* import kotlinx.serialization.json.Json -class SelfossApi(private val apiDetailsService: ApiDetailsService) { +class SelfossApi(private val appSettingsService: AppSettingsService) { var client = createHttpClient() @@ -31,13 +31,13 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { install(Logging) { logger = object : Logger { override fun log(message: String) { - apiDetailsService.logApiCalls(message) + appSettingsService.logApiCalls(message) } } level = LogLevel.ALL } install(HttpTimeout) { - requestTimeoutMillis = apiDetailsService.getApiTimeout() + requestTimeoutMillis = appSettingsService.getApiTimeout() } /* TODO: Auth as basic if (apiDetailsService.getUserName().isNotEmpty() && apiDetailsService.getPassword().isNotEmpty()) { @@ -58,17 +58,17 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { } fun url(path: String) = - "${apiDetailsService.getBaseUrl()}$path" + "${appSettingsService.getBaseUrl()}$path" fun refreshLoginInformation() { - apiDetailsService.refresh() + appSettingsService.refreshApiSettings() client = createHttpClient() } suspend fun login(): SelfossModel.SuccessResponse? = client.get(url("/login")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun getItems( @@ -81,45 +81,45 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { items: Int? = null ): List? = client.get(url("/items")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) parameter("type", type) parameter("tag", tag) parameter("source", source) parameter("search", search) parameter("updatedsince", updatedSince) - parameter("items", items ?: apiDetailsService.getItemsNumber()) + parameter("items", items ?: appSettingsService.getItemsNumber()) parameter("offset", offset) }.body() suspend fun stats(): SelfossModel.Stats? = client.get(url("/stats")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun tags(): List? = client.get(url("/tags")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun update(): String? = client.get(url("/update")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun spouts(): Map? = client.get(url("/sources/spouts")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun sources(): ArrayList? = client.get(url("/sources/list")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun version(): SelfossModel.ApiVersion? = @@ -127,34 +127,34 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { suspend fun markAsRead(id: String): SelfossModel.SuccessResponse? = client.post(url("/mark/$id")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun unmarkAsRead(id: String): SelfossModel.SuccessResponse? = client.post(url("/unmark/$id")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun starr(id: String): SelfossModel.SuccessResponse? = client.post(url("/starr/$id")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun unstarr(id: String): SelfossModel.SuccessResponse? = client.post(url("/unstarr/$id")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() suspend fun markAllAsRead(ids: List): SelfossModel.SuccessResponse? = client.submitForm( url = url("/mark"), formParameters = Parameters.build { - append("username", apiDetailsService.getUserName()) - append("password", apiDetailsService.getPassword()) + append("username", appSettingsService.getUserName()) + append("password", appSettingsService.getPassword()) ids.map { append("ids[]", it) } } ).body() @@ -181,7 +181,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { filter: String ): SelfossModel.SuccessResponse? = client.submitForm( - url = url("/source?username=${apiDetailsService.getUserName()}&password=${apiDetailsService.getPassword()}"), + url = url("/source?username=${appSettingsService.getUserName()}&password=${appSettingsService.getPassword()}"), formParameters = Parameters.build { append("title", title) append("url", url) @@ -199,7 +199,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { filter: String ): SelfossModel.SuccessResponse? = client.submitForm( - url = url("/source?username=${apiDetailsService.getUserName()}&password=${apiDetailsService.getPassword()}"), + url = url("/source?username=${appSettingsService.getUserName()}&password=${appSettingsService.getPassword()}"), formParameters = Parameters.build { append("title", title) append("url", url) @@ -211,7 +211,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) { suspend fun deleteSource(id: Int): SelfossModel.SuccessResponse? = client.delete(url("/source/$id")) { - parameter("username", apiDetailsService.getUserName()) - parameter("password", apiDetailsService.getPassword()) + parameter("username", appSettingsService.getUserName()) + parameter("password", appSettingsService.getPassword()) }.body() } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/ApiDetailsService.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/ApiDetailsService.kt deleted file mode 100644 index 6a48792..0000000 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/ApiDetailsService.kt +++ /dev/null @@ -1,97 +0,0 @@ -package bou.amine.apps.readerforselfossv2.service - -import com.russhwolf.settings.Settings -import io.github.aakira.napier.Napier -import io.ktor.client.plugins.* - -class ApiDetailsService { - val settings: Settings = Settings() - private var _apiVersion: Int = -1 - private var _baseUrl: String = "" - private var _userName: String = "" - private var _password: String = "" - private var _itemsNumber: Int? = null - private var _apiTimeout: Long? = null - - fun logApiCalls(message: String) { - Napier.d(message, tag = "LogApiCalls") - } - - - fun getApiVersion(): Int { - if (_apiVersion == -1) { - refreshApiVersion() - return _apiVersion - } - return _apiVersion - } - - fun refreshApiVersion() { - _apiVersion = settings.getInt("apiVersionMajor", -1) - } - - fun getBaseUrl(): String { - if (_baseUrl.isEmpty()) { - _baseUrl = settings.getString("url", "") - } - return _baseUrl - } - - fun getUserName(): String { - if (_userName.isEmpty()) { - _userName = settings.getString("login", "") - } - return _userName - } - - fun getPassword(): String { - if (_password.isEmpty()) { - _password = settings.getString("password", "") - } - return _password - } - - fun getItemsNumber(): Int { - if (_itemsNumber == null) { - refreshItemsNumber() - } - return _itemsNumber!! - } - - fun refreshItemsNumber() { - _itemsNumber = settings.getString("prefer_api_items_number", "200").toInt() - } - - fun getApiTimeout(): Long { - if (_apiTimeout == null) { - refreshApiTimeout() - } - return _apiTimeout!! - } - - fun refreshApiTimeout() { - val settingsTimeout = settings.getLong("api_timeout", HttpTimeout.INFINITE_TIMEOUT_MS) - _apiTimeout = if (settingsTimeout > 0) settingsTimeout else HttpTimeout.INFINITE_TIMEOUT_MS - } - - fun refresh() { - _password = settings.getString("password", "") - _userName = settings.getString("login", "") - _baseUrl = settings.getString("url", "") - refreshApiVersion() - refreshItemsNumber() - refreshApiTimeout() - } - - companion object { - const val translationUrl = "https://crwd.in/readerforselfoss" - - const val sourceUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform" - - const val trackerUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform/issues" - - const val syncChannelId = "sync-channel-id" - - const val newItemsChannelId = "new-items-channel-id" - } -} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/AppSettingsService.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/AppSettingsService.kt new file mode 100644 index 0000000..398323f --- /dev/null +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/service/AppSettingsService.kt @@ -0,0 +1,428 @@ +package bou.amine.apps.readerforselfossv2.service + +import com.russhwolf.settings.Settings +import io.github.aakira.napier.Napier +import io.ktor.client.plugins.* + +class AppSettingsService { + val settings: Settings = Settings() + + // Api related + private var _apiVersion: Int = -1 + private var _baseUrl: String = "" + private var _userName: String = "" + private var _password: String = "" + + // User settings related + private var _itemsCaching: Boolean? = null + private var _internalBrowser: Boolean? = null + private var _articleViewer: Boolean? = null + private var _shouldBeCardView: Boolean? = null + private var _displayUnreadCount: Boolean? = null + private var _displayAllCount: Boolean? = null + private var _fullHeightCards: Boolean? = null + private var _updateSources: Boolean? = null + private var _periodicRefresh: Boolean? = null + private var _refreshWhenChargingOnly: Boolean? = null + private var _infiniteLoading: Boolean? = null + private var _displayAccountHeader: Boolean? = null + private var _notifyNewItems: Boolean? = null + private var _itemsNumber: Int? = null + private var _apiTimeout: Long? = null + private var _hiddenTags: List? = null + private var _refreshMinutes: Long = 360 + private var _markOnScroll: Boolean? = null + private var _activeAlignment: Int? = null + + private var _fontSize: Int? = null // settings.getString("reader_font_size", "16").toInt() + private var _staticBar: Boolean? = null // settings.getBoolean("reader_static_bar", false) + private var _font: String = "" // settings.getString("reader_font", "") + + + init { + refreshApiSettings() + refreshUserSettings() + } + + fun logApiCalls(message: String) { + Napier.d(message, tag = "LogApiCalls") + } + + fun getApiVersion(): Int { + if (_apiVersion == -1) { + refreshApiVersion() + return _apiVersion + } + return _apiVersion + } + + fun refreshApiVersion() { + _apiVersion = settings.getInt("apiVersionMajor", -1) + } + + fun getBaseUrl(): String { + if (_baseUrl.isEmpty()) { + refreshBaseUrl() + } + return _baseUrl + } + + fun getUserName(): String { + if (_userName.isEmpty()) { + refrershUsername() + } + return _userName + } + + fun getPassword(): String { + if (_password.isEmpty()) { + refreshPassword() + } + return _password + } + + fun getItemsNumber(): Int { + if (_itemsNumber == null) { + refreshItemsNumber() + } + return _itemsNumber!! + } + + fun refreshItemsNumber() { + _itemsNumber = settings.getString("prefer_api_items_number", "200").toInt() + } + + fun getApiTimeout(): Long { + if (_apiTimeout == null) { + refreshApiTimeout() + } + return _apiTimeout!! + } + + private fun refreshApiTimeout() { + val settingsTimeout = settings.getLong("api_timeout", HttpTimeout.INFINITE_TIMEOUT_MS) + _apiTimeout = if (settingsTimeout > 0) settingsTimeout else HttpTimeout.INFINITE_TIMEOUT_MS + } + + private fun refreshBaseUrl() { + _baseUrl = settings.getString("url", "") + } + + private fun refrershUsername() { + _userName = settings.getString("login", "") + } + + private fun refreshPassword() { + _password = settings.getString("password", "") + } + + private fun refreshInternalBrowserEnabled() { + _internalBrowser = settings.getBoolean("prefer_internal_browser", true) + } + + fun isInternalBrowserEnabled(): Boolean { + if (_internalBrowser != null) { + refreshInternalBrowserEnabled() + } + return _internalBrowser == true + } + + private fun refreshArticleViewerEnabled() { + _articleViewer = settings.getBoolean("prefer_article_viewer", true) + } + + fun isArticleViewerEnabled(): Boolean { + if (_articleViewer != null) { + refreshArticleViewerEnabled() + } + return _articleViewer == true + } + private fun refreshShouldBeCardViewEnabled() { + _shouldBeCardView = settings.getBoolean("card_view_active", false) + } + + fun isCardViewEnabled(): Boolean { + if (_shouldBeCardView != null) { + refreshShouldBeCardViewEnabled() + } + return _shouldBeCardView == true + } + private fun refreshDisplayUnreadCountEnabled() { + _displayUnreadCount = settings.getBoolean("display_unread_count", true) + } + + fun isDisplayUnreadCountEnabled(): Boolean { + if (_displayUnreadCount != null) { + refreshDisplayUnreadCountEnabled() + } + return _displayUnreadCount == true + } + private fun refreshDisplayAllCountEnabled() { + _displayAllCount = settings.getBoolean("display_other_count", false) + } + + fun isDisplayAllCountEnabled(): Boolean { + if (_displayAllCount != null) { + refreshDisplayAllCountEnabled() + } + return _displayAllCount == true + } + private fun refreshFullHeightCardsEnabled() { + _fullHeightCards = settings.getBoolean("full_height_cards", false) + } + + fun isFullHeightCardsEnabled(): Boolean { + if (_fullHeightCards != null) { + refreshFullHeightCardsEnabled() + } + return _fullHeightCards == true + } + private fun refreshUpdateSourcesEnabled() { + _updateSources = settings.getBoolean("update_sources", true) + } + + fun isUpdateSourcesEnabled(): Boolean { + if (_updateSources != null) { + refreshUpdateSourcesEnabled() + } + return _updateSources == true + } + private fun refreshPeriodicRefreshEnabled() { + _periodicRefresh = settings.getBoolean("periodic_refresh", false) + } + + fun isPeriodicRefreshEnabled(): Boolean { + if (_periodicRefresh != null) { + refreshPeriodicRefreshEnabled() + } + return _periodicRefresh == true + } + + private fun refreshRefreshWhenChargingOnlyEnabled() { + _refreshWhenChargingOnly = settings.getBoolean("refresh_when_charging", false) + } + + fun isRefreshWhenChargingOnlyEnabled(): Boolean { + if (_refreshWhenChargingOnly != null) { + refreshRefreshWhenChargingOnlyEnabled() + } + return _refreshWhenChargingOnly == true + } + + private fun refreshRefreshMinutes() { + _refreshMinutes = settings.getString("periodic_refresh_minutes", "360").toLong() + if (_refreshMinutes <= 15) { + _refreshMinutes = 15 + } + } + + fun getRefreshMinutes(): Long { + if (_refreshMinutes != null) { + refreshRefreshMinutes() + } + return _refreshMinutes + } + + private fun refreshHiddenTags() { + if (settings.getString("hidden_tags", "").isNotEmpty()) { + _hiddenTags = settings.getString("hidden_tags", "").replace("\\s".toRegex(), "").split(",") + } + } + + fun getHiddenTags(): List { + if (_hiddenTags != null) { + refreshHiddenTags() + } + return _hiddenTags.orEmpty() + } + + private fun refreshInfiniteLoadingEnabled() { + _infiniteLoading = settings.getBoolean("infinite_loading", false) + } + + fun isInfiniteLoadingEnabled(): Boolean { + if (_infiniteLoading != null) { + refreshInfiniteLoadingEnabled() + } + return _infiniteLoading == true + } + + private fun refreshDisplayAccountHeaderEnabled() { + _displayAccountHeader = settings.getBoolean("account_header_displaying", false) + } + + fun isDisplayAccountHeaderEnabled(): Boolean { + if (_displayAccountHeader != null) { + refreshDisplayAccountHeaderEnabled() + } + return _displayAccountHeader == true + } + + private fun refreshItemCachingEnabled() { + _itemsCaching = settings.getBoolean("items_caching", false) + } + + fun isItemCachingEnabled(): Boolean { + if (_itemsCaching != null) { + refreshItemCachingEnabled() + } + return _itemsCaching == true + } + + private fun refreshNotifyNewItemsEnabled() { + _notifyNewItems = settings.getBoolean("notify_new_items", false) + } + + fun isNotifyNewItemsEnabled(): Boolean { + if (_notifyNewItems != null) { + refreshNotifyNewItemsEnabled() + } + return _notifyNewItems == true + } + + + private fun refreshMarkOnScrollEnabled() { + _markOnScroll = settings.getBoolean("mark_on_scroll", false) + } + + fun isMarkOnScrollEnabled(): Boolean { + if (_markOnScroll != null) { + refreshMarkOnScrollEnabled() + } + return _markOnScroll == true + } + + + private fun refreshActiveAllignment() { + _activeAlignment = settings.getInt("text_align", JUSTIFY) + } + + fun getActiveAllignment(): Int { + if (_activeAlignment != null) { + refreshActiveAllignment() + } + return _activeAlignment ?: JUSTIFY + } + + fun changeAllignment(allignment: Int) { + settings.putInt("text_align", allignment) + _activeAlignment = allignment + } + + private fun refreshFontSize() { + _fontSize = settings.getString("reader_font_size", "16").toInt() + } + + fun getFontSize(): Int { + if (_fontSize != null) { + refreshFontSize() + } + return _fontSize ?: 16 + } + + private fun refreshStaticBarEnabled() { + _staticBar = settings.getBoolean("reader_static_bar", false) + } + + fun isStaticBarEnabled(): Boolean { + if (_staticBar != null) { + refreshStaticBarEnabled() + } + return _staticBar == true + } + + private fun refreshFont() { + _font = settings.getString("reader_font", "") + } + + fun getFont(): String { + if (_font != null) { + refreshFont() + } + return _font + } + + fun refreshApiSettings() { + refreshPassword() + refrershUsername() + refreshBaseUrl() + refreshApiVersion() + } + + fun refreshUserSettings() { + refreshItemsNumber() + refreshApiTimeout() + refreshInternalBrowserEnabled() + refreshArticleViewerEnabled() + refreshShouldBeCardViewEnabled() + refreshDisplayUnreadCountEnabled() + refreshDisplayAllCountEnabled() + refreshFullHeightCardsEnabled() + refreshUpdateSourcesEnabled() + refreshPeriodicRefreshEnabled() + refreshRefreshWhenChargingOnlyEnabled() + refreshRefreshMinutes() + refreshHiddenTags() + refreshInfiniteLoadingEnabled() + refreshDisplayAccountHeaderEnabled() + refreshItemCachingEnabled() + refreshNotifyNewItemsEnabled() + refreshMarkOnScrollEnabled() + refreshActiveAllignment() + refreshFontSize() + refreshFont() + refreshStaticBarEnabled() + } + + fun refreshLoginInformation( + url: String, + login: String, + password: String, + selfSignedCert: Boolean + ) { + settings.putString("url", url) + settings.putString("login", login) + settings.putString("password", password) + settings.putBoolean("isSelfSignedCert", selfSignedCert) + refreshApiSettings() + } + + fun resetLoginInformation() { + settings.remove("url") + settings.remove("login") + settings.remove("password") + refreshApiSettings() + } + + fun updateApiVersion(apiMajorVersion: Int) { + settings.putInt("apiVersionMajor", apiMajorVersion) + refreshApiVersion() + } + + fun clearAll() { + settings.clear() + refreshApiSettings() + refreshUserSettings() + } + + fun disableArticleViewer() { + settings.putBoolean("prefer_article_viewer", false) + refreshArticleViewerEnabled() + } + + companion object { + const val translationUrl = "https://crwd.in/readerforselfoss" + + const val sourceUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform" + + const val trackerUrl = "https://gitea.amine-louveau.fr/Louvorg/ReaderForSelfoss-multiplatform/issues" + + const val syncChannelId = "sync-channel-id" + + const val newItemsChannelId = "new-items-channel-id" + + const val JUSTIFY = 1 + + const val ALIGN_LEFT = 2 + } +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index 41ae126..35ecfa5 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -1,13 +1,13 @@ package bou.amine.apps.readerforselfossv2.utils import bou.amine.apps.readerforselfossv2.model.SelfossModel -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService fun SelfossModel.Item.parseDate(dateUtils: DateUtils): Long = dateUtils.parseDate(this.datetime) -expect class DateUtils(apiDetailsService: ApiDetailsService) { +expect class DateUtils(appSettingsService: AppSettingsService) { fun parseDate(dateString: String): Long fun parseRelativeDate(dateString: String): String diff --git a/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index ec6fc1f..b217356 100644 --- a/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/iosArm64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -1,8 +1,8 @@ package bou.amine.apps.readerforselfossv2.utils -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService -actual class DateUtils actual constructor(apiDetailsService: ApiDetailsService) { +actual class DateUtils actual constructor(appSettingsService: AppSettingsService) { actual fun parseDate(dateString: String): Long { TODO("Not yet implemented") } diff --git a/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt b/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt index ec6fc1f..b217356 100644 --- a/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt +++ b/shared/src/iosX64Main/kotlin/bou/amine/apps/readerforselfossv2/utils/DateUtils.kt @@ -1,8 +1,8 @@ package bou.amine.apps.readerforselfossv2.utils -import bou.amine.apps.readerforselfossv2.service.ApiDetailsService +import bou.amine.apps.readerforselfossv2.service.AppSettingsService -actual class DateUtils actual constructor(apiDetailsService: ApiDetailsService) { +actual class DateUtils actual constructor(appSettingsService: AppSettingsService) { actual fun parseDate(dateString: String): Long { TODO("Not yet implemented") }