Compare commits
	
		
			12 Commits
		
	
	
		
			v171810292
			...
			v171811307
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | fec6683701 | ||
|  | 1549edb647 | ||
|  | 3de48ba162 | ||
|  | a2a3d6f1a7 | ||
|  | ccab2c7648 | ||
|  | 880dd1db5c | ||
|  | ed18fea356 | ||
|  | 9816b20bf6 | ||
|  | 0bb2195bff | ||
|  | ab2d0c4036 | ||
|  | 99fc417109 | ||
|  | dc304ef8c1 | 
| @@ -4,6 +4,8 @@ | |||||||
|  |  | ||||||
| - 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. | ||||||
|  |  | ||||||
|  | - Closing #38. Only doing api calls on network available. | ||||||
|  |  | ||||||
| **1.6.x** | **1.6.x** | ||||||
|  |  | ||||||
| - Handling hidden tags. | - Handling hidden tags. | ||||||
|   | |||||||
| @@ -160,6 +160,8 @@ dependencies { | |||||||
|  |  | ||||||
|     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" | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -3,6 +3,7 @@ | |||||||
|     package="apps.amine.bou.readerforselfoss" |     package="apps.amine.bou.readerforselfoss" | ||||||
|     xmlns:tools="http://schemas.android.com/tools"> |     xmlns:tools="http://schemas.android.com/tools"> | ||||||
|  |  | ||||||
|  |     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> | ||||||
|     <uses-permission android:name="android.permission.INTERNET" /> |     <uses-permission android:name="android.permission.INTERNET" /> | ||||||
|  |  | ||||||
|     <application |     <application | ||||||
|   | |||||||
| @@ -25,6 +25,11 @@ 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.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,6 +39,7 @@ 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.migrations.MIGRATION_1_2 | import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2 | ||||||
| import apps.amine.bou.readerforselfoss.settings.SettingsActivity | import apps.amine.bou.readerforselfoss.settings.SettingsActivity | ||||||
| @@ -47,6 +53,7 @@ import apps.amine.bou.readerforselfoss.utils.drawer.CustomUrlPrimaryDrawerItem | |||||||
| import apps.amine.bou.readerforselfoss.utils.flattenTags | import apps.amine.bou.readerforselfoss.utils.flattenTags | ||||||
| import apps.amine.bou.readerforselfoss.utils.longHash | import apps.amine.bou.readerforselfoss.utils.longHash | ||||||
| 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.persistence.toEntity | import apps.amine.bou.readerforselfoss.utils.persistence.toEntity | ||||||
| import apps.amine.bou.readerforselfoss.utils.persistence.toView | import apps.amine.bou.readerforselfoss.utils.persistence.toView | ||||||
| import co.zsmb.materialdrawerkt.builders.accountHeader | import co.zsmb.materialdrawerkt.builders.accountHeader | ||||||
| @@ -74,6 +81,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 { | ||||||
| @@ -179,6 +187,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|         handleDrawer() |         handleDrawer() | ||||||
|  |  | ||||||
|         handleSwipeRefreshLayout() |         handleSwipeRefreshLayout() | ||||||
|  |  | ||||||
|  |         handleRecurringTask() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun handleSwipeRefreshLayout() { |     private fun handleSwipeRefreshLayout() { | ||||||
| @@ -203,7 +213,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                     recyclerView: RecyclerView, |                     recyclerView: RecyclerView, | ||||||
|                     viewHolder: RecyclerView.ViewHolder |                     viewHolder: RecyclerView.ViewHolder | ||||||
|                 ): Int = |                 ): Int = | ||||||
|                     if (elementsShown != UNREAD_SHOWN) { |                     if (elementsShown != UNREAD_SHOWN || !this@HomeActivity.isNetworkAccessible(null)) { | ||||||
|                         0 |                         0 | ||||||
|                     } else { |                     } else { | ||||||
|                         super.getSwipeDirs( |                         super.getSwipeDirs( | ||||||
| @@ -333,7 +343,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|  |  | ||||||
|         getElementsAccordingToTab() |         getElementsAccordingToTab() | ||||||
|  |  | ||||||
|  |  | ||||||
|         handleGDPRDialog(sharedPref.getBoolean("GDPR_shown", false)) |         handleGDPRDialog(sharedPref.getBoolean("GDPR_shown", false)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -696,6 +705,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|             var sources: List<Source>? |             var sources: List<Source>? | ||||||
|  |  | ||||||
|             fun sourcesApiCall() { |             fun sourcesApiCall() { | ||||||
|  |                 if (this@HomeActivity.isNetworkAccessible(null)) { | ||||||
|                     api.sources.enqueue(object : Callback<List<Source>> { |                     api.sources.enqueue(object : Callback<List<Source>> { | ||||||
|                         override fun onResponse( |                         override fun onResponse( | ||||||
|                             call: Call<List<Source>>?, |                             call: Call<List<Source>>?, | ||||||
| @@ -712,7 +722,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                         } |                         } | ||||||
|                     }) |                     }) | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (this@HomeActivity.isNetworkAccessible(null)) { | ||||||
|                 api.tags.enqueue(object : Callback<List<Tag>> { |                 api.tags.enqueue(object : Callback<List<Tag>> { | ||||||
|                     override fun onResponse( |                     override fun onResponse( | ||||||
|                         call: Call<List<Tag>>, |                         call: Call<List<Tag>>, | ||||||
| @@ -727,6 +739,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                     } |                     } | ||||||
|                 }) |                 }) | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         drawer.addItem( |         drawer.addItem( | ||||||
|             PrimaryDrawerItem().withName(getString(R.string.drawer_loading)).withSelectable( |             PrimaryDrawerItem().withName(getString(R.string.drawer_loading)).withSelectable( | ||||||
| @@ -817,12 +830,52 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|             override fun onTabSelected(position: Int) { |             override fun onTabSelected(position: Int) { | ||||||
|                 offset = 0 |                 offset = 0 | ||||||
|                 lastFetchDone = false |                 lastFetchDone = false | ||||||
|  |  | ||||||
|  |                 if (itemsCaching) { | ||||||
|  |  | ||||||
|  |                     if (!swipeRefreshLayout.isRefreshing) { | ||||||
|  |                         swipeRefreshLayout.post { swipeRefreshLayout.isRefreshing = true } | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     thread { | ||||||
|  |                         val dbItems = db.itemsDao().items().map { it.toView() } | ||||||
|  |                         runOnUiThread { | ||||||
|  |                             if (dbItems.isNotEmpty()) { | ||||||
|  |                                 items = when (position) { | ||||||
|  |                                     0 -> ArrayList(dbItems.filter { it.unread }) | ||||||
|  |                                     1 -> ArrayList(dbItems.filter { !it.unread }) | ||||||
|  |                                     2 -> ArrayList(dbItems.filter { it.starred }) | ||||||
|  |                                     else -> ArrayList(dbItems.filter { it.unread }) | ||||||
|  |                                 } | ||||||
|  |                                 handleListResult() | ||||||
|                                 when (position) { |                                 when (position) { | ||||||
|                                     0 -> getUnRead() |                                     0 -> getUnRead() | ||||||
|                                     1 -> getRead() |                                     1 -> getRead() | ||||||
|                                     2 -> getStarred() |                                     2 -> getStarred() | ||||||
|                                     else -> Unit |                                     else -> Unit | ||||||
|                                 } |                                 } | ||||||
|  |                             } else { | ||||||
|  |                                 if (this@HomeActivity.isNetworkAccessible(this@HomeActivity.findViewById(R.id.coordLayout))) { | ||||||
|  |                                     when (position) { | ||||||
|  |                                         0 -> getUnRead() | ||||||
|  |                                         1 -> getRead() | ||||||
|  |                                         2 -> getStarred() | ||||||
|  |                                         else -> Unit | ||||||
|  |                                     } | ||||||
|  |                                     getAndStoreAllItems() | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                 } else { | ||||||
|  |                     when (position) { | ||||||
|  |                         0 -> getUnRead() | ||||||
|  |                         1 -> getRead() | ||||||
|  |                         2 -> getStarred() | ||||||
|  |                         else -> Unit | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|         }) |         }) | ||||||
|     } |     } | ||||||
| @@ -899,11 +952,13 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                         handleListResult() |                         handleListResult() | ||||||
|                         doGetAccordingToTab() |                         doGetAccordingToTab() | ||||||
|                     } else { |                     } else { | ||||||
|  |                         if (this@HomeActivity.isNetworkAccessible(this@HomeActivity.findViewById(R.id.coordLayout))) { | ||||||
|                             doGetAccordingToTab() |                             doGetAccordingToTab() | ||||||
|                             getAndStoreAllItems() |                             getAndStoreAllItems() | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|         } else { |         } else { | ||||||
|             doGetAccordingToTab() |             doGetAccordingToTab() | ||||||
| @@ -956,6 +1011,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|             swipeRefreshLayout.post { swipeRefreshLayout.isRefreshing = true } |             swipeRefreshLayout.post { swipeRefreshLayout.isRefreshing = true } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         if (this@HomeActivity.isNetworkAccessible(this@HomeActivity.findViewById(R.id.coordLayout))) { | ||||||
|             call(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter) |             call(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter) | ||||||
|                 .enqueue(object : Callback<List<Item>> { |                 .enqueue(object : Callback<List<Item>> { | ||||||
|                     override fun onResponse( |                     override fun onResponse( | ||||||
| @@ -974,6 +1030,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                         ).show() |                         ).show() | ||||||
|                     } |                     } | ||||||
|                 }) |                 }) | ||||||
|  |         } else { | ||||||
|  |             swipeRefreshLayout.post { swipeRefreshLayout.isRefreshing = false } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun getUnRead(appendResults: Boolean = false) { |     private fun getUnRead(appendResults: Boolean = false) { | ||||||
| @@ -1082,7 +1141,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun reloadBadges() { |     private fun reloadBadges() { | ||||||
|         if (displayUnreadCount || displayAllCount) { |         if (this@HomeActivity.isNetworkAccessible(null) && (displayUnreadCount || displayAllCount)) { | ||||||
|             api.stats.enqueue(object : Callback<Stats> { |             api.stats.enqueue(object : Callback<Stats> { | ||||||
|                 override fun onResponse(call: Call<Stats>, response: Response<Stats>) { |                 override fun onResponse(call: Call<Stats>, response: Response<Stats>) { | ||||||
|                     if (response.body() != null) { |                     if (response.body() != null) { | ||||||
| @@ -1188,6 +1247,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|     override fun onOptionsItemSelected(item: MenuItem): Boolean { |     override fun onOptionsItemSelected(item: MenuItem): Boolean { | ||||||
|         when (item.itemId) { |         when (item.itemId) { | ||||||
|             R.id.refresh -> { |             R.id.refresh -> { | ||||||
|  |                 if (this@HomeActivity.isNetworkAccessible(null)) { | ||||||
|                     needsConfirmation(R.string.menu_home_refresh, R.string.refresh_dialog_message) { |                     needsConfirmation(R.string.menu_home_refresh, R.string.refresh_dialog_message) { | ||||||
|                         api.update().enqueue(object : Callback<String> { |                         api.update().enqueue(object : Callback<String> { | ||||||
|                             override fun onResponse( |                             override fun onResponse( | ||||||
| @@ -1212,9 +1272,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|                         Toast.makeText(this, R.string.refresh_in_progress, Toast.LENGTH_SHORT).show() |                         Toast.makeText(this, R.string.refresh_in_progress, Toast.LENGTH_SHORT).show() | ||||||
|                     } |                     } | ||||||
|                     return true |                     return true | ||||||
|  |                 } else { | ||||||
|  |                     return false | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|             R.id.readAll -> { |             R.id.readAll -> { | ||||||
|                 if (elementsShown == UNREAD_SHOWN) { |                 if (elementsShown == UNREAD_SHOWN && this@HomeActivity.isNetworkAccessible(null)) { | ||||||
|                     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 } | ||||||
| @@ -1334,5 +1397,25 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener { | |||||||
|             alertDialog.show() |             alertDialog.show() | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private fun handleRecurringTask() { | ||||||
|  |         // TODO: add network type | ||||||
|  |         val myConstraints = Constraints.Builder() | ||||||
|  |             .setRequiresBatteryNotLow(true) | ||||||
|  |             .setRequiresStorageNotLow(true) | ||||||
|  |             .build() | ||||||
|  |  | ||||||
|  |         // TODO: make the time variable from the settings. | ||||||
|  |         val backgroundWork = | ||||||
|  |             PeriodicWorkRequestBuilder<LoadingWorker>(4, TimeUnit.HOURS) | ||||||
|  |                 .setConstraints(myConstraints) | ||||||
|  |                 .addTag("selfoss-loading") | ||||||
|  |                 .build() | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         WorkManager.getInstance().enqueueUniquePeriodicWork("selfoss-loading", ExistingPeriodicWorkPolicy.REPLACE, backgroundWork) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,6 +21,7 @@ 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.isBaseUrlValid | import apps.amine.bou.readerforselfoss.utils.isBaseUrlValid | ||||||
| import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException | import apps.amine.bou.readerforselfoss.utils.maybeHandleSilentException | ||||||
|  | import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible | ||||||
| import com.mikepenz.aboutlibraries.Libs | import com.mikepenz.aboutlibraries.Libs | ||||||
| import com.mikepenz.aboutlibraries.LibsBuilder | import com.mikepenz.aboutlibraries.LibsBuilder | ||||||
| import kotlinx.android.synthetic.main.activity_login.* | import kotlinx.android.synthetic.main.activity_login.* | ||||||
| @@ -196,6 +197,8 @@ class LoginActivity : AppCompatActivity() { | |||||||
|                 isWithSelfSignedCert, |                 isWithSelfSignedCert, | ||||||
|                 isWithSelfSignedCert |                 isWithSelfSignedCert | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|  |             if (this@LoginActivity.isNetworkAccessible(this@LoginActivity.findViewById(R.id.loginForm))) { | ||||||
|                 api.login().enqueue(object : Callback<SuccessResponse> { |                 api.login().enqueue(object : Callback<SuccessResponse> { | ||||||
|                     private fun preferenceError(t: Throwable) { |                     private fun preferenceError(t: Throwable) { | ||||||
|                         editor.remove("url") |                         editor.remove("url") | ||||||
| @@ -235,6 +238,9 @@ class LoginActivity : AppCompatActivity() { | |||||||
|                         preferenceError(t) |                         preferenceError(t) | ||||||
|                     } |                     } | ||||||
|                 }) |                 }) | ||||||
|  |             } else { | ||||||
|  |                 showProgress(false) | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -24,6 +24,7 @@ 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 | ||||||
| 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.persistence.toEntity | import apps.amine.bou.readerforselfoss.utils.persistence.toEntity | ||||||
| import apps.amine.bou.readerforselfoss.utils.succeeded | import apps.amine.bou.readerforselfoss.utils.succeeded | ||||||
| import apps.amine.bou.readerforselfoss.utils.toggleStar | import apps.amine.bou.readerforselfoss.utils.toggleStar | ||||||
| @@ -103,7 +104,8 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|  |  | ||||||
|         readItem(allItems[currentItem]) |         readItem(allItems[currentItem]) | ||||||
|  |  | ||||||
|         pager.adapter = ScreenSlidePagerAdapter(supportFragmentManager, AppColors(this@ReaderActivity)) |         pager.adapter = | ||||||
|  |                 ScreenSlidePagerAdapter(supportFragmentManager, AppColors(this@ReaderActivity)) | ||||||
|         pager.currentItem = currentItem |         pager.currentItem = currentItem | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -132,7 +134,7 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun readItem(item: Item) { |     fun readItem(item: Item) { | ||||||
|         if (markOnScroll) { |         if (this@ReaderActivity.isNetworkAccessible(this@ReaderActivity.findViewById(R.id.reader_activity_view)) && markOnScroll) { | ||||||
|             thread { |             thread { | ||||||
|                 db.itemsDao().delete(item.toEntity()) |                 db.itemsDao().delete(item.toEntity()) | ||||||
|             } |             } | ||||||
| @@ -164,7 +166,8 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|                             db.itemsDao().insertAllItems(item.toEntity()) |                             db.itemsDao().insertAllItems(item.toEntity()) | ||||||
|                         } |                         } | ||||||
|                         if (debugReadingItems) { |                         if (debugReadingItems) { | ||||||
|                             ACRA.getErrorReporter().maybeHandleSilentException(t, this@ReaderActivity) |                             ACRA.getErrorReporter() | ||||||
|  |                                 .maybeHandleSilentException(t, this@ReaderActivity) | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -191,7 +194,6 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|     private inner class ScreenSlidePagerAdapter(fm: FragmentManager, val appColors: AppColors) : |     private inner class ScreenSlidePagerAdapter(fm: FragmentManager, val appColors: AppColors) : | ||||||
|         FragmentStatePagerAdapter(fm) { |         FragmentStatePagerAdapter(fm) { | ||||||
|  |  | ||||||
|  |  | ||||||
|         override fun getCount(): Int { |         override fun getCount(): Int { | ||||||
|             return allItems.size |             return allItems.size | ||||||
|         } |         } | ||||||
| @@ -203,7 +205,12 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|         override fun startUpdate(container: ViewGroup) { |         override fun startUpdate(container: ViewGroup) { | ||||||
|             super.startUpdate(container) |             super.startUpdate(container) | ||||||
|  |  | ||||||
|             container.background = ColorDrawable(ContextCompat.getColor(this@ReaderActivity, appColors.colorBackground)) |             container.background = ColorDrawable( | ||||||
|  |                 ContextCompat.getColor( | ||||||
|  |                     this@ReaderActivity, | ||||||
|  |                     appColors.colorBackground | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -228,6 +235,7 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|                 return true |                 return true | ||||||
|             } |             } | ||||||
|             R.id.save -> { |             R.id.save -> { | ||||||
|  |                 if (this@ReaderActivity.isNetworkAccessible(null)) { | ||||||
|                     api.starrItem(allItems[pager.currentItem].id) |                     api.starrItem(allItems[pager.currentItem].id) | ||||||
|                         .enqueue(object : Callback<SuccessResponse> { |                         .enqueue(object : Callback<SuccessResponse> { | ||||||
|                             override fun onResponse( |                             override fun onResponse( | ||||||
| @@ -251,7 +259,9 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|                             } |                             } | ||||||
|                         }) |                         }) | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|             R.id.unsave -> { |             R.id.unsave -> { | ||||||
|  |                 if (this@ReaderActivity.isNetworkAccessible(null)) { | ||||||
|                     api.unstarrItem(allItems[pager.currentItem].id) |                     api.unstarrItem(allItems[pager.currentItem].id) | ||||||
|                         .enqueue(object : Callback<SuccessResponse> { |                         .enqueue(object : Callback<SuccessResponse> { | ||||||
|                             override fun onResponse( |                             override fun onResponse( | ||||||
| @@ -276,6 +286,7 @@ class ReaderActivity : AppCompatActivity() { | |||||||
|                         }) |                         }) | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|         return super.onOptionsItemSelected(item) |         return super.onOptionsItemSelected(item) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi | |||||||
| import apps.amine.bou.readerforselfoss.api.selfoss.Source | import apps.amine.bou.readerforselfoss.api.selfoss.Source | ||||||
| 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.utils.network.isNetworkAccessible | ||||||
| import com.ftinc.scoop.Scoop | import com.ftinc.scoop.Scoop | ||||||
| import kotlinx.android.synthetic.main.activity_sources.* | import kotlinx.android.synthetic.main.activity_sources.* | ||||||
| import retrofit2.Call | import retrofit2.Call | ||||||
| @@ -66,6 +67,7 @@ class SourcesActivity : AppCompatActivity() { | |||||||
|         recyclerView.setHasFixedSize(true) |         recyclerView.setHasFixedSize(true) | ||||||
|         recyclerView.layoutManager = mLayoutManager |         recyclerView.layoutManager = mLayoutManager | ||||||
|  |  | ||||||
|  |         if (this@SourcesActivity.isNetworkAccessible(this@SourcesActivity.findViewById(R.id.recyclerView))) { | ||||||
|             api.sources.enqueue(object : Callback<List<Source>> { |             api.sources.enqueue(object : Callback<List<Source>> { | ||||||
|                 override fun onResponse( |                 override fun onResponse( | ||||||
|                     call: Call<List<Source>>, |                     call: Call<List<Source>>, | ||||||
| @@ -94,6 +96,7 @@ class SourcesActivity : AppCompatActivity() { | |||||||
|                     ).show() |                     ).show() | ||||||
|                 } |                 } | ||||||
|             }) |             }) | ||||||
|  |         } | ||||||
|  |  | ||||||
|         fab.setOnClickListener { |         fab.setOnClickListener { | ||||||
|             startActivity(Intent(this@SourcesActivity, AddSourceActivity::class.java)) |             startActivity(Intent(this@SourcesActivity, AddSourceActivity::class.java)) | ||||||
|   | |||||||
| @@ -16,10 +16,12 @@ 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.themes.AppColors | import apps.amine.bou.readerforselfoss.themes.AppColors | ||||||
|  | import apps.amine.bou.readerforselfoss.utils.LinkOnTouchListener | ||||||
| import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent | import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent | ||||||
| import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper | import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper | ||||||
| import apps.amine.bou.readerforselfoss.utils.glide.bitmapCenterCrop | import apps.amine.bou.readerforselfoss.utils.glide.bitmapCenterCrop | ||||||
| import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable | import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable | ||||||
|  | import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible | ||||||
| import apps.amine.bou.readerforselfoss.utils.openInBrowserAsNewTask | import apps.amine.bou.readerforselfoss.utils.openInBrowserAsNewTask | ||||||
| import apps.amine.bou.readerforselfoss.utils.openItemUrl | import apps.amine.bou.readerforselfoss.utils.openItemUrl | ||||||
| import apps.amine.bou.readerforselfoss.utils.shareLink | import apps.amine.bou.readerforselfoss.utils.shareLink | ||||||
| @@ -65,6 +67,7 @@ class ItemCardAdapter( | |||||||
|  |  | ||||||
|         holder.mView.favButton.isLiked = itm.starred |         holder.mView.favButton.isLiked = itm.starred | ||||||
|         holder.mView.title.text = Html.fromHtml(itm.title) |         holder.mView.title.text = Html.fromHtml(itm.title) | ||||||
|  |         holder.mView.title.setOnTouchListener(LinkOnTouchListener()) | ||||||
|  |  | ||||||
|         holder.mView.title.setLinkTextColor(appColors.colorAccent) |         holder.mView.title.setLinkTextColor(appColors.colorAccent) | ||||||
|  |  | ||||||
| @@ -115,6 +118,7 @@ class ItemCardAdapter( | |||||||
|  |  | ||||||
|             mView.favButton.setOnLikeListener(object : OnLikeListener { |             mView.favButton.setOnLikeListener(object : OnLikeListener { | ||||||
|                 override fun liked(likeButton: LikeButton) { |                 override fun liked(likeButton: LikeButton) { | ||||||
|  |                     if (c.isNetworkAccessible(null)) { | ||||||
|                         val (id) = items[adapterPosition] |                         val (id) = items[adapterPosition] | ||||||
|                         api.starrItem(id).enqueue(object : Callback<SuccessResponse> { |                         api.starrItem(id).enqueue(object : Callback<SuccessResponse> { | ||||||
|                             override fun onResponse( |                             override fun onResponse( | ||||||
| @@ -136,8 +140,10 @@ class ItemCardAdapter( | |||||||
|                             } |                             } | ||||||
|                         }) |                         }) | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|                 override fun unLiked(likeButton: LikeButton) { |                 override fun unLiked(likeButton: LikeButton) { | ||||||
|  |                     if (c.isNetworkAccessible(null)) { | ||||||
|                         val (id) = items[adapterPosition] |                         val (id) = items[adapterPosition] | ||||||
|                         api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> { |                         api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> { | ||||||
|                             override fun onResponse( |                             override fun onResponse( | ||||||
| @@ -159,6 +165,7 @@ class ItemCardAdapter( | |||||||
|                             } |                             } | ||||||
|                         }) |                         }) | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|             }) |             }) | ||||||
|  |  | ||||||
|             mView.shareBtn.setOnClickListener { |             mView.shareBtn.setOnClickListener { | ||||||
|   | |||||||
| @@ -5,10 +5,14 @@ import android.content.Context | |||||||
| import androidx.constraintlayout.widget.ConstraintLayout | import androidx.constraintlayout.widget.ConstraintLayout | ||||||
| import androidx.recyclerview.widget.RecyclerView | import androidx.recyclerview.widget.RecyclerView | ||||||
| import android.text.Html | import android.text.Html | ||||||
|  | import android.text.Spannable | ||||||
|  | import android.text.style.ClickableSpan | ||||||
| import android.util.TypedValue | import android.util.TypedValue | ||||||
| import android.view.LayoutInflater | import android.view.LayoutInflater | ||||||
|  | import android.view.MotionEvent | ||||||
| import android.view.View | import android.view.View | ||||||
| import android.view.ViewGroup | import android.view.ViewGroup | ||||||
|  | import android.widget.TextView | ||||||
| import android.widget.Toast | import android.widget.Toast | ||||||
| import apps.amine.bou.readerforselfoss.R | import apps.amine.bou.readerforselfoss.R | ||||||
| import apps.amine.bou.readerforselfoss.api.selfoss.Item | import apps.amine.bou.readerforselfoss.api.selfoss.Item | ||||||
| @@ -16,6 +20,7 @@ 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.themes.AppColors | import apps.amine.bou.readerforselfoss.themes.AppColors | ||||||
|  | import apps.amine.bou.readerforselfoss.utils.LinkOnTouchListener | ||||||
| import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent | import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent | ||||||
| import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper | import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper | ||||||
| import apps.amine.bou.readerforselfoss.utils.glide.bitmapCenterCrop | import apps.amine.bou.readerforselfoss.utils.glide.bitmapCenterCrop | ||||||
| @@ -67,6 +72,8 @@ class ItemListAdapter( | |||||||
|  |  | ||||||
|         holder.mView.title.text = Html.fromHtml(itm.title) |         holder.mView.title.text = Html.fromHtml(itm.title) | ||||||
|  |  | ||||||
|  |         holder.mView.title.setOnTouchListener(LinkOnTouchListener()) | ||||||
|  |  | ||||||
|         holder.mView.title.setLinkTextColor(appColors.colorAccent) |         holder.mView.title.setLinkTextColor(appColors.colorAccent) | ||||||
|  |  | ||||||
|         holder.mView.sourceTitleAndDate.text = itm.sourceAndDateText() |         holder.mView.sourceTitleAndDate.text = itm.sourceAndDateText() | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ 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.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.persistence.toEntity | import apps.amine.bou.readerforselfoss.utils.persistence.toEntity | ||||||
| import apps.amine.bou.readerforselfoss.utils.succeeded | import apps.amine.bou.readerforselfoss.utils.succeeded | ||||||
| import org.acra.ACRA | import org.acra.ACRA | ||||||
| @@ -45,6 +46,7 @@ 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()) | ||||||
| @@ -70,6 +72,7 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte | |||||||
|                         } |                         } | ||||||
|                     }) |                     }) | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|         val view = s.view |         val view = s.view | ||||||
|         val tv: TextView = view.findViewById(com.google.android.material.R.id.snackbar_text) |         val tv: TextView = view.findViewById(com.google.android.material.R.id.snackbar_text) | ||||||
| @@ -78,7 +81,7 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     fun removeItemAtIndex(position: Int) { |     fun removeItemAtIndex(position: Int) { | ||||||
|  |         if (app.isNetworkAccessible(null)) { | ||||||
|             val i = items[position] |             val i = items[position] | ||||||
|  |  | ||||||
|             items.remove(i) |             items.remove(i) | ||||||
| @@ -133,6 +136,7 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte | |||||||
|                 } |                 } | ||||||
|             }) |             }) | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     fun addItemAtIndex(item: Item, position: Int) { |     fun addItemAtIndex(item: Item, position: Int) { | ||||||
|         items.add(position, item) |         items.add(position, item) | ||||||
|   | |||||||
| @@ -13,6 +13,7 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi | |||||||
| import apps.amine.bou.readerforselfoss.api.selfoss.Source | import apps.amine.bou.readerforselfoss.api.selfoss.Source | ||||||
| import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse | import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse | ||||||
| import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable | import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable | ||||||
|  | import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible | ||||||
| import apps.amine.bou.readerforselfoss.utils.toTextDrawableString | import apps.amine.bou.readerforselfoss.utils.toTextDrawableString | ||||||
| import com.amulyakhare.textdrawable.TextDrawable | import com.amulyakhare.textdrawable.TextDrawable | ||||||
| import com.amulyakhare.textdrawable.util.ColorGenerator | import com.amulyakhare.textdrawable.util.ColorGenerator | ||||||
| @@ -70,6 +71,7 @@ class SourcesListAdapter( | |||||||
|             val deleteBtn: Button = mView.findViewById(R.id.deleteBtn) |             val deleteBtn: Button = mView.findViewById(R.id.deleteBtn) | ||||||
|  |  | ||||||
|             deleteBtn.setOnClickListener { |             deleteBtn.setOnClickListener { | ||||||
|  |                 if (c.isNetworkAccessible(null)) { | ||||||
|                     val (id) = items[adapterPosition] |                     val (id) = items[adapterPosition] | ||||||
|                     api.deleteSource(id).enqueue(object : Callback<SuccessResponse> { |                     api.deleteSource(id).enqueue(object : Callback<SuccessResponse> { | ||||||
|                         override fun onResponse( |                         override fun onResponse( | ||||||
| @@ -100,4 +102,5 @@ class SourcesListAdapter( | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -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,9 +91,11 @@ class SelfossApi( | |||||||
|                     .build() |                     .build() | ||||||
|             service = retrofit.create(SelfossService::class.java) |             service = retrofit.create(SelfossService::class.java) | ||||||
|         } catch (e: IllegalArgumentException) { |         } catch (e: IllegalArgumentException) { | ||||||
|  |             if (callingActivity != null) { | ||||||
|                 Config.logoutAndRedirect(c, callingActivity, config.settings.edit(), baseUrlFail = true) |                 Config.logoutAndRedirect(c, callingActivity, config.settings.edit(), baseUrlFail = true) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     fun login(): Call<SuccessResponse> = |     fun login(): Call<SuccessResponse> = | ||||||
|         service.loginToSelfoss(config.userLogin, config.userPassword) |         service.loginToSelfoss(config.userLogin, config.userPassword) | ||||||
|   | |||||||
| @@ -0,0 +1,82 @@ | |||||||
|  | package apps.amine.bou.readerforselfoss.background | ||||||
|  |  | ||||||
|  | import android.content.Context | ||||||
|  | import android.preference.PreferenceManager | ||||||
|  | import androidx.room.Room | ||||||
|  | import androidx.work.Worker | ||||||
|  | import androidx.work.WorkerParameters | ||||||
|  | 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.migrations.MIGRATION_1_2 | ||||||
|  | import apps.amine.bou.readerforselfoss.utils.Config | ||||||
|  | import apps.amine.bou.readerforselfoss.utils.persistence.toEntity | ||||||
|  | import retrofit2.Call | ||||||
|  | import retrofit2.Callback | ||||||
|  | import retrofit2.Response | ||||||
|  | import kotlin.concurrent.thread | ||||||
|  | import android.app.NotificationManager | ||||||
|  | import android.app.NotificationChannel | ||||||
|  | import android.util.Log | ||||||
|  | import androidx.core.app.NotificationCompat | ||||||
|  | import apps.amine.bou.readerforselfoss.R | ||||||
|  |  | ||||||
|  | class LoadingWorker(val context: Context, params: WorkerParameters) : Worker(context, params) { | ||||||
|  |  | ||||||
|  |     override fun doWork(): Result { | ||||||
|  |         val notificationManager = | ||||||
|  |             applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager | ||||||
|  |  | ||||||
|  |         //If on Oreo then notification required a notification channel. | ||||||
|  |         if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { | ||||||
|  |             val channel = | ||||||
|  |                 NotificationChannel("default", "Default", NotificationManager.IMPORTANCE_DEFAULT) | ||||||
|  |             notificationManager.createNotificationChannel(channel) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         val notification = NotificationCompat.Builder(applicationContext, "default") | ||||||
|  |             .setContentTitle("Loading") | ||||||
|  |             .setContentText("Loading new items") | ||||||
|  |             .setOngoing(true) | ||||||
|  |             .setSmallIcon(R.mipmap.ic_launcher) | ||||||
|  |  | ||||||
|  |         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) | ||||||
|  |  | ||||||
|  |         val db = Room.databaseBuilder( | ||||||
|  |             applicationContext, | ||||||
|  |             AppDatabase::class.java, "selfoss-database" | ||||||
|  |         ).addMigrations(MIGRATION_1_2).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) { | ||||||
|  |                 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()) | ||||||
|  |                     } | ||||||
|  |                     notificationManager.cancel(1) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }) | ||||||
|  |         return Result.SUCCESS | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -29,6 +29,7 @@ import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent | |||||||
| import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper | import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper | ||||||
| import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString | import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString | ||||||
| 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.openItemUrl | import apps.amine.bou.readerforselfoss.utils.openItemUrl | ||||||
| import apps.amine.bou.readerforselfoss.utils.shareLink | import apps.amine.bou.readerforselfoss.utils.shareLink | ||||||
| import apps.amine.bou.readerforselfoss.utils.sourceAndDateText | import apps.amine.bou.readerforselfoss.utils.sourceAndDateText | ||||||
| @@ -135,7 +136,8 @@ class ArticleFragment : Fragment() { | |||||||
|                             false, |                             false, | ||||||
|                             activity!! |                             activity!! | ||||||
|                         ) |                         ) | ||||||
|                         R.id.unread_action -> api.unmarkItem(allItems[pageNumber.toInt()].id).enqueue( |                         R.id.unread_action -> if ((context != null && context!!.isNetworkAccessible(null)) || context == null) { | ||||||
|  |                             api.unmarkItem(allItems[pageNumber.toInt()].id).enqueue( | ||||||
|                                 object : Callback<SuccessResponse> { |                                 object : Callback<SuccessResponse> { | ||||||
|                                     override fun onResponse( |                                     override fun onResponse( | ||||||
|                                         call: Call<SuccessResponse>, |                                         call: Call<SuccessResponse>, | ||||||
| @@ -164,6 +166,7 @@ class ArticleFragment : Fragment() { | |||||||
|                                     } |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             ) |                             ) | ||||||
|  |                         } | ||||||
|                         else -> Unit |                         else -> Unit | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -212,6 +215,7 @@ class ArticleFragment : Fragment() { | |||||||
|         customTabsIntent: CustomTabsIntent, |         customTabsIntent: CustomTabsIntent, | ||||||
|         prefs: SharedPreferences |         prefs: SharedPreferences | ||||||
|     ) { |     ) { | ||||||
|  |         if ((context != null && context!!.isNetworkAccessible(null)) || context == null) { | ||||||
|             rootView.progressBar.visibility = View.VISIBLE |             rootView.progressBar.visibility = View.VISIBLE | ||||||
|             val parser = MercuryApi( |             val parser = MercuryApi( | ||||||
|                 prefs.getBoolean("should_log_everything", false) |                 prefs.getBoolean("should_log_everything", false) | ||||||
| @@ -303,6 +307,7 @@ class ArticleFragment : Fragment() { | |||||||
|                 } |                 } | ||||||
|             ) |             ) | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private fun htmlToWebview(c: String, prefs: SharedPreferences) { |     private fun htmlToWebview(c: String, prefs: SharedPreferences) { | ||||||
|         val stringColor = String.format("#%06X", 0xFFFFFF and appColors.colorAccent) |         val stringColor = String.format("#%06X", 0xFFFFFF and appColors.colorAccent) | ||||||
|   | |||||||
| @@ -6,8 +6,13 @@ import android.content.Context | |||||||
| import android.content.Intent | import android.content.Intent | ||||||
| import android.graphics.BitmapFactory | import android.graphics.BitmapFactory | ||||||
| import android.net.Uri | import android.net.Uri | ||||||
|  | import android.text.Spannable | ||||||
|  | import android.text.style.ClickableSpan | ||||||
| import androidx.browser.customtabs.CustomTabsIntent | import androidx.browser.customtabs.CustomTabsIntent | ||||||
| import android.util.Patterns | import android.util.Patterns | ||||||
|  | import android.view.MotionEvent | ||||||
|  | import android.view.View | ||||||
|  | import android.widget.TextView | ||||||
| import android.widget.Toast | import android.widget.Toast | ||||||
| import apps.amine.bou.readerforselfoss.R | import apps.amine.bou.readerforselfoss.R | ||||||
| import apps.amine.bou.readerforselfoss.ReaderActivity | import apps.amine.bou.readerforselfoss.ReaderActivity | ||||||
| @@ -146,3 +151,40 @@ fun Context.openInBrowserAsNewTask(i: Item) { | |||||||
|     intent.data = Uri.parse(i.getLinkDecoded().toStringUriWithHttp()) |     intent.data = Uri.parse(i.getLinkDecoded().toStringUriWithHttp()) | ||||||
|     startActivity(intent) |     startActivity(intent) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | class LinkOnTouchListener: View.OnTouchListener { | ||||||
|  |     override fun onTouch(v: View?, event: MotionEvent?): Boolean { | ||||||
|  |         var ret = false | ||||||
|  |         val widget: TextView = v as TextView | ||||||
|  |         val text: CharSequence = widget.text | ||||||
|  |         val stext = Spannable.Factory.getInstance().newSpannable(text) | ||||||
|  |  | ||||||
|  |         val action = event!!.action | ||||||
|  |  | ||||||
|  |         if (action == MotionEvent.ACTION_UP || | ||||||
|  |             action == MotionEvent.ACTION_DOWN) { | ||||||
|  |             var x: Float = event.x | ||||||
|  |             var y: Float = event.y | ||||||
|  |  | ||||||
|  |             x -= widget.totalPaddingLeft | ||||||
|  |             y -= widget.totalPaddingTop | ||||||
|  |  | ||||||
|  |             x += widget.scrollX | ||||||
|  |             y += widget.scrollY | ||||||
|  |  | ||||||
|  |             val layout = widget.layout | ||||||
|  |             val line = layout.getLineForVertical(y.toInt()) | ||||||
|  |             val off = layout.getOffsetForHorizontal(line, x) | ||||||
|  |  | ||||||
|  |             val link = stext.getSpans(off, off, ClickableSpan::class.java) | ||||||
|  |  | ||||||
|  |             if (link.isNotEmpty()) { | ||||||
|  |                 if (action == MotionEvent.ACTION_UP) { | ||||||
|  |                     link[0].onClick(widget) | ||||||
|  |                 } | ||||||
|  |                 ret = true | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return ret | ||||||
|  |     } | ||||||
|  | } | ||||||
|   | |||||||
| @@ -0,0 +1,41 @@ | |||||||
|  | package apps.amine.bou.readerforselfoss.utils.network | ||||||
|  |  | ||||||
|  | import android.content.Context | ||||||
|  | import android.graphics.Color | ||||||
|  | import android.net.ConnectivityManager | ||||||
|  | import android.net.NetworkInfo | ||||||
|  | import android.view.View | ||||||
|  | import android.widget.TextView | ||||||
|  | import apps.amine.bou.readerforselfoss.R | ||||||
|  | import com.google.android.material.snackbar.Snackbar | ||||||
|  |  | ||||||
|  | var snackBarShown = false | ||||||
|  | var view: View? = null | ||||||
|  |  | ||||||
|  | fun Context.isNetworkAccessible(v: View?): Boolean { | ||||||
|  |     val cm = this.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager | ||||||
|  |     val activeNetwork: NetworkInfo? = cm.activeNetworkInfo | ||||||
|  |     val networkIsAccessible = activeNetwork != null && activeNetwork.isConnectedOrConnecting | ||||||
|  |  | ||||||
|  |     if (v != null && !networkIsAccessible && (!snackBarShown || v != view)) { | ||||||
|  |         view = v | ||||||
|  |         val s = Snackbar | ||||||
|  |             .make( | ||||||
|  |                 v, | ||||||
|  |                 R.string.no_network_connectivity, | ||||||
|  |                 Snackbar.LENGTH_INDEFINITE | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |         s.setAction(android.R.string.ok) { | ||||||
|  |             snackBarShown = false | ||||||
|  |             s.dismiss() | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         val view = s.view | ||||||
|  |         val tv: TextView = view.findViewById(com.google.android.material.R.id.snackbar_text) | ||||||
|  |         tv.setTextColor(Color.WHITE) | ||||||
|  |         s.show() | ||||||
|  |         snackBarShown = true | ||||||
|  |     } | ||||||
|  |     return networkIsAccessible | ||||||
|  | } | ||||||
| @@ -2,6 +2,7 @@ | |||||||
| <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" | ||||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" |     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||||
|     android:layout_width="match_parent" |     android:layout_width="match_parent" | ||||||
|  |     android:id="@+id/reader_activity_view" | ||||||
|     android:layout_height="match_parent"> |     android:layout_height="match_parent"> | ||||||
|  |  | ||||||
|     <com.google.android.material.appbar.AppBarLayout |     <com.google.android.material.appbar.AppBarLayout | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <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">Sin conexión!</string> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -150,6 +150,7 @@ | |||||||
|     <string name="unmark">Marquer l\'article comme non lu</string> |     <string name="unmark">Marquer l\'article comme non lu</string> | ||||||
|     <string name="pref_header_offline">Hors ligne et cache</string> |     <string name="pref_header_offline">Hors ligne et cache</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_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 ne 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">Hors connexion !</string> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <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">Non conectado!</string> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -152,4 +152,5 @@ | |||||||
|     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</string> |     <string name="pref_switch_items_caching_off">Articles won\'t be saved to the device memory, and the app won\'t be usable offline.</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_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> | ||||||
| </resources> | </resources> | ||||||
|   | |||||||
| @@ -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() | ||||||
| @@ -15,7 +16,7 @@ buildscript { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     dependencies { |     dependencies { | ||||||
|         classpath 'com.android.tools.build:gradle:3.2.0' |         classpath 'com.android.tools.build:gradle:3.2.1' | ||||||
|         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" |         classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user