Compare commits

...

14 Commits

Author SHA1 Message Date
aeeac8cccd Little fix. 2018-11-04 14:56:48 +01:00
7292edf997 #Closes #179. 2018-11-04 14:37:22 +01:00
f49256c72f Manual sync for read/unread/star/unstar. 2018-11-04 14:33:50 +01:00
d02b28b81f Initial changes for #179. 2018-11-04 14:25:05 +01:00
08117043dd Do not replace the background task. 2018-11-03 21:07:27 +01:00
63496c993e New Crowdin translations (#233)
* New translations strings.xml (Catalan)

* New translations strings.xml (Japanese)

* New translations strings.xml (Vietnamese)

* New translations strings.xml (Ukrainian)

* New translations strings.xml (Turkish)

* New translations strings.xml (Swedish)

* New translations strings.xml (Spanish)

* New translations strings.xml (Serbian (Cyrillic))

* New translations strings.xml (Russian)

* New translations strings.xml (Romanian)

* New translations strings.xml (Portuguese, Brazilian)

* New translations strings.xml (Portuguese)

* New translations strings.xml (Polish)

* New translations strings.xml (Norwegian)

* New translations strings.xml (Korean)

* New translations strings.xml (Italian)

* New translations strings.xml (Afrikaans)

* New translations strings.xml (Indonesian)

* New translations strings.xml (Hungarian)

* New translations strings.xml (Hebrew)

* New translations strings.xml (Greek)

* New translations strings.xml (German)

* New translations strings.xml (French)

* New translations strings.xml (Finnish)

* New translations strings.xml (Dutch)

* New translations strings.xml (Danish)

* New translations strings.xml (Czech)

* New translations strings.xml (Chinese Traditional)

* New translations strings.xml (Chinese Simplified)

* New translations strings.xml (Arabic)

* New translations strings.xml (Galician)

* New translations strings.xml (French)

* New translations strings.xml (Chinese Simplified)
2018-11-03 19:01:40 +01:00
00ef542e49 Closes #33. 2018-11-03 18:48:50 +01:00
a78c6e6b33 Sync with settings. 2018-11-03 18:47:43 +01:00
363eaf9bf9 Preferences for the background tasks. 2018-11-03 18:14:22 +01:00
fec6683701 Merge branch 'master' of github.com:aminecmi/ReaderforSelfoss 2018-11-03 11:30:13 +01:00
1549edb647 ... 2018-11-03 11:29:53 +01:00
3de48ba162 Some more background tasks. 2018-11-03 11:29:03 +01:00
a2a3d6f1a7 New Crowdin translations (#232)
* New translations strings.xml (Spanish)

* New translations strings.xml (Galician)

* New translations strings.xml (French)
2018-11-02 10:34:04 +01:00
ccab2c7648 Initial work on background task. 2018-11-01 21:51:31 +01:00
56 changed files with 923 additions and 87 deletions

View File

@ -1,5 +1,9 @@
**1.7.x** **1.7.x**
- Closes #179. Sync of read/unread/star/unstar items on background task or on app reload with network available.
- Closes #33. Background sync with settings.
- Closing #1. Initial article caching. - Closing #1. Initial article caching.
- Closing #228 by removing the list action bar. Action buttons are exclusively on the card view from now on. - Closing #228 by removing the list action bar. Action buttons are exclusively on the card view from now on.

View File

@ -152,14 +152,16 @@ dependencies {
implementation 'androidx.core:core-ktx:1.0.0' implementation 'androidx.core:core-ktx:1.0.0'
// Crash // Crash
implementation 'ch.acra:acra-http:5.1.3' implementation 'ch.acra:acra-http:5.2.1'
implementation 'ch.acra:acra-dialog:5.1.3' implementation 'ch.acra:acra-dialog:5.2.1'
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version" implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
implementation "androidx.room:room-runtime:$room_version" implementation "androidx.room:room-runtime:$room_version"
kapt "androidx.room:room-compiler:$room_version" kapt "androidx.room:room-compiler:$room_version"
implementation "android.arch.work:work-runtime-ktx:$work_version"
} }

View File

@ -0,0 +1,226 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "7ad9c4961992c13b670128485ebb3efc",
"entities": [
{
"tableName": "tags",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`tag` TEXT NOT NULL, `color` TEXT NOT NULL, `unread` INTEGER NOT NULL, PRIMARY KEY(`tag`))",
"fields": [
{
"fieldPath": "tag",
"columnName": "tag",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "color",
"columnName": "color",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "unread",
"columnName": "unread",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"tag"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "sources",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `title` TEXT NOT NULL, `tags` TEXT NOT NULL, `spout` TEXT NOT NULL, `error` TEXT NOT NULL, `icon` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "spout",
"columnName": "spout",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "error",
"columnName": "error",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "items",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `datetime` TEXT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `thumbnail` TEXT NOT NULL, `icon` TEXT NOT NULL, `link` TEXT NOT NULL, `sourcetitle` TEXT NOT NULL, `tags` TEXT NOT NULL, PRIMARY KEY(`id`))",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "datetime",
"columnName": "datetime",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "title",
"columnName": "title",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "content",
"columnName": "content",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "unread",
"columnName": "unread",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "starred",
"columnName": "starred",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "thumbnail",
"columnName": "thumbnail",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "icon",
"columnName": "icon",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "link",
"columnName": "link",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "sourcetitle",
"columnName": "sourcetitle",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "tags",
"columnName": "tags",
"affinity": "TEXT",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": false
},
"indices": [],
"foreignKeys": []
},
{
"tableName": "actions",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `articleid` TEXT NOT NULL, `read` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `unstarred` INTEGER NOT NULL)",
"fields": [
{
"fieldPath": "id",
"columnName": "id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "articleId",
"columnName": "articleid",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "read",
"columnName": "read",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "unread",
"columnName": "unread",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "starred",
"columnName": "starred",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "unstarred",
"columnName": "unstarred",
"affinity": "INTEGER",
"notNull": true
}
],
"primaryKey": {
"columnNames": [
"id"
],
"autoGenerate": true
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"7ad9c4961992c13b670128485ebb3efc\")"
]
}
}

View File

@ -25,6 +25,12 @@ import android.view.View
import android.widget.Toast import android.widget.Toast
import androidx.room.Room import androidx.room.Room
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.work.Constraints
import androidx.work.ExistingPeriodicWorkPolicy
import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
import apps.amine.bou.readerforselfoss.adapters.ItemsAdapter import apps.amine.bou.readerforselfoss.adapters.ItemsAdapter
@ -34,8 +40,11 @@ import apps.amine.bou.readerforselfoss.api.selfoss.Source
import apps.amine.bou.readerforselfoss.api.selfoss.Stats import apps.amine.bou.readerforselfoss.api.selfoss.Stats
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.api.selfoss.Tag import apps.amine.bou.readerforselfoss.api.selfoss.Tag
import apps.amine.bou.readerforselfoss.background.LoadingWorker
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2 import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
import apps.amine.bou.readerforselfoss.settings.SettingsActivity import apps.amine.bou.readerforselfoss.settings.SettingsActivity
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.themes.Toppings import apps.amine.bou.readerforselfoss.themes.Toppings
@ -75,6 +84,7 @@ import org.acra.ACRA
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
import java.util.concurrent.TimeUnit
import kotlin.concurrent.thread import kotlin.concurrent.thread
class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
@ -111,6 +121,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
private var itemsCaching: Boolean = false private var itemsCaching: Boolean = false
private var hiddenTags: List<String> = emptyList() private var hiddenTags: List<String> = emptyList()
private var periodicRefresh = false
private var refreshMinutes: Long = 360L
private var refreshWhenChargingOnly = false
private lateinit var tabNewBadge: TextBadgeItem private lateinit var tabNewBadge: TextBadgeItem
private lateinit var tabArchiveBadge: TextBadgeItem private lateinit var tabArchiveBadge: TextBadgeItem
private lateinit var tabStarredBadge: TextBadgeItem private lateinit var tabStarredBadge: TextBadgeItem
@ -159,7 +173,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
db = Room.databaseBuilder( db = Room.databaseBuilder(
applicationContext, applicationContext,
AppDatabase::class.java, "selfoss-database" AppDatabase::class.java, "selfoss-database"
).addMigrations(MIGRATION_1_2).build() ).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).build()
customTabActivityHelper = CustomTabActivityHelper() customTabActivityHelper = CustomTabActivityHelper()
@ -204,7 +218,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
recyclerView: RecyclerView, recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder viewHolder: RecyclerView.ViewHolder
): Int = ): Int =
if (elementsShown != UNREAD_SHOWN || !this@HomeActivity.isNetworkAccessible(null)) { if (elementsShown != UNREAD_SHOWN) {
0 0
} else { } else {
super.getSwipeDirs( super.getSwipeDirs(
@ -335,6 +349,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
getElementsAccordingToTab() getElementsAccordingToTab()
handleGDPRDialog(sharedPref.getBoolean("GDPR_shown", false)) handleGDPRDialog(sharedPref.getBoolean("GDPR_shown", false))
handleRecurringTask()
handleOfflineActions()
} }
private fun getAndStoreAllItems() { private fun getAndStoreAllItems() {
@ -384,6 +402,13 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
} else { } else {
emptyList() emptyList()
} }
periodicRefresh = sharedPref.getBoolean("periodic_refresh", false)
refreshWhenChargingOnly = sharedPref.getBoolean("refresh_when_charging", false)
refreshMinutes = sharedPref.getString("periodic_refresh_minutes", "360").toLong()
if (refreshMinutes <= 15) {
refreshMinutes = 15
}
} }
private fun handleThemeBinding() { private fun handleThemeBinding() {
@ -1268,7 +1293,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
} }
} }
R.id.readAll -> { R.id.readAll -> {
if (elementsShown == UNREAD_SHOWN && this@HomeActivity.isNetworkAccessible(null)) { if (elementsShown == UNREAD_SHOWN) {
needsConfirmation(R.string.readAll, R.string.markall_dialog_message) { needsConfirmation(R.string.readAll, R.string.markall_dialog_message) {
swipeRefreshLayout.isRefreshing = false swipeRefreshLayout.isRefreshing = false
val ids = allItems.map { it.id } val ids = allItems.map { it.id }
@ -1282,7 +1307,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
ACRA.getErrorReporter().maybeHandleSilentException(e, this@HomeActivity) ACRA.getErrorReporter().maybeHandleSilentException(e, this@HomeActivity)
} }
if (ids.isNotEmpty()) { if (ids.isNotEmpty() && this@HomeActivity.isNetworkAccessible(null)) {
api.readAll(ids).enqueue(object : Callback<SuccessResponse> { api.readAll(ids).enqueue(object : Callback<SuccessResponse> {
override fun onResponse( override fun onResponse(
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
@ -1388,5 +1413,58 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
alertDialog.show() alertDialog.show()
} }
} }
private fun handleRecurringTask() {
if (periodicRefresh) {
val myConstraints = Constraints.Builder()
.setRequiresBatteryNotLow(true)
.setRequiresCharging(refreshWhenChargingOnly)
.setRequiresStorageNotLow(true)
.build()
val backgroundWork =
PeriodicWorkRequestBuilder<LoadingWorker>(refreshMinutes, TimeUnit.MINUTES)
.setConstraints(myConstraints)
.addTag("selfoss-loading")
.build()
WorkManager.getInstance().enqueueUniquePeriodicWork("selfoss-loading", ExistingPeriodicWorkPolicy.KEEP, backgroundWork)
}
}
private fun handleOfflineActions() {
fun <T>doAndReportOnFail(call: Call<T>, action: ActionEntity) {
call.enqueue(object: Callback<T> {
override fun onResponse(
call: Call<T>,
response: Response<T>
) {
thread {
db.actionsDao().delete(action)
}
}
override fun onFailure(call: Call<T>, t: Throwable) {
ACRA.getErrorReporter().maybeHandleSilentException(t, this@HomeActivity)
}
})
}
if (this@HomeActivity.isNetworkAccessible(null)) {
thread {
val actions = db.actionsDao().actions()
actions.forEach { action ->
when {
action.read -> doAndReportOnFail(api.markItem(action.articleId), action)
action.unread -> doAndReportOnFail(api.unmarkItem(action.articleId), action)
action.starred -> doAndReportOnFail(api.starrItem(action.articleId), action)
action.unstarred -> doAndReportOnFail(api.unstarrItem(action.articleId), action)
}
}
}
}
}
} }

View File

@ -1,8 +1,11 @@
package apps.amine.bou.readerforselfoss package apps.amine.bou.readerforselfoss
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.Context import android.content.Context
import android.graphics.drawable.Drawable import android.graphics.drawable.Drawable
import android.net.Uri import android.net.Uri
import android.os.Build
import android.preference.PreferenceManager import android.preference.PreferenceManager
import androidx.multidex.MultiDexApplication import androidx.multidex.MultiDexApplication
import android.widget.ImageView import android.widget.ImageView
@ -59,6 +62,18 @@ class MyApp : MultiDexApplication() {
initTheme() initTheme()
tryToHandleBug() tryToHandleBug()
handleNotificationChannels()
}
private fun handleNotificationChannels() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val name = getString(R.string.notification_channel_sync)
val importance = NotificationManager.IMPORTANCE_LOW
val mChannel = NotificationChannel(Config.syncChannelId, name, importance)
val notificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(mChannel)
}
} }
override fun attachBaseContext(base: Context?) { override fun attachBaseContext(base: Context?) {

View File

@ -19,7 +19,9 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.fragments.ArticleFragment import apps.amine.bou.readerforselfoss.fragments.ArticleFragment
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2 import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.themes.Toppings import apps.amine.bou.readerforselfoss.themes.Toppings
import apps.amine.bou.readerforselfoss.transformers.DepthPageTransformer import apps.amine.bou.readerforselfoss.transformers.DepthPageTransformer
@ -71,7 +73,7 @@ class ReaderActivity : AppCompatActivity() {
db = Room.databaseBuilder( db = Room.databaseBuilder(
applicationContext, applicationContext,
AppDatabase::class.java, "selfoss-database" AppDatabase::class.java, "selfoss-database"
).addMigrations(MIGRATION_1_2).build() ).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).build()
val scoop = Scoop.getInstance() val scoop = Scoop.getInstance()
scoop.bind(this, Toppings.PRIMARY.value, toolBar) scoop.bind(this, Toppings.PRIMARY.value, toolBar)
@ -134,44 +136,50 @@ class ReaderActivity : AppCompatActivity() {
} }
fun readItem(item: Item) { fun readItem(item: Item) {
if (this@ReaderActivity.isNetworkAccessible(this@ReaderActivity.findViewById(R.id.reader_activity_view)) && markOnScroll) { if (markOnScroll) {
thread { thread {
db.itemsDao().delete(item.toEntity()) db.itemsDao().delete(item.toEntity())
} }
api.markItem(item.id).enqueue( if (this@ReaderActivity.isNetworkAccessible(this@ReaderActivity.findViewById(R.id.reader_activity_view))) {
object : Callback<SuccessResponse> { api.markItem(item.id).enqueue(
override fun onResponse( object : Callback<SuccessResponse> {
call: Call<SuccessResponse>, override fun onResponse(
response: Response<SuccessResponse> call: Call<SuccessResponse>,
) { response: Response<SuccessResponse>
if (!response.succeeded() && debugReadingItems) { ) {
val message = if (!response.succeeded() && debugReadingItems) {
"message: ${response.message()} " + val message =
"response isSuccess: ${response.isSuccessful} " + "message: ${response.message()} " +
"response code: ${response.code()} " + "response isSuccess: ${response.isSuccessful} " +
"response message: ${response.message()} " + "response code: ${response.code()} " +
"response errorBody: ${response.errorBody()?.string()} " + "response message: ${response.message()} " +
"body success: ${response.body()?.success} " + "response errorBody: ${response.errorBody()?.string()} " +
"body isSuccess: ${response.body()?.isSuccess}" "body success: ${response.body()?.success} " +
ACRA.getErrorReporter() "body isSuccess: ${response.body()?.isSuccess}"
.maybeHandleSilentException(Exception(message), this@ReaderActivity) ACRA.getErrorReporter()
.maybeHandleSilentException(Exception(message), this@ReaderActivity)
}
} }
}
override fun onFailure( override fun onFailure(
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
t: Throwable t: Throwable
) { ) {
thread { thread {
db.itemsDao().insertAllItems(item.toEntity()) db.itemsDao().insertAllItems(item.toEntity())
} }
if (debugReadingItems) { if (debugReadingItems) {
ACRA.getErrorReporter() ACRA.getErrorReporter()
.maybeHandleSilentException(t, this@ReaderActivity) .maybeHandleSilentException(t, this@ReaderActivity)
}
} }
} }
)
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(item.id, true, false, false, false))
} }
) }
} }
} }
@ -229,6 +237,19 @@ class ReaderActivity : AppCompatActivity() {
} }
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
fun afterSave() {
allItems[pager.currentItem] =
allItems[pager.currentItem].toggleStar()
notifyAdapter()
canRemoveFromFavorite()
}
fun afterUnsave() {
allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar()
notifyAdapter()
canFavorite()
}
when (item.itemId) { when (item.itemId) {
android.R.id.home -> { android.R.id.home -> {
onBackPressed() onBackPressed()
@ -242,9 +263,7 @@ class ReaderActivity : AppCompatActivity() {
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
response: Response<SuccessResponse> response: Response<SuccessResponse>
) { ) {
allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar() afterSave()
notifyAdapter()
canRemoveFromFavorite()
} }
override fun onFailure( override fun onFailure(
@ -258,6 +277,11 @@ class ReaderActivity : AppCompatActivity() {
).show() ).show()
} }
}) })
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(allItems[pager.currentItem].id, false, false, true, false))
afterSave()
}
} }
} }
R.id.unsave -> { R.id.unsave -> {
@ -268,9 +292,7 @@ class ReaderActivity : AppCompatActivity() {
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
response: Response<SuccessResponse> response: Response<SuccessResponse>
) { ) {
allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar() afterUnsave()
notifyAdapter()
canFavorite()
} }
override fun onFailure( override fun onFailure(
@ -284,6 +306,11 @@ class ReaderActivity : AppCompatActivity() {
).show() ).show()
} }
}) })
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(allItems[pager.currentItem].id, false, false, false, true))
afterUnsave()
}
} }
} }
} }

View File

@ -15,6 +15,7 @@ import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.LinkOnTouchListener import apps.amine.bou.readerforselfoss.utils.LinkOnTouchListener
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
@ -36,6 +37,7 @@ import kotlinx.android.synthetic.main.card_item.view.*
import retrofit2.Call import retrofit2.Call
import retrofit2.Callback import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
import kotlin.concurrent.thread
class ItemCardAdapter( class ItemCardAdapter(
override val app: Activity, override val app: Activity,
@ -118,8 +120,8 @@ class ItemCardAdapter(
mView.favButton.setOnLikeListener(object : OnLikeListener { mView.favButton.setOnLikeListener(object : OnLikeListener {
override fun liked(likeButton: LikeButton) { override fun liked(likeButton: LikeButton) {
val (id) = items[adapterPosition]
if (c.isNetworkAccessible(null)) { if (c.isNetworkAccessible(null)) {
val (id) = items[adapterPosition]
api.starrItem(id).enqueue(object : Callback<SuccessResponse> { api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse( override fun onResponse(
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
@ -139,12 +141,16 @@ class ItemCardAdapter(
).show() ).show()
} }
}) })
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(id, false, false, true, false))
}
} }
} }
override fun unLiked(likeButton: LikeButton) { override fun unLiked(likeButton: LikeButton) {
val (id) = items[adapterPosition]
if (c.isNetworkAccessible(null)) { if (c.isNetworkAccessible(null)) {
val (id) = items[adapterPosition]
api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> { api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse( override fun onResponse(
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
@ -164,6 +170,10 @@ class ItemCardAdapter(
).show() ).show()
} }
}) })
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(id, false, false, false, true))
}
} }
} }
}) })

View File

@ -11,6 +11,7 @@ import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException
import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible
@ -46,14 +47,14 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
Snackbar.LENGTH_LONG Snackbar.LENGTH_LONG
) )
.setAction(R.string.undo_string) { .setAction(R.string.undo_string) {
if (app.isNetworkAccessible(null)) { items.add(position, i)
items.add(position, i) thread {
thread { db.itemsDao().insertAllItems(i.toEntity())
db.itemsDao().insertAllItems(i.toEntity()) }
} notifyItemInserted(position)
notifyItemInserted(position) updateItems(items)
updateItems(items)
if (app.isNetworkAccessible(null)) {
api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> { api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse( override fun onResponse(
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
@ -71,6 +72,10 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
doUnmark(i, position) doUnmark(i, position)
} }
}) })
} else {
thread {
db.actionsDao().deleteReadActionForArticle(i.id)
}
} }
} }
@ -81,20 +86,16 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
} }
fun removeItemAtIndex(position: Int) { fun removeItemAtIndex(position: Int) {
val i = items[position]
items.remove(i)
notifyItemRemoved(position)
updateItems(items)
thread {
db.itemsDao().delete(i.toEntity())
}
if (app.isNetworkAccessible(null)) { if (app.isNetworkAccessible(null)) {
val i = items[position]
items.remove(i)
notifyItemRemoved(position)
updateItems(items)
// TODO: Handle network status.
// IF offline, delete from cached articles, and add to some table that will replay the calls on network activation.
thread {
db.itemsDao().delete(i.toEntity())
}
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> { api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse( override fun onResponse(
call: Call<SuccessResponse>, call: Call<SuccessResponse>,
@ -135,6 +136,11 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
} }
} }
}) })
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(i.id, true, false, false, false))
doUnmark(i, position)
}
} }
} }

View File

@ -21,7 +21,7 @@ import java.util.concurrent.ConcurrentHashMap
class SelfossApi( class SelfossApi(
c: Context, c: Context,
callingActivity: Activity, callingActivity: Activity?,
isWithSelfSignedCert: Boolean, isWithSelfSignedCert: Boolean,
shouldLog: Boolean shouldLog: Boolean
) { ) {
@ -91,7 +91,9 @@ class SelfossApi(
.build() .build()
service = retrofit.create(SelfossService::class.java) service = retrofit.create(SelfossService::class.java)
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
Config.logoutAndRedirect(c, callingActivity, config.settings.edit(), baseUrlFail = true) if (callingActivity != null) {
Config.logoutAndRedirect(c, callingActivity, config.settings.edit(), baseUrlFail = true)
}
} }
} }

View File

@ -0,0 +1,126 @@
package apps.amine.bou.readerforselfoss.background
import android.app.NotificationManager
import android.content.Context
import android.os.Handler
import android.preference.PreferenceManager
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.PRIORITY_LOW
import androidx.room.Room
import androidx.work.Worker
import androidx.work.WorkerParameters
import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException
import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible
import apps.amine.bou.readerforselfoss.utils.persistence.toEntity
import org.acra.ACRA
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.util.*
import kotlin.concurrent.schedule
import kotlin.concurrent.thread
class LoadingWorker(val context: Context, params: WorkerParameters) : Worker(context, params) {
lateinit var db: AppDatabase
override fun doWork(): Result {
if (context.isNetworkAccessible(null)) {
val notificationManager =
applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val notification = NotificationCompat.Builder(applicationContext, Config.syncChannelId)
.setContentTitle(context.getString(R.string.loading_notification_title))
.setContentText(context.getString(R.string.loading_notification_text))
.setOngoing(true)
.setPriority(PRIORITY_LOW)
.setChannelId(Config.syncChannelId)
.setSmallIcon(R.drawable.ic_cloud_download)
notificationManager.notify(1, notification.build())
val settings =
this.context.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
val sharedPref = PreferenceManager.getDefaultSharedPreferences(this.context)
val shouldLogEverything = sharedPref.getBoolean("should_log_everything", false)
db = Room.databaseBuilder(
applicationContext,
AppDatabase::class.java, "selfoss-database"
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).build()
val api = SelfossApi(
this.context,
null,
settings.getBoolean("isSelfSignedCert", false),
shouldLogEverything
)
api.allItems().enqueue(object : Callback<List<Item>> {
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
Timer("", false).schedule(4000) {
notificationManager.cancel(1)
}
}
override fun onResponse(
call: Call<List<Item>>,
response: Response<List<Item>>
) {
thread {
if (response.body() != null) {
val apiItems = (response.body() as ArrayList<Item>)
db.itemsDao().deleteAllItems()
db.itemsDao()
.insertAllItems(*(apiItems.map { it.toEntity() }).toTypedArray())
}
Timer("", false).schedule(4000) {
notificationManager.cancel(1)
}
}
}
})
thread {
val actions = db.actionsDao().actions()
actions.forEach { action ->
when {
action.read -> doAndReportOnFail(api.markItem(action.articleId), action)
action.unread -> doAndReportOnFail(api.unmarkItem(action.articleId), action)
action.starred -> doAndReportOnFail(api.starrItem(action.articleId), action)
action.unstarred -> doAndReportOnFail(
api.unstarrItem(action.articleId),
action
)
}
}
}
}
return Result.SUCCESS
}
private fun <T> doAndReportOnFail(call: Call<T>, action: ActionEntity) {
call.enqueue(object : Callback<T> {
override fun onResponse(
call: Call<T>,
response: Response<T>
) {
thread {
db.actionsDao().delete(action)
}
}
override fun onFailure(call: Call<T>, t: Throwable) {
ACRA.getErrorReporter().maybeHandleSilentException(t, context)
}
})
}
}

View File

@ -17,12 +17,17 @@ import android.view.MenuItem
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.webkit.WebSettings import android.webkit.WebSettings
import androidx.room.Room
import apps.amine.bou.readerforselfoss.R import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent
import apps.amine.bou.readerforselfoss.api.selfoss.Item import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.Config import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
@ -45,6 +50,7 @@ import retrofit2.Callback
import retrofit2.Response import retrofit2.Response
import java.net.MalformedURLException import java.net.MalformedURLException
import java.net.URL import java.net.URL
import kotlin.concurrent.thread
class ArticleFragment : Fragment() { class ArticleFragment : Fragment() {
private lateinit var pageNumber: Number private lateinit var pageNumber: Number
@ -59,6 +65,7 @@ class ArticleFragment : Fragment() {
private lateinit var editor: SharedPreferences.Editor private lateinit var editor: SharedPreferences.Editor
private lateinit var fab: FloatingActionButton private lateinit var fab: FloatingActionButton
private lateinit var appColors: AppColors private lateinit var appColors: AppColors
private lateinit var db: AppDatabase
override fun onStop() { override fun onStop() {
super.onStop() super.onStop()
@ -72,6 +79,11 @@ class ArticleFragment : Fragment() {
pageNumber = arguments!!.getInt(ARG_POSITION) pageNumber = arguments!!.getInt(ARG_POSITION)
allItems = arguments!!.getParcelableArrayList(ARG_ITEMS) allItems = arguments!!.getParcelableArrayList(ARG_ITEMS)
db = Room.databaseBuilder(
context!!,
AppDatabase::class.java, "selfoss-database"
).addMigrations(MIGRATION_1_2).addMigrations(MIGRATION_2_3).build()
} }
private lateinit var rootView: ViewGroup private lateinit var rootView: ViewGroup
@ -166,6 +178,10 @@ class ArticleFragment : Fragment() {
} }
} }
) )
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(allItems[pageNumber.toInt()].id, false, true, false, false))
}
} }
else -> Unit else -> Unit
} }

View File

@ -0,0 +1,23 @@
package apps.amine.bou.readerforselfoss.persistence.dao
import androidx.room.Dao
import androidx.room.Delete
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.Query
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
@Dao
interface ActionsDao {
@Query("SELECT * FROM actions order by id asc")
fun actions(): List<ActionEntity>
@Insert(onConflict = OnConflictStrategy.REPLACE)
fun insertAllActions(vararg actions: ActionEntity)
@Query("DELETE FROM actions WHERE articleid = :article_id AND read = 1")
fun deleteReadActionForArticle(article_id: String)
@Delete
fun delete(action: ActionEntity)
}

View File

@ -2,15 +2,19 @@ package apps.amine.bou.readerforselfoss.persistence.database
import androidx.room.RoomDatabase import androidx.room.RoomDatabase
import androidx.room.Database import androidx.room.Database
import apps.amine.bou.readerforselfoss.persistence.dao.ActionsDao
import apps.amine.bou.readerforselfoss.persistence.dao.DrawerDataDao import apps.amine.bou.readerforselfoss.persistence.dao.DrawerDataDao
import apps.amine.bou.readerforselfoss.persistence.dao.ItemsDao import apps.amine.bou.readerforselfoss.persistence.dao.ItemsDao
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
import apps.amine.bou.readerforselfoss.persistence.entities.ItemEntity import apps.amine.bou.readerforselfoss.persistence.entities.ItemEntity
import apps.amine.bou.readerforselfoss.persistence.entities.SourceEntity import apps.amine.bou.readerforselfoss.persistence.entities.SourceEntity
import apps.amine.bou.readerforselfoss.persistence.entities.TagEntity import apps.amine.bou.readerforselfoss.persistence.entities.TagEntity
@Database(entities = [TagEntity::class, SourceEntity::class, ItemEntity::class], version = 2) @Database(entities = [TagEntity::class, SourceEntity::class, ItemEntity::class, ActionEntity::class], version = 3)
abstract class AppDatabase : RoomDatabase() { abstract class AppDatabase : RoomDatabase() {
abstract fun drawerDataDao(): DrawerDataDao abstract fun drawerDataDao(): DrawerDataDao
abstract fun itemsDao(): ItemsDao abstract fun itemsDao(): ItemsDao
abstract fun actionsDao(): ActionsDao
} }

View File

@ -0,0 +1,22 @@
package apps.amine.bou.readerforselfoss.persistence.entities
import androidx.room.ColumnInfo
import androidx.room.Entity
import androidx.room.PrimaryKey
@Entity(tableName = "actions")
data class ActionEntity(
@ColumnInfo(name = "articleid")
val articleId: String,
@ColumnInfo(name = "read")
val read: Boolean,
@ColumnInfo(name = "unread")
val unread: Boolean,
@ColumnInfo(name = "starred")
var starred: Boolean,
@ColumnInfo(name = "unstarred")
var unstarred: Boolean
) {
@PrimaryKey(autoGenerate = true)
var id: Int = 0
}

View File

@ -8,3 +8,9 @@ val MIGRATION_1_2: Migration = object : Migration(1, 2) {
database.execSQL("CREATE TABLE IF NOT EXISTS `items` (`id` TEXT NOT NULL, `datetime` TEXT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `thumbnail` TEXT NOT NULL, `icon` TEXT NOT NULL, `link` TEXT NOT NULL, `sourcetitle` TEXT NOT NULL, `tags` TEXT NOT NULL, PRIMARY KEY(`id`))") database.execSQL("CREATE TABLE IF NOT EXISTS `items` (`id` TEXT NOT NULL, `datetime` TEXT NOT NULL, `title` TEXT NOT NULL, `content` TEXT NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `thumbnail` TEXT NOT NULL, `icon` TEXT NOT NULL, `link` TEXT NOT NULL, `sourcetitle` TEXT NOT NULL, `tags` TEXT NOT NULL, PRIMARY KEY(`id`))")
} }
} }
val MIGRATION_2_3: Migration = object : Migration(2, 3) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("CREATE TABLE IF NOT EXISTS `actions` (`id` INTEGER NOT NULL, `articleid` TEXT NOT NULL, `read` INTEGER NOT NULL, `unread` INTEGER NOT NULL, `starred` INTEGER NOT NULL, `unstarred` INTEGER NOT NULL, PRIMARY KEY(`id`))")
}
}

View File

@ -36,6 +36,8 @@ class Config(c: Context) {
const val trackerUrl = "https://github.com/aminecmi/ReaderforSelfoss/issues" const val trackerUrl = "https://github.com/aminecmi/ReaderforSelfoss/issues"
const val syncChannelId = "sync-channel-id"
fun logoutAndRedirect( fun logoutAndRedirect(
c: Context, c: Context,
callingActivity: Activity, callingActivity: Activity,

Binary file not shown.

After

Width:  |  Height:  |  Size: 334 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 380 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 678 B

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -152,5 +152,13 @@
<string name="pref_switch_items_caching_off">Los artículos no se guardarán en la memoria del dispositivo y la aplicación no se podrá utilizar sin conexión.</string> <string name="pref_switch_items_caching_off">Los artículos no se guardarán en la memoria del dispositivo y la aplicación no se podrá utilizar sin conexión.</string>
<string name="pref_switch_items_caching_on">Los artículos se guardarán en la memoria del dispositivo y se utilizarán para el uso sin conexión.</string> <string name="pref_switch_items_caching_on">Los artículos se guardarán en la memoria del dispositivo y se utilizarán para el uso sin conexión.</string>
<string name="pref_switch_items_caching">Guardar elementos para uso sin conexión</string> <string name="pref_switch_items_caching">Guardar elementos para uso sin conexión</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Sin conexión!</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -152,5 +152,13 @@
<string name="pref_switch_items_caching_off">Les articles ne seront pas enregistrés et l\'application ne sera pas utilisable hors ligne.</string> <string name="pref_switch_items_caching_off">Les articles ne seront pas enregistrés et l\'application ne sera pas utilisable hors ligne.</string>
<string name="pref_switch_items_caching_on">Les articles seront enregistrés et l\'application sera utilisable hors ligne.</string> <string name="pref_switch_items_caching_on">Les articles seront enregistrés et l\'application sera utilisable hors ligne.</string>
<string name="pref_switch_items_caching">Sauvegarder les articles pour une utilisation hors ligne</string> <string name="pref_switch_items_caching">Sauvegarder les articles pour une utilisation hors ligne</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Hors connexion !</string>
<string name="pref_switch_periodic_refresh">Synchroniser les articles</string>
<string name="pref_switch_periodic_refresh_off">Les articles ne seront pas synchronisés en arrière plan</string>
<string name="pref_switch_periodic_refresh_on">Articles seront périodiquement synchronisées</string>
<string name="pref_periodic_refresh_minutes_title"><![CDATA[Interval de synchronisation ( >= 15 minutes)]]></string>
<string name="pref_switch_refresh_when_charging">Synchroniser uniquement lorsque le téléphone est en charge</string>
<string name="loading_notification_title">Chargement ...</string>
<string name="loading_notification_text">Selfoss synchronise vos articles</string>
<string name="notification_channel_sync">Notification de synchronisation</string>
</resources> </resources>

View File

@ -152,5 +152,13 @@
<string name="pref_switch_items_caching_off">Os artigos non se gardaran na memoria do dispositivo e non se poderá utilizar a aplicación sen conexión.</string> <string name="pref_switch_items_caching_off">Os artigos non se gardaran na memoria do dispositivo e non se poderá utilizar a aplicación sen conexión.</string>
<string name="pref_switch_items_caching_on">Os artigos gardaranse na memoria do dispositivo e estarán dispoñibles sen conexión.</string> <string name="pref_switch_items_caching_on">Os artigos gardaranse na memoria do dispositivo e estarán dispoñibles sen conexión.</string>
<string name="pref_switch_items_caching">Gardar elementos para uso sen conexión</string> <string name="pref_switch_items_caching">Gardar elementos para uso sen conexión</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Non conectado!</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -108,7 +108,7 @@
<string name="self_signed_cert_warning">出于安全考虑, 默认情况下不支持自签名证书。如果激活此项, 您遇到的任何安全问题我将概不负责。</string> <string name="self_signed_cert_warning">出于安全考虑, 默认情况下不支持自签名证书。如果激活此项, 您遇到的任何安全问题我将概不负责。</string>
<string name="pref_selfoss_category">塞尔福斯 Api</string> <string name="pref_selfoss_category">塞尔福斯 Api</string>
<string name="pref_api_items_number_title">已加载项目编号</string> <string name="pref_api_items_number_title">已加载项目编号</string>
<string name="pref_hidden_tags">Hidden Tags</string> <string name="pref_hidden_tags">隐藏段落</string>
<string name="read_debug_title">已读文章显示为未读?</string> <string name="read_debug_title">已读文章显示为未读?</string>
<string name="read_debug_off">将项目标记为已读时没有记录</string> <string name="read_debug_off">将项目标记为已读时没有记录</string>
<string name="read_debug_on">将项目标记为已读时将记录 Api 调用</string> <string name="read_debug_on">将项目标记为已读时将记录 Api 调用</string>
@ -133,7 +133,7 @@
<string name="pref_content_reader_font_size">Article reader content font size</string> <string name="pref_content_reader_font_size">Article reader content font size</string>
<string name="pref_header_viewer">Article viewer</string> <string name="pref_header_viewer">Article viewer</string>
<string name="refresh_dialog_message">This will refresh your Selfoss instance.</string> <string name="refresh_dialog_message">This will refresh your Selfoss instance.</string>
<string name="markall_dialog_message">This will mark all the items as read.</string> <string name="markall_dialog_message">這會使全部項目標示為已讀</string>
<string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string> <string name="pref_switch_actions_pager_scroll">Mark as read on swipe</string>
<string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string> <string name="pref_switch_actions_pager_scroll_off">Don\'t mark articles as read when swiping.</string>
<string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string> <string name="gdpr_dialog_message">The app does not collect any personal data. Every analytics tools were removed. Crash reports sending is now optional, as is the debug logging. Keep in mind that debugging and crash reports are essential for the app development (You can configure everything in Settings &gt; Debug).</string>
@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -153,4 +153,12 @@
<string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string> <string name="pref_switch_items_caching_on">Articles will be saved to the device memory and will be used for offline use.</string>
<string name="pref_switch_items_caching">Save items for offline use</string> <string name="pref_switch_items_caching">Save items for offline use</string>
<string name="no_network_connectivity">Not connected !</string> <string name="no_network_connectivity">Not connected !</string>
<string name="pref_switch_periodic_refresh">Sync articles</string>
<string name="pref_switch_periodic_refresh_off">Articles will not be synced in the background</string>
<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_text">Selfoss is syncing your articles</string>
<string name="notification_channel_sync">Sync notification</string>
</resources> </resources>

View File

@ -5,4 +5,27 @@
android:summaryOff="@string/pref_switch_items_caching_off" android:summaryOff="@string/pref_switch_items_caching_off"
android:summaryOn="@string/pref_switch_items_caching_on" android:summaryOn="@string/pref_switch_items_caching_on"
android:title="@string/pref_switch_items_caching" /> android:title="@string/pref_switch_items_caching" />
<SwitchPreference
android:defaultValue="false"
android:key="periodic_refresh"
android:dependency="items_caching"
android:summaryOff="@string/pref_switch_periodic_refresh_off"
android:summaryOn="@string/pref_switch_periodic_refresh_on"
android:title="@string/pref_switch_periodic_refresh" />
<EditTextPreference
android:dependency="periodic_refresh"
android:defaultValue="360"
android:inputType="number"
android:key="periodic_refresh_minutes"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="@string/pref_periodic_refresh_minutes_title" />
<SwitchPreference
android:defaultValue="false"
android:key="refresh_when_charging"
android:dependency="periodic_refresh"
android:title="@string/pref_switch_refresh_when_charging" />
</PreferenceScreen> </PreferenceScreen>

View File

@ -6,6 +6,7 @@ buildscript {
android_version = '1.0.0' android_version = '1.0.0'
lifecycle_version = '2.0.0' lifecycle_version = '2.0.0'
room_version = '2.1.0-alpha01' room_version = '2.1.0-alpha01'
work_version = "1.0.0-alpha10"
} }
repositories { repositories {
google() google()

View File

@ -1,14 +1 @@
include ':app' include ':app'
ext.isCiServer = !!System.getProperty("CI")
buildCache {
local {
enabled = !isCiServer
}
remote(HttpBuildCache) {
// DO NOT COMMIT !!!!!
url = 'http://amine-bou.fr:8885/cache/'
push = isCiServer
}
}