Compare commits
	
		
			8 Commits
		
	
	
		
			v125010111
			...
			2f5ebe2420
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | 2f5ebe2420 | ||
| 1893904135 | |||
| a4cb28ba81 | |||
| ae3cada1c7 | |||
|  | 309500276f | ||
| ce255b23cd | |||
| 3b3a575dae | |||
|  | 7bcf4574b4 | 
							
								
								
									
										24
									
								
								CHANGELOG.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								CHANGELOG.md
									
									
									
									
									
								
							| @@ -1,3 +1,27 @@ | |||||||
|  | **v125010201 | ||||||
|  |  | ||||||
|  | - fix: Handle empty url issue. | ||||||
|  | - Merge pull request 'Removed the floating bar.' (#177) from floating-bar into master | ||||||
|  | - chore: changing actions in reader fragment. | ||||||
|  | - Changelog for v125010131 | ||||||
|  |  | ||||||
|  | -------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | **v125010131 | ||||||
|  |  | ||||||
|  | - fix: reload the adapter when it's needed. Fixes #128. (#176) | ||||||
|  | - feat: basic auth and images loading. Fixes #172. (#175) | ||||||
|  | - Changelog for v125010111 | ||||||
|  |  | ||||||
|  | -------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  | **v125010111 | ||||||
|  |  | ||||||
|  | - Debug trying to fix context issues. (#174) | ||||||
|  | - Changelog for v125010031 | ||||||
|  |  | ||||||
|  | -------------------------------------------------------------------- | ||||||
|  |  | ||||||
| **v125010031 | **v125010031 | ||||||
|  |  | ||||||
| - Merge pull request 'Bump dependencies' (#173) from upgarde into master | - Merge pull request 'Bump dependencies' (#173) from upgarde into master | ||||||
|   | |||||||
| @@ -156,7 +156,7 @@ dependencies { | |||||||
|     implementation("com.github.bumptech.glide:okhttp3-integration:4.16.0") |     implementation("com.github.bumptech.glide:okhttp3-integration:4.16.0") | ||||||
|  |  | ||||||
|     // Themes |     // Themes | ||||||
|     implementation("com.github.rubensousa:floatingtoolbar:1.5.1") |     implementation("com.leinardi.android:speed-dial:3.3.0") | ||||||
|  |  | ||||||
|     // Pager |     // Pager | ||||||
|     implementation("me.relex:circleindicator:2.1.6") |     implementation("me.relex:circleindicator:2.1.6") | ||||||
|   | |||||||
| @@ -65,19 +65,6 @@ class SettingsActivityGeneralTest { | |||||||
|                 ), |                 ), | ||||||
|             ), |             ), | ||||||
|         ) |         ) | ||||||
|         onView(withSettingsCheckboxWidget(R.string.reader_static_bar_title)).check( |  | ||||||
|             matches( |  | ||||||
|                 allOf( |  | ||||||
|                     isDisplayed(), |  | ||||||
|                     not(isChecked()), |  | ||||||
|                 ), |  | ||||||
|             ), |  | ||||||
|         ) |  | ||||||
|         onView(withSettingsCheckboxFrame(R.string.reader_static_bar_title)).check( |  | ||||||
|             matches( |  | ||||||
|                 isEnabled(), |  | ||||||
|             ), |  | ||||||
|         ) |  | ||||||
|         onView(withText(R.string.pref_general_category_displaying)).check(matches(isDisplayed())) |         onView(withText(R.string.pref_general_category_displaying)).check(matches(isDisplayed())) | ||||||
|         onView(withSettingsCheckboxWidget(R.string.pref_switch_card_view_title)).check( |         onView(withSettingsCheckboxWidget(R.string.pref_switch_card_view_title)).check( | ||||||
|             matches( |             matches( | ||||||
| @@ -161,19 +148,6 @@ class SettingsActivityGeneralTest { | |||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
|     fun testGeneralActionsCheckboxes() { |     fun testGeneralActionsCheckboxes() { | ||||||
|         // article viewer settings |  | ||||||
|         onView(withSettingsCheckboxFrame(R.string.reader_static_bar_title)).check( |  | ||||||
|             matches( |  | ||||||
|                 isEnabled(), |  | ||||||
|             ), |  | ||||||
|         ) |  | ||||||
|         onView(withSettingsCheckboxWidget(R.string.pref_article_viewer_title)).perform(click()) |  | ||||||
|         onView(withSettingsCheckboxFrame(R.string.reader_static_bar_title)).check( |  | ||||||
|             matches( |  | ||||||
|                 not(isEnabled()), |  | ||||||
|             ), |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         onView(withSettingsCheckboxFrame(R.string.card_height_title)).check(matches(not(isEnabled()))) |         onView(withSettingsCheckboxFrame(R.string.card_height_title)).check(matches(not(isEnabled()))) | ||||||
|         onView(withSettingsCheckboxWidget(R.string.pref_switch_card_view_title)).perform(click()) |         onView(withSettingsCheckboxWidget(R.string.pref_switch_card_view_title)).perform(click()) | ||||||
|         onView(withSettingsCheckboxFrame(R.string.card_height_title)).check(matches(isEnabled())) |         onView(withSettingsCheckboxFrame(R.string.card_height_title)).check(matches(isEnabled())) | ||||||
|   | |||||||
| @@ -317,13 +317,9 @@ class HomeActivity : | |||||||
|  |  | ||||||
|     private fun reloadLayoutManager() { |     private fun reloadLayoutManager() { | ||||||
|         val currentManager = binding.recyclerView.layoutManager |         val currentManager = binding.recyclerView.layoutManager | ||||||
|         val layoutManager: RecyclerView.LayoutManager |  | ||||||
|  |  | ||||||
|         // This will only update the layout manager if settings changed |         fun gridLayoutManager() { | ||||||
|         when (currentManager) { |             val layoutManager = | ||||||
|             is StaggeredGridLayoutManager -> |  | ||||||
|                 if (!appSettingsService.isCardViewEnabled()) { |  | ||||||
|                     layoutManager = |  | ||||||
|                 GridLayoutManager( |                 GridLayoutManager( | ||||||
|                     this, |                     this, | ||||||
|                     calculateNoOfColumns(), |                     calculateNoOfColumns(), | ||||||
| @@ -331,9 +327,8 @@ class HomeActivity : | |||||||
|             binding.recyclerView.layoutManager = layoutManager |             binding.recyclerView.layoutManager = layoutManager | ||||||
|         } |         } | ||||||
|  |  | ||||||
|             is GridLayoutManager -> |         fun staggererdGridLayoutManager() { | ||||||
|                 if (appSettingsService.isCardViewEnabled()) { |             var layoutManager = | ||||||
|                     layoutManager = |  | ||||||
|                 StaggeredGridLayoutManager( |                 StaggeredGridLayoutManager( | ||||||
|                     calculateNoOfColumns(), |                     calculateNoOfColumns(), | ||||||
|                     StaggeredGridLayoutManager.VERTICAL, |                     StaggeredGridLayoutManager.VERTICAL, | ||||||
| @@ -343,24 +338,23 @@ class HomeActivity : | |||||||
|             binding.recyclerView.layoutManager = layoutManager |             binding.recyclerView.layoutManager = layoutManager | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         when (currentManager) { | ||||||
|  |             is StaggeredGridLayoutManager -> | ||||||
|  |                 if (!appSettingsService.isCardViewEnabled()) { | ||||||
|  |                     gridLayoutManager() | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |             is GridLayoutManager -> | ||||||
|  |                 if (appSettingsService.isCardViewEnabled()) { | ||||||
|  |                     staggererdGridLayoutManager() | ||||||
|  |                 } | ||||||
|  |  | ||||||
|             else -> |             else -> | ||||||
|                 if (currentManager == null) { |                 if (currentManager == null) { | ||||||
|                     if (!appSettingsService.isCardViewEnabled()) { |                     if (!appSettingsService.isCardViewEnabled()) { | ||||||
|                         layoutManager = |                         gridLayoutManager() | ||||||
|                             GridLayoutManager( |  | ||||||
|                                 this, |  | ||||||
|                                 calculateNoOfColumns(), |  | ||||||
|                             ) |  | ||||||
|                         binding.recyclerView.layoutManager = layoutManager |  | ||||||
|                     } else { |                     } else { | ||||||
|                         layoutManager = |                         staggererdGridLayoutManager() | ||||||
|                             StaggeredGridLayoutManager( |  | ||||||
|                                 calculateNoOfColumns(), |  | ||||||
|                                 StaggeredGridLayoutManager.VERTICAL, |  | ||||||
|                             ) |  | ||||||
|                         layoutManager.gapStrategy = |  | ||||||
|                             StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS |  | ||||||
|                         binding.recyclerView.layoutManager = layoutManager |  | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
| @@ -485,8 +479,8 @@ class HomeActivity : | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun handleListResult(appendResults: Boolean = false) { |     private fun handleListResult(appendResults: Boolean = false) { | ||||||
|         if (appendResults) { |  | ||||||
|         val oldManager = binding.recyclerView.layoutManager |         val oldManager = binding.recyclerView.layoutManager | ||||||
|  |         if (appendResults) { | ||||||
|             firstVisible = |             firstVisible = | ||||||
|                 when (oldManager) { |                 when (oldManager) { | ||||||
|                     is StaggeredGridLayoutManager -> |                     is StaggeredGridLayoutManager -> | ||||||
| @@ -499,7 +493,13 @@ class HomeActivity : | |||||||
|                 } |                 } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (recyclerAdapter == null) { |         @Suppress("detekt:ComplexCondition") | ||||||
|  |         if (recyclerAdapter == null || | ||||||
|  |             ( | ||||||
|  |                 (recyclerAdapter is ItemListAdapter && appSettingsService.isCardViewEnabled()) || | ||||||
|  |                     (recyclerAdapter is ItemCardAdapter && !appSettingsService.isCardViewEnabled()) | ||||||
|  |             ) | ||||||
|  |         ) { | ||||||
|             if (appSettingsService.isCardViewEnabled()) { |             if (appSettingsService.isCardViewEnabled()) { | ||||||
|                 recyclerAdapter = |                 recyclerAdapter = | ||||||
|                     ItemCardAdapter( |                     ItemCardAdapter( | ||||||
|   | |||||||
| @@ -118,13 +118,13 @@ class ItemCardAdapter( | |||||||
|                 binding.itemImage.setImageDrawable(null) |                 binding.itemImage.setImageDrawable(null) | ||||||
|             } else { |             } else { | ||||||
|                 binding.itemImage.visibility = View.VISIBLE |                 binding.itemImage.visibility = View.VISIBLE | ||||||
|                 c.bitmapCenterCrop(itm.getThumbnail(repository.baseUrl), binding.itemImage) |                 c.bitmapCenterCrop(itm.getThumbnail(repository.baseUrl), binding.itemImage, appSettingsService) | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if (itm.getIcon(repository.baseUrl).isEmpty()) { |             if (itm.getIcon(repository.baseUrl).isEmpty()) { | ||||||
|                 binding.sourceImage.setBackgroundAndText(itm.sourcetitle.getHtmlDecoded()) |                 binding.sourceImage.setBackgroundAndText(itm.sourcetitle.getHtmlDecoded()) | ||||||
|             } else { |             } else { | ||||||
|                 c.circularDrawable(itm.getIcon(repository.baseUrl), binding.sourceImage) |                 c.circularDrawable(itm.getIcon(repository.baseUrl), binding.sourceImage, appSettingsService) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -65,10 +65,10 @@ class ItemListAdapter( | |||||||
|                 if (itm.getIcon(repository.baseUrl).isEmpty()) { |                 if (itm.getIcon(repository.baseUrl).isEmpty()) { | ||||||
|                     binding.itemImage.setBackgroundAndText(itm.sourcetitle.getHtmlDecoded()) |                     binding.itemImage.setBackgroundAndText(itm.sourcetitle.getHtmlDecoded()) | ||||||
|                 } else { |                 } else { | ||||||
|                     c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage) |                     c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage, appSettingsService) | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 c.circularDrawable(itm.getThumbnail(repository.baseUrl), binding.itemImage) |                 c.circularDrawable(itm.getThumbnail(repository.baseUrl), binding.itemImage, appSettingsService) | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -16,6 +16,7 @@ import bou.amine.apps.readerforselfossv2.android.databinding.SourceListItemBindi | |||||||
| import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable | import bou.amine.apps.readerforselfossv2.android.utils.glide.circularDrawable | ||||||
| import bou.amine.apps.readerforselfossv2.model.SelfossModel | import bou.amine.apps.readerforselfossv2.model.SelfossModel | ||||||
| import bou.amine.apps.readerforselfossv2.repository.Repository | import bou.amine.apps.readerforselfossv2.repository.Repository | ||||||
|  | import bou.amine.apps.readerforselfossv2.service.AppSettingsService | ||||||
| import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded | import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded | ||||||
| import bou.amine.apps.readerforselfossv2.utils.getIcon | import bou.amine.apps.readerforselfossv2.utils.getIcon | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| @@ -36,6 +37,7 @@ class SourcesListAdapter( | |||||||
|  |  | ||||||
|     override val di: DI by closestDI(app) |     override val di: DI by closestDI(app) | ||||||
|     private val repository: Repository by instance() |     private val repository: Repository by instance() | ||||||
|  |     private val appSettingsService: AppSettingsService by instance() | ||||||
|  |  | ||||||
|     override fun onCreateViewHolder( |     override fun onCreateViewHolder( | ||||||
|         parent: ViewGroup, |         parent: ViewGroup, | ||||||
| @@ -82,7 +84,7 @@ class SourcesListAdapter( | |||||||
|         if (itm.getIcon(repository.baseUrl).isEmpty()) { |         if (itm.getIcon(repository.baseUrl).isEmpty()) { | ||||||
|             binding.itemImage.setBackgroundAndText(itm.title.getHtmlDecoded()) |             binding.itemImage.setBackgroundAndText(itm.title.getHtmlDecoded()) | ||||||
|         } else { |         } else { | ||||||
|             c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage) |             c.circularDrawable(itm.getIcon(repository.baseUrl), binding.itemImage, appSettingsService) | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (!itm.error.isNullOrBlank()) { |         if (!itm.error.isNullOrBlank()) { | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ class LoadingWorker( | |||||||
|                         handleNewItemsNotification(apiItems, notificationManager) |                         handleNewItemsNotification(apiItems, notificationManager) | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 apiItems.map { it.preloadImages(context) } |                 apiItems.map { it.preloadImages(context, appSettingsService) } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         return Result.success() |         return Result.success() | ||||||
|   | |||||||
| @@ -2,18 +2,14 @@ package bou.amine.apps.readerforselfossv2.android.fragments | |||||||
|  |  | ||||||
| import android.content.Context | import android.content.Context | ||||||
| import android.content.Intent | import android.content.Intent | ||||||
| import android.content.res.ColorStateList |  | ||||||
| import android.content.res.TypedArray | import android.content.res.TypedArray | ||||||
| import android.graphics.Bitmap | import android.graphics.Bitmap | ||||||
| import android.graphics.Typeface | import android.graphics.Typeface | ||||||
| import android.graphics.drawable.ColorDrawable |  | ||||||
| import android.os.Bundle | import android.os.Bundle | ||||||
| import android.util.TypedValue |  | ||||||
| import android.util.TypedValue.DATA_NULL_UNDEFINED | import android.util.TypedValue.DATA_NULL_UNDEFINED | ||||||
| import android.view.GestureDetector | import android.view.GestureDetector | ||||||
| import android.view.InflateException | import android.view.InflateException | ||||||
| import android.view.LayoutInflater | import android.view.LayoutInflater | ||||||
| import android.view.MenuItem |  | ||||||
| import android.view.MotionEvent | import android.view.MotionEvent | ||||||
| import android.view.View | import android.view.View | ||||||
| import android.view.ViewGroup | import android.view.ViewGroup | ||||||
| @@ -23,7 +19,6 @@ import android.webkit.WebView | |||||||
| import android.webkit.WebViewClient | import android.webkit.WebViewClient | ||||||
| import android.widget.Toast | import android.widget.Toast | ||||||
| import androidx.appcompat.app.AlertDialog | import androidx.appcompat.app.AlertDialog | ||||||
| import androidx.core.widget.NestedScrollView |  | ||||||
| import androidx.fragment.app.Fragment | import androidx.fragment.app.Fragment | ||||||
| import bou.amine.apps.readerforselfossv2.android.ImageActivity | import bou.amine.apps.readerforselfossv2.android.ImageActivity | ||||||
| import bou.amine.apps.readerforselfossv2.android.R | import bou.amine.apps.readerforselfossv2.android.R | ||||||
| @@ -32,7 +27,11 @@ import bou.amine.apps.readerforselfossv2.android.model.ParecelableItem | |||||||
| import bou.amine.apps.readerforselfossv2.android.model.toModel | import bou.amine.apps.readerforselfossv2.android.model.toModel | ||||||
| import bou.amine.apps.readerforselfossv2.android.model.toParcelable | import bou.amine.apps.readerforselfossv2.android.model.toParcelable | ||||||
| import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName | import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName | ||||||
|  | import bou.amine.apps.readerforselfossv2.android.utils.bottombar.addHomeMadeActionItem | ||||||
|  | import bou.amine.apps.readerforselfossv2.android.utils.getColorFromAttr | ||||||
|  | import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapFitCenter | ||||||
| import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream | import bou.amine.apps.readerforselfossv2.android.utils.glide.getBitmapInputStream | ||||||
|  | import bou.amine.apps.readerforselfossv2.android.utils.glide.getGlideImageForResource | ||||||
| import bou.amine.apps.readerforselfossv2.android.utils.isUrlValid | import bou.amine.apps.readerforselfossv2.android.utils.isUrlValid | ||||||
| import bou.amine.apps.readerforselfossv2.android.utils.openItemUrlInBrowserAsNewTask | import bou.amine.apps.readerforselfossv2.android.utils.openItemUrlInBrowserAsNewTask | ||||||
| import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowser | import bou.amine.apps.readerforselfossv2.android.utils.openUrlInBrowser | ||||||
| @@ -46,11 +45,7 @@ import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded | |||||||
| import bou.amine.apps.readerforselfossv2.utils.getImages | import bou.amine.apps.readerforselfossv2.utils.getImages | ||||||
| import bou.amine.apps.readerforselfossv2.utils.getThumbnail | import bou.amine.apps.readerforselfossv2.utils.getThumbnail | ||||||
| import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString | import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString | ||||||
| import com.bumptech.glide.Glide | import com.leinardi.android.speeddial.SpeedDialView | ||||||
| import com.bumptech.glide.load.engine.DiskCacheStrategy |  | ||||||
| import com.bumptech.glide.request.RequestOptions |  | ||||||
| import com.github.rubensousa.floatingtoolbar.FloatingToolbar |  | ||||||
| import com.google.android.material.floatingactionbutton.FloatingActionButton |  | ||||||
| import kotlinx.coroutines.CoroutineScope | import kotlinx.coroutines.CoroutineScope | ||||||
| import kotlinx.coroutines.Dispatchers | import kotlinx.coroutines.Dispatchers | ||||||
| import kotlinx.coroutines.launch | import kotlinx.coroutines.launch | ||||||
| @@ -65,6 +60,8 @@ import java.util.Locale | |||||||
| import java.util.concurrent.ExecutionException | import java.util.concurrent.ExecutionException | ||||||
|  |  | ||||||
| private const val IMAGE_JPG = "image/jpg" | private const val IMAGE_JPG = "image/jpg" | ||||||
|  | private const val IMAGE_PNG = "image/png" | ||||||
|  | private const val IMAGE_WEBP = "image/webp" | ||||||
|  |  | ||||||
| private const val WHITE_COLOR_HEX = 0xFFFFFF | private const val WHITE_COLOR_HEX = 0xFFFFFF | ||||||
|  |  | ||||||
| @@ -73,6 +70,8 @@ private const val DEFAULT_FONT_SIZE = 16 | |||||||
| class ArticleFragment : | class ArticleFragment : | ||||||
|     Fragment(), |     Fragment(), | ||||||
|     DIAware { |     DIAware { | ||||||
|  |     private var colorOnSurface: Int = 0 | ||||||
|  |     private var colorSurface: Int = 0 | ||||||
|     private var fontSize: Int = DEFAULT_FONT_SIZE |     private var fontSize: Int = DEFAULT_FONT_SIZE | ||||||
|     private lateinit var item: SelfossModel.Item |     private lateinit var item: SelfossModel.Item | ||||||
|     private lateinit var url: String |     private lateinit var url: String | ||||||
| @@ -81,7 +80,7 @@ class ArticleFragment : | |||||||
|     private lateinit var contentImage: String |     private lateinit var contentImage: String | ||||||
|     private lateinit var contentTitle: String |     private lateinit var contentTitle: String | ||||||
|     private lateinit var allImages: ArrayList<String> |     private lateinit var allImages: ArrayList<String> | ||||||
|     private lateinit var fab: FloatingActionButton |     private lateinit var fab: SpeedDialView | ||||||
|     private lateinit var textAlignment: String |     private lateinit var textAlignment: String | ||||||
|     private lateinit var binding: FragmentArticleBinding |     private lateinit var binding: FragmentArticleBinding | ||||||
|  |  | ||||||
| @@ -92,7 +91,6 @@ class ArticleFragment : | |||||||
|     private var typeface: Typeface? = null |     private var typeface: Typeface? = null | ||||||
|     private var resId: Int = 0 |     private var resId: Int = 0 | ||||||
|     private var font = "" |     private var font = "" | ||||||
|     private var staticBar = false |  | ||||||
|  |  | ||||||
|     private val mercuryApi: MercuryApi by instance() |     private val mercuryApi: MercuryApi by instance() | ||||||
|  |  | ||||||
| @@ -119,6 +117,9 @@ class ArticleFragment : | |||||||
|                 e.sendSilentlyWithAcra() |                 e.sendSilentlyWithAcra() | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             colorOnSurface = requireContext().getColorFromAttr(R.attr.colorOnSurface) | ||||||
|  |             colorSurface = requireContext().getColorFromAttr(R.attr.colorSurface) | ||||||
|  |  | ||||||
|             contentText = item.content |             contentText = item.content | ||||||
|             contentTitle = item.title.getHtmlDecoded() |             contentTitle = item.title.getHtmlDecoded() | ||||||
|             contentImage = item.getThumbnail(repository.baseUrl) |             contentImage = item.getThumbnail(repository.baseUrl) | ||||||
| @@ -132,23 +133,11 @@ class ArticleFragment : | |||||||
|             allImages = item.getImages() |             allImages = item.getImages() | ||||||
|  |  | ||||||
|             fontSize = appSettingsService.getFontSize() |             fontSize = appSettingsService.getFontSize() | ||||||
|             staticBar = appSettingsService.isStaticBarEnabled() |  | ||||||
|             font = appSettingsService.getFont() |             font = appSettingsService.getFont() | ||||||
|  |  | ||||||
|             refreshAlignment() |             refreshAlignment() | ||||||
|  |  | ||||||
|             fab = binding.fab |             handleFloatingToolbar() | ||||||
|  |  | ||||||
|             fab.backgroundTintList = ColorStateList.valueOf(resources.getColor(R.color.colorAccent)) |  | ||||||
|  |  | ||||||
|             fab.rippleColor = resources.getColor(R.color.colorAccentDark) |  | ||||||
|  |  | ||||||
|             val floatingToolbar: FloatingToolbar = handleFloatingToolbar() |  | ||||||
|  |  | ||||||
|             if (staticBar) { |  | ||||||
|                 fab.hide() |  | ||||||
|                 floatingToolbar.show() |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             binding.source.text = contentSource |             binding.source.text = contentSource | ||||||
|             if (typeface != null) { |             if (typeface != null) { | ||||||
| @@ -156,21 +145,6 @@ class ArticleFragment : | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             handleContent() |             handleContent() | ||||||
|  |  | ||||||
|             binding.nestedScrollView.setOnScrollChangeListener( |  | ||||||
|                 NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY -> |  | ||||||
|                     if (scrollY > oldScrollY) { |  | ||||||
|                         floatingToolbar.hide() |  | ||||||
|                         fab.hide() |  | ||||||
|                     } else { |  | ||||||
|                         if (staticBar) { |  | ||||||
|                             floatingToolbar.show() |  | ||||||
|                         } else { |  | ||||||
|                             if (floatingToolbar.isShowing) floatingToolbar.hide() else fab.show() |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 }, |  | ||||||
|             ) |  | ||||||
|         } catch (e: InflateException) { |         } catch (e: InflateException) { | ||||||
|             e.sendSilentlyWithAcraWithName("webview not available") |             e.sendSilentlyWithAcraWithName("webview not available") | ||||||
|             try { |             try { | ||||||
| @@ -208,31 +182,22 @@ class ArticleFragment : | |||||||
|  |  | ||||||
|             if (!contentImage.isEmptyOrNullOrNullString() && context != null) { |             if (!contentImage.isEmptyOrNullOrNullString() && context != null) { | ||||||
|                 binding.imageView.visibility = View.VISIBLE |                 binding.imageView.visibility = View.VISIBLE | ||||||
|                 Glide |                 requireContext().bitmapFitCenter(contentImage, binding.imageView, appSettingsService) | ||||||
|                     .with(requireContext()) |  | ||||||
|                     .asBitmap() |  | ||||||
|                     .load(contentImage) |  | ||||||
|                     .apply(RequestOptions.fitCenterTransform()) |  | ||||||
|                     .into(binding.imageView) |  | ||||||
|             } else { |             } else { | ||||||
|                 binding.imageView.visibility = View.GONE |                 binding.imageView.visibility = View.GONE | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun handleFloatingToolbar(): FloatingToolbar { |     private fun handleFloatingToolbar() { | ||||||
|         val floatingToolbar: FloatingToolbar = binding.floatingToolbar |         fab = binding.speedDial | ||||||
|         if (appSettingsService.getPublicAccess()) { |         fab.mainFabClosedIconColor = colorOnSurface | ||||||
|             floatingToolbar.setMenu(R.menu.reader_toolbar_no_read) |         fab.mainFabOpenedIconColor = colorOnSurface | ||||||
|         } |  | ||||||
|         floatingToolbar.attachFab(fab) |  | ||||||
|  |  | ||||||
|         floatingToolbar.background = ColorDrawable(resources.getColor(R.color.colorAccent)) |         handleFloatingToolbarActionItems() | ||||||
|  |  | ||||||
|         floatingToolbar.setClickListener( |         fab.setOnActionSelectedListener { actionItem -> | ||||||
|             object : FloatingToolbar.ItemClickListener { |             when (actionItem.id) { | ||||||
|                 override fun onItemClick(item: MenuItem) { |  | ||||||
|                     when (item.itemId) { |  | ||||||
|                 R.id.share_action -> requireActivity().shareLink(url, contentTitle) |                 R.id.share_action -> requireActivity().shareLink(url, contentTitle) | ||||||
|                 R.id.open_action -> requireActivity().openItemUrlInBrowserAsNewTask(this@ArticleFragment.item) |                 R.id.open_action -> requireActivity().openItemUrlInBrowserAsNewTask(this@ArticleFragment.item) | ||||||
|                 R.id.unread_action -> |                 R.id.unread_action -> | ||||||
| @@ -266,14 +231,35 @@ class ArticleFragment : | |||||||
|  |  | ||||||
|                 else -> Unit |                 else -> Unit | ||||||
|             } |             } | ||||||
|  |             false | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|                 override fun onItemLongClick(item: MenuItem?) { |     private fun handleFloatingToolbarActionItems() { | ||||||
|                     // We do nothing |         fab.addHomeMadeActionItem( | ||||||
|                 } |             R.id.share_action, | ||||||
|             }, |             resources.getDrawable(R.drawable.ic_share_white_24dp), | ||||||
|  |             R.string.reader_action_share, | ||||||
|  |             colorOnSurface, | ||||||
|  |             colorSurface, | ||||||
|  |             requireContext(), | ||||||
|  |         ) | ||||||
|  |         fab.addHomeMadeActionItem( | ||||||
|  |             R.id.open_action, | ||||||
|  |             resources.getDrawable(R.drawable.ic_open_in_browser_white_24dp), | ||||||
|  |             R.string.reader_action_open, | ||||||
|  |             colorOnSurface, | ||||||
|  |             colorSurface, | ||||||
|  |             requireContext(), | ||||||
|  |         ) | ||||||
|  |         fab.addHomeMadeActionItem( | ||||||
|  |             R.id.unread_action, | ||||||
|  |             resources.getDrawable(R.drawable.ic_baseline_white_eye_24dp), | ||||||
|  |             R.string.unmark, | ||||||
|  |             colorOnSurface, | ||||||
|  |             colorSurface, | ||||||
|  |             requireContext(), | ||||||
|         ) |         ) | ||||||
|         return floatingToolbar |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun refreshAlignment() { |     private fun refreshAlignment() { | ||||||
| @@ -327,13 +313,7 @@ class ArticleFragment : | |||||||
|     private fun handleLeadImage(leadImageUrl: String?) { |     private fun handleLeadImage(leadImageUrl: String?) { | ||||||
|         if (!leadImageUrl.isNullOrEmpty() && context != null) { |         if (!leadImageUrl.isNullOrEmpty() && context != null) { | ||||||
|             binding.imageView.visibility = View.VISIBLE |             binding.imageView.visibility = View.VISIBLE | ||||||
|             Glide |             requireContext().bitmapFitCenter(leadImageUrl, binding.imageView, appSettingsService) | ||||||
|                 .with(requireContext()) |  | ||||||
|                 .asBitmap() |  | ||||||
|                 .load( |  | ||||||
|                     leadImageUrl, |  | ||||||
|                 ).apply(RequestOptions.fitCenterTransform()) |  | ||||||
|                 .into(binding.imageView) |  | ||||||
|         } else { |         } else { | ||||||
|             binding.imageView.visibility = View.GONE |             binding.imageView.visibility = View.GONE | ||||||
|         } |         } | ||||||
| @@ -357,78 +337,37 @@ class ArticleFragment : | |||||||
|                         false |                         false | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                 @Suppress("detekt:LongMethod", "detekt:SwallowedException") |                 @Suppress("detekt:SwallowedException", "detekt:ReturnCount") | ||||||
|                 @Deprecated("Deprecated in Java") |                 @Deprecated("Deprecated in Java") | ||||||
|                 override fun shouldInterceptRequest( |                 override fun shouldInterceptRequest( | ||||||
|                     view: WebView, |                     view: WebView, | ||||||
|                     url: String, |                     url: String, | ||||||
|                 ): WebResourceResponse? { |                 ): WebResourceResponse? { | ||||||
|                     val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL) |                     val (mime: String?, compression: Bitmap.CompressFormat) = | ||||||
|                     var glideResource: WebResourceResponse? = null |                         if (url | ||||||
|                     if (url.lowercase(Locale.US).contains(".jpg") || |  | ||||||
|                         url |  | ||||||
|                                 .lowercase(Locale.US) |                                 .lowercase(Locale.US) | ||||||
|                             .contains(".jpeg") |                                 .contains(".jpg") || | ||||||
|  |                             url.lowercase(Locale.US).contains(".jpeg") | ||||||
|                         ) { |                         ) { | ||||||
|                         try { |                             Pair(IMAGE_JPG, Bitmap.CompressFormat.JPEG) | ||||||
|                             val image = |  | ||||||
|                                 Glide |  | ||||||
|                                     .with(view) |  | ||||||
|                                     .asBitmap() |  | ||||||
|                                     .apply(glideOptions) |  | ||||||
|                                     .load(url) |  | ||||||
|                                     .submit() |  | ||||||
|                                     .get() |  | ||||||
|                             glideResource = |  | ||||||
|                                 WebResourceResponse( |  | ||||||
|                                     IMAGE_JPG, |  | ||||||
|                                     "UTF-8", |  | ||||||
|                                     getBitmapInputStream(image, Bitmap.CompressFormat.JPEG), |  | ||||||
|                                 ) |  | ||||||
|                         } catch (e: ExecutionException) { |  | ||||||
|                             // Do nothing |  | ||||||
|                         } |  | ||||||
|                         } else if (url.lowercase(Locale.US).contains(".png")) { |                         } else if (url.lowercase(Locale.US).contains(".png")) { | ||||||
|                         try { |                             Pair(IMAGE_PNG, Bitmap.CompressFormat.PNG) | ||||||
|                             val image = |  | ||||||
|                                 Glide |  | ||||||
|                                     .with(view) |  | ||||||
|                                     .asBitmap() |  | ||||||
|                                     .apply(glideOptions) |  | ||||||
|                                     .load(url) |  | ||||||
|                                     .submit() |  | ||||||
|                                     .get() |  | ||||||
|                             glideResource = |  | ||||||
|                                 WebResourceResponse( |  | ||||||
|                                     IMAGE_JPG, |  | ||||||
|                                     "UTF-8", |  | ||||||
|                                     getBitmapInputStream(image, Bitmap.CompressFormat.PNG), |  | ||||||
|                                 ) |  | ||||||
|                         } catch (e: ExecutionException) { |  | ||||||
|                             // Do nothing |  | ||||||
|                         } |  | ||||||
|                         } else if (url.lowercase(Locale.US).contains(".webp")) { |                         } else if (url.lowercase(Locale.US).contains(".webp")) { | ||||||
|                         try { |                             Pair(IMAGE_WEBP, Bitmap.CompressFormat.WEBP) | ||||||
|                             val image = |                         } else { | ||||||
|                                 Glide |                             return super.shouldInterceptRequest(view, url) | ||||||
|                                     .with(view) |  | ||||||
|                                     .asBitmap() |  | ||||||
|                                     .apply(glideOptions) |  | ||||||
|                                     .load(url) |  | ||||||
|                                     .submit() |  | ||||||
|                                     .get() |  | ||||||
|                             glideResource = |  | ||||||
|                                 WebResourceResponse( |  | ||||||
|                                     IMAGE_JPG, |  | ||||||
|                                     "UTF-8", |  | ||||||
|                                     getBitmapInputStream(image, Bitmap.CompressFormat.WEBP), |  | ||||||
|                                 ) |  | ||||||
|                         } catch (e: ExecutionException) { |  | ||||||
|                             // Do nothing |  | ||||||
|                         } |  | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                     return glideResource ?: super.shouldInterceptRequest(view, url) |                     try { | ||||||
|  |                         val image = view.getGlideImageForResource(url, appSettingsService) | ||||||
|  |                         return WebResourceResponse( | ||||||
|  |                             mime, | ||||||
|  |                             "UTF-8", | ||||||
|  |                             getBitmapInputStream(image, compression), | ||||||
|  |                         ) | ||||||
|  |                     } catch (e: ExecutionException) { | ||||||
|  |                         return super.shouldInterceptRequest(view, url) | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|     } |     } | ||||||
| @@ -443,19 +382,12 @@ class ArticleFragment : | |||||||
|             return |             return | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         val colorOnSurface = TypedValue() |  | ||||||
|         val colorSurface = TypedValue() |  | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             val attrs: IntArray = intArrayOf(android.R.attr.fontFamily) |             val attrs: IntArray = intArrayOf(android.R.attr.fontFamily) | ||||||
|             val a: TypedArray = context.obtainStyledAttributes(resId, attrs) |             val a: TypedArray = context.obtainStyledAttributes(resId, attrs) | ||||||
|  |  | ||||||
|             binding.webcontent.settings.standardFontFamily = a.getString(0) |             binding.webcontent.settings.standardFontFamily = a.getString(0) | ||||||
|             binding.webcontent.visibility = View.VISIBLE |             binding.webcontent.visibility = View.VISIBLE | ||||||
|  |  | ||||||
|             context.theme.resolveAttribute(R.attr.colorOnSurface, colorOnSurface, true) |  | ||||||
|  |  | ||||||
|             context.theme.resolveAttribute(R.attr.colorSurface, colorSurface, true) |  | ||||||
|         } catch (e: IllegalStateException) { |         } catch (e: IllegalStateException) { | ||||||
|             e.sendSilentlyWithAcraWithName("Context issue when setting attributes, but context wasn't null before") |             e.sendSilentlyWithAcraWithName("Context issue when setting attributes, but context wasn't null before") | ||||||
|         } |         } | ||||||
| @@ -463,13 +395,13 @@ class ArticleFragment : | |||||||
|         val colorSurfaceString = |         val colorSurfaceString = | ||||||
|             String.format( |             String.format( | ||||||
|                 "#%06X", |                 "#%06X", | ||||||
|                 WHITE_COLOR_HEX and (if (colorSurface.data != DATA_NULL_UNDEFINED) colorSurface.data else WHITE_COLOR_HEX), |                 WHITE_COLOR_HEX and (if (colorSurface != DATA_NULL_UNDEFINED) colorSurface else WHITE_COLOR_HEX), | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|         val colorOnSurfaceString = |         val colorOnSurfaceString = | ||||||
|             String.format( |             String.format( | ||||||
|                 "#%06X", |                 "#%06X", | ||||||
|                 WHITE_COLOR_HEX and (if (colorOnSurface.data != DATA_NULL_UNDEFINED) colorOnSurface.data else 0), |                 WHITE_COLOR_HEX and (if (colorOnSurface != DATA_NULL_UNDEFINED) colorOnSurface else 0), | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|   | |||||||
| @@ -16,11 +16,12 @@ import bou.amine.apps.readerforselfossv2.android.HomeActivity | |||||||
| import bou.amine.apps.readerforselfossv2.android.R | import bou.amine.apps.readerforselfossv2.android.R | ||||||
| import bou.amine.apps.readerforselfossv2.android.databinding.FilterFragmentBinding | import bou.amine.apps.readerforselfossv2.android.databinding.FilterFragmentBinding | ||||||
| import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName | import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName | ||||||
|  | import bou.amine.apps.readerforselfossv2.android.utils.glide.imageIntoViewTarget | ||||||
| import bou.amine.apps.readerforselfossv2.repository.Repository | import bou.amine.apps.readerforselfossv2.repository.Repository | ||||||
|  | import bou.amine.apps.readerforselfossv2.service.AppSettingsService | ||||||
| import bou.amine.apps.readerforselfossv2.utils.getColorHexCode | import bou.amine.apps.readerforselfossv2.utils.getColorHexCode | ||||||
| import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded | import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded | ||||||
| import bou.amine.apps.readerforselfossv2.utils.getIcon | import bou.amine.apps.readerforselfossv2.utils.getIcon | ||||||
| import com.bumptech.glide.Glide |  | ||||||
| import com.bumptech.glide.request.target.ViewTarget | import com.bumptech.glide.request.target.ViewTarget | ||||||
| import com.bumptech.glide.request.transition.Transition | import com.bumptech.glide.request.transition.Transition | ||||||
| import com.google.android.material.bottomsheet.BottomSheetDialogFragment | import com.google.android.material.bottomsheet.BottomSheetDialogFragment | ||||||
| @@ -41,6 +42,7 @@ class FilterSheetFragment : | |||||||
|     private lateinit var binding: FilterFragmentBinding |     private lateinit var binding: FilterFragmentBinding | ||||||
|     override val di: DI by closestDI() |     override val di: DI by closestDI() | ||||||
|     private val repository: Repository by instance() |     private val repository: Repository by instance() | ||||||
|  |     private val appSettingsService: AppSettingsService by instance() | ||||||
|  |  | ||||||
|     private var selectedChip: Chip? = null |     private var selectedChip: Chip? = null | ||||||
|  |  | ||||||
| @@ -84,10 +86,8 @@ class FilterSheetFragment : | |||||||
|             val c = Chip(context) |             val c = Chip(context) | ||||||
|             c.ellipsize = TextUtils.TruncateAt.END |             c.ellipsize = TextUtils.TruncateAt.END | ||||||
|  |  | ||||||
|             Glide |             context.imageIntoViewTarget( | ||||||
|                 .with(context) |                 source.getIcon(repository.baseUrl), | ||||||
|                 .load(source.getIcon(repository.baseUrl)) |  | ||||||
|                 .into( |  | ||||||
|                 object : ViewTarget<Chip?, Drawable?>(c) { |                 object : ViewTarget<Chip?, Drawable?>(c) { | ||||||
|                     override fun onResourceReady( |                     override fun onResourceReady( | ||||||
|                         resource: Drawable, |                         resource: Drawable, | ||||||
| @@ -100,6 +100,7 @@ class FilterSheetFragment : | |||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 }, |                 }, | ||||||
|  |                 appSettingsService, | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|             c.text = source.title.getHtmlDecoded() |             c.text = source.title.getHtmlDecoded() | ||||||
|   | |||||||
| @@ -6,13 +6,19 @@ import android.view.View | |||||||
| import android.view.ViewGroup | import android.view.ViewGroup | ||||||
| import androidx.fragment.app.Fragment | import androidx.fragment.app.Fragment | ||||||
| import bou.amine.apps.readerforselfossv2.android.databinding.FragmentImageBinding | import bou.amine.apps.readerforselfossv2.android.databinding.FragmentImageBinding | ||||||
| import com.bumptech.glide.Glide | import bou.amine.apps.readerforselfossv2.android.utils.glide.bitmapWithCache | ||||||
| import com.bumptech.glide.load.engine.DiskCacheStrategy | import bou.amine.apps.readerforselfossv2.service.AppSettingsService | ||||||
| import com.bumptech.glide.request.RequestOptions | import org.kodein.di.DI | ||||||
|  | import org.kodein.di.DIAware | ||||||
|  | import org.kodein.di.android.x.closestDI | ||||||
|  | import org.kodein.di.instance | ||||||
|  |  | ||||||
| class ImageFragment : Fragment() { | class ImageFragment : | ||||||
|  |     Fragment(), | ||||||
|  |     DIAware { | ||||||
|  |     override val di: DI by closestDI() | ||||||
|  |     private val appSettingsService: AppSettingsService by instance() | ||||||
|     private lateinit var imageUrl: String |     private lateinit var imageUrl: String | ||||||
|     private val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL) |  | ||||||
|     private var _binding: FragmentImageBinding? = null |     private var _binding: FragmentImageBinding? = null | ||||||
|     val binding get() = _binding |     val binding get() = _binding | ||||||
|  |  | ||||||
| @@ -31,12 +37,7 @@ class ImageFragment : Fragment() { | |||||||
|         val view = binding?.root |         val view = binding?.root | ||||||
|  |  | ||||||
|         binding!!.photoView.visibility = View.VISIBLE |         binding!!.photoView.visibility = View.VISIBLE | ||||||
|         Glide |         requireActivity().bitmapWithCache(imageUrl, binding!!.photoView, appSettingsService) | ||||||
|             .with(requireActivity()) |  | ||||||
|             .asBitmap() |  | ||||||
|             .apply(glideOptions) |  | ||||||
|             .load(imageUrl) |  | ||||||
|             .into(binding!!.photoView) |  | ||||||
|  |  | ||||||
|         return view |         return view | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -3,28 +3,21 @@ package bou.amine.apps.readerforselfossv2.android.model | |||||||
| import android.content.Context | import android.content.Context | ||||||
| import android.webkit.URLUtil | import android.webkit.URLUtil | ||||||
| import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName | import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName | ||||||
|  | import bou.amine.apps.readerforselfossv2.android.utils.glide.preloadImage | ||||||
| import bou.amine.apps.readerforselfossv2.model.SelfossModel | import bou.amine.apps.readerforselfossv2.model.SelfossModel | ||||||
|  | import bou.amine.apps.readerforselfossv2.service.AppSettingsService | ||||||
| import bou.amine.apps.readerforselfossv2.utils.getImages | import bou.amine.apps.readerforselfossv2.utils.getImages | ||||||
| import com.bumptech.glide.Glide |  | ||||||
| import com.bumptech.glide.load.engine.DiskCacheStrategy |  | ||||||
| import com.bumptech.glide.request.RequestOptions |  | ||||||
|  |  | ||||||
| private const val PRELOAD_IMAGE_TIMEOUT = 10000 | fun SelfossModel.Item.preloadImages( | ||||||
|  |     context: Context, | ||||||
| fun SelfossModel.Item.preloadImages(context: Context): Boolean { |     appSettingsService: AppSettingsService, | ||||||
|  | ): Boolean { | ||||||
|     val imageUrls = this.getImages() |     val imageUrls = this.getImages() | ||||||
|  |  | ||||||
|     val glideOptions = RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL).timeout(PRELOAD_IMAGE_TIMEOUT) |  | ||||||
|  |  | ||||||
|     try { |     try { | ||||||
|         for (url in imageUrls) { |         for (url in imageUrls) { | ||||||
|             if (URLUtil.isValidUrl(url)) { |             if (URLUtil.isValidUrl(url)) { | ||||||
|                 Glide |                 context.preloadImage(url, appSettingsService) | ||||||
|                     .with(context) |  | ||||||
|                     .asBitmap() |  | ||||||
|                     .apply(glideOptions) |  | ||||||
|                     .load(url) |  | ||||||
|                     .submit() |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } catch (e: Error) { |     } catch (e: Error) { | ||||||
|   | |||||||
| @@ -2,7 +2,11 @@ package bou.amine.apps.readerforselfossv2.android.utils | |||||||
|  |  | ||||||
| import android.content.Context | import android.content.Context | ||||||
| import android.content.Intent | import android.content.Intent | ||||||
|  | import android.util.TypedValue | ||||||
|  | import androidx.annotation.AttrRes | ||||||
|  | import androidx.annotation.ColorInt | ||||||
| import bou.amine.apps.readerforselfossv2.android.R | import bou.amine.apps.readerforselfossv2.android.R | ||||||
|  | import bou.amine.apps.readerforselfossv2.android.utils.acra.sendSilentlyWithAcraWithName | ||||||
| import bou.amine.apps.readerforselfossv2.utils.toStringUriWithHttp | import bou.amine.apps.readerforselfossv2.utils.toStringUriWithHttp | ||||||
|  |  | ||||||
| fun Context.shareLink( | fun Context.shareLink( | ||||||
| @@ -23,3 +27,17 @@ fun Context.shareLink( | |||||||
|             ).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), |             ).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK), | ||||||
|     ) |     ) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ColorInt | ||||||
|  | fun Context.getColorFromAttr( | ||||||
|  |     @AttrRes attrColor: Int, | ||||||
|  |     resolveRefs: Boolean = true, | ||||||
|  | ): Int { | ||||||
|  |     val typedValue = TypedValue() | ||||||
|  |     try { | ||||||
|  |         this.theme.resolveAttribute(attrColor, typedValue, resolveRefs) | ||||||
|  |     } catch (e: Throwable) { | ||||||
|  |         e.sendSilentlyWithAcraWithName("ColorFromAttr") | ||||||
|  |     } | ||||||
|  |     return typedValue.data | ||||||
|  | } | ||||||
|   | |||||||
| @@ -1,6 +1,13 @@ | |||||||
| package bou.amine.apps.readerforselfossv2.android.utils.bottombar | package bou.amine.apps.readerforselfossv2.android.utils.bottombar | ||||||
|  |  | ||||||
|  | import android.content.Context | ||||||
|  | import android.graphics.drawable.Drawable | ||||||
|  | import androidx.annotation.IdRes | ||||||
|  | import androidx.annotation.StringRes | ||||||
|  | import bou.amine.apps.readerforselfossv2.android.R | ||||||
| import com.ashokvarma.bottomnavigation.TextBadgeItem | import com.ashokvarma.bottomnavigation.TextBadgeItem | ||||||
|  | import com.leinardi.android.speeddial.SpeedDialActionItem | ||||||
|  | import com.leinardi.android.speeddial.SpeedDialView | ||||||
|  |  | ||||||
| fun TextBadgeItem.removeBadge(): TextBadgeItem { | fun TextBadgeItem.removeBadge(): TextBadgeItem { | ||||||
|     this.setText("") |     this.setText("") | ||||||
| @@ -9,3 +16,25 @@ fun TextBadgeItem.removeBadge(): TextBadgeItem { | |||||||
| } | } | ||||||
|  |  | ||||||
| fun TextBadgeItem.maybeShow(): TextBadgeItem = if (this.isHidden) this.show() else this | fun TextBadgeItem.maybeShow(): TextBadgeItem = if (this.isHidden) this.show() else this | ||||||
|  |  | ||||||
|  | @Suppress("detekt:LongParameterList") | ||||||
|  | fun SpeedDialView.addHomeMadeActionItem( | ||||||
|  |     @IdRes actionId: Int, | ||||||
|  |     actionIcon: Drawable, | ||||||
|  |     @StringRes labelId: Int, | ||||||
|  |     colorOnSurface: Int, | ||||||
|  |     colorSurface: Int, | ||||||
|  |     context: Context, | ||||||
|  | ) { | ||||||
|  |     this.addActionItem( | ||||||
|  |         SpeedDialActionItem | ||||||
|  |             .Builder(actionId, actionIcon) | ||||||
|  |             .setFabBackgroundColor(context.resources.getColor(R.color.colorAccent)) | ||||||
|  |             .setFabImageTintColor(colorOnSurface) | ||||||
|  |             .setLabel(context.getString(labelId)) | ||||||
|  |             .setLabelClickable(false) | ||||||
|  |             .setLabelBackgroundColor(colorOnSurface) | ||||||
|  |             .setLabelColor(colorSurface) | ||||||
|  |             .create(), | ||||||
|  |     ) | ||||||
|  | } | ||||||
|   | |||||||
| @@ -2,33 +2,123 @@ package bou.amine.apps.readerforselfossv2.android.utils.glide | |||||||
|  |  | ||||||
| import android.content.Context | import android.content.Context | ||||||
| import android.graphics.Bitmap | import android.graphics.Bitmap | ||||||
|  | import android.graphics.drawable.Drawable | ||||||
|  | import android.webkit.WebView | ||||||
| import android.widget.ImageView | import android.widget.ImageView | ||||||
| import bou.amine.apps.readerforselfossv2.android.utils.CircleImageView | import bou.amine.apps.readerforselfossv2.android.utils.CircleImageView | ||||||
|  | import bou.amine.apps.readerforselfossv2.service.AppSettingsService | ||||||
|  | import bou.amine.apps.readerforselfossv2.utils.isEmptyOrNullOrNullString | ||||||
| import com.bumptech.glide.Glide | import com.bumptech.glide.Glide | ||||||
|  | import com.bumptech.glide.load.engine.DiskCacheStrategy | ||||||
|  | import com.bumptech.glide.load.model.GlideUrl | ||||||
|  | import com.bumptech.glide.load.model.LazyHeaders | ||||||
| import com.bumptech.glide.request.RequestOptions | import com.bumptech.glide.request.RequestOptions | ||||||
|  | import com.bumptech.glide.request.target.ViewTarget | ||||||
|  | import com.google.android.material.chip.Chip | ||||||
| import java.io.ByteArrayInputStream | import java.io.ByteArrayInputStream | ||||||
| import java.io.ByteArrayOutputStream | import java.io.ByteArrayOutputStream | ||||||
| import java.io.InputStream | import java.io.InputStream | ||||||
|  | import kotlin.io.encoding.Base64 | ||||||
|  | import kotlin.io.encoding.ExperimentalEncodingApi | ||||||
|  |  | ||||||
|  | private const val PRELOAD_IMAGE_TIMEOUT = 10000 | ||||||
|  |  | ||||||
|  | @OptIn(ExperimentalEncodingApi::class) | ||||||
|  | fun String.toGlideUrl(appSettingsService: AppSettingsService): GlideUrl { | ||||||
|  |     if (this.isEmptyOrNullOrNullString()) { | ||||||
|  |         return GlideUrl("") | ||||||
|  |     } | ||||||
|  |     if (appSettingsService.getBasicUserName().isNotEmpty()) { | ||||||
|  |         val authString = "${appSettingsService.getBasicUserName()}:${appSettingsService.getBasicPassword()}" | ||||||
|  |         val authBuf = Base64.encode(authString.toByteArray(Charsets.UTF_8)) | ||||||
|  |  | ||||||
|  |         return GlideUrl( | ||||||
|  |             this, | ||||||
|  |             LazyHeaders | ||||||
|  |                 .Builder() | ||||||
|  |                 .addHeader("Authorization", "Basic $authBuf") | ||||||
|  |                 .build(), | ||||||
|  |         ) | ||||||
|  |     } else { | ||||||
|  |         return GlideUrl( | ||||||
|  |             this, | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | fun WebView.getGlideImageForResource( | ||||||
|  |     url: String, | ||||||
|  |     appSettingsService: AppSettingsService, | ||||||
|  | ) = Glide | ||||||
|  |     .with(this) | ||||||
|  |     .asBitmap() | ||||||
|  |     .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)) | ||||||
|  |     .load(url.toGlideUrl(appSettingsService)) | ||||||
|  |     .submit() | ||||||
|  |     .get() | ||||||
|  |  | ||||||
|  | fun Context.preloadImage( | ||||||
|  |     url: String, | ||||||
|  |     appSettingsService: AppSettingsService, | ||||||
|  | ) = Glide | ||||||
|  |     .with(this) | ||||||
|  |     .asBitmap() | ||||||
|  |     .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL).timeout(PRELOAD_IMAGE_TIMEOUT)) | ||||||
|  |     .load(url.toGlideUrl(appSettingsService)) | ||||||
|  |     .submit() | ||||||
|  |  | ||||||
|  | fun Context.imageIntoViewTarget( | ||||||
|  |     url: String, | ||||||
|  |     target: ViewTarget<Chip?, Drawable?>, | ||||||
|  |     appSettingsService: AppSettingsService, | ||||||
|  | ) = Glide | ||||||
|  |     .with(this) | ||||||
|  |     .load(url.toGlideUrl(appSettingsService)) | ||||||
|  |     .into(target) | ||||||
|  |  | ||||||
|  | fun Context.bitmapWithCache( | ||||||
|  |     url: String, | ||||||
|  |     iv: ImageView, | ||||||
|  |     appSettingsService: AppSettingsService, | ||||||
|  | ) = Glide | ||||||
|  |     .with(this) | ||||||
|  |     .asBitmap() | ||||||
|  |     .apply(RequestOptions.diskCacheStrategyOf(DiskCacheStrategy.ALL)) | ||||||
|  |     .load(url.toGlideUrl(appSettingsService)) | ||||||
|  |     .into(iv) | ||||||
|  |  | ||||||
| fun Context.bitmapCenterCrop( | fun Context.bitmapCenterCrop( | ||||||
|     url: String, |     url: String, | ||||||
|     iv: ImageView, |     iv: ImageView, | ||||||
|  |     appSettingsService: AppSettingsService, | ||||||
| ) = Glide | ) = Glide | ||||||
|     .with(this) |     .with(this) | ||||||
|     .asBitmap() |     .asBitmap() | ||||||
|     .load(url) |     .load(url.toGlideUrl(appSettingsService)) | ||||||
|     .apply(RequestOptions.centerCropTransform()) |     .apply(RequestOptions.centerCropTransform()) | ||||||
|     .into(iv) |     .into(iv) | ||||||
|  |  | ||||||
|  | fun Context.bitmapFitCenter( | ||||||
|  |     url: String, | ||||||
|  |     iv: ImageView, | ||||||
|  |     appSettingsService: AppSettingsService, | ||||||
|  | ) = Glide | ||||||
|  |     .with(this) | ||||||
|  |     .asBitmap() | ||||||
|  |     .load(url.toGlideUrl(appSettingsService)) | ||||||
|  |     .apply(RequestOptions.fitCenterTransform()) | ||||||
|  |     .into(iv) | ||||||
|  |  | ||||||
| fun Context.circularDrawable( | fun Context.circularDrawable( | ||||||
|     url: String, |     url: String, | ||||||
|     view: CircleImageView, |     view: CircleImageView, | ||||||
|  |     appSettingsService: AppSettingsService, | ||||||
| ) { | ) { | ||||||
|     view.textView.text = "" |     view.textView.text = "" | ||||||
|  |  | ||||||
|     Glide |     Glide | ||||||
|         .with(this) |         .with(this) | ||||||
|         .load(url) |         .load(url.toGlideUrl(appSettingsService)) | ||||||
|         .into(view.imageView) |         .into(view.imageView) | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -71,35 +71,13 @@ | |||||||
|  |  | ||||||
|     </androidx.core.widget.NestedScrollView> |     </androidx.core.widget.NestedScrollView> | ||||||
|  |  | ||||||
|     <FrameLayout |     <com.leinardi.android.speeddial.SpeedDialView | ||||||
|         android:layout_width="match_parent" |         android:id="@+id/speedDial" | ||||||
|         android:layout_height="wrap_content" |  | ||||||
|         android:layout_gravity="start|bottom|end" |  | ||||||
|         app:layout_constraintBottom_toBottomOf="parent" |  | ||||||
|         app:layout_constraintEnd_toEndOf="parent" |  | ||||||
|         app:layout_constraintStart_toStartOf="parent"> |  | ||||||
|  |  | ||||||
|         <com.github.rubensousa.floatingtoolbar.FloatingToolbar |  | ||||||
|             android:id="@+id/floatingToolbar" |  | ||||||
|             android:layout_width="match_parent" |  | ||||||
|             android:layout_height="?attr/actionBarSize" |  | ||||||
|             android:layout_gravity="bottom" |  | ||||||
|             app:floatingMenu="@menu/reader_toolbar" /> |  | ||||||
|  |  | ||||||
|         <com.google.android.material.floatingactionbutton.FloatingActionButton |  | ||||||
|             android:id="@+id/fab" |  | ||||||
|         android:layout_width="wrap_content" |         android:layout_width="wrap_content" | ||||||
|         android:layout_height="wrap_content" |         android:layout_height="wrap_content" | ||||||
|             android:layout_gravity="end|bottom" |         android:layout_gravity="bottom|end" | ||||||
|             android:layout_marginEnd="16dp" |         app:layout_behavior="@string/speeddial_scrolling_view_snackbar_behavior" | ||||||
|             android:layout_marginBottom="16dp" |         app:sdMainFabClosedSrc="@drawable/ic_add_white_24dp" /> | ||||||
|             android:paddingTop="@dimen/activity_vertical_margin" |  | ||||||
|             android:paddingBottom="@dimen/activity_vertical_margin" |  | ||||||
|             android:src="@drawable/ic_add_white_24dp" |  | ||||||
|             app:backgroundTint="?attr/colorAccent" |  | ||||||
|             app:fabSize="mini" |  | ||||||
|             app:rippleColor="?attr/colorAccentDark" /> |  | ||||||
|     </FrameLayout> |  | ||||||
|  |  | ||||||
|     <FrameLayout |     <FrameLayout | ||||||
|         android:id="@+id/progressBar" |         android:id="@+id/progressBar" | ||||||
| @@ -119,4 +97,5 @@ | |||||||
|             android:progressTint="?attr/colorAccent" /> |             android:progressTint="?attr/colorAccent" /> | ||||||
|     </FrameLayout> |     </FrameLayout> | ||||||
|  |  | ||||||
|  |  | ||||||
| </androidx.coordinatorlayout.widget.CoordinatorLayout> | </androidx.coordinatorlayout.widget.CoordinatorLayout> | ||||||
| @@ -1,23 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <menu xmlns:android="http://schemas.android.com/apk/res/android" |  | ||||||
|     xmlns:app="http://schemas.android.com/apk/res-auto"> |  | ||||||
|  |  | ||||||
|     <item |  | ||||||
|         android:id="@+id/unread_action" |  | ||||||
|         android:icon="@drawable/ic_baseline_white_eye_24dp" |  | ||||||
|         android:title="@string/unmark" |  | ||||||
|         app:showAsAction="ifRoom" /> |  | ||||||
|  |  | ||||||
|     <item |  | ||||||
|         android:id="@+id/open_action" |  | ||||||
|         android:icon="@drawable/ic_open_in_browser_white_24dp" |  | ||||||
|         android:title="@string/reader_action_open" |  | ||||||
|         app:showAsAction="ifRoom" /> |  | ||||||
|  |  | ||||||
|     <item |  | ||||||
|         android:id="@+id/share_action" |  | ||||||
|         android:icon="@drawable/ic_share_white_24dp" |  | ||||||
|         android:title="@string/reader_action_share" |  | ||||||
|         app:showAsAction="ifRoom" /> |  | ||||||
|  |  | ||||||
| </menu> |  | ||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Linksbündig</string> |     <string name="reader_text_align_left">Linksbündig</string> | ||||||
|     <string name="reader_text_align_justify">Blocksatz</string> |     <string name="reader_text_align_justify">Blocksatz</string> | ||||||
|     <string name="settings_reader_font">Schriftgröße im Lesemodus</string> |     <string name="settings_reader_font">Schriftgröße im Lesemodus</string> | ||||||
|     <string name="reader_static_bar_title">Statische untere Leiste im Lesemodus</string> |  | ||||||
|     <string name="reader_static_bar_on">Die untere Leiste wird dauerhaft angezeigt</string> |  | ||||||
|     <string name="reader_static_bar_off">Die untere Leiste kann über einen schwebenden Button angezeigt werden</string> |  | ||||||
|     <string name="remove_source">Quelle entfernen</string> |     <string name="remove_source">Quelle entfernen</string> | ||||||
|     <string name="pref_theme_title">Heller/Dunkler Modus</string> |     <string name="pref_theme_title">Heller/Dunkler Modus</string> | ||||||
|     <string name="mode_dark">Dunkler Modus</string> |     <string name="mode_dark">Dunkler Modus</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Alinear a la izquierda</string> |     <string name="reader_text_align_left">Alinear a la izquierda</string> | ||||||
|     <string name="reader_text_align_justify">Justificado</string> |     <string name="reader_text_align_justify">Justificado</string> | ||||||
|     <string name="settings_reader_font">Modo lectura</string> |     <string name="settings_reader_font">Modo lectura</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Aligner à gauche</string> |     <string name="reader_text_align_left">Aligner à gauche</string> | ||||||
|     <string name="reader_text_align_justify">Justifier le texte</string> |     <string name="reader_text_align_justify">Justifier le texte</string> | ||||||
|     <string name="settings_reader_font">Police du lecteur d\'articles</string> |     <string name="settings_reader_font">Police du lecteur d\'articles</string> | ||||||
|     <string name="reader_static_bar_title">Barre statique pour le visionneur d\'articles</string> |  | ||||||
|     <string name="reader_static_bar_on">La barre sera affichée</string> |  | ||||||
|     <string name="reader_static_bar_off">La barre sera affichée grâce au bouton</string> |  | ||||||
|     <string name="remove_source">Supprimer la source</string> |     <string name="remove_source">Supprimer la source</string> | ||||||
|     <string name="pref_theme_title">Thème Clair/Sombre</string> |     <string name="pref_theme_title">Thème Clair/Sombre</string> | ||||||
|     <string name="mode_dark">Thème sombre</string> |     <string name="mode_dark">Thème sombre</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Aliñar á esquerda</string> |     <string name="reader_text_align_left">Aliñar á esquerda</string> | ||||||
|     <string name="reader_text_align_justify">Xustificado</string> |     <string name="reader_text_align_justify">Xustificado</string> | ||||||
|     <string name="settings_reader_font">Modo lector</string> |     <string name="settings_reader_font">Modo lector</string> | ||||||
|     <string name="reader_static_bar_title">Barra inferior estática na vista de artigos</string> |  | ||||||
|     <string name="reader_static_bar_on">A barra inferior mostrarase sempre</string> |  | ||||||
|     <string name="reader_static_bar_off">A barra inferior pode mostrarse a través do botón flotante</string> |  | ||||||
|     <string name="remove_source">Eliminar fonte</string> |     <string name="remove_source">Eliminar fonte</string> | ||||||
|     <string name="pref_theme_title">Modo Claro/Escuro</string> |     <string name="pref_theme_title">Modo Claro/Escuro</string> | ||||||
|     <string name="mode_dark">Modo escuro</string> |     <string name="mode_dark">Modo escuro</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -23,6 +23,7 @@ | |||||||
|     <string name="wrong_infos">"Controleer de gegevens nogmaals."</string> |     <string name="wrong_infos">"Controleer de gegevens nogmaals."</string> | ||||||
|     <string name="all_posts_not_read">"Fout bij markeren als gelezen"</string> |     <string name="all_posts_not_read">"Fout bij markeren als gelezen"</string> | ||||||
|     <string name="all_posts_read">"Alle artikelen gemarkeerd als gelezen"</string> |     <string name="all_posts_read">"Alle artikelen gemarkeerd als gelezen"</string> | ||||||
|  |     <string name="undo_string">"Ongedaan maken"</string> | ||||||
|     <string name="addStringNoUrl">"Login om bronnen toe te voegen"</string> |     <string name="addStringNoUrl">"Login om bronnen toe te voegen"</string> | ||||||
|     <string name="cant_get_sources">"Kan de lijst met bronnen niet ophalen"</string> |     <string name="cant_get_sources">"Kan de lijst met bronnen niet ophalen"</string> | ||||||
|     <string name="cant_create_source">"Kan bron niet creëeren"</string> |     <string name="cant_create_source">"Kan bron niet creëeren"</string> | ||||||
| @@ -105,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
| @@ -131,5 +129,4 @@ | |||||||
|     <string name="action_about">"Over"</string> |     <string name="action_about">"Over"</string> | ||||||
|     <string name="marked_as_read">"Artikel gelezen"</string> |     <string name="marked_as_read">"Artikel gelezen"</string> | ||||||
|     <string name="marked_as_unread">"Item unread"</string> |     <string name="marked_as_unread">"Item unread"</string> | ||||||
|     <string name="undo_string">"Ongedaan maken"</string> |  | ||||||
| </resources> | </resources> | ||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">左对齐</string> |     <string name="reader_text_align_left">左对齐</string> | ||||||
|     <string name="reader_text_align_justify">左右对齐</string> |     <string name="reader_text_align_justify">左右对齐</string> | ||||||
|     <string name="settings_reader_font">阅读器字体</string> |     <string name="settings_reader_font">阅读器字体</string> | ||||||
|     <string name="reader_static_bar_title">文章查看器中的静态底部栏</string> |  | ||||||
|     <string name="reader_static_bar_on">底部栏将始终显示</string> |  | ||||||
|     <string name="reader_static_bar_off">底部栏可以通过浮动按钮显示</string> |  | ||||||
|     <string name="remove_source">删除源</string> |     <string name="remove_source">删除源</string> | ||||||
|     <string name="pref_theme_title">浅色/深色模式</string> |     <string name="pref_theme_title">浅色/深色模式</string> | ||||||
|     <string name="mode_dark">深色模式</string> |     <string name="mode_dark">深色模式</string> | ||||||
|   | |||||||
| @@ -106,9 +106,6 @@ | |||||||
|     <string name="reader_text_align_left">Align left</string> |     <string name="reader_text_align_left">Align left</string> | ||||||
|     <string name="reader_text_align_justify">Justify</string> |     <string name="reader_text_align_justify">Justify</string> | ||||||
|     <string name="settings_reader_font">Reader font</string> |     <string name="settings_reader_font">Reader font</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								androidApp/src/main/res/values/ids.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								androidApp/src/main/res/values/ids.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <resources> | ||||||
|  |     <item name="unread_action" type="id" /> | ||||||
|  |     <item name="open_action" type="id" /> | ||||||
|  |     <item name="share_action" type="id" /> | ||||||
|  | </resources> | ||||||
| @@ -108,9 +108,6 @@ | |||||||
|     <string name="source_code_pro_font_id" translatable="false">source_code_pro_medium</string> |     <string name="source_code_pro_font_id" translatable="false">source_code_pro_medium</string> | ||||||
|     <string name="open_sans_font_id" translatable="false">open_sans</string> |     <string name="open_sans_font_id" translatable="false">open_sans</string> | ||||||
|     <string name="roboto_font_id" translatable="false">roboto</string> |     <string name="roboto_font_id" translatable="false">roboto</string> | ||||||
|     <string name="reader_static_bar_title">Static bottom bar in the article viewer</string> |  | ||||||
|     <string name="reader_static_bar_on">The bottom bar will always be displayed</string> |  | ||||||
|     <string name="reader_static_bar_off">The bottom bar can be shown through the floating button</string> |  | ||||||
|     <string name="remove_source">Remove source</string> |     <string name="remove_source">Remove source</string> | ||||||
|     <string name="pref_theme_title">Light/Dark mode</string> |     <string name="pref_theme_title">Light/Dark mode</string> | ||||||
|     <string name="mode_dark">Dark mode</string> |     <string name="mode_dark">Dark mode</string> | ||||||
|   | |||||||
| @@ -30,14 +30,6 @@ | |||||||
|         android:summaryOn="@string/pref_article_viewer_on" |         android:summaryOn="@string/pref_article_viewer_on" | ||||||
|         android:title="@string/pref_article_viewer_title" |         android:title="@string/pref_article_viewer_title" | ||||||
|         app:iconSpaceReserved="false"/> |         app:iconSpaceReserved="false"/> | ||||||
|     <SwitchPreference |  | ||||||
|         android:defaultValue="false" |  | ||||||
|         android:dependency="prefer_article_viewer" |  | ||||||
|         android:key="reader_static_bar" |  | ||||||
|         android:summaryOff="@string/reader_static_bar_off" |  | ||||||
|         android:summaryOn="@string/reader_static_bar_on" |  | ||||||
|         android:title="@string/reader_static_bar_title" |  | ||||||
|         app:iconSpaceReserved="false"/> |  | ||||||
|  |  | ||||||
|     <PreferenceCategory |     <PreferenceCategory | ||||||
|         android:title="@string/pref_general_category_displaying"> |         android:title="@string/pref_general_category_displaying"> | ||||||
|   | |||||||
| @@ -0,0 +1,4 @@ | |||||||
|  | **v125010111** | ||||||
|  |  | ||||||
|  | - Debug trying to fix context issues. (#174) | ||||||
|  | - Changelog for v125010031 | ||||||
| @@ -0,0 +1,5 @@ | |||||||
|  | **v125010131** | ||||||
|  |  | ||||||
|  | - fix: reload the adapter when it's needed. Fixes #128. (#176) | ||||||
|  | - feat: basic auth and images loading. Fixes #172. (#175) | ||||||
|  | - Changelog for v125010111 | ||||||
| @@ -0,0 +1,6 @@ | |||||||
|  | **v125010201** | ||||||
|  |  | ||||||
|  | - fix: Handle empty url issue. | ||||||
|  | - Merge pull request 'Removed the floating bar.' (#177) from floating-bar into master | ||||||
|  | - chore: changing actions in reader fragment. | ||||||
|  | - Changelog for v125010131 | ||||||
| @@ -18,7 +18,7 @@ kotlin.code.style=official | |||||||
| #Android | #Android | ||||||
| android.useAndroidX=true | android.useAndroidX=true | ||||||
| #android.nonTransitiveRClass=true | #android.nonTransitiveRClass=true | ||||||
| android.enableJetifier=true | android.enableJetifier=false | ||||||
| android.nonTransitiveRClass=false | android.nonTransitiveRClass=false | ||||||
| #MPP | #MPP | ||||||
| kotlin.mpp.enableCInteropCommonization=true | kotlin.mpp.enableCInteropCommonization=true | ||||||
|   | |||||||
| @@ -53,7 +53,6 @@ class AppSettingsService( | |||||||
|     private var activeAlignment: Int? = null |     private var activeAlignment: Int? = null | ||||||
|  |  | ||||||
|     private var fontSize: Int? = null |     private var fontSize: Int? = null | ||||||
|     private var staticBar: Boolean? = null |  | ||||||
|     private var font: String = "" |     private var font: String = "" | ||||||
|     private var theme: Int? = null |     private var theme: Int? = null | ||||||
|  |  | ||||||
| @@ -386,17 +385,6 @@ class AppSettingsService( | |||||||
|         return fontSize ?: DEFAULT_FONT_SIZE |         return fontSize ?: DEFAULT_FONT_SIZE | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private fun refreshStaticBarEnabled() { |  | ||||||
|         staticBar = settings.getBoolean(READER_STATIC_BAR, false) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     fun isStaticBarEnabled(): Boolean { |  | ||||||
|         if (staticBar != null) { |  | ||||||
|             refreshStaticBarEnabled() |  | ||||||
|         } |  | ||||||
|         return staticBar == true |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     private fun refreshFont() { |     private fun refreshFont() { | ||||||
|         font = settings.getString(READER_FONT, "") |         font = settings.getString(READER_FONT, "") | ||||||
|     } |     } | ||||||
| @@ -449,7 +437,6 @@ class AppSettingsService( | |||||||
|         refreshActiveAllignment() |         refreshActiveAllignment() | ||||||
|         refreshFontSize() |         refreshFontSize() | ||||||
|         refreshFont() |         refreshFont() | ||||||
|         refreshStaticBarEnabled() |  | ||||||
|         refreshCurrentTheme() |         refreshCurrentTheme() | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -547,8 +534,6 @@ class AppSettingsService( | |||||||
|  |  | ||||||
|         const val READER_FONT = "reader_font" |         const val READER_FONT = "reader_font" | ||||||
|  |  | ||||||
|         const val READER_STATIC_BAR = "reader_static_bar" |  | ||||||
|  |  | ||||||
|         const val READER_FONT_SIZE = "reader_font_size" |         const val READER_FONT_SIZE = "reader_font_size" | ||||||
|  |  | ||||||
|         const val TEXT_ALIGN = "text_align" |         const val TEXT_ALIGN = "text_align" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user