Compare commits

..

7 Commits

Author SHA1 Message Date
ae32cbfb6f Add missing imports (#367) 2021-10-26 12:54:57 +02:00
2dff3d9191 Use FLAG_IMMUTABLE as required by android 12 (#366) 2021-10-26 12:46:30 +02:00
c0ae0466c2 Remove the LikeButton library (#363)
* Add functions to add and remove favorites from SharedItems

* Remove the LikeButton dependency

* Use the theme colors for the icon tint
2021-10-22 20:06:39 +02:00
58b0574cf9 Use the drawer image loader to load images (#364) 2021-10-22 20:04:28 +02:00
5472c607cd Upgrade bottom navigation library (#362) 2021-10-15 20:15:30 +02:00
f95cb20408 Upgrade gradle to latest version (#361) 2021-10-15 20:15:17 +02:00
5640b7e56c Upgrade MaterialDrawer (#359)
* Upgrade material drawer library

* Add footer options to drawer

* Apply styles to drawer

* Added sources and tags to side drawer

* Hide bottom bar when the side drawer is opened

* Display hamburger icon to open the side drawer

* Add information about libraries to the side drawer

* Cleanup

* Implement reloading badges
2021-10-15 20:14:21 +02:00
18 changed files with 464 additions and 425 deletions

View File

@ -36,7 +36,7 @@ android {
targetCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8
} }
compileSdkVersion 31 compileSdkVersion 31
buildToolsVersion '30.0.3' buildToolsVersion '31.0.0'
buildFeatures { buildFeatures {
viewBinding true viewBinding true
} }
@ -108,6 +108,8 @@ dependencies {
implementation 'androidx.vectordrawable:vectordrawable:1.2.0-alpha02' implementation 'androidx.vectordrawable:vectordrawable:1.2.0-alpha02'
implementation "androidx.browser:browser:1.3.0" implementation "androidx.browser:browser:1.3.0"
implementation "androidx.cardview:cardview:$android_version" implementation "androidx.cardview:cardview:$android_version"
implementation "androidx.annotation:annotation:1.2.0"
implementation 'androidx.work:work-runtime-ktx:2.7.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.1' implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
implementation 'org.jsoup:jsoup:1.13.1' implementation 'org.jsoup:jsoup:1.13.1'
@ -120,7 +122,7 @@ dependencies {
} }
// Async // Async
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
// Retrofit + http logging + okhttp // Retrofit + http logging + okhttp
implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:retrofit:2.9.0'
@ -130,15 +132,14 @@ dependencies {
// Material-ish things // Material-ish things
implementation 'com.ashokvarma.android:bottom-navigation-bar:2.1.0' implementation 'com.ashokvarma.android:bottom-navigation-bar:2.1.0'
implementation 'com.github.jd-alexander:LikeButton:0.2.3'
implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1' implementation 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
// glide // glide
implementation 'com.github.bumptech.glide:glide:4.1.1' kapt 'com.github.bumptech.glide:compiler:4.11.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.1.1' implementation 'com.github.bumptech.glide:okhttp3-integration:4.1.1'
// Drawer // Drawer
implementation 'co.zsmb:materialdrawer-kt:2.0.2' implementation 'com.mikepenz:materialdrawer:8.4.4'
// Themes // Themes
implementation 'com.52inc:scoops:1.0.0' implementation 'com.52inc:scoops:1.0.0'
@ -151,13 +152,13 @@ dependencies {
//PhotoView //PhotoView
implementation 'com.github.chrisbanes:PhotoView:2.0.0' implementation 'com.github.chrisbanes:PhotoView:2.0.0'
implementation 'androidx.core:core-ktx:1.7.0-beta02' implementation 'androidx.core:core-ktx:1.7.0-rc01'
implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0-rc01" implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.4.0-rc01"
implementation "androidx.lifecycle:lifecycle-common-java8:2.4.0-rc01" implementation "androidx.lifecycle:lifecycle-common-java8:2.4.0-rc01"
implementation "androidx.room:room-ktx:2.4.0-alpha05" implementation "androidx.room:room-ktx:2.4.0-beta01"
kapt "androidx.room:room-compiler:2.4.0-alpha05" kapt "androidx.room:room-compiler:2.4.0-beta01"
implementation "android.arch.work:work-runtime-ktx:$work_version" implementation "android.arch.work:work-runtime-ktx:$work_version"
} }

View File

@ -4,7 +4,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
@ -13,12 +13,15 @@ import android.preference.PreferenceManager
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.View import android.view.View
import android.widget.ImageView
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.ActionBarDrawerToggle
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.SearchView import androidx.appcompat.widget.SearchView
import androidx.core.view.MenuItemCompat import androidx.core.view.MenuItemCompat
import androidx.core.view.doOnNextLayout import androidx.core.view.doOnNextLayout
import androidx.drawerlayout.widget.DrawerLayout
import androidx.recyclerview.widget.* import androidx.recyclerview.widget.*
import androidx.room.Room import androidx.room.Room
import androidx.work.Constraints import androidx.work.Constraints
@ -48,23 +51,26 @@ import apps.amine.bou.readerforselfoss.utils.longHash
import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible 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.drawer
import co.zsmb.materialdrawerkt.builders.footer
import co.zsmb.materialdrawerkt.draweritems.badgeable.primaryItem
import co.zsmb.materialdrawerkt.draweritems.profile.profile
import com.ashokvarma.bottomnavigation.BottomNavigationBar import com.ashokvarma.bottomnavigation.BottomNavigationBar
import com.ashokvarma.bottomnavigation.BottomNavigationItem import com.ashokvarma.bottomnavigation.BottomNavigationItem
import com.ashokvarma.bottomnavigation.TextBadgeItem import com.ashokvarma.bottomnavigation.TextBadgeItem
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.ftinc.scoop.Scoop import com.ftinc.scoop.Scoop
import com.mikepenz.aboutlibraries.LibsBuilder import com.mikepenz.aboutlibraries.LibsBuilder
import com.mikepenz.materialdrawer.Drawer
import com.mikepenz.materialdrawer.holder.BadgeStyle import com.mikepenz.materialdrawer.holder.BadgeStyle
import com.mikepenz.materialdrawer.holder.ColorHolder
import com.mikepenz.materialdrawer.holder.StringHolder import com.mikepenz.materialdrawer.holder.StringHolder
import com.mikepenz.materialdrawer.model.DividerDrawerItem import com.mikepenz.materialdrawer.model.DividerDrawerItem
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
import com.mikepenz.materialdrawer.model.interfaces.*
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerImageLoader
import com.mikepenz.materialdrawer.util.addStickyFooterItem
import com.mikepenz.materialdrawer.util.updateBadge
import com.mikepenz.materialdrawer.widget.AccountHeaderView
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@ -116,7 +122,6 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
private lateinit var tabNewBadge: TextBadgeItem private lateinit var tabNewBadge: TextBadgeItem
private lateinit var tabArchiveBadge: TextBadgeItem private lateinit var tabArchiveBadge: TextBadgeItem
private lateinit var tabStarredBadge: TextBadgeItem private lateinit var tabStarredBadge: TextBadgeItem
private lateinit var drawer: Drawer
private lateinit var api: SelfossApi private lateinit var api: SelfossApi
private lateinit var customTabActivityHelper: CustomTabActivityHelper private lateinit var customTabActivityHelper: CustomTabActivityHelper
private lateinit var editor: SharedPreferences.Editor private lateinit var editor: SharedPreferences.Editor
@ -166,6 +171,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
handleThemeBinding() handleThemeBinding()
setSupportActionBar(binding.toolBar) setSupportActionBar(binding.toolBar)
supportActionBar!!.setDisplayHomeAsUpEnabled(true)
supportActionBar!!.setHomeButtonEnabled(true)
val mDrawerToggle = ActionBarDrawerToggle(this, binding.drawerContainer, binding.toolBar, R.string.material_drawer_open, R.string.material_drawer_close)
binding.drawerContainer.addDrawerListener(mDrawerToggle)
mDrawerToggle.syncState()
db = Room.databaseBuilder( db = Room.databaseBuilder(
applicationContext, applicationContext,
@ -446,61 +456,86 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
} }
private fun handleDrawer() { private fun handleDrawer() {
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
Glide.with(this@HomeActivity)
.asBitmap()
.load(uri)
.apply(RequestOptions()
.placeholder(R.mipmap.ic_launcher)
.fallback(R.mipmap.ic_launcher)
.fitCenter())
.into(imageView)
}
override fun cancel(imageView: ImageView) {
Glide.with(this@HomeActivity).clear(imageView)
}
})
val drawerListener = object : DrawerLayout.DrawerListener {
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
}
override fun onDrawerOpened(drawerView: View) {
binding.bottomBar.hide()
}
override fun onDrawerClosed(drawerView: View) {
binding.bottomBar.show()
}
override fun onDrawerStateChanged(newState: Int) {
}
}
binding.drawerContainer.addDrawerListener(drawerListener)
displayAccountHeader = displayAccountHeader =
PreferenceManager.getDefaultSharedPreferences(this) PreferenceManager.getDefaultSharedPreferences(this)
.getBoolean("account_header_displaying", false) .getBoolean("account_header_displaying", false)
drawer = drawer { binding.mainDrawer.addStickyFooterItem(
rootViewRes = R.id.drawer_layout PrimaryDrawerItem().apply {
toolbar = binding.toolBar nameRes = R.string.drawer_report_bug
actionBarDrawerToggleEnabled = true iconRes = R.drawable.ic_bug_report_black_24dp
actionBarDrawerToggleAnimated = true isIconTinted = true
showOnFirstLaunch = true onDrawerItemClickListener = { _, _, _ ->
onSlide { _, p1 -> val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(Config.trackerUrl))
binding.bottomBar.alpha = (1 - p1) startActivity(browserIntent)
} false
onClosed {
binding.bottomBar.show()
}
onOpened {
binding.bottomBar.hide()
}
if (displayAccountHeader) {
accountHeader {
background = R.drawable.bg
profile(settings.getString("url", "")!!) {
iconDrawable = resources.getDrawable(R.mipmap.ic_launcher)
}
selectionListEnabledForSingleProfile = false
} }
} })
footer { binding.mainDrawer.addStickyFooterItem(
primaryItem(R.string.drawer_report_bug) { PrimaryDrawerItem().apply {
icon = R.drawable.ic_bug_report_black_24dp nameRes = R.string.title_activity_settings
iconTintingEnabled = true iconRes = R.drawable.ic_settings_black_24dp
onClick { _ -> isIconTinted = true
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(Config.trackerUrl)) onDrawerItemClickListener = { _, _, _ ->
startActivity(browserIntent) startActivityForResult(
false Intent(
} this@HomeActivity,
SettingsActivity::class.java
),
MENU_PREFERENCES
)
false
} }
})
primaryItem(R.string.title_activity_settings) { if (displayAccountHeader) {
icon = R.drawable.ic_settings_black_24dp AccountHeaderView(this).apply {
iconTintingEnabled = true attachToSliderView(binding.mainDrawer)
onClick { _ -> addProfiles(
startActivityForResult( ProfileDrawerItem().apply {
Intent( nameText = settings.getString("url", "").toString()
this@HomeActivity, setBackgroundResource(R.drawable.bg)
SettingsActivity::class.java iconRes = R.mipmap.ic_launcher
), selectionListEnabledForSingleProfile = false
MENU_PREFERENCES
)
false
} }
} )
} }
} }
} }
@ -511,10 +546,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
fun handleTags(maybeTags: List<Tag>?) { fun handleTags(maybeTags: List<Tag>?) {
if (maybeTags == null) { if (maybeTags == null) {
if (loadedFromCache) { if (loadedFromCache) {
drawer.addItem( binding.mainDrawer.itemAdapter.add(
SecondaryDrawerItem() SecondaryDrawerItem()
.withName(getString(R.string.drawer_error_loading_tags)) .apply { nameRes = R.string.drawer_error_loading_tags; isSelectable = false }
.withSelectable(false)
) )
} }
} else { } else {
@ -523,39 +557,38 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
.sortedBy { it.unread == 0 } .sortedBy { it.unread == 0 }
tagsBadge = filteredTags.map { tagsBadge = filteredTags.map {
val gd = GradientDrawable() val gd = GradientDrawable()
val color = try { val gdColor = try {
Color.parseColor(it.color) Color.parseColor(it.color)
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
appColors.colorPrimary appColors.colorPrimary
} }
gd.setColor(color) gd.setColor(gdColor)
gd.shape = GradientDrawable.RECTANGLE gd.shape = GradientDrawable.RECTANGLE
gd.setSize(30, 30) gd.setSize(30, 30)
gd.cornerRadius = 30F gd.cornerRadius = 30F
var drawerItem = val drawerItem =
PrimaryDrawerItem() PrimaryDrawerItem()
.withName(it.tag) .apply {
.withIdentifier(it.tag.longHash()) nameText = it.getTitleDecoded()
.withIcon(gd) identifier = it.tag.longHash()
.withBadgeStyle( iconDrawable = gd
BadgeStyle().withTextColor(Color.WHITE) badgeStyle = BadgeStyle().apply {
.withColor(appColors.colorAccent) textColor = ColorHolder.fromColor(Color.WHITE)
) color = ColorHolder.fromColor(appColors.colorAccent) }
.withOnDrawerItemClickListener { _, _, _ -> onDrawerItemClickListener = { _,_,_ ->
allItems = ArrayList() allItems = ArrayList()
maybeTagFilter = it maybeTagFilter = it
SharedItems.tagFilter = it.tag SharedItems.tagFilter = it.tag
getElementsAccordingToTab() getElementsAccordingToTab()
fetchOnEmptyList() fetchOnEmptyList()
false false
} } }
if (it.unread > 0) { if (it.unread > 0) {
drawerItem = drawerItem.withBadge("${it.unread}") drawerItem.badgeText = it.unread.toString()
} }
drawer.addItem(
drawerItem binding.mainDrawer.itemAdapter.add(drawerItem)
)
(it.tag.longHash() to it.unread) (it.tag.longHash() to it.unread)
}.toMap() }.toMap()
@ -565,10 +598,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
fun handleHiddenTags(maybeTags: List<Tag>?) { fun handleHiddenTags(maybeTags: List<Tag>?) {
if (maybeTags == null) { if (maybeTags == null) {
if (loadedFromCache) { if (loadedFromCache) {
drawer.addItem( binding.mainDrawer.itemAdapter.add(
SecondaryDrawerItem() SecondaryDrawerItem().apply {
.withName(getString(R.string.drawer_error_loading_tags)) nameRes = R.string.drawer_error_loading_tags
.withSelectable(false) isSelectable = false
}
) )
} }
} else { } else {
@ -576,39 +610,37 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
maybeTags.filter { hiddenTags.contains(it.tag) } maybeTags.filter { hiddenTags.contains(it.tag) }
tagsBadge = filteredHiddenTags.map { tagsBadge = filteredHiddenTags.map {
val gd = GradientDrawable() val gd = GradientDrawable()
val color = try { val gdColor = try {
Color.parseColor(it.color) Color.parseColor(it.color)
} catch (e: IllegalArgumentException) { } catch (e: IllegalArgumentException) {
appColors.colorPrimary appColors.colorPrimary
} }
gd.setColor(color) gd.setColor(gdColor)
gd.shape = GradientDrawable.RECTANGLE gd.shape = GradientDrawable.RECTANGLE
gd.setSize(30, 30) gd.setSize(30, 30)
gd.cornerRadius = 30F gd.cornerRadius = 30F
var drawerItem = val drawerItem =
PrimaryDrawerItem() PrimaryDrawerItem().apply {
.withName(it.tag) nameText = it.getTitleDecoded()
.withIdentifier(it.tag.longHash()) identifier = it.tag.longHash()
.withIcon(gd) iconDrawable = gd
.withBadgeStyle( badgeStyle = BadgeStyle().apply {
BadgeStyle().withTextColor(Color.WHITE) textColor = ColorHolder.fromColor(Color.WHITE)
.withColor(appColors.colorAccent) color = ColorHolder.fromColor(appColors.colorAccent) }
) onDrawerItemClickListener = { _,_,_ ->
.withOnDrawerItemClickListener { _, _, _ ->
allItems = ArrayList() allItems = ArrayList()
maybeTagFilter = it maybeTagFilter = it
SharedItems.tagFilter = it.tag SharedItems.tagFilter = it.tag
getElementsAccordingToTab() getElementsAccordingToTab()
fetchOnEmptyList() fetchOnEmptyList()
false false
} } }
if (it.unread > 0) { if (it.unread > 0) {
drawerItem = drawerItem.withBadge("${it.unread}") drawerItem.badgeText = it.unread.toString()
} }
drawer.addItem( binding.mainDrawer.itemAdapter.add(drawerItem)
drawerItem
)
(it.tag.longHash() to it.unread) (it.tag.longHash() to it.unread)
}.toMap() }.toMap()
@ -618,51 +650,43 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
fun handleSources(maybeSources: List<Source>?) { fun handleSources(maybeSources: List<Source>?) {
if (maybeSources == null) { if (maybeSources == null) {
if (loadedFromCache) { if (loadedFromCache) {
drawer.addItem( binding.mainDrawer.itemAdapter.add(
SecondaryDrawerItem() SecondaryDrawerItem().apply {
.withName(getString(R.string.drawer_error_loading_sources)) nameRes = R.string.drawer_error_loading_sources
.withSelectable(false) isSelectable = false
}
) )
} }
} else { } else {
for (tag in maybeSources) { for (source in maybeSources) {
val item = PrimaryDrawerItem() val item = PrimaryDrawerItem().apply {
.withName(tag.getTitleDecoded()) nameText = source.getTitleDecoded()
.withIdentifier(tag.id.toLong()) identifier = source.id.toLong()
.withOnDrawerItemClickListener { _, _, _ -> iconUrl = source.getIcon(this@HomeActivity)
allItems = ArrayList() onDrawerItemClickListener = { _,_,_ ->
maybeSourceFilter = tag allItems = ArrayList()
SharedItems.sourceIDFilter = tag.id.toLong() maybeSourceFilter = source
SharedItems.sourceFilter = tag.title SharedItems.sourceIDFilter = source.id.toLong()
getElementsAccordingToTab() SharedItems.sourceFilter = source.title
fetchOnEmptyList() getElementsAccordingToTab()
false fetchOnEmptyList()
} false
if (tag.getIcon(this@HomeActivity).isNotBlank()) {
thread {
try {
item.withIcon(BitmapDrawable(resources, Glide.with(this@HomeActivity).asBitmap().load(tag.getIcon(this@HomeActivity)).submit(100, 100).get()))
} catch (e: Exception) {
}
} }
} else {
item.withIcon(R.mipmap.ic_launcher)
} }
drawer.addItem(item) binding.mainDrawer.itemAdapter.add(item)
} }
} }
} }
drawer.removeAllItems() binding.mainDrawer.itemAdapter.clear()
if (maybeDrawerData != null) { if (maybeDrawerData != null) {
drawer.addItem( binding.mainDrawer.itemAdapter.add(
SecondaryDrawerItem() SecondaryDrawerItem().apply {
.withName(getString(R.string.drawer_item_filters)) nameRes = R.string.drawer_item_filters
.withSelectable(false) isSelectable = false
.withIdentifier(DRAWER_ID_FILTERS) identifier = DRAWER_ID_FILTERS
.withBadge(getString(R.string.drawer_action_clear)) badgeRes = R.string.drawer_action_clear
.withOnDrawerItemClickListener { _, _, _ -> onDrawerItemClickListener = { _,_,_ ->
allItems = ArrayList() allItems = ArrayList()
maybeSourceFilter = null maybeSourceFilter = null
SharedItems.sourceFilter = null SharedItems.sourceFilter = null
@ -673,55 +697,59 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
fetchOnEmptyList() fetchOnEmptyList()
false false
} }
}
) )
if (hiddenTags.isNotEmpty()) { if (hiddenTags.isNotEmpty()) {
drawer.addItem(DividerDrawerItem()) binding.mainDrawer.itemAdapter.add(
drawer.addItem( DividerDrawerItem(),
SecondaryDrawerItem() SecondaryDrawerItem().apply {
.withName(getString(R.string.drawer_item_hidden_tags)) nameRes = R.string.drawer_item_hidden_tags
.withIdentifier(DRAWER_ID_HIDDEN_TAGS) identifier = DRAWER_ID_HIDDEN_TAGS
.withSelectable(false) isSelectable = false
}
) )
handleHiddenTags(maybeDrawerData.tags) handleHiddenTags(maybeDrawerData.tags)
} }
drawer.addItem(DividerDrawerItem()) binding.mainDrawer.itemAdapter.add(
drawer.addItem( DividerDrawerItem(),
SecondaryDrawerItem() SecondaryDrawerItem().apply {
.withName(getString(R.string.drawer_item_tags)) nameRes = R.string.drawer_item_tags
.withIdentifier(DRAWER_ID_TAGS) identifier = DRAWER_ID_TAGS
.withSelectable(false) isSelectable = false
}
) )
handleTags(maybeDrawerData.tags) handleTags(maybeDrawerData.tags)
drawer.addItem(DividerDrawerItem()) binding.mainDrawer.itemAdapter.add(
drawer.addItem( DividerDrawerItem(),
SecondaryDrawerItem() SecondaryDrawerItem().apply {
.withName(getString(R.string.drawer_item_sources)) nameRes = R.string.drawer_item_sources
.withIdentifier(DRAWER_ID_TAGS) identifier = DRAWER_ID_SOURCES
.withBadge(getString(R.string.drawer_action_edit)) isSelectable = false
.withSelectable(false) badgeRes = R.string.drawer_action_edit
.withOnDrawerItemClickListener { _, _, _ -> onDrawerItemClickListener = { v,_,_ ->
startActivity(Intent(this, SourcesActivity::class.java)) startActivity(Intent(v!!.context, SourcesActivity::class.java))
false false
} }
}
) )
handleSources(maybeDrawerData.sources) handleSources(maybeDrawerData.sources)
drawer.addItem(DividerDrawerItem()) binding.mainDrawer.itemAdapter.add(
drawer.addItem( DividerDrawerItem(),
PrimaryDrawerItem() PrimaryDrawerItem().apply {
.withName(R.string.action_about) nameRes = R.string.action_about
.withSelectable(false) isSelectable = false
.withIcon(R.drawable.ic_info_outline_white_24dp) iconRes = R.drawable.ic_info_outline_white_24dp
.withIconTintingEnabled(true) isIconTinted = true
.withOnDrawerItemClickListener { _, _, _ -> onDrawerItemClickListener = { _,_,_ ->
LibsBuilder() LibsBuilder()
.withAboutIconShown(true) .withAboutIconShown(true)
.withAboutVersionShown(true) .withAboutVersionShown(true)
.start(this@HomeActivity) .start(this@HomeActivity)
false false
} }
}
) )
if (!loadedFromCache) { if (!loadedFromCache) {
if (maybeDrawerData.tags != null) { if (maybeDrawerData.tags != null) {
thread { thread {
@ -741,17 +769,17 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
} }
} else { } else {
if (!loadedFromCache) { if (!loadedFromCache) {
drawer.addItem( binding.mainDrawer.itemAdapter.add(
PrimaryDrawerItem() PrimaryDrawerItem().apply {
.withName(getString(R.string.no_tags_loaded)) nameRes = R.string.no_tags_loaded
.withIdentifier(DRAWER_ID_TAGS) identifier = DRAWER_ID_TAGS
.withSelectable(false) isSelectable = false
) },
drawer.addItem( PrimaryDrawerItem().apply {
PrimaryDrawerItem() nameRes = R.string.no_sources_loaded
.withName(getString(R.string.no_sources_loaded)) identifier = DRAWER_ID_SOURCES
.withIdentifier(DRAWER_ID_SOURCES) isSelectable = false
.withSelectable(false) }
) )
} }
} }
@ -802,14 +830,15 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
} }
} }
drawer.addItem( binding.mainDrawer.itemAdapter.add(
PrimaryDrawerItem().withName(getString(R.string.drawer_loading)).withSelectable( PrimaryDrawerItem().apply {
false nameRes = R.string.drawer_loading
) isSelectable = false
}
) )
thread { thread {
var drawerData = DrawerData(db.drawerDataDao().tags().map { it.toView() }, val drawerData = DrawerData(db.drawerDataDao().tags().map { it.toView() },
db.drawerDataDao().sources().map { it.toView() }) db.drawerDataDao().sources().map { it.toView() })
runOnUiThread { runOnUiThread {
handleDrawerData(drawerData, loadedFromCache = true) handleDrawerData(drawerData, loadedFromCache = true)
@ -1095,9 +1124,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
private fun reloadTagsBadges() { private fun reloadTagsBadges() {
tagsBadge.forEach { tagsBadge.forEach {
drawer.updateBadge(it.key, StringHolder("${it.value}")) binding.mainDrawer.updateBadge(it.key, StringHolder(it.value.toString()))
} }
drawer.resetDrawerContent() binding.mainDrawer.resetDrawerContent()
} }
private fun calculateNoOfColumns(): Int { private fun calculateNoOfColumns(): Int {
@ -1127,7 +1156,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
override fun onActivityResult(req: Int, result: Int, data: Intent?) { override fun onActivityResult(req: Int, result: Int, data: Intent?) {
when (req) { when (req) {
MENU_PREFERENCES -> { MENU_PREFERENCES -> {
drawer.closeDrawer() //drawer.closeDrawer()
recreate() recreate()
} }
else -> super.onActivityResult(req, result, data) else -> super.onActivityResult(req, result, data)

View File

@ -60,23 +60,18 @@ class MyApp : MultiDexApplication() {
private fun initDrawerImageLoader() { private fun initDrawerImageLoader() {
DrawerImageLoader.init(object : AbstractDrawerImageLoader() { DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
override fun set( override fun set(imageView: ImageView, uri: Uri, placeholder: Drawable, tag: String?) {
imageView: ImageView?,
uri: Uri?,
placeholder: Drawable?,
tag: String?
) {
Glide.with(imageView?.context) Glide.with(imageView?.context)
.loadMaybeBasicAuth(config, uri.toString()) .loadMaybeBasicAuth(config, uri.toString())
.apply(RequestOptions.fitCenterTransform().placeholder(placeholder)) .apply(RequestOptions.fitCenterTransform().placeholder(placeholder))
.into(imageView) .into(imageView)
} }
override fun cancel(imageView: ImageView?) { override fun cancel(imageView: ImageView) {
Glide.with(imageView?.context).clear(imageView) Glide.with(imageView?.context).clear(imageView)
} }
override fun placeholder(ctx: Context?, tag: String?): Drawable { override fun placeholder(ctx: Context, tag: String?): Drawable {
return baseContext.resources.getDrawable(R.mipmap.ic_launcher) return baseContext.resources.getDrawable(R.mipmap.ic_launcher)
} }
}) })

View File

@ -2,6 +2,9 @@ package apps.amine.bou.readerforselfoss
import android.content.Context import android.content.Context
import android.content.SharedPreferences import android.content.SharedPreferences
import android.graphics.Color
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
@ -14,17 +17,12 @@ import androidx.appcompat.app.AppCompatActivity
import android.view.Menu import android.view.Menu
import android.view.MenuItem import android.view.MenuItem
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.Toast
import androidx.fragment.app.Fragment
import androidx.room.Room import androidx.room.Room
import apps.amine.bou.readerforselfoss.api.selfoss.Item import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.databinding.ActivityImageBinding
import apps.amine.bou.readerforselfoss.databinding.ActivityReaderBinding import apps.amine.bou.readerforselfoss.databinding.ActivityReaderBinding
import apps.amine.bou.readerforselfoss.fragments.ArticleFragment import apps.amine.bou.readerforselfoss.fragments.ArticleFragment
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2 import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_1_2
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3 import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_2_3
import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_3_4 import apps.amine.bou.readerforselfoss.persistence.migrations.MIGRATION_3_4
@ -33,16 +31,9 @@ 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.Config import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.SharedItems import apps.amine.bou.readerforselfoss.utils.SharedItems
import apps.amine.bou.readerforselfoss.utils.network.isNetworkAccessible
import apps.amine.bou.readerforselfoss.utils.persistence.toEntity
import apps.amine.bou.readerforselfoss.utils.succeeded
import apps.amine.bou.readerforselfoss.utils.toggleStar import apps.amine.bou.readerforselfoss.utils.toggleStar
import com.ftinc.scoop.Scoop import com.ftinc.scoop.Scoop
import me.relex.circleindicator.CircleIndicator import me.relex.circleindicator.CircleIndicator
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlin.concurrent.thread
class ReaderActivity : AppCompatActivity() { class ReaderActivity : AppCompatActivity() {
@ -63,8 +54,11 @@ class ReaderActivity : AppCompatActivity() {
val ALIGN_LEFT = 2 val ALIGN_LEFT = 2
private fun showMenuItem(willAddToFavorite: Boolean) { private fun showMenuItem(willAddToFavorite: Boolean) {
toolbarMenu.findItem(R.id.save).isVisible = willAddToFavorite if (willAddToFavorite) {
toolbarMenu.findItem(R.id.unsave).isVisible = !willAddToFavorite toolbarMenu.findItem(R.id.star).icon.colorFilter = PorterDuffColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP)
} else {
toolbarMenu.findItem(R.id.star).icon.colorFilter = PorterDuffColorFilter(Color.RED, PorterDuff.Mode.SRC_ATOP)
}
} }
private fun canFavorite() { private fun canFavorite() {
@ -241,62 +235,23 @@ class ReaderActivity : AppCompatActivity() {
onBackPressed() onBackPressed()
return true return true
} }
R.id.save -> { R.id.star -> {
if (this@ReaderActivity.isNetworkAccessible(null)) { if (allItems[binding.pager.currentItem].starred) {
api.starrItem(allItems[binding.pager.currentItem].id) SharedItems.unstarItem(
.enqueue(object : Callback<SuccessResponse> { this@ReaderActivity,
override fun onResponse( api,
call: Call<SuccessResponse>, db,
response: Response<SuccessResponse> allItems[binding.pager.currentItem]
) { )
afterSave() afterUnsave()
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
Toast.makeText(
baseContext,
R.string.cant_mark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
} else { } else {
thread { SharedItems.starItem(
db.actionsDao().insertAllActions(ActionEntity(allItems[binding.pager.currentItem].id, false, false, true, false)) this@ReaderActivity,
afterSave() api,
} db,
} allItems[binding.pager.currentItem]
} )
R.id.unsave -> { afterSave()
if (this@ReaderActivity.isNetworkAccessible(null)) {
api.unstarrItem(allItems[binding.pager.currentItem].id)
.enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
afterUnsave()
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
Toast.makeText(
baseContext,
R.string.cant_unmark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(allItems[binding.pager.currentItem].id, false, false, false, true))
afterUnsave()
}
} }
} }
R.id.align_left -> { R.id.align_left -> {

View File

@ -7,23 +7,21 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.widget.ImageView.ScaleType import android.widget.ImageView.ScaleType
import android.widget.Toast
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
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
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.databinding.CardItemBinding import apps.amine.bou.readerforselfoss.databinding.CardItemBinding
import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase import apps.amine.bou.readerforselfoss.persistence.database.AppDatabase
import apps.amine.bou.readerforselfoss.persistence.entities.ActionEntity
import apps.amine.bou.readerforselfoss.themes.AppColors import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.Config import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.LinkOnTouchListener import apps.amine.bou.readerforselfoss.utils.LinkOnTouchListener
import apps.amine.bou.readerforselfoss.utils.SharedItems
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.network.isNetworkAvailable
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
@ -32,12 +30,6 @@ 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
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
import com.like.LikeButton
import com.like.OnLikeListener
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import kotlin.concurrent.thread
class ItemCardAdapter( class ItemCardAdapter(
override val app: Activity, override val app: Activity,
@ -67,13 +59,13 @@ class ItemCardAdapter(
with(holder) { with(holder) {
val itm = items[position] val itm = items[position]
binding.favButton.isSelected = itm.starred
binding.favButton.isLiked = itm.starred
binding.title.text = itm.getTitleDecoded() binding.title.text = itm.getTitleDecoded()
binding.title.setTextColor(ContextCompat.getColor( binding.title.setTextColor(ContextCompat.getColor(
c, c,
appColors.textColor appColors.textColor
)) ))
binding.title.setOnTouchListener(LinkOnTouchListener()) binding.title.setOnTouchListener(LinkOnTouchListener())
binding.title.setLinkTextColor(appColors.colorAccent) binding.title.setLinkTextColor(appColors.colorAccent)
@ -111,8 +103,6 @@ class ItemCardAdapter(
} else { } else {
c.circularBitmapDrawable(config, itm.getIcon(c), binding.sourceImage) c.circularBitmapDrawable(config, itm.getIcon(c), binding.sourceImage)
} }
binding.favButton.isLiked = itm.starred
} }
} }
@ -129,75 +119,30 @@ class ItemCardAdapter(
private fun handleClickListeners() { private fun handleClickListeners() {
binding.favButton.setOnLikeListener(object : OnLikeListener { binding.favButton.setOnClickListener {
override fun liked(likeButton: LikeButton) {
val (id) = items[bindingAdapterPosition]
if (c.isNetworkAccessible(null)) {
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
binding.favButton.isLiked = false
Toast.makeText(
c,
R.string.cant_mark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(id, false, false, true, false))
}
}
}
override fun unLiked(likeButton: LikeButton) {
val (id) = items[bindingAdapterPosition]
if (c.isNetworkAccessible(null)) {
api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
binding.favButton.isLiked = true
Toast.makeText(
c,
R.string.cant_unmark_favortie,
Toast.LENGTH_SHORT
).show()
}
})
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(id, false, false, false, true))
}
}
}
})
binding.shareBtn.setOnClickListener {
val item = items[bindingAdapterPosition] val item = items[bindingAdapterPosition]
c.shareLink(item.getLinkDecoded(), item.getTitleDecoded()) if (isNetworkAvailable(c)) {
if (item.starred) {
SharedItems.unstarItem(c, api, db, item)
item.starred = false
binding.favButton.isSelected = false
} else {
SharedItems.starItem(c, api, db, item)
item.starred = true
binding.favButton.isSelected = true
}
}
} }
binding.browserBtn.setOnClickListener { binding.shareBtn.setOnClickListener {
c.openInBrowserAsNewTask(items[bindingAdapterPosition]) val item = items[bindingAdapterPosition]
c.shareLink(item.getLinkDecoded(), item.getTitleDecoded())
}
binding.browserBtn.setOnClickListener {
c.openInBrowserAsNewTask(items[bindingAdapterPosition])
}
} }
}
private fun handleCustomTabActions() { private fun handleCustomTabActions() {
val customTabsIntent = c.buildCustomTabsIntent() val customTabsIntent = c.buildCustomTabsIntent()

View File

@ -30,7 +30,11 @@ data class Tag(
@SerializedName("tag") val tag: String, @SerializedName("tag") val tag: String,
@SerializedName("color") val color: String, @SerializedName("color") val color: String,
@SerializedName("unread") val unread: Int @SerializedName("unread") val unread: Int
) ) {
fun getTitleDecoded(): String {
return Html.fromHtml(tag).toString()
}
}
class SuccessResponse(@SerializedName("success") val success: Boolean) { class SuccessResponse(@SerializedName("success") val success: Boolean) {
val isSuccess: Boolean val isSuccess: Boolean

View File

@ -4,6 +4,7 @@ import android.app.NotificationManager
import android.app.PendingIntent import android.app.PendingIntent
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.os.Build
import android.preference.PreferenceManager import android.preference.PreferenceManager
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT import androidx.core.app.NotificationCompat.PRIORITY_DEFAULT
@ -117,8 +118,12 @@ override fun doWork(): Result {
val intent = Intent(context, MainActivity::class.java).apply { val intent = Intent(context, MainActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
} }
val pendingIntent: PendingIntent = val pflags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
PendingIntent.getActivity(context, 0, intent, 0) PendingIntent.FLAG_IMMUTABLE
} else {
0
}
val pendingIntent: PendingIntent = PendingIntent.getActivity(context, 0, intent, pflags)
val newItemsNotification = val newItemsNotification =
NotificationCompat.Builder(applicationContext, Config.newItemsChannelId) NotificationCompat.Builder(applicationContext, Config.newItemsChannelId)

View File

@ -59,9 +59,9 @@ class AppColors(a: Activity) {
} }
textColor = if (isDarkTheme) { textColor = if (isDarkTheme) {
R.color.md_white_1000 R.color.white
} else { } else {
R.color.md_grey_900 R.color.grey_900
} }
val wrapper = Context::class.java val wrapper = Context::class.java

View File

@ -7,6 +7,7 @@ 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.os.Build
import android.text.Spannable import android.text.Spannable
import android.text.style.ClickableSpan import android.text.style.ClickableSpan
import androidx.browser.customtabs.CustomTabsIntent import androidx.browser.customtabs.CustomTabsIntent
@ -26,12 +27,17 @@ fun Context.buildCustomTabsIntent(): CustomTabsIntent {
val actionIntent = Intent(Intent.ACTION_SEND) val actionIntent = Intent(Intent.ACTION_SEND)
actionIntent.type = "text/plain" actionIntent.type = "text/plain"
val createPendingShareIntent: PendingIntent = PendingIntent.getActivity( val pflags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
this, PendingIntent.FLAG_IMMUTABLE
0, } else {
actionIntent,
0 0
) }
val createPendingShareIntent: PendingIntent = PendingIntent.getActivity(
this,
0,
actionIntent,
pflags
)
val intentBuilder = CustomTabsIntent.Builder() val intentBuilder = CustomTabsIntent.Builder()

View File

@ -291,6 +291,92 @@ object SharedItems {
} }
} }
fun starItem(app: Context, api: SelfossApi, db: AppDatabase, item: Item) {
if (items.contains(item) && !item.starred) {
position = items.indexOf(item)
starItemAtPosition(app, api, db)
}
}
private fun starItemAtPosition(app: Context, api: SelfossApi, db: AppDatabase) {
val i = items[position]
if (app.isNetworkAccessible(null)) {
api.starrItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
val tmpItems = items
tmpItems[position].starred = true
items = tmpItems
resetDBItem(db)
getFocusedItems()
badgeStarred++
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
Toast.makeText(
app,
app.getString(R.string.cant_mark_favortie),
Toast.LENGTH_SHORT
).show()
}
})
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(i.id, false, false, true, false))
}
}
}
fun unstarItem(app: Context, api: SelfossApi, db: AppDatabase, item: Item) {
if (items.contains(item) && item.starred) {
position = items.indexOf(item)
unstarItemAtPosition(app, api, db)
}
}
private fun unstarItemAtPosition(app: Context, api: SelfossApi, db: AppDatabase) {
val i = items[position]
if (app.isNetworkAccessible(null)) {
api.unstarrItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(
call: Call<SuccessResponse>,
response: Response<SuccessResponse>
) {
val tmpItems = items
tmpItems[position].starred = false
items = tmpItems
resetDBItem(db)
getFocusedItems()
badgeStarred--
}
override fun onFailure(
call: Call<SuccessResponse>,
t: Throwable
) {
Toast.makeText(
app,
app.getString(R.string.cant_unmark_favortie),
Toast.LENGTH_SHORT
).show()
}
})
} else {
thread {
db.actionsDao().insertAllActions(ActionEntity(i.id, false, false, false, true))
}
}
}
private fun resetDBItem(db: AppDatabase) { private fun resetDBItem(db: AppDatabase) {
if (itemsCaching) { if (itemsCaching) {
val i = items[position] val i = items[position]

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true"
android:color="@color/red"/>
<item android:state_selected="false"
android:color="?android:attr/textColorPrimary" />
</selector>

View File

@ -0,0 +1,5 @@
<vector android:height="54.751434dp" android:viewportHeight="18.756023"
android:viewportWidth="20.554007" android:width="60dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFFFF"
android:pathData="m5.7968,14.6109c-2.7907,-2.7367 -4.4957,-4.7131 -5.018,-5.8165 -2.102,-4.4408 0.2424,-8.7943 4.7357,-8.7943 1.635,0 2.7056,0.425 3.9688,1.5755l0.7937,0.723 0.7937,-0.723c1.2631,-1.1505 2.3337,-1.5755 3.9688,-1.5755 4.4933,0 6.8377,4.3535 4.7357,8.7943 -0.5223,1.1035 -2.2274,3.0799 -5.018,5.8165 -2.3248,2.2798 -4.3409,4.1451 -4.4802,4.1451 -0.1393,0 -2.1554,-1.8653 -4.4802,-4.1451z" android:strokeWidth="0.0933392"/>
</vector>

View File

@ -1,7 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout <androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawerContainer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context="apps.amine.bou.readerforselfoss.HomeActivity" tools:context="apps.amine.bou.readerforselfoss.HomeActivity"
@ -36,51 +37,43 @@
</com.google.android.material.appbar.AppBarLayout> </com.google.android.material.appbar.AppBarLayout>
<FrameLayout <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/drawer_layout" android:id="@+id/swipeRefreshLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout <LinearLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent"
android:orientation="vertical"
android:background="?android:attr/windowBackground">
<LinearLayout <TextView
android:id="@+id/emptyText"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:gravity="center_horizontal"
android:background="?android:attr/windowBackground"> android:paddingTop="100dp"
android:text="@string/nothing_here"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:background="@android:color/transparent"
android:visibility="gone" />
<TextView <androidx.recyclerview.widget.RecyclerView
android:id="@+id/emptyText" android:id="@+id/recyclerView"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:gravity="fill" android:background="@android:color/transparent"
android:paddingTop="100dp" android:clipToPadding="false"
android:text="@string/nothing_here" android:paddingBottom="60dp"
android:textAlignment="center" android:scrollbars="vertical"
android:textAppearance="@style/TextAppearance.AppCompat.Headline" app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:background="@android:color/transparent" tools:listitem="@layout/list_item"/>
android:visibility="gone" /> </LinearLayout>
<androidx.recyclerview.widget.RecyclerView </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@android:color/transparent"
android:clipToPadding="false"
android:paddingBottom="60dp"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:listitem="@layout/list_item"/>
</LinearLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</FrameLayout>
</LinearLayout> </LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
@ -90,4 +83,11 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp"/> android:layout_height="60dp"/>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>
</RelativeLayout>
<com.mikepenz.materialdrawer.widget.MaterialDrawerSliderView
android:id="@+id/mainDrawer"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true" />
</androidx.drawerlayout.widget.DrawerLayout>

View File

@ -92,20 +92,22 @@
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/sourceTitleAndDate"> app:layout_constraintTop_toBottomOf="@+id/sourceTitleAndDate">
<com.like.LikeButton <ImageButton
android:id="@+id/favButton" android:id="@+id/favButton"
android:layout_width="35dp" android:layout_width="35dp"
android:layout_height="35dp" android:layout_height="35dp"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
android:layout_alignParentRight="true" android:layout_alignParentRight="true"
android:layout_centerVertical="true" android:layout_centerVertical="true"
android:layout_marginEnd="8dp" android:layout_marginEnd="8dp"
android:layout_marginRight="8dp" android:layout_marginRight="8dp"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:elevation="5dp" android:elevation="5dp"
android:padding="4dp" android:padding="4dp"
app:icon_size="22dp" android:scaleType="centerCrop"
app:icon_type="heart" /> app:srcCompat="@drawable/ic_menu_heart_60dp"
app:tint="@color/ic_menu_heart_color" />
<ImageButton <ImageButton
android:id="@+id/shareBtn" android:id="@+id/shareBtn"
@ -121,8 +123,8 @@
android:elevation="5dp" android:elevation="5dp"
android:padding="4dp" android:padding="4dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@drawable/ic_share_black_24dp" app:srcCompat="@drawable/ic_share_black_24dp"
android:tint="?android:attr/textColorPrimary" /> app:tint="?android:attr/textColorPrimary" />
<ImageButton <ImageButton
android:id="@+id/browserBtn" android:id="@+id/browserBtn"
@ -138,8 +140,8 @@
android:elevation="5dp" android:elevation="5dp"
android:padding="4dp" android:padding="4dp"
android:scaleType="centerCrop" android:scaleType="centerCrop"
android:src="@drawable/ic_open_in_browser_black_24dp" app:srcCompat="@drawable/ic_open_in_browser_black_24dp"
android:tint="?android:attr/textColorPrimary" /> app:tint="?android:attr/textColorPrimary" />
</RelativeLayout> </RelativeLayout>

View File

@ -15,14 +15,8 @@
android:title="@string/reader_text_align_justify" /> android:title="@string/reader_text_align_justify" />
<item <item
android:id="@+id/unsave" android:id="@+id/star"
android:icon="@drawable/heart_on" android:icon="@drawable/ic_menu_heart_60dp"
android:title="@string/remove_to_favs_reader"
android:visible="true"
app:showAsAction="ifRoom" />
<item
android:id="@+id/save"
android:icon="@drawable/heart_off"
android:title="@string/add_to_favs_reader" android:title="@string/add_to_favs_reader"
android:visible="true" android:visible="true"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />

View File

@ -7,6 +7,7 @@
<color name="pink">#FFe91e63</color> <color name="pink">#FFe91e63</color>
<color name="white">#FFFFFFFF</color> <color name="white">#FFFFFFFF</color>
<color name="black">#FF000000</color> <color name="black">#FF000000</color>
<color name="red">#FF0000</color>
<color name="refresh_progress_1">@color/colorAccentDark</color> <color name="refresh_progress_1">@color/colorAccentDark</color>
<color name="refresh_progress_2">@color/colorAccent</color> <color name="refresh_progress_2">@color/colorAccent</color>
<color name="refresh_progress_3">@color/pink</color> <color name="refresh_progress_3">@color/pink</color>

View File

@ -4,30 +4,34 @@
<item name="android:windowBackground">@drawable/background_splash</item> <item name="android:windowBackground">@drawable/background_splash</item>
</style> </style>
<style name="NoBar" parent="MaterialDrawerTheme.Light"> <style name="NoBar" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
<item name="colorAccentDark">@color/colorAccentDark</item> <item name="colorAccentDark">@color/colorAccentDark</item>
<item name="cardBackgroundColor">@color/white</item> <item name="cardBackgroundColor">@color/white</item>
<item name="android:colorBackground">@color/md_grey_50</item> <item name="android:colorBackground">@color/grey_50</item>
<item name="android:textColorPrimary">@color/md_grey_900</item> <item name="colorSurface">@color/grey_50</item>
<item name="android:textColorSecondary">@color/md_grey_400</item> <item name="android:textColorPrimary">@color/grey_900</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item> <item name="android:textColorSecondary">@color/grey_400</item>
<item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyle</item>
<item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyle</item>
<item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item> <item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Light</item>
</style> </style>
<style name="NoBarDark" parent="MaterialDrawerTheme"> <style name="NoBarDark" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item> <item name="colorAccent">@color/colorAccent</item>
<item name="colorAccentDark">@color/colorAccentDark</item> <item name="colorAccentDark">@color/colorAccentDark</item>
<item name="cardBackgroundColor">@color/md_grey_800</item> <item name="cardBackgroundColor">@color/grey_800</item>
<item name="android:colorBackground">@color/darkBackground</item> <item name="android:colorBackground">@color/darkBackground</item>
<item name="bnbBackgroundColor">@color/md_grey_900</item> <item name="colorSurface">@color/darkBackground</item>
<item name="android:textColorPrimary">@color/md_white_1000</item> <item name="bnbBackgroundColor">@color/grey_900</item>
<item name="android:textColorSecondary">@color/md_grey_600</item> <item name="android:textColorPrimary">@color/white</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item> <item name="android:textColorSecondary">@color/grey_600</item>
<item name="materialDrawerStyle">@style/Widget.MaterialDrawerStyle</item>
<item name="materialDrawerHeaderStyle">@style/Widget.MaterialDrawerHeaderStyle</item>
<item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Dark</item> <item name="toolbarPopupTheme">@style/ThemeOverlay.AppCompat.Dark</item>
</style> </style>
@ -35,7 +39,6 @@
<style name="ToolBarStyle" parent="Theme.AppCompat"> <style name="ToolBarStyle" parent="Theme.AppCompat">
<item name="android:textColorPrimary">@color/white</item> <item name="android:textColorPrimary">@color/white</item>
<item name="android:textColorSecondary">@color/white</item> <item name="android:textColorSecondary">@color/white</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
<item name="actionMenuTextColor">@color/white</item> <item name="actionMenuTextColor">@color/white</item>
<!--<item name="actionOverflowButtonStyle">@style/ActionButtonOverflowStyle</item> <!--<item name="actionOverflowButtonStyle">@style/ActionButtonOverflowStyle</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>--> <item name="drawerArrowStyle">@style/DrawerArrowStyle</item>-->

View File

@ -17,7 +17,7 @@ buildscript {
} }
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:7.0.2' classpath 'com.android.tools.build:gradle:7.0.3'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
} }
} }