Compare commits
67 Commits
b16f86dda1
...
v122102881
Author | SHA1 | Date | |
---|---|---|---|
|
8b0bbe71c9 | ||
8bfe14c019 | |||
208babbce3 | |||
02098a7aa9 | |||
d0a982f385 | |||
1d1c121aab | |||
fe12819163 | |||
|
023a30c008 | ||
|
a2862a2587 | ||
|
054e936657 | ||
1d2e5069b8 | |||
a147646743 | |||
32e7fc0038 | |||
c15bf44032 | |||
0bcd55bd4e | |||
ebef0b3511 | |||
713ceb05bf | |||
dc8381b661 | |||
b5b820c64b | |||
f7055626d9 | |||
|
6ec3e96909 | ||
22da30eaa8 | |||
79fd115f5e | |||
8dc3d319cd | |||
27bb056397 | |||
f9ba13dc32 | |||
6f60ef4346 | |||
28b950f467 | |||
a9c7ec3dc1 | |||
920d4ac1ef | |||
0e96d313ec | |||
7211fdb1a3 | |||
|
381d6acc82 | ||
d311c2cdeb | |||
219cae5d74 | |||
2968aee309 | |||
6cb4b35c93 | |||
15ec0f2d26 | |||
4781e30da2 | |||
c8759cc035 | |||
cb4f2f02ef | |||
7517626ab7 | |||
41c951b659 | |||
|
ad279c6683 | ||
|
5f0817ddb7 | ||
|
7124cbcacd | ||
|
2a710a1a08 | ||
|
82ec2445a1 | ||
|
cabb6d494d | ||
|
5c12481813 | ||
e2afff0b8e | |||
a382fc89ea | |||
3f0a3903ae | |||
f46f98cef0 | |||
bf6f1a917e | |||
71c0a4d340 | |||
63c550ead3 | |||
366b2e10f1 | |||
d2436bb976 | |||
ef994460c1 | |||
758708e18d | |||
c0381144d1 | |||
cda3ba6cb4 | |||
a4636cc0c8 | |||
60c24fc75a | |||
5853a19937 | |||
99f2c04bf6 |
@@ -5,7 +5,6 @@ name: test
|
||||
steps:
|
||||
- name: AnylyseBuildTest
|
||||
image: mingc/android-build-box:latest
|
||||
failure: ignore
|
||||
commands:
|
||||
- echo "---------------------------------------------------------"
|
||||
- echo "Analysing..."
|
||||
@@ -16,6 +15,7 @@ steps:
|
||||
- echo "---------------------------------------------------------"
|
||||
- echo "Testing..."
|
||||
- echo "---------------------------------------------------------"
|
||||
- ./gradlew test -PignoreGitVersion=true -P appLoginUrl="\"URL\"" -P appLoginUsername="\"LOGIN\"" -P appLoginPassword="\"PASS\"" -P pushCache=false
|
||||
environment:
|
||||
SONAR_HOST_URL:
|
||||
from_secret: sonarScannerHostUrl
|
||||
|
@@ -15,9 +15,6 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.ActionBarDrawerToggle
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_NO
|
||||
import androidx.appcompat.app.AppCompatDelegate.MODE_NIGHT_YES
|
||||
import androidx.appcompat.widget.SearchView
|
||||
import androidx.core.view.doOnNextLayout
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
@@ -92,15 +89,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
||||
|
||||
private val settingsLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
appSettingsService.refreshUserSettings()
|
||||
AppCompatDelegate.setDefaultNightMode(if (appSettingsService.isDarkThemeEnabled()) MODE_NIGHT_YES else MODE_NIGHT_NO)
|
||||
}
|
||||
|
||||
override val di by closestDI()
|
||||
private val repository : Repository by instance()
|
||||
private val appSettingsService : AppSettingsService by instance()
|
||||
|
||||
data class DrawerData(val tags: List<SelfossModel.Tag>?, val sources: List<SelfossModel.Source>?)
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivityHomeBinding.inflate(layoutInflater)
|
||||
@@ -353,27 +347,15 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
||||
)
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val drawerData = DrawerData(repository.getDBTags().map { it.toView() },
|
||||
repository.getDBSources().map { it.toView() })
|
||||
val tags = repository.getTags()
|
||||
val sources = repository.getSources()
|
||||
runOnUiThread {
|
||||
// Only refresh if there is no data in the DB, or if the `UpdateSources` setting is enabled
|
||||
if (drawerData.sources?.isEmpty() == true || appSettingsService.isUpdateSourcesEnabled()) {
|
||||
drawerApiCalls(drawerData)
|
||||
} else {
|
||||
handleDrawerData(drawerData, loadedFromCache = true)
|
||||
}
|
||||
handleDrawerData(tags, sources)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawerApiCalls(drawerData: DrawerData) {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
val apiDrawerData = DrawerData(repository.getTags(), repository.getSources())
|
||||
handleDrawerData(if (drawerData != apiDrawerData) apiDrawerData else drawerData)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleDrawerData(drawerData: DrawerData, loadedFromCache: Boolean = false) {
|
||||
private fun handleDrawerData(tags: List<SelfossModel.Tag>, sources: List<SelfossModel.Source>) {
|
||||
binding.mainDrawer.itemAdapter.clear()
|
||||
|
||||
// Filters title with clear action
|
||||
@@ -387,24 +369,24 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
||||
}
|
||||
|
||||
// Hidden tags
|
||||
if (drawerData.tags != null && drawerData.tags.isNotEmpty() && appSettingsService.getHiddenTags().isNotEmpty()) {
|
||||
if (tags.isNotEmpty() && appSettingsService.getHiddenTags().isNotEmpty()) {
|
||||
secondaryItem(
|
||||
withDivider = true,
|
||||
R.string.drawer_item_hidden_tags,
|
||||
DRAWER_ID_HIDDEN_TAGS
|
||||
)
|
||||
handleHiddenTags(drawerData.tags)
|
||||
handleHiddenTags(tags)
|
||||
}
|
||||
|
||||
// Tags
|
||||
secondaryItem(withDivider = true, R.string.drawer_item_tags, DRAWER_ID_TAGS)
|
||||
if (drawerData.tags == null && !loadedFromCache) {
|
||||
if (tags.isEmpty()) {
|
||||
binding.mainDrawer.itemAdapter.add(
|
||||
SecondaryDrawerItem()
|
||||
.apply { nameRes = R.string.drawer_error_loading_tags; isSelectable = false }
|
||||
)
|
||||
} else {
|
||||
handleTags(drawerData.tags!!)
|
||||
handleTags(tags)
|
||||
}
|
||||
|
||||
// Sources
|
||||
@@ -412,15 +394,15 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener, DIAwar
|
||||
startActivity(Intent(v!!.context, SourcesActivity::class.java))
|
||||
false
|
||||
}
|
||||
if (drawerData.sources == null && !loadedFromCache) {
|
||||
if (sources.isEmpty()) {
|
||||
binding.mainDrawer.itemAdapter.add(
|
||||
SecondaryDrawerItem().apply {
|
||||
nameRes = R.string.drawer_error_loading_tags
|
||||
nameRes = R.string.drawer_error_loading_sources
|
||||
isSelectable = false
|
||||
}
|
||||
)
|
||||
} else {
|
||||
handleSources(drawerData.sources!!)
|
||||
handleSources(sources)
|
||||
}
|
||||
|
||||
// About action
|
||||
|
@@ -38,7 +38,7 @@ class LoginActivity : AppCompatActivity(), DIAware {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
AppCompatDelegate.setDefaultNightMode(if (appSettingsService.isDarkThemeEnabled()) AppCompatDelegate.MODE_NIGHT_YES else AppCompatDelegate.MODE_NIGHT_NO)
|
||||
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM)
|
||||
|
||||
binding = ActivityLoginBinding.inflate(layoutInflater)
|
||||
val view = binding.root
|
||||
@@ -163,7 +163,6 @@ class LoginActivity : AppCompatActivity(), DIAware {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val result = repository.login()
|
||||
if (result) {
|
||||
repository.updateApiVersion()
|
||||
goToMain()
|
||||
} else {
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
|
@@ -75,7 +75,6 @@ class MyApp : MultiDexApplication(), DIAware {
|
||||
).show()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun handleNotificationChannels() {
|
||||
|
@@ -28,7 +28,7 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
||||
updateItems(this.items)
|
||||
}
|
||||
|
||||
private fun unmarkSnackbar(position: Int) {
|
||||
private fun unmarkSnackbar(item: SelfossModel.Item, position: Int) {
|
||||
val s = Snackbar
|
||||
.make(
|
||||
app.findViewById(R.id.coordLayout),
|
||||
@@ -37,7 +37,7 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
||||
)
|
||||
.setAction(R.string.undo_string) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
unreadItemAtIndex(position, false)
|
||||
unreadItemAtIndex(item, position, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
||||
s.show()
|
||||
}
|
||||
|
||||
private fun markSnackbar(position: Int) {
|
||||
private fun markSnackbar(item: SelfossModel.Item, position: Int) {
|
||||
val s = Snackbar
|
||||
.make(
|
||||
app.findViewById(R.id.coordLayout),
|
||||
@@ -55,7 +55,7 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
||||
Snackbar.LENGTH_LONG
|
||||
)
|
||||
.setAction(R.string.undo_string) {
|
||||
readItemAtIndex(position)
|
||||
readItemAtIndex(item, position, false)
|
||||
}
|
||||
|
||||
val view = s.view
|
||||
@@ -66,37 +66,36 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
||||
|
||||
fun handleItemAtIndex(position: Int) {
|
||||
if (items[position].unread) {
|
||||
readItemAtIndex(position)
|
||||
readItemAtIndex(items[position], position)
|
||||
} else {
|
||||
unreadItemAtIndex(position)
|
||||
unreadItemAtIndex(items[position], position)
|
||||
}
|
||||
}
|
||||
|
||||
private fun readItemAtIndex(position: Int, showSnackbar: Boolean = true) {
|
||||
val i = items[position]
|
||||
private fun readItemAtIndex(item: SelfossModel.Item, position: Int, showSnackbar: Boolean = true) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
repository.markAsRead(i)
|
||||
repository.markAsRead(item)
|
||||
}
|
||||
if (repository.displayedItems == ItemType.UNREAD) {
|
||||
items.remove(i)
|
||||
items.remove(item)
|
||||
notifyItemRemoved(position)
|
||||
updateItems(items)
|
||||
} else {
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
if (showSnackbar) {
|
||||
unmarkSnackbar(position)
|
||||
unmarkSnackbar(item, position)
|
||||
}
|
||||
}
|
||||
|
||||
private fun unreadItemAtIndex(position: Int, showSnackbar: Boolean = true) {
|
||||
private fun unreadItemAtIndex(item: SelfossModel.Item, position: Int, showSnackbar: Boolean = true) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
repository.unmarkAsRead(items[position])
|
||||
repository.unmarkAsRead(item)
|
||||
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
if (showSnackbar) {
|
||||
markSnackbar(position)
|
||||
markSnackbar(item, position)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -52,11 +52,13 @@ override fun doWork(): Result {
|
||||
|
||||
repository.handleDBActions()
|
||||
|
||||
val apiItems = repository.tryToCacheItemsAndGetNewOnes()
|
||||
if (appSettingsService.isNotifyNewItemsEnabled()) {
|
||||
launch {
|
||||
handleNewItemsNotification(repository.tryToCacheItemsAndGetNewOnes(), notificationManager)
|
||||
handleNewItemsNotification(apiItems, notificationManager)
|
||||
}
|
||||
}
|
||||
apiItems.map { it.preloadImages(context) }
|
||||
}
|
||||
}
|
||||
return Result.success()
|
||||
@@ -66,6 +68,7 @@ override fun doWork(): Result {
|
||||
newItems: List<SelfossModel.Item>?,
|
||||
notificationManager: NotificationManager
|
||||
) {
|
||||
// TODO: Check if this coroutine is actually required
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val apiItems = newItems.orEmpty()
|
||||
|
||||
@@ -102,7 +105,6 @@ override fun doWork(): Result {
|
||||
notificationManager.notify(2, newItemsNotification.build())
|
||||
}
|
||||
}
|
||||
apiItems.map { it.preloadImages(context) }
|
||||
Timer("", false).schedule(4000) {
|
||||
notificationManager.cancel(1)
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ import android.graphics.Typeface
|
||||
import android.graphics.drawable.ColorDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.*
|
||||
import android.webkit.WebResourceResponse
|
||||
import android.webkit.WebSettings
|
||||
@@ -56,6 +57,7 @@ import java.net.URL
|
||||
import java.util.*
|
||||
import java.util.concurrent.ExecutionException
|
||||
|
||||
|
||||
class ArticleFragment : Fragment(), DIAware {
|
||||
private var fontSize: Int = 16
|
||||
private lateinit var item: SelfossModel.Item
|
||||
@@ -333,7 +335,6 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
}
|
||||
|
||||
private fun htmlToWebview() {
|
||||
val stringColor = String.format("#%06X", 0xFFFFFF and resources.getColor(R.color.colorAccent))
|
||||
|
||||
val attrs: IntArray = intArrayOf(android.R.attr.fontFamily)
|
||||
val a: TypedArray = requireContext().obtainStyledAttributes(resId, attrs)
|
||||
@@ -342,12 +343,11 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
binding.webcontent.settings.standardFontFamily = a.getString(0)
|
||||
binding.webcontent.visibility = View.VISIBLE
|
||||
|
||||
// TODO: Set the color strings programmatically
|
||||
val (stringTextColor, stringBackgroundColor) = if (appSettingsService.isDarkThemeEnabled()) {
|
||||
Pair("#FFFFFF", "#303030")
|
||||
} else {
|
||||
Pair("#212121", "#FAFAFA")
|
||||
}
|
||||
val colorOnSurface = TypedValue()
|
||||
requireContext().theme.resolveAttribute(R.attr.colorOnSurface, colorOnSurface, true)
|
||||
|
||||
val colorSurface = TypedValue()
|
||||
requireContext().theme.resolveAttribute(R.attr.colorSurface, colorSurface, true)
|
||||
|
||||
binding.webcontent.settings.useWideViewPort = true
|
||||
binding.webcontent.settings.loadWithOverviewMode = true
|
||||
@@ -436,10 +436,10 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
| max-width: 100%;
|
||||
| }
|
||||
| a {
|
||||
| color: $stringColor !important;
|
||||
| color: ${String.format("#%06X", 0xFFFFFF and resources.getColor(R.color.colorAccent))} !important;
|
||||
| }
|
||||
| *:not(a) {
|
||||
| color: $stringTextColor;
|
||||
| color: ${String.format("#%06X", 0xFFFFFF and colorOnSurface.data)};
|
||||
| }
|
||||
| * {
|
||||
| font-size: ${fontSize}px;
|
||||
@@ -447,11 +447,11 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
| word-break: break-word;
|
||||
| overflow:hidden;
|
||||
| line-height: 1.5em;
|
||||
| background-color: $stringBackgroundColor;
|
||||
| background-color: ${String.format("#%06X", 0xFFFFFF and colorSurface.data)};
|
||||
| }
|
||||
| body, html {
|
||||
| background-color: $stringBackgroundColor !important;
|
||||
| border-color: $stringBackgroundColor !important;
|
||||
| background-color: ${String.format("#%06X", 0xFFFFFF and colorSurface.data)} !important;
|
||||
| border-color: ${String.format("#%06X", 0xFFFFFF and colorSurface.data)} !important;
|
||||
| padding: 0 !important;
|
||||
| margin: 0 !important;
|
||||
| }
|
||||
@@ -461,7 +461,7 @@ class ArticleFragment : Fragment(), DIAware {
|
||||
| pre, code {
|
||||
| white-space: pre-wrap;
|
||||
| width:100%;
|
||||
| background-color: $stringBackgroundColor;
|
||||
| background-color: ${String.format("#%06X", 0xFFFFFF and colorSurface.data)};
|
||||
| }
|
||||
| </style>
|
||||
| $fontLinkAndStyle
|
||||
|
@@ -9,6 +9,7 @@ import android.text.InputType
|
||||
import android.text.TextWatcher
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.preference.EditTextPreference
|
||||
import androidx.preference.Preference
|
||||
@@ -155,7 +156,11 @@ class SettingsActivity : AppCompatActivity(),
|
||||
class ThemePreferenceFragment : PreferenceFragmentCompat() {
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.pref_theme, rootKey)
|
||||
setHasOptionsMenu(true)
|
||||
|
||||
preferenceManager.findPreference<Preference>("currentMode")?.onPreferenceChangeListener = Preference.OnPreferenceChangeListener { _, newValue ->
|
||||
AppCompatDelegate.setDefaultNightMode(newValue.toString().toInt()) // ListPreference Only takes string-arrays ¯\_(ツ)_/¯
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,8 +16,7 @@
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
card_view:cardElevation="2dp"
|
||||
card_view:cardUseCompatPadding="true"
|
||||
card_view:layout_constraintBottom_toBottomOf="parent"
|
||||
app:cardBackgroundColor="?cardBackgroundColor">
|
||||
card_view:layout_constraintBottom_toBottomOf="parent">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
|
@@ -66,7 +66,7 @@
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="24dp"
|
||||
android:paddingBottom="48dp"
|
||||
android:background="?android:colorBackground"
|
||||
android:background="?attr/webviewBackground"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<string name="error_field_required">"Champ requis"</string>
|
||||
<string name="prompt_url">"Url Selfoss"</string>
|
||||
<string name="withLoginSwitch">"Avec login ?"</string>
|
||||
<string name="login_url_problem">"Petit souci. Il manque peut être un / à la fin ?"</string>
|
||||
<string name="login_url_problem">"Petit souci. Il manque peut-être un / à la fin ?"</string>
|
||||
<string name="prompt_login">"Utilisateur"</string>
|
||||
<string name="label_share">"Partager"</string>
|
||||
<string name="readAll">"Tout lire"</string>
|
||||
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">La barre sera affichée</string>
|
||||
<string name="reader_static_bar_off">La barre sera affichée grâce au bouton</string>
|
||||
<string name="remove_source">Supprimer la source</string>
|
||||
<string name="pref_theme_title">Thème Clair/Sombre</string>
|
||||
<string name="mode_dark">Thème sombre</string>
|
||||
<string name="mode_system">Utiliser les paramètres système</string>
|
||||
<string name="mode_light">Thème clair</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">A barra inferior mostrarase sempre</string>
|
||||
<string name="reader_static_bar_off">A barra inferior pode mostrarse a través do botón flotante</string>
|
||||
<string name="remove_source">Eliminar fonte</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -4,10 +4,10 @@
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="colorAccentDark">@color/colorAccentDark</item>
|
||||
<item name="cardBackgroundColor">@color/white</item>
|
||||
<item name="preferenceTheme">@style/PreferenceStyle</item>
|
||||
<item name="android:statusBarColor">@color/dark</item>
|
||||
<item name="bottomBarBackground">@color/dark</item>
|
||||
<item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Dark</item>
|
||||
<item name="webviewBackground">@color/dark</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -47,7 +47,7 @@
|
||||
<string name="switch_unread_count_title">"显示未读数"</string>
|
||||
<string name="display_all_counts_title">"显示收藏和已读的计数"</string>
|
||||
<string name="text_wrong_url">"您似乎试图使用无效的 URL。确保它是正确的,如果问题仍然存在,请与我联系 (通过商店的联系链接)。请注意,该应用程序需要您使用 Selfoss。没有它,您无法访问 RSS 源。"</string>
|
||||
<string name="pref_article_viewer_title">"打开应用程序中的链接"</string>
|
||||
<string name="pref_article_viewer_title">"在应用内打开链接"</string>
|
||||
<string name="pref_article_viewer_on">"文章将在应用程序内打开"</string>
|
||||
<string name="pref_article_viewer_off">"文章将使用默认浏览器打开"</string>
|
||||
<string name="pref_general_category_links">"链接处理"</string>
|
||||
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">底部栏将始终显示</string>
|
||||
<string name="reader_static_bar_off">底部栏可以通过浮动按钮显示</string>
|
||||
<string name="remove_source">删除源</string>
|
||||
<string name="pref_theme_title">浅色/深色模式</string>
|
||||
<string name="mode_dark">深色模式</string>
|
||||
<string name="mode_system">遵循系统设置</string>
|
||||
<string name="mode_light">浅色模式</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -128,4 +128,9 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
</resources>
|
||||
|
@@ -4,5 +4,6 @@
|
||||
<attr name="colorAccentDark" format="reference|color" />
|
||||
<attr name="bottomBarBackground" format="reference|color" />
|
||||
<attr name="toolbarPopupTheme" format="reference|color" />
|
||||
<attr name="webviewBackground" format="reference|color" />
|
||||
</declare-styleable>
|
||||
</resources>
|
32
androidApp/src/main/res/values/mode_settings.xml
Normal file
32
androidApp/src/main/res/values/mode_settings.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="ModeTitles">
|
||||
<item>@string/mode_light</item>
|
||||
<item>@string/mode_dark</item>
|
||||
<item>@string/mode_system</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="ModeValues">
|
||||
<item>1</item> <!--MODE_NIGHT_NO-->
|
||||
<item>2</item> <!--MODE_NIGHT_YES-->
|
||||
<item>0</item> <!--MODE_NIGHT_AUTO_TIME-->
|
||||
</string-array>
|
||||
|
||||
<string-array name="Voice">
|
||||
<item>Male</item>
|
||||
<item>Female</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="VoiceAlias">
|
||||
<item>"usenglishmale"</item>
|
||||
<item>"usenglishfemale"</item>
|
||||
<item>"ukenglishmale"</item>
|
||||
<item>"ukenglishfemale"</item>
|
||||
<item>"eurfrenchmale"</item>
|
||||
<item>"eurfrenchfemale"</item>
|
||||
<item>"eurspanishmale"</item>
|
||||
<item>"eurspanishfemale"</item>
|
||||
<item>"euritalianmale"</item>
|
||||
<item>"euritalianfemale"</item>
|
||||
</string-array>
|
||||
</resources>
|
@@ -63,6 +63,7 @@
|
||||
<string name="card_height_off">Card height will be fixed</string>
|
||||
<string name="source_code">Source code</string>
|
||||
<string name="drawer_error_loading_tags">Error loading tags…</string>
|
||||
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||
<string name="drawer_item_filters">Filters</string>
|
||||
<string name="drawer_action_clear">clear</string>
|
||||
<string name="drawer_item_tags">Tags</string>
|
||||
@@ -109,7 +110,7 @@
|
||||
<string name="pref_switch_periodic_refresh_on">Articles will periodically be synced</string>
|
||||
<string name="pref_periodic_refresh_minutes_title"><![CDATA[Sync interval ( >= 15 minutes)]]></string>
|
||||
<string name="pref_switch_refresh_when_charging">Only refresh when phone is charging</string>
|
||||
<string name="loading_notification_title">Loading ...</string>
|
||||
<string name="loading_notification_title">Loading …</string>
|
||||
<string name="loading_notification_text">Selfoss is syncing your articles</string>
|
||||
<string name="notification_channel_sync">Sync notification</string>
|
||||
<string name="new_items_channel_sync">New items notification</string>
|
||||
@@ -130,4 +131,8 @@
|
||||
<string name="reader_static_bar_on">The bottom bar will always be displayed</string>
|
||||
<string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string>
|
||||
<string name="remove_source">Remove source</string>
|
||||
<string name="pref_theme_title">Light/Dark mode</string>
|
||||
<string name="mode_dark">Dark mode</string>
|
||||
<string name="mode_system">Follow the system setting</string>
|
||||
<string name="mode_light">Light mode</string>
|
||||
</resources>
|
||||
|
@@ -9,11 +9,11 @@
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="colorAccentDark">@color/colorAccentDark</item>
|
||||
<item name="cardBackgroundColor">@color/white</item>
|
||||
<item name="preferenceTheme">@style/PreferenceStyle</item>
|
||||
<item name="android:statusBarColor">?attr/colorPrimary</item>
|
||||
<item name="bottomBarBackground">@color/white</item>
|
||||
<item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
|
||||
<item name="webviewBackground">@color/white</item>
|
||||
</style>
|
||||
|
||||
<!-- Preference Theme -->
|
||||
|
@@ -1,11 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<!-- TODO translate this file -->
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="dark_theme"
|
||||
<ListPreference
|
||||
android:defaultValue="0"
|
||||
android:entries="@array/ModeTitles"
|
||||
android:entryValues="@array/ModeValues"
|
||||
android:key="currentMode"
|
||||
app:iconSpaceReserved="false"
|
||||
android:title="Dark theme" />
|
||||
android:title="@string/pref_theme_title"
|
||||
app:useSimpleSummaryProvider="false" />
|
||||
</PreferenceScreen>
|
@@ -56,6 +56,8 @@ kotlin {
|
||||
dependencies {
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
implementation("io.mockk:mockk:1.12.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.0")
|
||||
}
|
||||
}
|
||||
val androidMain by getting {
|
||||
|
@@ -138,7 +138,11 @@ class SelfossModel {
|
||||
object BooleanSerializer : KSerializer<Boolean> {
|
||||
override fun deserialize(decoder: Decoder): Boolean {
|
||||
val json = ((decoder as JsonDecoder).decodeJsonElement()).jsonPrimitive
|
||||
return json.booleanOrNull ?: json.int == 1
|
||||
return if (json.booleanOrNull != null) {
|
||||
json.boolean
|
||||
} else {
|
||||
json.int == 1
|
||||
}
|
||||
}
|
||||
|
||||
override val descriptor: SerialDescriptor
|
||||
|
@@ -11,6 +11,7 @@ import io.github.aakira.napier.Napier
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
class Repository(private val api: SelfossApi, private val appSettingsService: AppSettingsService, connectivityStatus: ConnectivityStatus, private val db: ReaderForSelfossDB) {
|
||||
|
||||
@@ -36,9 +37,13 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
var badgeStarred = 0
|
||||
set(value) {field = if (value < 0) { 0 } else { value } }
|
||||
|
||||
private var fetchedSources = false
|
||||
private var fetchedTags = false
|
||||
|
||||
init {
|
||||
// TODO: Dispatchers.IO not available in KMM, an alternative solution should be found
|
||||
CoroutineScope(Dispatchers.Main).launch {
|
||||
connectivityStatus.start()
|
||||
runBlocking {
|
||||
updateApiVersion()
|
||||
dateUtils = DateUtils(appSettingsService)
|
||||
reloadBadges()
|
||||
@@ -61,12 +66,19 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
} else {
|
||||
if (appSettingsService.isItemCachingEnabled()) {
|
||||
fromDB = true
|
||||
var dbItems = getDBItems().filter {
|
||||
displayedItems == ItemType.ALL ||
|
||||
(it.unread && displayedItems == ItemType.UNREAD) ||
|
||||
(it.starred && displayedItems == ItemType.STARRED)
|
||||
}
|
||||
if (tagFilter != null) {
|
||||
dbItems = dbItems.filter { it.tags.split(',').contains(tagFilter!!.tag) }
|
||||
}
|
||||
if (sourceFilter != null) {
|
||||
dbItems = dbItems.filter { it.sourcetitle == sourceFilter!!.title }
|
||||
}
|
||||
fetchedItems = SelfossModel.StatusAndData.succes(
|
||||
getDBItems().filter {
|
||||
displayedItems == ItemType.ALL ||
|
||||
(it.unread && displayedItems == ItemType.UNREAD) ||
|
||||
(it.starred && displayedItems == ItemType.STARRED)
|
||||
}.map { it.toView() }
|
||||
dbItems.map { it.toView() }
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -105,9 +117,9 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
val items = api.getItems(
|
||||
itemType.type,
|
||||
0,
|
||||
tagFilter?.tag,
|
||||
sourceFilter?.id?.toLong(),
|
||||
searchFilter,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
200
|
||||
)
|
||||
@@ -131,32 +143,40 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
badgeStarred = response.data.starred
|
||||
success = true
|
||||
}
|
||||
} else {
|
||||
} else if (appSettingsService.isItemCachingEnabled()) {
|
||||
// TODO: do this differently, because it's not efficient
|
||||
val dbItems = getDBItems()
|
||||
badgeUnread = dbItems.filter { item -> item.unread }.size
|
||||
badgeStarred = dbItems.filter { item -> item.starred }.size
|
||||
badgeAll = items.size
|
||||
badgeAll = dbItems.size
|
||||
success = true
|
||||
}
|
||||
return success
|
||||
}
|
||||
|
||||
suspend fun getTags(): List<SelfossModel.Tag>? {
|
||||
return if (isNetworkAvailable()) {
|
||||
suspend fun getTags(): List<SelfossModel.Tag> {
|
||||
val isDatabaseEnabled = appSettingsService.isItemCachingEnabled() || !appSettingsService.isUpdateSourcesEnabled()
|
||||
return if (isNetworkAvailable() && !fetchedTags) {
|
||||
val apiTags = api.tags()
|
||||
if (apiTags.success && apiTags.data != null && (appSettingsService.isItemCachingEnabled() || !appSettingsService.isUpdateSourcesEnabled())) {
|
||||
if (apiTags.success && apiTags.data != null && isDatabaseEnabled) {
|
||||
resetDBTagsWithData(apiTags.data)
|
||||
if (!appSettingsService.isUpdateSourcesEnabled()) {
|
||||
fetchedTags = true
|
||||
}
|
||||
}
|
||||
apiTags.data
|
||||
} else {
|
||||
apiTags.data ?: emptyList()
|
||||
} else if (isDatabaseEnabled) {
|
||||
getDBTags().map { it.toView() }
|
||||
} else {
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getSpouts(): Map<String, SelfossModel.Spout>? {
|
||||
// TODO: Add tests
|
||||
suspend fun getSpouts(): Map<String, SelfossModel.Spout> {
|
||||
return if (isNetworkAvailable()) {
|
||||
val spouts = api.spouts()
|
||||
return if (spouts.success && spouts.data != null) {
|
||||
if (spouts.success && spouts.data != null) {
|
||||
spouts.data
|
||||
} else {
|
||||
emptyMap() // TODO: do something here
|
||||
@@ -166,18 +186,25 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getSources(): ArrayList<SelfossModel.Source>? {
|
||||
return if (isNetworkAvailable()) {
|
||||
suspend fun getSources(): ArrayList<SelfossModel.Source> {
|
||||
val isDatabaseEnabled = appSettingsService.isItemCachingEnabled() || !appSettingsService.isUpdateSourcesEnabled()
|
||||
return if (isNetworkAvailable() && !fetchedSources) {
|
||||
val apiSources = api.sources()
|
||||
if (apiSources.success && apiSources.data != null && (appSettingsService.isItemCachingEnabled() || !appSettingsService.isUpdateSourcesEnabled())) {
|
||||
if (apiSources.success && apiSources.data != null && isDatabaseEnabled) {
|
||||
resetDBSourcesWithData(apiSources.data)
|
||||
if (!appSettingsService.isUpdateSourcesEnabled()) {
|
||||
fetchedSources = true
|
||||
}
|
||||
}
|
||||
apiSources.data
|
||||
} else {
|
||||
apiSources.data ?: ArrayList()
|
||||
} else if (isDatabaseEnabled) {
|
||||
ArrayList(getDBSources().map { it.toView() })
|
||||
} else {
|
||||
ArrayList()
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add tests
|
||||
suspend fun markAsRead(item: SelfossModel.Item): Boolean {
|
||||
val success = markAsReadById(item.id)
|
||||
|
||||
@@ -189,14 +216,14 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
|
||||
private suspend fun markAsReadById(id: Int): Boolean {
|
||||
return if (isNetworkAvailable()) {
|
||||
api.markAsRead(id.toString())?.isSuccess
|
||||
api.markAsRead(id.toString()).isSuccess
|
||||
} else {
|
||||
insertDBAction(id.toString(), read = true)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: Add tests
|
||||
suspend fun unmarkAsRead(item: SelfossModel.Item): Boolean {
|
||||
val success = unmarkAsReadById(item.id)
|
||||
|
||||
@@ -208,13 +235,14 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
|
||||
private suspend fun unmarkAsReadById(id: Int): Boolean {
|
||||
return if (isNetworkAvailable()) {
|
||||
api.unmarkAsRead(id.toString())?.isSuccess
|
||||
api.unmarkAsRead(id.toString()).isSuccess
|
||||
} else {
|
||||
insertDBAction(id.toString(), unread = true)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add tests
|
||||
suspend fun starr(item: SelfossModel.Item): Boolean {
|
||||
val success = starrById(item.id)
|
||||
|
||||
@@ -226,13 +254,14 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
|
||||
private suspend fun starrById(id: Int): Boolean {
|
||||
return if (isNetworkAvailable()) {
|
||||
api.starr(id.toString())?.isSuccess
|
||||
api.starr(id.toString()).isSuccess
|
||||
} else {
|
||||
insertDBAction(id.toString(), starred = true)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add tests
|
||||
suspend fun unstarr(item: SelfossModel.Item): Boolean {
|
||||
val success = unstarrById(item.id)
|
||||
|
||||
@@ -244,17 +273,18 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
|
||||
private suspend fun unstarrById(id: Int): Boolean {
|
||||
return if (isNetworkAvailable()) {
|
||||
api.unstarr(id.toString())?.isSuccess
|
||||
api.unstarr(id.toString()).isSuccess
|
||||
} else {
|
||||
insertDBAction(id.toString(), starred = true)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add tests
|
||||
suspend fun markAllAsRead(items: ArrayList<SelfossModel.Item>): Boolean {
|
||||
var success = false
|
||||
|
||||
if (isNetworkAvailable() && api.markAllAsRead(items.map { it.id.toString() })?.isSuccess) {
|
||||
if (isNetworkAvailable() && api.markAllAsRead(items.map { it.id.toString() }).isSuccess) {
|
||||
success = true
|
||||
for (item in items) {
|
||||
markAsReadLocally(item)
|
||||
@@ -323,7 +353,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
tags,
|
||||
filter,
|
||||
appSettingsService.getApiVersion()
|
||||
)?.isSuccess == true
|
||||
).isSuccess == true
|
||||
}
|
||||
|
||||
return response
|
||||
@@ -333,9 +363,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
var success = false
|
||||
if (isNetworkAvailable()) {
|
||||
val response = api.deleteSource(id)
|
||||
if (response != null) {
|
||||
success = response.isSuccess
|
||||
}
|
||||
success = response.isSuccess
|
||||
}
|
||||
|
||||
return success
|
||||
@@ -343,7 +371,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
|
||||
suspend fun updateRemote(): Boolean {
|
||||
return if (isNetworkAvailable()) {
|
||||
api.update()?.equals("finished")
|
||||
api.update().data.equals("finished")
|
||||
} else {
|
||||
false
|
||||
}
|
||||
@@ -354,7 +382,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
if (isNetworkAvailable()) {
|
||||
try {
|
||||
val response = api.login()
|
||||
result = response?.isSuccess == true
|
||||
result = response.isSuccess == true
|
||||
if (result) {
|
||||
updateApiVersion()
|
||||
}
|
||||
@@ -371,7 +399,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
api.refreshLoginInformation()
|
||||
}
|
||||
|
||||
suspend fun updateApiVersion() {
|
||||
private suspend fun updateApiVersion() {
|
||||
val apiMajorVersion = appSettingsService.getApiVersion()
|
||||
|
||||
if (isNetworkAvailable()) {
|
||||
@@ -390,9 +418,9 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
private fun deleteDBAction(action: ACTION) =
|
||||
db.actionsQueries.deleteAction(action.id)
|
||||
|
||||
fun getDBTags(): List<TAG> = db.tagsQueries.tags().executeAsList()
|
||||
private fun getDBTags(): List<TAG> = db.tagsQueries.tags().executeAsList()
|
||||
|
||||
fun getDBSources(): List<SOURCE> = db.sourcesQueries.sources().executeAsList()
|
||||
private fun getDBSources(): List<SOURCE> = db.sourcesQueries.sources().executeAsList()
|
||||
|
||||
private fun resetDBTagsWithData(tagEntities: List<SelfossModel.Tag>) {
|
||||
db.tagsQueries.deleteAllTags()
|
||||
@@ -430,8 +458,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
private fun updateDBItem(item: SelfossModel.Item) =
|
||||
db.itemsQueries.updateItem(item.datetime, item.title.getHtmlDecoded(), item.content, item.unread, item.starred, item.thumbnail, item.icon, item.link, item.sourcetitle, item.tags.joinToString(","), item.id.toString())
|
||||
|
||||
|
||||
suspend fun tryToCacheItemsAndGetNewOnes(): List<SelfossModel.Item>? {
|
||||
suspend fun tryToCacheItemsAndGetNewOnes(): List<SelfossModel.Item> {
|
||||
try {
|
||||
val newItems = getMaxItemsForBackground(ItemType.UNREAD)
|
||||
val allItems = getMaxItemsForBackground(ItemType.ALL)
|
||||
@@ -444,6 +471,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
// TODO: Add tests
|
||||
suspend fun handleDBActions() {
|
||||
|
||||
val actions: List<ACTION> = getDBActions()
|
||||
|
@@ -34,7 +34,6 @@ class AppSettingsService {
|
||||
|
||||
private var _fontSize: Int? = null
|
||||
private var _staticBar: Boolean? = null
|
||||
private var _darkTheme: Boolean? = null
|
||||
private var _font: String = ""
|
||||
|
||||
|
||||
@@ -308,17 +307,6 @@ class AppSettingsService {
|
||||
return _staticBar == true
|
||||
}
|
||||
|
||||
private fun refreshDarkThemeEnabled() {
|
||||
_darkTheme = settings.getBoolean("dark_theme", false)
|
||||
}
|
||||
|
||||
fun isDarkThemeEnabled(): Boolean {
|
||||
if (_darkTheme != null) {
|
||||
refreshDarkThemeEnabled()
|
||||
}
|
||||
return _darkTheme == true
|
||||
}
|
||||
|
||||
private fun refreshFont() {
|
||||
_font = settings.getString("reader_font", "")
|
||||
}
|
||||
@@ -358,7 +346,6 @@ class AppSettingsService {
|
||||
refreshFontSize()
|
||||
refreshFont()
|
||||
refreshStaticBarEnabled()
|
||||
refreshDarkThemeEnabled()
|
||||
}
|
||||
|
||||
fun refreshLoginInformation(
|
||||
|
@@ -65,6 +65,6 @@ fun SelfossModel.Item.toEntity(): ITEM =
|
||||
this.thumbnail,
|
||||
this.icon,
|
||||
this.link,
|
||||
this.title.getHtmlDecoded(),
|
||||
this.sourcetitle.getHtmlDecoded(),
|
||||
this.tags.joinToString(",")
|
||||
)
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user