More debugging. Source adding is still broken. Needs DB integration.
This commit is contained in:
parent
6e38e8753c
commit
4c69e72499
@ -133,7 +133,7 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
var items = api!!.spouts()
|
var items = api!!.spouts()
|
||||||
if (items != null) {
|
if (items != null) {
|
||||||
|
|
||||||
@ -192,7 +192,7 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
val response: SelfossModel.SuccessResponse? = api.createSourceForVersion(
|
val response: SelfossModel.SuccessResponse? = api.createSourceForVersion(
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
|
@ -235,7 +235,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
lastFetchDone = false
|
lastFetchDone = false
|
||||||
handleDrawerItems()
|
handleDrawerItems()
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
service.refreshFocusedItems(itemsNumber, applicationContext.isNetworkAvailable())
|
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
binding.swipeRefreshLayout.isRefreshing = false
|
binding.swipeRefreshLayout.isRefreshing = false
|
||||||
}
|
}
|
||||||
@ -276,7 +275,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
reloadBadgeContent()
|
reloadBadgeContent()
|
||||||
|
|
||||||
val tagHashes = i.tags.split(",").map { it.longHash() }
|
val tagHashes = i.tags.map { it.longHash() }
|
||||||
tagsBadge = tagsBadge.map {
|
tagsBadge = tagsBadge.map {
|
||||||
if (tagHashes.contains(it.key)) {
|
if (tagHashes.contains(it.key)) {
|
||||||
(it.key to (it.value - 1))
|
(it.key to (it.value - 1))
|
||||||
@ -868,9 +867,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
override fun onTabUnselected(position: Int) = Unit
|
override fun onTabUnselected(position: Int) = Unit
|
||||||
|
|
||||||
override fun onTabReselected(position: Int) {
|
override fun onTabReselected(position: Int) {
|
||||||
val layoutManager = binding.recyclerView.adapter
|
|
||||||
|
|
||||||
when (layoutManager) {
|
when (val layoutManager = binding.recyclerView.adapter) {
|
||||||
is StaggeredGridLayoutManager ->
|
is StaggeredGridLayoutManager ->
|
||||||
if (layoutManager.findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
|
if (layoutManager.findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
@ -902,10 +900,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
private fun fetchOnEmptyList() {
|
private fun fetchOnEmptyList() {
|
||||||
binding.recyclerView.doOnNextLayout {
|
binding.recyclerView.doOnNextLayout {
|
||||||
// Todo:
|
// TODO: do if last element (or is empty ?)
|
||||||
// if (SharedItems.focusedItems.size - 1 == getLastVisibleItem()) {
|
getElementsAccordingToTab(true)
|
||||||
// getElementsAccordingToTab(true)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -927,8 +923,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getLastVisibleItem() : Int {
|
private fun getLastVisibleItem() : Int {
|
||||||
val manager = binding.recyclerView.layoutManager
|
return when (val manager = binding.recyclerView.layoutManager) {
|
||||||
return when (manager) {
|
|
||||||
is StaggeredGridLayoutManager -> manager.findLastCompletelyVisibleItemPositions(
|
is StaggeredGridLayoutManager -> manager.findLastCompletelyVisibleItemPositions(
|
||||||
null
|
null
|
||||||
).last()
|
).last()
|
||||||
@ -945,8 +940,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getElementsAccordingToTab(
|
private fun getElementsAccordingToTab(
|
||||||
appendResults: Boolean = false,
|
appendResults: Boolean = false
|
||||||
offsetOverride: Int? = null
|
|
||||||
) {
|
) {
|
||||||
fun doGetAccordingToTab() {
|
fun doGetAccordingToTab() {
|
||||||
when (elementsShown) {
|
when (elementsShown) {
|
||||||
@ -957,12 +951,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Todo:
|
offset = if (appendResults && items.size > 0) {
|
||||||
// offset = if (appendResults) {
|
items.size - 1
|
||||||
// SharedItems.focusedItems.size - 1
|
} else {
|
||||||
// } else {
|
0
|
||||||
// 0
|
}
|
||||||
// }
|
|
||||||
firstVisible = if (appendResults) firstVisible else 0
|
firstVisible = if (appendResults) firstVisible else 0
|
||||||
|
|
||||||
doGetAccordingToTab()
|
doGetAccordingToTab()
|
||||||
@ -970,41 +963,42 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
private fun getUnRead(appendResults: Boolean = false) {
|
private fun getUnRead(appendResults: Boolean = false) {
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
// Todo:
|
binding.swipeRefreshLayout.isRefreshing = true
|
||||||
// if (appendResults || !SharedItems.fetchedUnread) {
|
val apiItems = service.getUnreadItems(itemsNumber, offset, applicationContext.isNetworkAvailable())
|
||||||
// binding.swipeRefreshLayout.isRefreshing = true
|
if (appendResults) {
|
||||||
// service.getUnreadItems(itemsNumber, offset, applicationContext.isNetworkAvailable())
|
apiItems?.let { items.addAll(it) }
|
||||||
// binding.swipeRefreshLayout.isRefreshing = false
|
} else {
|
||||||
// }
|
items = apiItems.orEmpty() as ArrayList<SelfossModel.Item>
|
||||||
// Todo: SharedItems.getUnRead()
|
}
|
||||||
// Todo: items = SharedItems.focusedItems
|
binding.swipeRefreshLayout.isRefreshing = false
|
||||||
handleListResult()
|
handleListResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRead(appendResults: Boolean = false) {
|
private fun getRead(appendResults: Boolean = false) {
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
// Todo:
|
binding.swipeRefreshLayout.isRefreshing = true
|
||||||
// if (appendResults || !SharedItems.fetchedAll) {
|
val apiItems = service.getReadItems(itemsNumber, offset, applicationContext.isNetworkAvailable())
|
||||||
// binding.swipeRefreshLayout.isRefreshing = true
|
if (appendResults) {
|
||||||
// service.getReadItems(itemsNumber, offset, applicationContext.isNetworkAvailable())
|
apiItems?.let { items.addAll(it) }
|
||||||
// binding.swipeRefreshLayout.isRefreshing = false
|
} else {
|
||||||
// }
|
items = apiItems.orEmpty() as ArrayList<SelfossModel.Item>
|
||||||
// SharedItems.getAll()
|
}
|
||||||
// items = SharedItems.focusedItems
|
binding.swipeRefreshLayout.isRefreshing = false
|
||||||
handleListResult()
|
handleListResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getStarred(appendResults: Boolean = false) {
|
private fun getStarred(appendResults: Boolean = false) {
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
if (appendResults || !searchService.fetchedStarred) {
|
binding.swipeRefreshLayout.isRefreshing = true
|
||||||
binding.swipeRefreshLayout.isRefreshing = true
|
val apiItems = service.getStarredItems(itemsNumber, offset, applicationContext.isNetworkAvailable())
|
||||||
service.getStarredItems(itemsNumber, offset, applicationContext.isNetworkAvailable())
|
if (appendResults) {
|
||||||
binding.swipeRefreshLayout.isRefreshing = false
|
apiItems?.let { items.addAll(it) }
|
||||||
|
} else {
|
||||||
|
items = apiItems.orEmpty() as ArrayList<SelfossModel.Item>
|
||||||
}
|
}
|
||||||
// Todo: SharedItems.getStarred()
|
binding.swipeRefreshLayout.isRefreshing = false
|
||||||
// Todo: items = SharedItems.focusedItems
|
|
||||||
handleListResult()
|
handleListResult()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1069,7 +1063,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
binding.recyclerView.adapter = recyclerAdapter
|
binding.recyclerView.adapter = recyclerAdapter
|
||||||
} else {
|
} else {
|
||||||
(recyclerAdapter as ItemsAdapter<*>).updateAllItems()
|
(recyclerAdapter as ItemsAdapter<*>).updateAllItems(items)
|
||||||
}
|
}
|
||||||
|
|
||||||
reloadBadges()
|
reloadBadges()
|
||||||
@ -1186,7 +1180,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
if (this@HomeActivity.isNetworkAvailable(null, offlineShortcut)) {
|
if (this@HomeActivity.isNetworkAvailable(null, offlineShortcut)) {
|
||||||
CoroutineScope(Dispatchers.Main).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
val success = service.readAll(applicationContext.isNetworkAvailable())
|
val success = service.readAll(items.map { it.id.toString() }, applicationContext.isNetworkAvailable())
|
||||||
if (success) {
|
if (success) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
|
@ -130,7 +130,8 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
private fun readItem(item: SelfossModel.Item) {
|
private fun readItem(item: SelfossModel.Item) {
|
||||||
if (markOnScroll) {
|
if (markOnScroll) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
// Todo: SharedItems.readItem(applicationContext, api, db, item)
|
api.markAsRead(item.id.toString())
|
||||||
|
// TODO: update item in DB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -177,7 +178,7 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
inflater.inflate(R.menu.reader_menu, menu)
|
inflater.inflate(R.menu.reader_menu, menu)
|
||||||
toolbarMenu = menu
|
toolbarMenu = menu
|
||||||
|
|
||||||
if (allItems.isNotEmpty() && allItems[currentItem].starred == 1) {
|
if (allItems.isNotEmpty() && allItems[currentItem].starred) {
|
||||||
canRemoveFromFavorite()
|
canRemoveFromFavorite()
|
||||||
} else {
|
} else {
|
||||||
canFavorite()
|
canFavorite()
|
||||||
@ -194,7 +195,7 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
override fun onPageSelected(position: Int) {
|
override fun onPageSelected(position: Int) {
|
||||||
super.onPageSelected(position)
|
super.onPageSelected(position)
|
||||||
|
|
||||||
if (allItems[position].starred == 1) {
|
if (allItems[position].starred) {
|
||||||
canRemoveFromFavorite()
|
canRemoveFromFavorite()
|
||||||
} else {
|
} else {
|
||||||
canFavorite()
|
canFavorite()
|
||||||
@ -225,26 +226,16 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.star -> {
|
R.id.star -> {
|
||||||
if (allItems[binding.pager.currentItem].starred == 1) {
|
if (allItems[binding.pager.currentItem].starred) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
// Todo:
|
api.unstarr(allItems[binding.pager.currentItem].id.toString())
|
||||||
// SharedItems.unstarItem(
|
// TODO: update in DB
|
||||||
// this@ReaderActivity,
|
|
||||||
// api,
|
|
||||||
// db,
|
|
||||||
// allItems[binding.pager.currentItem]
|
|
||||||
// )
|
|
||||||
}
|
}
|
||||||
afterUnsave()
|
afterUnsave()
|
||||||
} else {
|
} else {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
// Todo:
|
api.starr(allItems[binding.pager.currentItem].id.toString())
|
||||||
// SharedItems.starItem(
|
// TODO: update in DB
|
||||||
// this@ReaderActivity,
|
|
||||||
// api,
|
|
||||||
// db,
|
|
||||||
// allItems[binding.pager.currentItem]
|
|
||||||
// )
|
|
||||||
}
|
}
|
||||||
afterSave()
|
afterSave()
|
||||||
}
|
}
|
||||||
|
@ -80,7 +80,7 @@ class SourcesActivity : AppCompatActivity() {
|
|||||||
binding.recyclerView.layoutManager = mLayoutManager
|
binding.recyclerView.layoutManager = mLayoutManager
|
||||||
|
|
||||||
if (this@SourcesActivity.isNetworkAvailable(binding.recyclerView)) {
|
if (this@SourcesActivity.isNetworkAvailable(binding.recyclerView)) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.Main).launch {
|
||||||
val response = api.sources()
|
val response = api.sources()
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
items = response
|
items = response
|
||||||
|
@ -59,7 +59,7 @@ class ItemCardAdapter(
|
|||||||
with(holder) {
|
with(holder) {
|
||||||
val itm = items[position]
|
val itm = items[position]
|
||||||
|
|
||||||
binding.favButton.isSelected = itm.starred == 1
|
binding.favButton.isSelected = itm.starred
|
||||||
binding.title.text = itm.getTitleDecoded()
|
binding.title.text = itm.getTitleDecoded()
|
||||||
|
|
||||||
binding.title.setOnTouchListener(LinkOnTouchListener())
|
binding.title.setOnTouchListener(LinkOnTouchListener())
|
||||||
@ -112,17 +112,19 @@ class ItemCardAdapter(
|
|||||||
binding.favButton.setOnClickListener {
|
binding.favButton.setOnClickListener {
|
||||||
val item = items[bindingAdapterPosition]
|
val item = items[bindingAdapterPosition]
|
||||||
if (c.isNetworkAvailable()) {
|
if (c.isNetworkAvailable()) {
|
||||||
if (item.starred == 1) {
|
if (item.starred) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
// Todo: SharedItems.unstarItem(c, api, db, item)
|
api.unstarr(item.id.toString())
|
||||||
|
// TODO: save to db
|
||||||
}
|
}
|
||||||
item.starred = 0
|
item.starred = false
|
||||||
binding.favButton.isSelected = false
|
binding.favButton.isSelected = false
|
||||||
} else {
|
} else {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
// Todo: SharedItems.starItem(c, api, db, item)
|
api.starr(item.id.toString())
|
||||||
|
// TODO: save to db
|
||||||
}
|
}
|
||||||
item.starred = 1
|
item.starred = true
|
||||||
binding.favButton.isSelected = true
|
binding.favButton.isSelected = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,10 +29,10 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
|||||||
abstract val searchService: SearchService
|
abstract val searchService: SearchService
|
||||||
abstract val updateItems: (ArrayList<SelfossModel.Item>) -> Unit
|
abstract val updateItems: (ArrayList<SelfossModel.Item>) -> Unit
|
||||||
|
|
||||||
fun updateAllItems() {
|
fun updateAllItems(items: ArrayList<SelfossModel.Item>) {
|
||||||
items = ArrayList() // TODO: SharedItems.focusedItems
|
this.items = items
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
updateItems(items)
|
updateItems(this.items)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unmarkSnackbar(i: SelfossModel.Item, position: Int) {
|
private fun unmarkSnackbar(i: SelfossModel.Item, position: Int) {
|
||||||
@ -44,14 +44,8 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
|||||||
)
|
)
|
||||||
.setAction(R.string.undo_string) {
|
.setAction(R.string.undo_string) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
// Todo: SharedItems.unreadItem(app, api, db, i)
|
unreadItemAtIndex(position, false)
|
||||||
}
|
}
|
||||||
// Todo:
|
|
||||||
// if (SharedItems.displayedItems == "unread") {
|
|
||||||
// addItemAtIndex(i, position)
|
|
||||||
// } else {
|
|
||||||
// notifyItemChanged(position)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val view = s.view
|
val view = s.view
|
||||||
@ -68,17 +62,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) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
readItemAtIndex(position)
|
||||||
// Todo: SharedItems.readItem(app, api, db, items[position])
|
|
||||||
}
|
|
||||||
// Todo: items = SharedItems.focusedItems
|
|
||||||
// Todo:
|
|
||||||
// if (SharedItems.displayedItems == "unread") {
|
|
||||||
// notifyItemRemoved(position)
|
|
||||||
// updateItems(items)
|
|
||||||
// } else {
|
|
||||||
// notifyItemChanged(position)
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val view = s.view
|
val view = s.view
|
||||||
@ -88,18 +72,19 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun handleItemAtIndex(position: Int) {
|
fun handleItemAtIndex(position: Int) {
|
||||||
// Todo:
|
if (items[position].unread) {
|
||||||
// if (SharedItems.unreadItemStatusAtIndex(position)) {
|
readItemAtIndex(position)
|
||||||
// readItemAtIndex(position)
|
} else {
|
||||||
// } else {
|
unreadItemAtIndex(position)
|
||||||
// unreadItemAtIndex(position)
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun readItemAtIndex(position: Int) {
|
private fun readItemAtIndex(position: Int, showSnackbar: Boolean = true) {
|
||||||
val i = items[position]
|
val i = items[position]
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
// Todo: SharedItems.readItem(app, api, db, i)
|
api.markAsRead(i.id.toString())
|
||||||
|
// TODO: update db
|
||||||
|
|
||||||
}
|
}
|
||||||
// Todo:
|
// Todo:
|
||||||
// if (SharedItems.displayedItems == "unread") {
|
// if (SharedItems.displayedItems == "unread") {
|
||||||
@ -109,15 +94,22 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
|||||||
// } else {
|
// } else {
|
||||||
// notifyItemChanged(position)
|
// notifyItemChanged(position)
|
||||||
// }
|
// }
|
||||||
unmarkSnackbar(i, position)
|
if (showSnackbar) {
|
||||||
|
unmarkSnackbar(i, position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun unreadItemAtIndex(position: Int) {
|
private fun unreadItemAtIndex(position: Int, showSnackbar: Boolean = true) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
api.unmarkAsRead(items[position].id.toString())
|
||||||
// Todo: SharedItems.unreadItem(app, api, db, items[position])
|
// Todo: SharedItems.unreadItem(app, api, db, items[position])
|
||||||
|
// TODO: update db
|
||||||
|
|
||||||
}
|
}
|
||||||
notifyItemChanged(position)
|
notifyItemChanged(position)
|
||||||
markSnackbar(position)
|
if (showSnackbar) {
|
||||||
|
markSnackbar(position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addItemAtIndex(item: SelfossModel.Item, position: Int) {
|
fun addItemAtIndex(item: SelfossModel.Item, position: Int) {
|
||||||
|
@ -28,7 +28,6 @@ import bou.amine.apps.readerforselfossv2.android.utils.network.isNetworkAvailabl
|
|||||||
|
|
||||||
import bou.amine.apps.readerforselfossv2.rest.SelfossApi
|
import bou.amine.apps.readerforselfossv2.rest.SelfossApi
|
||||||
import bou.amine.apps.readerforselfossv2.rest.SelfossModel
|
import bou.amine.apps.readerforselfossv2.rest.SelfossModel
|
||||||
import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
|
||||||
import bou.amine.apps.readerforselfossv2.service.SearchService
|
import bou.amine.apps.readerforselfossv2.service.SearchService
|
||||||
import bou.amine.apps.readerforselfossv2.service.SelfossService
|
import bou.amine.apps.readerforselfossv2.service.SelfossService
|
||||||
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
import bou.amine.apps.readerforselfossv2.utils.DateUtils
|
||||||
@ -109,21 +108,33 @@ override fun doWork(): Result {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
service.getAndStoreAllItems(context.isNetworkAvailable())
|
if (context.isNetworkAvailable()) {
|
||||||
// TODO: SharedItems.updateDatabase(db, dateUtils)
|
launch {
|
||||||
storeItems(notifyNewItems, notificationManager)
|
try {
|
||||||
|
val newItems = service.allNewItems()
|
||||||
|
handleNewItemsNotification(newItems, notifyNewItems, notificationManager)
|
||||||
|
val readItems = service.allReadItems()
|
||||||
|
val starredItems = service.allStarredItems()
|
||||||
|
// TODO: save all to DB
|
||||||
|
} catch (e: Throwable) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Result.success()
|
return Result.success()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun storeItems(notifyNewItems: Boolean, notificationManager: NotificationManager) {
|
private fun handleNewItemsNotification(
|
||||||
|
newItems: List<SelfossModel.Item>?,
|
||||||
|
notifyNewItems: Boolean,
|
||||||
|
notificationManager: NotificationManager
|
||||||
|
) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
val apiItems = emptyList<SelfossModel.Item>() // TODO: SharedItems.items
|
val apiItems = newItems.orEmpty()
|
||||||
|
|
||||||
|
|
||||||
val newSize = apiItems.filter { it.unread == 1 }.size
|
val newSize = apiItems.filter { it.unread }.size
|
||||||
if (notifyNewItems && newSize > 0) {
|
if (notifyNewItems && newSize > 0) {
|
||||||
|
|
||||||
val intent = Intent(context, MainActivity::class.java).apply {
|
val intent = Intent(context, MainActivity::class.java).apply {
|
||||||
|
@ -111,7 +111,9 @@ class ArticleFragment : Fragment() {
|
|||||||
|
|
||||||
service = SelfossService(SelfossApi(apiDetailsService), dbService, SearchService(DateUtils(apiDetailsService)))
|
service = SelfossService(SelfossApi(apiDetailsService), dbService, SearchService(DateUtils(apiDetailsService)))
|
||||||
|
|
||||||
item = requireArguments().getParcelable(ARG_ITEMS)!!
|
val pi: ParecelableItem = requireArguments().getParcelable(ARG_ITEMS)!!
|
||||||
|
|
||||||
|
item = pi.toModel()
|
||||||
|
|
||||||
db = Room.databaseBuilder(
|
db = Room.databaseBuilder(
|
||||||
requireContext(),
|
requireContext(),
|
||||||
@ -187,17 +189,12 @@ class ArticleFragment : Fragment() {
|
|||||||
R.id.share_action -> requireActivity().shareLink(url, contentTitle)
|
R.id.share_action -> requireActivity().shareLink(url, contentTitle)
|
||||||
R.id.open_action -> requireActivity().openInBrowserAsNewTask(this@ArticleFragment.item)
|
R.id.open_action -> requireActivity().openInBrowserAsNewTask(this@ArticleFragment.item)
|
||||||
R.id.unread_action -> if (context != null) {
|
R.id.unread_action -> if (context != null) {
|
||||||
if (this@ArticleFragment.item.unread == 1) {
|
if (this@ArticleFragment.item.unread) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
// TODO:
|
api.markAsRead(this@ArticleFragment.item.id.toString())
|
||||||
// dbService.readItem(
|
// TODO: Update in DB
|
||||||
// context!!,
|
|
||||||
// api,
|
|
||||||
// db,
|
|
||||||
// this@ArticleFragment.item
|
|
||||||
// )
|
|
||||||
}
|
}
|
||||||
this@ArticleFragment.item.unread = 0
|
this@ArticleFragment.item.unread = false
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
R.string.marked_as_read,
|
R.string.marked_as_read,
|
||||||
@ -205,15 +202,10 @@ class ArticleFragment : Fragment() {
|
|||||||
).show()
|
).show()
|
||||||
} else {
|
} else {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
// TODO
|
api.unmarkAsRead(this@ArticleFragment.item.id.toString())
|
||||||
// .unreadItem(
|
// TODO: Update in DB
|
||||||
// context!!,
|
|
||||||
// api,
|
|
||||||
// db,
|
|
||||||
// this@ArticleFragment.item
|
|
||||||
// )
|
|
||||||
}
|
}
|
||||||
this@ArticleFragment.item.unread = 1
|
this@ArticleFragment.item.unread = true
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
R.string.marked_as_unread,
|
R.string.marked_as_unread,
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package bou.amine.apps.readerforselfossv2.android.model
|
package bou.amine.apps.readerforselfossv2.android.model
|
||||||
|
|
||||||
|
import android.os.Build
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import androidx.annotation.RequiresApi
|
||||||
import bou.amine.apps.readerforselfossv2.rest.SelfossModel
|
import bou.amine.apps.readerforselfossv2.rest.SelfossModel
|
||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
@ -17,15 +19,29 @@ fun SelfossModel.Item.toParcelable() : ParecelableItem =
|
|||||||
this.icon,
|
this.icon,
|
||||||
this.link,
|
this.link,
|
||||||
this.sourcetitle,
|
this.sourcetitle,
|
||||||
this.tags
|
this.tags.joinToString(",")
|
||||||
|
)
|
||||||
|
fun ParecelableItem.toModel() : SelfossModel.Item =
|
||||||
|
SelfossModel.Item(
|
||||||
|
this.id,
|
||||||
|
this.datetime,
|
||||||
|
this.title,
|
||||||
|
this.content,
|
||||||
|
this.unread,
|
||||||
|
this.starred,
|
||||||
|
this.thumbnail,
|
||||||
|
this.icon,
|
||||||
|
this.link,
|
||||||
|
this.sourcetitle,
|
||||||
|
this.tags.split(",")
|
||||||
)
|
)
|
||||||
data class ParecelableItem(
|
data class ParecelableItem(
|
||||||
@SerializedName("id") val id: String,
|
@SerializedName("id") val id: Int,
|
||||||
@SerializedName("datetime") val datetime: String,
|
@SerializedName("datetime") val datetime: String,
|
||||||
@SerializedName("title") val title: String,
|
@SerializedName("title") val title: String,
|
||||||
@SerializedName("content") val content: String,
|
@SerializedName("content") val content: String,
|
||||||
@SerializedName("unread") var unread: Int,
|
@SerializedName("unread") var unread: Boolean,
|
||||||
@SerializedName("starred") var starred: Int,
|
@SerializedName("starred") var starred: Boolean,
|
||||||
@SerializedName("thumbnail") val thumbnail: String?,
|
@SerializedName("thumbnail") val thumbnail: String?,
|
||||||
@SerializedName("icon") val icon: String?,
|
@SerializedName("icon") val icon: String?,
|
||||||
@SerializedName("link") val link: String,
|
@SerializedName("link") val link: String,
|
||||||
@ -42,12 +58,12 @@ data class ParecelableItem(
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(source: Parcel) : this(
|
constructor(source: Parcel) : this(
|
||||||
id = source.readString().orEmpty(),
|
id = source.readInt(),
|
||||||
datetime = source.readString().orEmpty(),
|
datetime = source.readString().orEmpty(),
|
||||||
title = source.readString().orEmpty(),
|
title = source.readString().orEmpty(),
|
||||||
content = source.readString().orEmpty(),
|
content = source.readString().orEmpty(),
|
||||||
unread = source.readInt(),
|
unread = source.readByte().toInt() != 0,
|
||||||
starred = source.readInt(),
|
starred = source.readByte().toInt() != 0,
|
||||||
thumbnail = source.readString(),
|
thumbnail = source.readString(),
|
||||||
icon = source.readString(),
|
icon = source.readString(),
|
||||||
link = source.readString().orEmpty(),
|
link = source.readString().orEmpty(),
|
||||||
@ -58,12 +74,12 @@ data class ParecelableItem(
|
|||||||
override fun describeContents() = 0
|
override fun describeContents() = 0
|
||||||
|
|
||||||
override fun writeToParcel(dest: Parcel, flags: Int) {
|
override fun writeToParcel(dest: Parcel, flags: Int) {
|
||||||
dest.writeString(id)
|
dest.writeInt(id)
|
||||||
dest.writeString(datetime)
|
dest.writeString(datetime)
|
||||||
dest.writeString(title)
|
dest.writeString(title)
|
||||||
dest.writeString(content)
|
dest.writeString(content)
|
||||||
dest.writeInt(unread)
|
dest.writeByte(if (unread) 1 else 0)
|
||||||
dest.writeInt(starred)
|
dest.writeByte(if (starred) 1 else 0)
|
||||||
dest.writeString(thumbnail)
|
dest.writeString(thumbnail)
|
||||||
dest.writeString(icon)
|
dest.writeString(icon)
|
||||||
dest.writeString(link)
|
dest.writeString(link)
|
||||||
|
@ -23,11 +23,11 @@ class AndroidDeviceDatabaseService(db: AndroidDeviceDatabase, searchService: Sea
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun appendNewItems(newItems: List<SelfossModel.Item>) {
|
override fun appendNewItems(newItems: List<SelfossModel.Item>) {
|
||||||
var tmpItems = items
|
var oldItems = items
|
||||||
if (tmpItems != newItems) {
|
if (oldItems != newItems) {
|
||||||
tmpItems = tmpItems.filter { item -> newItems.find { it.id == item.id } == null } as ArrayList<SelfossModel.Item>
|
oldItems = oldItems.filter { item -> newItems.find { it.id == item.id } == null } as ArrayList<SelfossModel.Item>
|
||||||
tmpItems.addAll(newItems)
|
oldItems.addAll(newItems)
|
||||||
items = tmpItems
|
items = oldItems
|
||||||
|
|
||||||
sortItems()
|
sortItems()
|
||||||
getFocusedItems()
|
getFocusedItems()
|
||||||
|
@ -8,40 +8,41 @@ import bou.amine.apps.readerforselfossv2.service.ApiDetailsService
|
|||||||
|
|
||||||
class AndroidApiDetailsService(c: Context) : ApiDetailsService {
|
class AndroidApiDetailsService(c: Context) : ApiDetailsService {
|
||||||
val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(c)
|
val settings: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(c)
|
||||||
private var apiVersion: Int = -1
|
private var _apiVersion: Int = -1
|
||||||
private var baseUrl: String = ""
|
private var _baseUrl: String = ""
|
||||||
private var userName: String = ""
|
private var _userName: String = ""
|
||||||
private var password: String = ""
|
private var _password: String = ""
|
||||||
override fun logApiCalls(message: String) {
|
override fun logApiCalls(message: String) {
|
||||||
Log.d("LogApiCalls", message)
|
Log.d("LogApiCalls", message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
override fun getApiVersion(): Int {
|
override fun getApiVersion(): Int {
|
||||||
if (apiVersion != -1) {
|
if (_apiVersion == -1) {
|
||||||
apiVersion = settings.getInt("apiVersion", -1)!!
|
_apiVersion = settings.getInt("apiVersionMajor", -1)!!
|
||||||
|
return settings.getInt("apiVersionMajor", -1)!!
|
||||||
}
|
}
|
||||||
return apiVersion
|
return _apiVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getBaseUrl(): String {
|
override fun getBaseUrl(): String {
|
||||||
if (baseUrl.isEmpty()) {
|
if (_baseUrl.isEmpty()) {
|
||||||
baseUrl = settings.getString("url", "")!!
|
_baseUrl = settings.getString("url", "")!!
|
||||||
}
|
}
|
||||||
return baseUrl
|
return _baseUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getUserName(): String {
|
override fun getUserName(): String {
|
||||||
if (userName.isEmpty()) {
|
if (_userName.isEmpty()) {
|
||||||
userName = settings.getString("login", "")!!
|
_userName = settings.getString("login", "")!!
|
||||||
}
|
}
|
||||||
return userName
|
return _userName
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPassword(): String {
|
override fun getPassword(): String {
|
||||||
if (password.isEmpty()) {
|
if (_password.isEmpty()) {
|
||||||
password = settings.getString("password", "")!!
|
_password = settings.getString("password", "")!!
|
||||||
}
|
}
|
||||||
return password
|
return _password
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,15 +24,6 @@ fun SelfossModel.Item.sourceAndDateText(dateUtils: DateUtils): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun SelfossModel.Item.toggleStar(): SelfossModel.Item {
|
fun SelfossModel.Item.toggleStar(): SelfossModel.Item {
|
||||||
this.starred = if (this.starred == 0) 1 else 0
|
this.starred = !this.starred
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun List<SelfossModel.Item>.flattenTags(): List<SelfossModel.Item> =
|
|
||||||
this.flatMap {
|
|
||||||
val item = it
|
|
||||||
val tags: List<String> = it.tags.split(",")
|
|
||||||
tags.map { t ->
|
|
||||||
item.copy(tags = t.trim())
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,7 +16,7 @@ fun TagEntity.toView(): SelfossModel.Tag =
|
|||||||
|
|
||||||
fun SourceEntity.toView(): SelfossModel.Source =
|
fun SourceEntity.toView(): SelfossModel.Source =
|
||||||
SelfossModel.Source(
|
SelfossModel.Source(
|
||||||
this.id,
|
this.id.toInt(),
|
||||||
this.title,
|
this.title,
|
||||||
this.tags.split(","),
|
this.tags.split(","),
|
||||||
this.spout,
|
this.spout,
|
||||||
@ -26,7 +26,7 @@ fun SourceEntity.toView(): SelfossModel.Source =
|
|||||||
|
|
||||||
fun SelfossModel.Source.toEntity(): SourceEntity =
|
fun SelfossModel.Source.toEntity(): SourceEntity =
|
||||||
SourceEntity(
|
SourceEntity(
|
||||||
this.id,
|
this.id.toString(),
|
||||||
this.getTitleDecoded(),
|
this.getTitleDecoded(),
|
||||||
this.tags.joinToString(","),
|
this.tags.joinToString(","),
|
||||||
this.spout,
|
this.spout,
|
||||||
@ -43,30 +43,30 @@ fun SelfossModel.Tag.toEntity(): TagEntity =
|
|||||||
|
|
||||||
fun AndroidItemEntity.toView(): SelfossModel.Item =
|
fun AndroidItemEntity.toView(): SelfossModel.Item =
|
||||||
SelfossModel.Item(
|
SelfossModel.Item(
|
||||||
this.id,
|
this.id.toInt(),
|
||||||
this.datetime,
|
this.datetime,
|
||||||
this.title,
|
this.title,
|
||||||
this.content,
|
this.content,
|
||||||
if (this.unread) 1 else 0,
|
this.unread,
|
||||||
if (this.starred) 1 else 0,
|
this.starred,
|
||||||
this.thumbnail,
|
this.thumbnail,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.link,
|
this.link,
|
||||||
this.sourcetitle,
|
this.sourcetitle,
|
||||||
this.tags
|
this.tags.split(",")
|
||||||
)
|
)
|
||||||
|
|
||||||
fun SelfossModel.Item.toEntity(): AndroidItemEntity =
|
fun SelfossModel.Item.toEntity(): AndroidItemEntity =
|
||||||
AndroidItemEntity(
|
AndroidItemEntity(
|
||||||
this.id,
|
this.id.toString(),
|
||||||
this.datetime,
|
this.datetime,
|
||||||
this.getTitleDecoded(),
|
this.getTitleDecoded(),
|
||||||
this.content,
|
this.content,
|
||||||
this.unread == 1,
|
this.unread,
|
||||||
this.starred == 1,
|
this.starred,
|
||||||
this.thumbnail,
|
this.thumbnail,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.link,
|
this.link,
|
||||||
this.getSourceTitle(),
|
this.getSourceTitle(),
|
||||||
this.tags
|
this.tags.joinToString(",")
|
||||||
)
|
)
|
@ -7,6 +7,7 @@ import io.ktor.client.engine.*
|
|||||||
import io.ktor.client.engine.ProxyBuilder.http
|
import io.ktor.client.engine.ProxyBuilder.http
|
||||||
import io.ktor.client.plugins.auth.*
|
import io.ktor.client.plugins.auth.*
|
||||||
import io.ktor.client.plugins.auth.providers.*
|
import io.ktor.client.plugins.auth.providers.*
|
||||||
|
import io.ktor.client.plugins.cache.*
|
||||||
import io.ktor.client.request.*
|
import io.ktor.client.request.*
|
||||||
import io.ktor.client.request.forms.*
|
import io.ktor.client.request.forms.*
|
||||||
import io.ktor.http.*
|
import io.ktor.http.*
|
||||||
@ -19,6 +20,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
|
|||||||
|
|
||||||
private val client = HttpClient() {
|
private val client = HttpClient() {
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
|
install(HttpCache)
|
||||||
json(Json {
|
json(Json {
|
||||||
prettyPrint = true
|
prettyPrint = true
|
||||||
isLenient = true
|
isLenient = true
|
||||||
@ -100,7 +102,7 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
|
|||||||
}.body()
|
}.body()
|
||||||
|
|
||||||
suspend fun spouts(): Map<String, SelfossModel.Spout>? =
|
suspend fun spouts(): Map<String, SelfossModel.Spout>? =
|
||||||
client.get(url("/a/spouts")) {
|
client.get(url("/sources/spouts")) {
|
||||||
parameter("username", apiDetailsService.getUserName())
|
parameter("username", apiDetailsService.getUserName())
|
||||||
parameter("password", apiDetailsService.getPassword())
|
parameter("password", apiDetailsService.getPassword())
|
||||||
}.body()
|
}.body()
|
||||||
@ -115,55 +117,38 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
|
|||||||
client.get(url("/api/about")).body()
|
client.get(url("/api/about")).body()
|
||||||
|
|
||||||
suspend fun markAsRead(id: String): SelfossModel.SuccessResponse? =
|
suspend fun markAsRead(id: String): SelfossModel.SuccessResponse? =
|
||||||
client.submitForm(
|
client.post(url("/mark/$id")) {
|
||||||
url = url("/mark/$id"),
|
parameter("username", apiDetailsService.getUserName())
|
||||||
formParameters = Parameters.build {
|
parameter("password", apiDetailsService.getPassword())
|
||||||
append("username", apiDetailsService.getUserName())
|
}.body()
|
||||||
append("password", apiDetailsService.getPassword())
|
|
||||||
},
|
|
||||||
encodeInQuery = true
|
|
||||||
).body()
|
|
||||||
|
|
||||||
suspend fun unmarkAsRead(id: String): SelfossModel.SuccessResponse? =
|
suspend fun unmarkAsRead(id: String): SelfossModel.SuccessResponse? =
|
||||||
client.submitForm(
|
client.post(url("/unmark/$id")) {
|
||||||
url = url("/unmark/$id"),
|
parameter("username", apiDetailsService.getUserName())
|
||||||
formParameters = Parameters.build {
|
parameter("password", apiDetailsService.getPassword())
|
||||||
append("username", apiDetailsService.getUserName())
|
}.body()
|
||||||
append("password", apiDetailsService.getPassword())
|
|
||||||
},
|
|
||||||
encodeInQuery = true
|
|
||||||
).body()
|
|
||||||
|
|
||||||
suspend fun starr(id: String): SelfossModel.SuccessResponse? =
|
suspend fun starr(id: String): SelfossModel.SuccessResponse? =
|
||||||
client.submitForm(
|
client.post(url("/starr/$id")) {
|
||||||
url = url("/starr/$id"),
|
parameter("username", apiDetailsService.getUserName())
|
||||||
formParameters = Parameters.build {
|
parameter("password", apiDetailsService.getPassword())
|
||||||
append("username", apiDetailsService.getUserName())
|
}.body()
|
||||||
append("password", apiDetailsService.getPassword())
|
|
||||||
},
|
|
||||||
encodeInQuery = true
|
|
||||||
).body()
|
|
||||||
|
|
||||||
suspend fun unstarr(id: String): SelfossModel.SuccessResponse? =
|
suspend fun unstarr(id: String): SelfossModel.SuccessResponse? =
|
||||||
client.submitForm(
|
client.post(url("/unstarr/$id")) {
|
||||||
url = url("/unstarr/$id"),
|
parameter("username", apiDetailsService.getUserName())
|
||||||
formParameters = Parameters.build {
|
parameter("password", apiDetailsService.getPassword())
|
||||||
append("username", apiDetailsService.getUserName())
|
}.body()
|
||||||
append("password", apiDetailsService.getPassword())
|
|
||||||
},
|
|
||||||
encodeInQuery = true
|
|
||||||
).body()
|
|
||||||
|
|
||||||
suspend fun markAllAsRead(ids: List<String>): SelfossModel.SuccessResponse? =
|
suspend fun markAllAsRead(ids: List<String>): SelfossModel.SuccessResponse? =
|
||||||
client.submitForm(
|
client.submitForm(
|
||||||
url = url("/mark"),
|
url = url("/mark"),
|
||||||
formParameters = Parameters.build {
|
formParameters = Parameters.build {
|
||||||
append("username", apiDetailsService.getUserName())
|
append("username", apiDetailsService.getUserName())
|
||||||
append("password", apiDetailsService.getPassword())
|
append("password", apiDetailsService.getPassword())
|
||||||
append("ids[]", ids.joinToString(","))
|
ids.map { append("ids[]", it) }
|
||||||
},
|
}
|
||||||
encodeInQuery = true
|
).body()
|
||||||
).body()
|
|
||||||
|
|
||||||
suspend fun createSourceForVersion(
|
suspend fun createSourceForVersion(
|
||||||
title: String,
|
title: String,
|
||||||
@ -186,19 +171,15 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
|
|||||||
tags: String,
|
tags: String,
|
||||||
filter: String
|
filter: String
|
||||||
): SelfossModel.SuccessResponse? =
|
): SelfossModel.SuccessResponse? =
|
||||||
client.submitForm(
|
client.post(url("/source")) {
|
||||||
url = url("/source"),
|
parameter("username", apiDetailsService.getUserName())
|
||||||
formParameters = Parameters.build {
|
parameter("password", apiDetailsService.getPassword())
|
||||||
append("username", apiDetailsService.getUserName())
|
parameter("title", title)
|
||||||
append("password", apiDetailsService.getPassword())
|
parameter("url", url)
|
||||||
append("title", title)
|
parameter("spout", spout)
|
||||||
append("url", url)
|
parameter("tags", tags)
|
||||||
append("spout", spout)
|
parameter("filter", filter)
|
||||||
append("tags", tags)
|
}.body()
|
||||||
append("filter", filter)
|
|
||||||
},
|
|
||||||
encodeInQuery = true
|
|
||||||
).body()
|
|
||||||
|
|
||||||
private suspend fun createSource2(
|
private suspend fun createSource2(
|
||||||
title: String,
|
title: String,
|
||||||
@ -207,21 +188,17 @@ class SelfossApi(private val apiDetailsService: ApiDetailsService) {
|
|||||||
tags: String,
|
tags: String,
|
||||||
filter: String
|
filter: String
|
||||||
): SelfossModel.SuccessResponse? =
|
): SelfossModel.SuccessResponse? =
|
||||||
client.submitForm(
|
client.post(url("/source")) {
|
||||||
url = url("/source"),
|
parameter("username", apiDetailsService.getUserName())
|
||||||
formParameters = Parameters.build {
|
parameter("password", apiDetailsService.getPassword())
|
||||||
append("username", apiDetailsService.getUserName())
|
parameter("title", title)
|
||||||
append("password", apiDetailsService.getPassword())
|
parameter("url", url)
|
||||||
append("title", title)
|
parameter("spout", spout)
|
||||||
append("url", url)
|
parameter("tags[]", tags)
|
||||||
append("spout", spout)
|
parameter("filter", filter)
|
||||||
append("tags[]", tags)
|
}.body()
|
||||||
append("filter", filter)
|
|
||||||
},
|
|
||||||
encodeInQuery = true
|
|
||||||
).body()
|
|
||||||
|
|
||||||
suspend fun deleteSource(id: String): SelfossModel.SuccessResponse? =
|
suspend fun deleteSource(id: Int): SelfossModel.SuccessResponse? =
|
||||||
client.delete(url("/source/$id")) {
|
client.delete(url("/source/$id")) {
|
||||||
parameter("username", apiDetailsService.getUserName())
|
parameter("username", apiDetailsService.getUserName())
|
||||||
parameter("password", apiDetailsService.getPassword())
|
parameter("password", apiDetailsService.getPassword())
|
||||||
|
@ -52,7 +52,7 @@ class SelfossModel {
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Source(
|
data class Source(
|
||||||
val id: String,
|
val id: Int,
|
||||||
val title: String,
|
val title: String,
|
||||||
val tags: List<String>,
|
val tags: List<String>,
|
||||||
val spout: String,
|
val spout: String,
|
||||||
@ -62,16 +62,16 @@ class SelfossModel {
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Item(
|
data class Item(
|
||||||
val id: String,
|
val id: Int,
|
||||||
val datetime: String,
|
val datetime: String,
|
||||||
val title: String,
|
val title: String,
|
||||||
val content: String,
|
val content: String,
|
||||||
var unread: Int,
|
var unread: Boolean,
|
||||||
var starred: Int,
|
var starred: Boolean,
|
||||||
val thumbnail: String?,
|
val thumbnail: String?,
|
||||||
val icon: String?,
|
val icon: String?,
|
||||||
val link: String,
|
val link: String,
|
||||||
val sourcetitle: String,
|
val sourcetitle: String,
|
||||||
val tags: String
|
val tags: List<String>
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -27,8 +27,8 @@ abstract class DeviceDataBaseService<ItemEntity>(val db: DeviceDatabase<ItemEnti
|
|||||||
// This filtered items from items val. Do not use
|
// This filtered items from items val. Do not use
|
||||||
fun getFocusedItems() {}
|
fun getFocusedItems() {}
|
||||||
fun computeBadges() {
|
fun computeBadges() {
|
||||||
searchService.badgeUnread = items.filter { item -> item.unread == 1 }.size
|
searchService.badgeUnread = items.filter { item -> item.unread }.size
|
||||||
searchService.badgeStarred = items.filter { item -> item.starred == 1 }.size
|
searchService.badgeStarred = items.filter { item -> item.starred }.size
|
||||||
searchService.badgeAll = items.size
|
searchService.badgeAll = items.size
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,10 +21,6 @@ class SearchService(val dateUtils: DateUtils) {
|
|||||||
var tagFilter: String? = null
|
var tagFilter: String? = null
|
||||||
var itemsCaching = false
|
var itemsCaching = false
|
||||||
|
|
||||||
var fetchedUnread = false
|
|
||||||
var fetchedAll = false
|
|
||||||
var fetchedStarred = false
|
|
||||||
|
|
||||||
var badgeUnread = -1
|
var badgeUnread = -1
|
||||||
var badgeAll = -1
|
var badgeAll = -1
|
||||||
var badgeStarred = -1
|
var badgeStarred = -1
|
||||||
|
@ -7,90 +7,48 @@ import kotlinx.coroutines.*
|
|||||||
|
|
||||||
class SelfossService<ItemEntity>(val api: SelfossApi, private val dbService: DeviceDataBaseService<ItemEntity>, private val searchService: SearchService) {
|
class SelfossService<ItemEntity>(val api: SelfossApi, private val dbService: DeviceDataBaseService<ItemEntity>, private val searchService: SearchService) {
|
||||||
|
|
||||||
suspend fun getAndStoreAllItems(isNetworkAvailable: Boolean) = withContext(
|
suspend fun getReadItems(itemsNumber: Int, offset: Int, isNetworkAvailable: Boolean): List<SelfossModel.Item>? = withContext(
|
||||||
Dispatchers.Default) {
|
Dispatchers.Default) {
|
||||||
if (isNetworkAvailable) {
|
if (isNetworkAvailable) {
|
||||||
launch {
|
val apiItems = readItems( itemsNumber, offset)
|
||||||
try {
|
// SAVE OR UPDATE IN DB
|
||||||
enqueueArticles(allNewItems(), true)
|
return@withContext apiItems
|
||||||
} catch (e: Throwable) {}
|
|
||||||
}
|
|
||||||
launch {
|
|
||||||
try {
|
|
||||||
enqueueArticles(allReadItems(), false)
|
|
||||||
} catch (e: Throwable) {}
|
|
||||||
}
|
|
||||||
launch {
|
|
||||||
try {
|
|
||||||
enqueueArticles(allStarredItems(), false)
|
|
||||||
} catch (e: Throwable) {}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
launch { dbService.updateDatabase() }
|
// GET FROM DB
|
||||||
|
return@withContext emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun refreshFocusedItems(itemsNumber: Int, isNetworkAvailable: Boolean) = withContext(
|
suspend fun getUnreadItems(itemsNumber: Int, offset: Int, isNetworkAvailable: Boolean): List<SelfossModel.Item>? = withContext(
|
||||||
Dispatchers.Default) {
|
Dispatchers.Default) {
|
||||||
if (isNetworkAvailable) {
|
if (isNetworkAvailable) {
|
||||||
val response = when (searchService.displayedItems) {
|
val apiItems = newItems(itemsNumber, offset)
|
||||||
"read" -> readItems(itemsNumber, 0)
|
// SAVE OR UPDATE IN DB
|
||||||
"unread" -> newItems(itemsNumber, 0)
|
return@withContext apiItems
|
||||||
"starred" -> starredItems(itemsNumber, 0)
|
} else {
|
||||||
else -> readItems(itemsNumber, 0)
|
// GET FROM DB
|
||||||
}
|
return@withContext emptyList()
|
||||||
|
|
||||||
if (response != null) {
|
|
||||||
// TODO:
|
|
||||||
// dbService.refreshFocusedItems(response.body() as ArrayList<SelfossModel.Item>)
|
|
||||||
dbService.updateDatabase()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getReadItems(itemsNumber: Int, offset: Int, isNetworkAvailable: Boolean) = withContext(
|
suspend fun getStarredItems(itemsNumber: Int, offset: Int, isNetworkAvailable: Boolean): List<SelfossModel.Item>? = withContext(
|
||||||
Dispatchers.Default) {
|
Dispatchers.Default) {
|
||||||
if (isNetworkAvailable) {
|
if (isNetworkAvailable) {
|
||||||
try {
|
val apiItems = starredItems(itemsNumber, offset)
|
||||||
enqueueArticles(readItems( itemsNumber, offset), false)
|
// SAVE OR UPDATE IN DB
|
||||||
searchService.fetchedAll = true
|
return@withContext apiItems
|
||||||
dbService.updateDatabase()
|
} else {
|
||||||
} catch (e: Throwable) {}
|
// GET FROM DB
|
||||||
|
return@withContext emptyList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun getUnreadItems(itemsNumber: Int, offset: Int, isNetworkAvailable: Boolean) = withContext(
|
suspend fun readAll(ids: List<String>, isNetworkAvailable: Boolean): Boolean {
|
||||||
Dispatchers.Default) {
|
// Add ids params
|
||||||
if (isNetworkAvailable) {
|
|
||||||
try {
|
|
||||||
if (!searchService.fetchedUnread) {
|
|
||||||
dbService.clearDBItems()
|
|
||||||
}
|
|
||||||
enqueueArticles(newItems(itemsNumber, offset), false)
|
|
||||||
searchService.fetchedUnread = true
|
|
||||||
} catch (e: Throwable) {}
|
|
||||||
}
|
|
||||||
dbService.updateDatabase()
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun getStarredItems(itemsNumber: Int, offset: Int, isNetworkAvailable: Boolean) = withContext(
|
|
||||||
Dispatchers.Default) {
|
|
||||||
if (isNetworkAvailable) {
|
|
||||||
try {
|
|
||||||
enqueueArticles(starredItems(itemsNumber, offset), false)
|
|
||||||
searchService.fetchedStarred = true
|
|
||||||
dbService.updateDatabase()
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun readAll(isNetworkAvailable: Boolean): Boolean {
|
|
||||||
var success = false
|
var success = false
|
||||||
if (isNetworkAvailable) {
|
if (isNetworkAvailable) {
|
||||||
// Do api call to read all
|
success = api.markAllAsRead(ids)?.isSuccess == true
|
||||||
} else {
|
// SAVE OR UPDATE IN DB
|
||||||
// Do db call to read all
|
|
||||||
}
|
}
|
||||||
// refresh view
|
// refresh view
|
||||||
return success
|
return success
|
||||||
@ -100,7 +58,6 @@ class SelfossService<ItemEntity>(val api: SelfossApi, private val dbService: Dev
|
|||||||
if (isNetworkAvailable) {
|
if (isNetworkAvailable) {
|
||||||
try {
|
try {
|
||||||
val response = api.stats()
|
val response = api.stats()
|
||||||
|
|
||||||
if (response != null) {
|
if (response != null) {
|
||||||
searchService.badgeUnread = response.unread
|
searchService.badgeUnread = response.unread
|
||||||
searchService.badgeAll = response.total
|
searchService.badgeAll = response.total
|
||||||
@ -123,13 +80,13 @@ class SelfossService<ItemEntity>(val api: SelfossApi, private val dbService: Dev
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun allNewItems(): List<SelfossModel.Item>? =
|
suspend fun allNewItems(): List<SelfossModel.Item>? =
|
||||||
readItems(200, 0)
|
readItems(200, 0)
|
||||||
|
|
||||||
private suspend fun allReadItems(): List<SelfossModel.Item>? =
|
suspend fun allReadItems(): List<SelfossModel.Item>? =
|
||||||
newItems(200, 0)
|
newItems(200, 0)
|
||||||
|
|
||||||
private suspend fun allStarredItems(): List<SelfossModel.Item>? =
|
suspend fun allStarredItems(): List<SelfossModel.Item>? =
|
||||||
starredItems(200, 0)
|
starredItems(200, 0)
|
||||||
|
|
||||||
private suspend fun readItems(
|
private suspend fun readItems(
|
||||||
|
Loading…
Reference in New Issue
Block a user