Reformated code according to official kotling style.
This commit is contained in:
parent
3013ae4f35
commit
4d4a2039c8
@ -41,10 +41,10 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
try {
|
try {
|
||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
api = SelfossApi(
|
api = SelfossApi(
|
||||||
this,
|
this,
|
||||||
this@AddSourceActivity,
|
this@AddSourceActivity,
|
||||||
prefs.getBoolean("isSelfSignedCert", false),
|
prefs.getBoolean("isSelfSignedCert", false),
|
||||||
prefs.getBoolean("should_log_everything", false)
|
prefs.getBoolean("should_log_everything", false)
|
||||||
)
|
)
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
mustLoginToAddSource()
|
mustLoginToAddSource()
|
||||||
@ -69,10 +69,10 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSpoutsSpinner(
|
private fun handleSpoutsSpinner(
|
||||||
spoutsSpinner: Spinner,
|
spoutsSpinner: Spinner,
|
||||||
api: SelfossApi?,
|
api: SelfossApi?,
|
||||||
mProgress: ProgressBar,
|
mProgress: ProgressBar,
|
||||||
formContainer: ConstraintLayout
|
formContainer: ConstraintLayout
|
||||||
) {
|
) {
|
||||||
val spoutsKV = HashMap<String, String>()
|
val spoutsKV = HashMap<String, String>()
|
||||||
spoutsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
spoutsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
@ -91,8 +91,8 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
var items: Map<String, Spout>
|
var items: Map<String, Spout>
|
||||||
api!!.spouts().enqueue(object : Callback<Map<String, Spout>> {
|
api!!.spouts().enqueue(object : Callback<Map<String, Spout>> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<Map<String, Spout>>,
|
call: Call<Map<String, Spout>>,
|
||||||
response: Response<Map<String, Spout>>
|
response: Response<Map<String, Spout>>
|
||||||
) {
|
) {
|
||||||
if (response.body() != null) {
|
if (response.body() != null) {
|
||||||
items = response.body()!!
|
items = response.body()!!
|
||||||
@ -106,11 +106,11 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
formContainer.visibility = View.VISIBLE
|
formContainer.visibility = View.VISIBLE
|
||||||
|
|
||||||
val spinnerArrayAdapter =
|
val spinnerArrayAdapter =
|
||||||
ArrayAdapter(
|
ArrayAdapter(
|
||||||
this@AddSourceActivity,
|
this@AddSourceActivity,
|
||||||
android.R.layout.simple_spinner_item,
|
android.R.layout.simple_spinner_item,
|
||||||
itemsStrings
|
itemsStrings
|
||||||
)
|
)
|
||||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||||
spoutsSpinner.adapter = spinnerArrayAdapter
|
spoutsSpinner.adapter = spinnerArrayAdapter
|
||||||
} else {
|
} else {
|
||||||
@ -124,9 +124,9 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun handleProblemWithSpouts() {
|
private fun handleProblemWithSpouts() {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@AddSourceActivity,
|
this@AddSourceActivity,
|
||||||
R.string.cant_get_spouts,
|
R.string.cant_get_spouts,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
mProgress.visibility = View.GONE
|
mProgress.visibility = View.GONE
|
||||||
}
|
}
|
||||||
@ -134,9 +134,9 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun maybeGetDetailsFromIntentSharing(
|
private fun maybeGetDetailsFromIntentSharing(
|
||||||
intent: Intent,
|
intent: Intent,
|
||||||
sourceUri: EditText,
|
sourceUri: EditText,
|
||||||
nameInput: EditText
|
nameInput: EditText
|
||||||
) {
|
) {
|
||||||
if (Intent.ACTION_SEND == intent.action && "text/plain" == intent.type) {
|
if (Intent.ACTION_SEND == intent.action && "text/plain" == intent.type) {
|
||||||
sourceUri.setText(intent.getStringExtra(Intent.EXTRA_TEXT))
|
sourceUri.setText(intent.getStringExtra(Intent.EXTRA_TEXT))
|
||||||
@ -153,38 +153,39 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun handleSaveSource(tags: EditText, title: String, url: String, api: SelfossApi) {
|
private fun handleSaveSource(tags: EditText, title: String, url: String, api: SelfossApi) {
|
||||||
|
|
||||||
val sourceDetailsAvailable = title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()
|
val sourceDetailsAvailable =
|
||||||
|
title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()
|
||||||
|
|
||||||
if (sourceDetailsAvailable) {
|
if (sourceDetailsAvailable) {
|
||||||
Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
api.createSource(
|
api.createSource(
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
mSpoutsValue!!,
|
mSpoutsValue!!,
|
||||||
tags.text.toString(),
|
tags.text.toString(),
|
||||||
""
|
""
|
||||||
).enqueue(object : Callback<SuccessResponse> {
|
).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
if (response.body() != null && response.body()!!.isSuccess) {
|
if (response.body() != null && response.body()!!.isSuccess) {
|
||||||
finish()
|
finish()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@AddSourceActivity,
|
this@AddSourceActivity,
|
||||||
R.string.cant_create_source,
|
R.string.cant_create_source,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@AddSourceActivity,
|
this@AddSourceActivity,
|
||||||
R.string.cant_create_source,
|
R.string.cant_create_source,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -151,10 +151,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
|
sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
api = SelfossApi(
|
api = SelfossApi(
|
||||||
this,
|
this,
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
settings.getBoolean("isSelfSignedCert", false),
|
settings.getBoolean("isSelfSignedCert", false),
|
||||||
sharedPref.getBoolean("should_log_everything", false)
|
sharedPref.getBoolean("should_log_everything", false)
|
||||||
)
|
)
|
||||||
items = ArrayList()
|
items = ArrayList()
|
||||||
|
|
||||||
@ -168,9 +168,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
private fun handleSwipeRefreshLayout() {
|
private fun handleSwipeRefreshLayout() {
|
||||||
swipeRefreshLayout.setColorSchemeResources(
|
swipeRefreshLayout.setColorSchemeResources(
|
||||||
R.color.refresh_progress_1,
|
R.color.refresh_progress_1,
|
||||||
R.color.refresh_progress_2,
|
R.color.refresh_progress_2,
|
||||||
R.color.refresh_progress_3
|
R.color.refresh_progress_3
|
||||||
)
|
)
|
||||||
swipeRefreshLayout.setOnRefreshListener {
|
swipeRefreshLayout.setOnRefreshListener {
|
||||||
handleDrawerItems()
|
handleDrawerItems()
|
||||||
@ -178,79 +178,79 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val simpleItemTouchCallback =
|
val simpleItemTouchCallback =
|
||||||
object : ItemTouchHelper.SimpleCallback(
|
object : ItemTouchHelper.SimpleCallback(
|
||||||
0,
|
0,
|
||||||
ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
|
ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT
|
||||||
) {
|
) {
|
||||||
override fun getSwipeDirs(
|
override fun getSwipeDirs(
|
||||||
recyclerView: RecyclerView?,
|
recyclerView: RecyclerView?,
|
||||||
viewHolder: RecyclerView.ViewHolder?
|
viewHolder: RecyclerView.ViewHolder?
|
||||||
): Int =
|
): Int =
|
||||||
if (elementsShown != UNREAD_SHOWN) {
|
if (elementsShown != UNREAD_SHOWN) {
|
||||||
0
|
0
|
||||||
} else {
|
} else {
|
||||||
super.getSwipeDirs(
|
super.getSwipeDirs(
|
||||||
recyclerView,
|
recyclerView,
|
||||||
viewHolder
|
viewHolder
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMove(
|
override fun onMove(
|
||||||
recyclerView: RecyclerView,
|
recyclerView: RecyclerView,
|
||||||
viewHolder: RecyclerView.ViewHolder,
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
target: RecyclerView.ViewHolder
|
target: RecyclerView.ViewHolder
|
||||||
): Boolean = false
|
): Boolean = false
|
||||||
|
|
||||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
|
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
|
||||||
try {
|
try {
|
||||||
val i = items[viewHolder.adapterPosition]
|
val i = items[viewHolder.adapterPosition]
|
||||||
val position = items.indexOf(i)
|
val position = items.indexOf(i)
|
||||||
|
|
||||||
val adapter = recyclerView.adapter
|
val adapter = recyclerView.adapter
|
||||||
when (adapter) {
|
when (adapter) {
|
||||||
is ItemCardAdapter -> adapter.removeItemAtIndex(position)
|
is ItemCardAdapter -> adapter.removeItemAtIndex(position)
|
||||||
is ItemListAdapter -> adapter.removeItemAtIndex(position)
|
is ItemListAdapter -> adapter.removeItemAtIndex(position)
|
||||||
}
|
|
||||||
|
|
||||||
if (items.size > 0) {
|
|
||||||
badgeNew--
|
|
||||||
reloadBadgeContent()
|
|
||||||
} else {
|
|
||||||
tabNewBadge.hide()
|
|
||||||
}
|
|
||||||
|
|
||||||
val manager = recyclerView.layoutManager
|
|
||||||
val lastVisibleItem: Int = when (manager) {
|
|
||||||
is StaggeredGridLayoutManager -> manager.findLastCompletelyVisibleItemPositions(
|
|
||||||
null
|
|
||||||
).last()
|
|
||||||
is GridLayoutManager -> manager.findLastCompletelyVisibleItemPosition()
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastVisibleItem === items.size &&
|
|
||||||
items.size <= maxItemNumber() &&
|
|
||||||
(maxItemNumber() >= itemsNumber || !lastFetchDone)
|
|
||||||
) {
|
|
||||||
if (maxItemNumber() < itemsNumber) {
|
|
||||||
lastFetchDone = true
|
|
||||||
}
|
|
||||||
getElementsAccordingToTab(
|
|
||||||
appendResults = true,
|
|
||||||
offsetOverride = lastVisibleItem
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} catch (e: IndexOutOfBoundsException) {
|
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
|
||||||
Crashlytics.log(
|
|
||||||
100,
|
|
||||||
"SWIPE_INDEX_OUT_OF_BOUND",
|
|
||||||
"IndexOutOfBoundsException when swiping"
|
|
||||||
)
|
|
||||||
Crashlytics.logException(e)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (items.size > 0) {
|
||||||
|
badgeNew--
|
||||||
|
reloadBadgeContent()
|
||||||
|
} else {
|
||||||
|
tabNewBadge.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
val manager = recyclerView.layoutManager
|
||||||
|
val lastVisibleItem: Int = when (manager) {
|
||||||
|
is StaggeredGridLayoutManager -> manager.findLastCompletelyVisibleItemPositions(
|
||||||
|
null
|
||||||
|
).last()
|
||||||
|
is GridLayoutManager -> manager.findLastCompletelyVisibleItemPosition()
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastVisibleItem === items.size &&
|
||||||
|
items.size <= maxItemNumber() &&
|
||||||
|
(maxItemNumber() >= itemsNumber || !lastFetchDone)
|
||||||
|
) {
|
||||||
|
if (maxItemNumber() < itemsNumber) {
|
||||||
|
lastFetchDone = true
|
||||||
|
}
|
||||||
|
getElementsAccordingToTab(
|
||||||
|
appendResults = true,
|
||||||
|
offsetOverride = lastVisibleItem
|
||||||
|
)
|
||||||
|
}
|
||||||
|
} catch (e: IndexOutOfBoundsException) {
|
||||||
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"SWIPE_INDEX_OUT_OF_BOUND",
|
||||||
|
"IndexOutOfBoundsException when swiping"
|
||||||
|
)
|
||||||
|
Crashlytics.logException(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ItemTouchHelper(simpleItemTouchCallback).attachToRecyclerView(recyclerView)
|
ItemTouchHelper(simpleItemTouchCallback).attachToRecyclerView(recyclerView)
|
||||||
}
|
}
|
||||||
@ -258,43 +258,43 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
private fun handleBottomBar() {
|
private fun handleBottomBar() {
|
||||||
|
|
||||||
tabNewBadge = TextBadgeItem()
|
tabNewBadge = TextBadgeItem()
|
||||||
.setText("")
|
.setText("")
|
||||||
.setHideOnSelect(false).hide(false)
|
.setHideOnSelect(false).hide(false)
|
||||||
.setBackgroundColor(appColors.primary)
|
.setBackgroundColor(appColors.primary)
|
||||||
tabArchiveBadge = TextBadgeItem()
|
tabArchiveBadge = TextBadgeItem()
|
||||||
.setText("")
|
.setText("")
|
||||||
.setHideOnSelect(false).hide(false)
|
.setHideOnSelect(false).hide(false)
|
||||||
.setBackgroundColor(appColors.primary)
|
.setBackgroundColor(appColors.primary)
|
||||||
tabStarredBadge = TextBadgeItem()
|
tabStarredBadge = TextBadgeItem()
|
||||||
.setText("")
|
.setText("")
|
||||||
.setHideOnSelect(false).hide(false)
|
.setHideOnSelect(false).hide(false)
|
||||||
.setBackgroundColor(appColors.primary)
|
.setBackgroundColor(appColors.primary)
|
||||||
|
|
||||||
val tabNew =
|
val tabNew =
|
||||||
BottomNavigationItem(
|
BottomNavigationItem(
|
||||||
R.drawable.ic_fiber_new_black_24dp,
|
R.drawable.ic_fiber_new_black_24dp,
|
||||||
getString(R.string.tab_new)
|
getString(R.string.tab_new)
|
||||||
).setActiveColor(appColors.accent)
|
).setActiveColor(appColors.accent)
|
||||||
.setBadgeItem(tabNewBadge)
|
.setBadgeItem(tabNewBadge)
|
||||||
val tabArchive =
|
val tabArchive =
|
||||||
BottomNavigationItem(
|
BottomNavigationItem(
|
||||||
R.drawable.ic_archive_black_24dp,
|
R.drawable.ic_archive_black_24dp,
|
||||||
getString(R.string.tab_read)
|
getString(R.string.tab_read)
|
||||||
).setActiveColor(appColors.dark)
|
).setActiveColor(appColors.dark)
|
||||||
.setBadgeItem(tabArchiveBadge)
|
.setBadgeItem(tabArchiveBadge)
|
||||||
val tabStarred =
|
val tabStarred =
|
||||||
BottomNavigationItem(
|
BottomNavigationItem(
|
||||||
R.drawable.ic_favorite_black_24dp,
|
R.drawable.ic_favorite_black_24dp,
|
||||||
getString(R.string.tab_favs)
|
getString(R.string.tab_favs)
|
||||||
).setActiveColorResource(R.color.pink)
|
).setActiveColorResource(R.color.pink)
|
||||||
.setBadgeItem(tabStarredBadge)
|
.setBadgeItem(tabStarredBadge)
|
||||||
|
|
||||||
bottomBar
|
bottomBar
|
||||||
.addItem(tabNew)
|
.addItem(tabNew)
|
||||||
.addItem(tabArchive)
|
.addItem(tabArchive)
|
||||||
.addItem(tabStarred)
|
.addItem(tabStarred)
|
||||||
.setFirstSelectedPosition(0)
|
.setFirstSelectedPosition(0)
|
||||||
.initialise()
|
.initialise()
|
||||||
|
|
||||||
bottomBar.setMode(BottomNavigationBar.MODE_SHIFTING)
|
bottomBar.setMode(BottomNavigationBar.MODE_SHIFTING)
|
||||||
bottomBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC)
|
bottomBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC)
|
||||||
@ -351,7 +351,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
private fun handleDrawer() {
|
private fun handleDrawer() {
|
||||||
displayAccountHeader =
|
displayAccountHeader =
|
||||||
PreferenceManager.getDefaultSharedPreferences(this)
|
PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
.getBoolean("account_header_displaying", false)
|
.getBoolean("account_header_displaying", false)
|
||||||
|
|
||||||
drawer = drawer {
|
drawer = drawer {
|
||||||
rootViewRes = R.id.drawer_layout
|
rootViewRes = R.id.drawer_layout
|
||||||
@ -385,17 +385,17 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
iconTintingEnabled = true
|
iconTintingEnabled = true
|
||||||
onClick { _ ->
|
onClick { _ ->
|
||||||
IssueReporterLauncher.forTarget(
|
IssueReporterLauncher.forTarget(
|
||||||
getString(R.string.report_github_user),
|
getString(R.string.report_github_user),
|
||||||
getString(R.string.report_github_repo)
|
getString(R.string.report_github_repo)
|
||||||
)
|
)
|
||||||
.theme(R.style.Theme_App_Light)
|
.theme(R.style.Theme_App_Light)
|
||||||
.guestToken(BuildConfig.GITHUB_TOKEN)
|
.guestToken(BuildConfig.GITHUB_TOKEN)
|
||||||
.guestEmailRequired(true)
|
.guestEmailRequired(true)
|
||||||
.minDescriptionLength(20)
|
.minDescriptionLength(20)
|
||||||
.putExtraInfo("Unique ID", settings.getString("unique_id", ""))
|
.putExtraInfo("Unique ID", settings.getString("unique_id", ""))
|
||||||
.putExtraInfo("From github", BuildConfig.GITHUB_VERSION)
|
.putExtraInfo("From github", BuildConfig.GITHUB_VERSION)
|
||||||
.homeAsUpEnabled(true)
|
.homeAsUpEnabled(true)
|
||||||
.launch(this@HomeActivity)
|
.launch(this@HomeActivity)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -405,11 +405,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
iconTintingEnabled = true
|
iconTintingEnabled = true
|
||||||
onClick { _ ->
|
onClick { _ ->
|
||||||
startActivityForResult(
|
startActivityForResult(
|
||||||
Intent(
|
Intent(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
SettingsActivity::class.java
|
SettingsActivity::class.java
|
||||||
),
|
),
|
||||||
MENU_PREFERENCES
|
MENU_PREFERENCES
|
||||||
)
|
)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@ -424,9 +424,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
if (maybeTags == null) {
|
if (maybeTags == null) {
|
||||||
if (loadedFromCache) {
|
if (loadedFromCache) {
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_error_loading_tags))
|
.withName(getString(R.string.drawer_error_loading_tags))
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -443,20 +443,20 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
gd.setSize(30, 30)
|
gd.setSize(30, 30)
|
||||||
gd.cornerRadius = 30F
|
gd.cornerRadius = 30F
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
PrimaryDrawerItem()
|
PrimaryDrawerItem()
|
||||||
.withName(tag.tag)
|
.withName(tag.tag)
|
||||||
.withIdentifier(tag.tag.longHash())
|
.withIdentifier(tag.tag.longHash())
|
||||||
.withIcon(gd)
|
.withIcon(gd)
|
||||||
.withBadge("${tag.unread}")
|
.withBadge("${tag.unread}")
|
||||||
.withBadgeStyle(
|
.withBadgeStyle(
|
||||||
BadgeStyle().withTextColor(Color.WHITE)
|
BadgeStyle().withTextColor(Color.WHITE)
|
||||||
.withColor(appColors.accent)
|
.withColor(appColors.accent)
|
||||||
)
|
)
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
maybeTagFilter = tag
|
maybeTagFilter = tag
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -466,23 +466,23 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
if (maybeSources == null) {
|
if (maybeSources == null) {
|
||||||
if (loadedFromCache) {
|
if (loadedFromCache) {
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_error_loading_sources))
|
.withName(getString(R.string.drawer_error_loading_sources))
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (tag in maybeSources) {
|
for (tag in maybeSources) {
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
CustomUrlPrimaryDrawerItem()
|
CustomUrlPrimaryDrawerItem()
|
||||||
.withName(tag.title)
|
.withName(tag.title)
|
||||||
.withIdentifier(tag.id.toLong())
|
.withIdentifier(tag.id.toLong())
|
||||||
.withIcon(tag.getIcon(this@HomeActivity))
|
.withIcon(tag.getIcon(this@HomeActivity))
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
maybeSourceFilter = tag
|
maybeSourceFilter = tag
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -491,86 +491,86 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
drawer.removeAllItems()
|
drawer.removeAllItems()
|
||||||
if (maybeDrawerData != null) {
|
if (maybeDrawerData != null) {
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_item_filters))
|
.withName(getString(R.string.drawer_item_filters))
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
.withIdentifier(DRAWER_ID_FILTERS)
|
.withIdentifier(DRAWER_ID_FILTERS)
|
||||||
.withBadge(getString(R.string.drawer_action_clear))
|
.withBadge(getString(R.string.drawer_action_clear))
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
maybeSourceFilter = null
|
maybeSourceFilter = null
|
||||||
maybeTagFilter = null
|
maybeTagFilter = null
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
drawer.addItem(DividerDrawerItem())
|
drawer.addItem(DividerDrawerItem())
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_item_tags))
|
.withName(getString(R.string.drawer_item_tags))
|
||||||
.withIdentifier(DRAWER_ID_TAGS)
|
.withIdentifier(DRAWER_ID_TAGS)
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
)
|
)
|
||||||
handleTags(maybeDrawerData.tags)
|
handleTags(maybeDrawerData.tags)
|
||||||
drawer.addItem(DividerDrawerItem())
|
drawer.addItem(DividerDrawerItem())
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_item_sources))
|
.withName(getString(R.string.drawer_item_sources))
|
||||||
.withIdentifier(DRAWER_ID_TAGS)
|
.withIdentifier(DRAWER_ID_TAGS)
|
||||||
.withBadge(getString(R.string.drawer_action_edit))
|
.withBadge(getString(R.string.drawer_action_edit))
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
startActivity(Intent(this, SourcesActivity::class.java))
|
startActivity(Intent(this, SourcesActivity::class.java))
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
handleSources(maybeDrawerData.sources)
|
handleSources(maybeDrawerData.sources)
|
||||||
drawer.addItem(DividerDrawerItem())
|
drawer.addItem(DividerDrawerItem())
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
PrimaryDrawerItem()
|
PrimaryDrawerItem()
|
||||||
.withName(R.string.action_about)
|
.withName(R.string.action_about)
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
.withIcon(R.drawable.ic_info_outline)
|
.withIcon(R.drawable.ic_info_outline)
|
||||||
.withIconTintingEnabled(true)
|
.withIconTintingEnabled(true)
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
LibsBuilder()
|
LibsBuilder()
|
||||||
.withActivityStyle(
|
.withActivityStyle(
|
||||||
if (appColors.isDarkTheme) {
|
if (appColors.isDarkTheme) {
|
||||||
Libs.ActivityStyle.LIGHT_DARK_TOOLBAR
|
Libs.ActivityStyle.LIGHT_DARK_TOOLBAR
|
||||||
} else {
|
} else {
|
||||||
Libs.ActivityStyle.DARK
|
Libs.ActivityStyle.DARK
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.withAboutIconShown(true)
|
.withAboutIconShown(true)
|
||||||
.withAboutVersionShown(true)
|
.withAboutVersionShown(true)
|
||||||
.start(this@HomeActivity)
|
.start(this@HomeActivity)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if (!loadedFromCache) {
|
if (!loadedFromCache) {
|
||||||
Reservoir.putAsync(
|
Reservoir.putAsync(
|
||||||
"drawerData", maybeDrawerData, object : ReservoirPutCallback {
|
"drawerData", maybeDrawerData, object : ReservoirPutCallback {
|
||||||
override fun onSuccess() {
|
override fun onSuccess() {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(p0: Exception?) {
|
override fun onFailure(p0: Exception?) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!loadedFromCache) {
|
if (!loadedFromCache) {
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
PrimaryDrawerItem()
|
PrimaryDrawerItem()
|
||||||
.withName(getString(R.string.no_tags_loaded))
|
.withName(getString(R.string.no_tags_loaded))
|
||||||
.withIdentifier(DRAWER_ID_TAGS)
|
.withIdentifier(DRAWER_ID_TAGS)
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
)
|
)
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
PrimaryDrawerItem()
|
PrimaryDrawerItem()
|
||||||
.withName(getString(R.string.no_sources_loaded))
|
.withName(getString(R.string.no_sources_loaded))
|
||||||
.withIdentifier(DRAWER_ID_SOURCES)
|
.withIdentifier(DRAWER_ID_SOURCES)
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -583,8 +583,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
fun sourcesApiCall() {
|
fun sourcesApiCall() {
|
||||||
api.sources.enqueue(object : Callback<List<Sources>> {
|
api.sources.enqueue(object : Callback<List<Sources>> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<List<Sources>>?,
|
call: Call<List<Sources>>?,
|
||||||
response: Response<List<Sources>>
|
response: Response<List<Sources>>
|
||||||
) {
|
) {
|
||||||
sources = response.body()
|
sources = response.body()
|
||||||
val apiDrawerData = DrawerData(tags, sources)
|
val apiDrawerData = DrawerData(tags, sources)
|
||||||
@ -600,8 +600,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
api.tags.enqueue(object : Callback<List<Tag>> {
|
api.tags.enqueue(object : Callback<List<Tag>> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<List<Tag>>,
|
call: Call<List<Tag>>,
|
||||||
response: Response<List<Tag>>
|
response: Response<List<Tag>>
|
||||||
) {
|
) {
|
||||||
tags = response.body()
|
tags = response.body()
|
||||||
sourcesApiCall()
|
sourcesApiCall()
|
||||||
@ -614,23 +614,23 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
PrimaryDrawerItem().withName(getString(R.string.drawer_loading)).withSelectable(
|
PrimaryDrawerItem().withName(getString(R.string.drawer_loading)).withSelectable(
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val resultType = object : TypeToken<DrawerData>() {}.type
|
val resultType = object : TypeToken<DrawerData>() {}.type
|
||||||
Reservoir.getAsync(
|
Reservoir.getAsync(
|
||||||
"drawerData", resultType, object : ReservoirGetCallback<DrawerData> {
|
"drawerData", resultType, object : ReservoirGetCallback<DrawerData> {
|
||||||
override fun onSuccess(maybeDrawerData: DrawerData?) {
|
override fun onSuccess(maybeDrawerData: DrawerData?) {
|
||||||
handleDrawerData(maybeDrawerData, loadedFromCache = true)
|
handleDrawerData(maybeDrawerData, loadedFromCache = true)
|
||||||
drawerApiCalls(maybeDrawerData)
|
drawerApiCalls(maybeDrawerData)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(p0: Exception?) {
|
override fun onFailure(p0: Exception?) {
|
||||||
drawerApiCalls(null)
|
drawerApiCalls(null)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun reloadLayoutManager() {
|
private fun reloadLayoutManager() {
|
||||||
@ -640,19 +640,20 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
// This will only update the layout manager if settings changed
|
// This will only update the layout manager if settings changed
|
||||||
when (currentManager) {
|
when (currentManager) {
|
||||||
is StaggeredGridLayoutManager ->
|
is StaggeredGridLayoutManager ->
|
||||||
if (!shouldBeCardView) {
|
if (!shouldBeCardView) {
|
||||||
layoutManager = GridLayoutManager(this, calculateNoOfColumns())
|
layoutManager = GridLayoutManager(this, calculateNoOfColumns())
|
||||||
recyclerView.layoutManager = layoutManager
|
recyclerView.layoutManager = layoutManager
|
||||||
}
|
}
|
||||||
is GridLayoutManager ->
|
is GridLayoutManager ->
|
||||||
if (shouldBeCardView) {
|
if (shouldBeCardView) {
|
||||||
layoutManager = StaggeredGridLayoutManager(
|
layoutManager = StaggeredGridLayoutManager(
|
||||||
calculateNoOfColumns(),
|
calculateNoOfColumns(),
|
||||||
StaggeredGridLayoutManager.VERTICAL
|
StaggeredGridLayoutManager.VERTICAL
|
||||||
)
|
)
|
||||||
layoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
|
layoutManager.gapStrategy =
|
||||||
recyclerView.layoutManager = layoutManager
|
StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
|
||||||
}
|
recyclerView.layoutManager = layoutManager
|
||||||
|
}
|
||||||
else ->
|
else ->
|
||||||
if (currentManager == null) {
|
if (currentManager == null) {
|
||||||
if (!shouldBeCardView) {
|
if (!shouldBeCardView) {
|
||||||
@ -660,10 +661,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
recyclerView.layoutManager = layoutManager
|
recyclerView.layoutManager = layoutManager
|
||||||
} else {
|
} else {
|
||||||
layoutManager = StaggeredGridLayoutManager(
|
layoutManager = StaggeredGridLayoutManager(
|
||||||
calculateNoOfColumns(),
|
calculateNoOfColumns(),
|
||||||
StaggeredGridLayoutManager.VERTICAL
|
StaggeredGridLayoutManager.VERTICAL
|
||||||
)
|
)
|
||||||
layoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
|
layoutManager.gapStrategy =
|
||||||
|
StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS
|
||||||
recyclerView.layoutManager = layoutManager
|
recyclerView.layoutManager = layoutManager
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -717,7 +719,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
val manager = recyclerView.layoutManager
|
val manager = recyclerView.layoutManager
|
||||||
val lastVisibleItem: Int = when (manager) {
|
val lastVisibleItem: Int = when (manager) {
|
||||||
is StaggeredGridLayoutManager -> manager.findLastCompletelyVisibleItemPositions(
|
is StaggeredGridLayoutManager -> manager.findLastCompletelyVisibleItemPositions(
|
||||||
null
|
null
|
||||||
).last()
|
).last()
|
||||||
is GridLayoutManager -> manager.findLastCompletelyVisibleItemPosition()
|
is GridLayoutManager -> manager.findLastCompletelyVisibleItemPosition()
|
||||||
else -> 0
|
else -> 0
|
||||||
@ -736,17 +738,17 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun mayBeEmpty() =
|
private fun mayBeEmpty() =
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
emptyText.visibility = View.VISIBLE
|
emptyText.visibility = View.VISIBLE
|
||||||
recyclerView.visibility = View.GONE
|
recyclerView.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
emptyText.visibility = View.GONE
|
emptyText.visibility = View.GONE
|
||||||
recyclerView.visibility = View.VISIBLE
|
recyclerView.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getElementsAccordingToTab(
|
private fun getElementsAccordingToTab(
|
||||||
appendResults: Boolean = false,
|
appendResults: Boolean = false,
|
||||||
offsetOverride: Int? = null
|
offsetOverride: Int? = null
|
||||||
) {
|
) {
|
||||||
offset = if (appendResults && offsetOverride === null) {
|
offset = if (appendResults && offsetOverride === null) {
|
||||||
(offset + itemsNumber)
|
(offset + itemsNumber)
|
||||||
@ -764,9 +766,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun doCallTo(
|
private fun doCallTo(
|
||||||
appendResults: Boolean,
|
appendResults: Boolean,
|
||||||
toastMessage: Int,
|
toastMessage: Int,
|
||||||
call: (String?, Long?, String?) -> Call<List<Item>>
|
call: (String?, Long?, String?) -> Call<List<Item>>
|
||||||
) {
|
) {
|
||||||
fun handleItemsResponse(response: Response<List<Item>>) {
|
fun handleItemsResponse(response: Response<List<Item>>) {
|
||||||
val shouldUpdate = (response.body() != items)
|
val shouldUpdate = (response.body() != items)
|
||||||
@ -792,34 +794,34 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
call(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter)
|
call(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter)
|
||||||
.enqueue(object : Callback<List<Item>> {
|
.enqueue(object : Callback<List<Item>> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<List<Item>>,
|
call: Call<List<Item>>,
|
||||||
response: Response<List<Item>>
|
response: Response<List<Item>>
|
||||||
) {
|
) {
|
||||||
handleItemsResponse(response)
|
handleItemsResponse(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
||||||
swipeRefreshLayout.isRefreshing = false
|
swipeRefreshLayout.isRefreshing = false
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
toastMessage,
|
toastMessage,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getUnRead(appendResults: Boolean = false) {
|
private fun getUnRead(appendResults: Boolean = false) {
|
||||||
elementsShown = UNREAD_SHOWN
|
elementsShown = UNREAD_SHOWN
|
||||||
doCallTo(appendResults, R.string.cant_get_new_elements) { t, id, f ->
|
doCallTo(appendResults, R.string.cant_get_new_elements) { t, id, f ->
|
||||||
api.newItems(
|
api.newItems(
|
||||||
t,
|
t,
|
||||||
id,
|
id,
|
||||||
f,
|
f,
|
||||||
itemsNumber,
|
itemsNumber,
|
||||||
offset
|
offset
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -828,11 +830,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
elementsShown = READ_SHOWN
|
elementsShown = READ_SHOWN
|
||||||
doCallTo(appendResults, R.string.cant_get_read) { t, id, f ->
|
doCallTo(appendResults, R.string.cant_get_read) { t, id, f ->
|
||||||
api.readItems(
|
api.readItems(
|
||||||
t,
|
t,
|
||||||
id,
|
id,
|
||||||
f,
|
f,
|
||||||
itemsNumber,
|
itemsNumber,
|
||||||
offset
|
offset
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -841,11 +843,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
elementsShown = FAV_SHOWN
|
elementsShown = FAV_SHOWN
|
||||||
doCallTo(appendResults, R.string.cant_get_favs) { t, id, f ->
|
doCallTo(appendResults, R.string.cant_get_favs) { t, id, f ->
|
||||||
api.starredItems(
|
api.starredItems(
|
||||||
t,
|
t,
|
||||||
id,
|
id,
|
||||||
f,
|
f,
|
||||||
itemsNumber,
|
itemsNumber,
|
||||||
offset
|
offset
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -866,36 +868,36 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
if (shouldBeCardView) {
|
if (shouldBeCardView) {
|
||||||
recyclerAdapter =
|
recyclerAdapter =
|
||||||
ItemCardAdapter(
|
ItemCardAdapter(
|
||||||
this,
|
this,
|
||||||
items,
|
items,
|
||||||
api,
|
api,
|
||||||
customTabActivityHelper,
|
customTabActivityHelper,
|
||||||
internalBrowser,
|
internalBrowser,
|
||||||
articleViewer,
|
articleViewer,
|
||||||
fullHeightCards,
|
fullHeightCards,
|
||||||
appColors,
|
appColors,
|
||||||
debugReadingItems,
|
debugReadingItems,
|
||||||
userIdentifier
|
userIdentifier
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
recyclerAdapter =
|
recyclerAdapter =
|
||||||
ItemListAdapter(
|
ItemListAdapter(
|
||||||
this,
|
this,
|
||||||
items,
|
items,
|
||||||
api,
|
api,
|
||||||
customTabActivityHelper,
|
customTabActivityHelper,
|
||||||
clickBehavior,
|
clickBehavior,
|
||||||
internalBrowser,
|
internalBrowser,
|
||||||
articleViewer,
|
articleViewer,
|
||||||
debugReadingItems,
|
debugReadingItems,
|
||||||
userIdentifier
|
userIdentifier
|
||||||
)
|
)
|
||||||
|
|
||||||
recyclerView.addItemDecoration(
|
recyclerView.addItemDecoration(
|
||||||
DividerItemDecoration(
|
DividerItemDecoration(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
DividerItemDecoration.VERTICAL
|
DividerItemDecoration.VERTICAL
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
recyclerView.adapter = recyclerAdapter
|
recyclerView.adapter = recyclerAdapter
|
||||||
@ -935,16 +937,16 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
if (succeeded) {
|
if (succeeded) {
|
||||||
if (displayUnreadCount) {
|
if (displayUnreadCount) {
|
||||||
tabNewBadge
|
tabNewBadge
|
||||||
.setText(badgeNew.toString())
|
.setText(badgeNew.toString())
|
||||||
.maybeShow()
|
.maybeShow()
|
||||||
}
|
}
|
||||||
if (displayAllCount) {
|
if (displayAllCount) {
|
||||||
tabArchiveBadge
|
tabArchiveBadge
|
||||||
.setText(badgeAll.toString())
|
.setText(badgeAll.toString())
|
||||||
.maybeShow()
|
.maybeShow()
|
||||||
tabStarredBadge
|
tabStarredBadge
|
||||||
.setText(badgeFavs.toString())
|
.setText(badgeFavs.toString())
|
||||||
.maybeShow()
|
.maybeShow()
|
||||||
} else {
|
} else {
|
||||||
tabArchiveBadge.removeBadge()
|
tabArchiveBadge.removeBadge()
|
||||||
tabStarredBadge.removeBadge()
|
tabStarredBadge.removeBadge()
|
||||||
@ -1009,21 +1011,21 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
R.id.refresh -> {
|
R.id.refresh -> {
|
||||||
api.update().enqueue(object : Callback<String> {
|
api.update().enqueue(object : Callback<String> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<String>,
|
call: Call<String>,
|
||||||
response: Response<String>
|
response: Response<String>
|
||||||
) {
|
) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
R.string.refresh_success_response, Toast.LENGTH_LONG
|
R.string.refresh_success_response, Toast.LENGTH_LONG
|
||||||
)
|
)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<String>, t: Throwable) {
|
override fun onFailure(call: Call<String>, t: Throwable) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
R.string.refresh_failer_message,
|
R.string.refresh_failer_message,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -1037,21 +1039,21 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
api.readAll(ids).enqueue(object : Callback<SuccessResponse> {
|
api.readAll(ids).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
if (response.body() != null && response.body()!!.isSuccess) {
|
if (response.body() != null && response.body()!!.isSuccess) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
R.string.all_posts_read,
|
R.string.all_posts_read,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
tabNewBadge.removeBadge()
|
tabNewBadge.removeBadge()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
R.string.all_posts_not_read,
|
R.string.all_posts_not_read,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1060,9 +1062,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
R.string.all_posts_not_read,
|
R.string.all_posts_not_read,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
swipeRefreshLayout.isRefreshing = false
|
swipeRefreshLayout.isRefreshing = false
|
||||||
}
|
}
|
||||||
@ -1070,9 +1072,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
items = ArrayList()
|
items = ArrayList()
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@HomeActivity,
|
this@HomeActivity,
|
||||||
R.string.nothing_here,
|
R.string.nothing_here,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
handleListResult()
|
handleListResult()
|
||||||
@ -1084,7 +1086,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
R.id.action_share_the_app -> {
|
R.id.action_share_the_app -> {
|
||||||
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
|
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
|
||||||
val share = AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
|
val share =
|
||||||
|
AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
|
||||||
.setMessage(getString(R.string.invitation_message))
|
.setMessage(getString(R.string.invitation_message))
|
||||||
.setDeepLink(Uri.parse("https://ymbh5.app.goo.gl/qbvQ"))
|
.setDeepLink(Uri.parse("https://ymbh5.app.goo.gl/qbvQ"))
|
||||||
.setCallToActionText(getString(R.string.invitation_cta))
|
.setCallToActionText(getString(R.string.invitation_cta))
|
||||||
@ -1094,8 +1097,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
val sendIntent = Intent()
|
val sendIntent = Intent()
|
||||||
sendIntent.action = Intent.ACTION_SEND
|
sendIntent.action = Intent.ACTION_SEND
|
||||||
sendIntent.putExtra(
|
sendIntent.putExtra(
|
||||||
Intent.EXTRA_TEXT,
|
Intent.EXTRA_TEXT,
|
||||||
getString(R.string.invitation_message) + " https://ymbh5.app.goo.gl/qbvQ"
|
getString(R.string.invitation_message) + " https://ymbh5.app.goo.gl/qbvQ"
|
||||||
)
|
)
|
||||||
sendIntent.type = "text/plain"
|
sendIntent.type = "text/plain"
|
||||||
startActivityForResult(sendIntent, REQUEST_INVITE_BYMAIL)
|
startActivityForResult(sendIntent, REQUEST_INVITE_BYMAIL)
|
||||||
@ -1107,10 +1110,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun maxItemNumber(): Int =
|
private fun maxItemNumber(): Int =
|
||||||
when (elementsShown) {
|
when (elementsShown) {
|
||||||
UNREAD_SHOWN -> badgeNew
|
UNREAD_SHOWN -> badgeNew
|
||||||
READ_SHOWN -> badgeAll
|
READ_SHOWN -> badgeAll
|
||||||
FAV_SHOWN -> badgeFavs
|
FAV_SHOWN -> badgeFavs
|
||||||
else -> badgeNew // if !elementsShown then unread are fetched.
|
else -> badgeNew // if !elementsShown then unread are fetched.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,42 +18,42 @@ class IntroActivity : MaterialIntroActivity() {
|
|||||||
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
|
||||||
|
|
||||||
addSlide(
|
addSlide(
|
||||||
SlideFragmentBuilder()
|
SlideFragmentBuilder()
|
||||||
.backgroundColor(R.color.colorPrimary)
|
.backgroundColor(R.color.colorPrimary)
|
||||||
.buttonsColor(R.color.colorAccent)
|
.buttonsColor(R.color.colorAccent)
|
||||||
.image(R.drawable.web_hi_res_512)
|
.image(R.drawable.web_hi_res_512)
|
||||||
.title(getString(R.string.intro_hello_title))
|
.title(getString(R.string.intro_hello_title))
|
||||||
.description(getString(R.string.intro_hello_message))
|
.description(getString(R.string.intro_hello_message))
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
|
|
||||||
addSlide(
|
addSlide(
|
||||||
SlideFragmentBuilder()
|
SlideFragmentBuilder()
|
||||||
.backgroundColor(R.color.colorAccent)
|
.backgroundColor(R.color.colorAccent)
|
||||||
.buttonsColor(R.color.colorPrimary)
|
.buttonsColor(R.color.colorPrimary)
|
||||||
.image(R.drawable.ic_info_outline_white_48px)
|
.image(R.drawable.ic_info_outline_white_48px)
|
||||||
.title(getString(R.string.intro_needs_selfoss_title))
|
.title(getString(R.string.intro_needs_selfoss_title))
|
||||||
.description(getString(R.string.intro_needs_selfoss_message))
|
.description(getString(R.string.intro_needs_selfoss_message))
|
||||||
.build(),
|
.build(),
|
||||||
MessageButtonBehaviour(
|
MessageButtonBehaviour(
|
||||||
View.OnClickListener {
|
View.OnClickListener {
|
||||||
val browserIntent = Intent(
|
val browserIntent = Intent(
|
||||||
Intent.ACTION_VIEW,
|
Intent.ACTION_VIEW,
|
||||||
Uri.parse("https://selfoss.aditu.de")
|
Uri.parse("https://selfoss.aditu.de")
|
||||||
)
|
)
|
||||||
startActivity(browserIntent)
|
startActivity(browserIntent)
|
||||||
}, getString(R.string.intro_needs_selfoss_link)
|
}, getString(R.string.intro_needs_selfoss_link)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
addSlide(
|
addSlide(
|
||||||
SlideFragmentBuilder()
|
SlideFragmentBuilder()
|
||||||
.backgroundColor(R.color.colorPrimaryDark)
|
.backgroundColor(R.color.colorPrimaryDark)
|
||||||
.buttonsColor(R.color.colorAccentDark)
|
.buttonsColor(R.color.colorAccentDark)
|
||||||
.image(R.drawable.ic_thumb_up_white_48px)
|
.image(R.drawable.ic_thumb_up_white_48px)
|
||||||
.title(getString(R.string.intro_all_set_title))
|
.title(getString(R.string.intro_all_set_title))
|
||||||
.description(getString(R.string.intro_all_set_message))
|
.description(getString(R.string.intro_all_set_message))
|
||||||
.build()
|
.build()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,13 +77,13 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
passwordView.setOnEditorActionListener(
|
passwordView.setOnEditorActionListener(
|
||||||
TextView.OnEditorActionListener { _, id, _ ->
|
TextView.OnEditorActionListener { _, id, _ ->
|
||||||
if (id == R.id.loginView || id == EditorInfo.IME_NULL) {
|
if (id == R.id.loginView || id == EditorInfo.IME_NULL) {
|
||||||
attemptLogin()
|
attemptLogin()
|
||||||
return@OnEditorActionListener true
|
return@OnEditorActionListener true
|
||||||
}
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
signInButton.setOnClickListener { attemptLogin() }
|
signInButton.setOnClickListener { attemptLogin() }
|
||||||
@ -111,9 +111,9 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
||||||
alertDialog.setMessage(getString(R.string.base_url_error))
|
alertDialog.setMessage(getString(R.string.base_url_error))
|
||||||
alertDialog.setButton(
|
alertDialog.setButton(
|
||||||
AlertDialog.BUTTON_NEUTRAL,
|
AlertDialog.BUTTON_NEUTRAL,
|
||||||
"OK",
|
"OK",
|
||||||
{ dialog, _ -> dialog.dismiss() }
|
{ dialog, _ -> dialog.dismiss() }
|
||||||
)
|
)
|
||||||
alertDialog.show()
|
alertDialog.show()
|
||||||
}
|
}
|
||||||
@ -154,9 +154,9 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
||||||
alertDialog.setMessage(getString(R.string.text_wrong_url))
|
alertDialog.setMessage(getString(R.string.text_wrong_url))
|
||||||
alertDialog.setButton(
|
alertDialog.setButton(
|
||||||
AlertDialog.BUTTON_NEUTRAL,
|
AlertDialog.BUTTON_NEUTRAL,
|
||||||
"OK",
|
"OK",
|
||||||
{ dialog, _ -> dialog.dismiss() }
|
{ dialog, _ -> dialog.dismiss() }
|
||||||
)
|
)
|
||||||
alertDialog.show()
|
alertDialog.show()
|
||||||
inValidCount = 0
|
inValidCount = 0
|
||||||
@ -191,10 +191,10 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
editor.apply()
|
editor.apply()
|
||||||
|
|
||||||
val api = SelfossApi(
|
val api = SelfossApi(
|
||||||
this,
|
this,
|
||||||
this@LoginActivity,
|
this@LoginActivity,
|
||||||
isWithSelfSignedCert,
|
isWithSelfSignedCert,
|
||||||
isWithSelfSignedCert
|
isWithSelfSignedCert
|
||||||
)
|
)
|
||||||
api.login().enqueue(object : Callback<SuccessResponse> {
|
api.login().enqueue(object : Callback<SuccessResponse> {
|
||||||
private fun preferenceError(t: Throwable) {
|
private fun preferenceError(t: Throwable) {
|
||||||
@ -214,17 +214,17 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
Crashlytics.log(100, "LOGIN_DEBUG_ERRROR", t.message)
|
Crashlytics.log(100, "LOGIN_DEBUG_ERRROR", t.message)
|
||||||
Crashlytics.logException(t)
|
Crashlytics.logException(t)
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@LoginActivity,
|
this@LoginActivity,
|
||||||
t.message,
|
t.message,
|
||||||
Toast.LENGTH_LONG
|
Toast.LENGTH_LONG
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
showProgress(false)
|
showProgress(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
if (response.body() != null && response.body()!!.isSuccess) {
|
if (response.body() != null && response.body()!!.isSuccess) {
|
||||||
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, Bundle())
|
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, Bundle())
|
||||||
@ -246,28 +246,28 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
loginForm.visibility = if (show) View.GONE else View.VISIBLE
|
loginForm.visibility = if (show) View.GONE else View.VISIBLE
|
||||||
loginForm
|
loginForm
|
||||||
.animate()
|
.animate()
|
||||||
.setDuration(shortAnimTime.toLong())
|
.setDuration(shortAnimTime.toLong())
|
||||||
.alpha(
|
.alpha(
|
||||||
if (show) 0F else 1F
|
if (show) 0F else 1F
|
||||||
).setListener(object : AnimatorListenerAdapter() {
|
).setListener(object : AnimatorListenerAdapter() {
|
||||||
override fun onAnimationEnd(animation: Animator) {
|
override fun onAnimationEnd(animation: Animator) {
|
||||||
loginForm.visibility = if (show) View.GONE else View.VISIBLE
|
loginForm.visibility = if (show) View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
|
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
|
||||||
loginProgress
|
loginProgress
|
||||||
.animate()
|
.animate()
|
||||||
.setDuration(shortAnimTime.toLong())
|
.setDuration(shortAnimTime.toLong())
|
||||||
.alpha(
|
.alpha(
|
||||||
if (show) 1F else 0F
|
if (show) 1F else 0F
|
||||||
).setListener(object : AnimatorListenerAdapter() {
|
).setListener(object : AnimatorListenerAdapter() {
|
||||||
override fun onAnimationEnd(animation: Animator) {
|
override fun onAnimationEnd(animation: Animator) {
|
||||||
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
|
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -281,10 +281,10 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.about -> {
|
R.id.about -> {
|
||||||
LibsBuilder()
|
LibsBuilder()
|
||||||
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
|
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
|
||||||
.withAboutIconShown(true)
|
.withAboutIconShown(true)
|
||||||
.withAboutVersionShown(true)
|
.withAboutVersionShown(true)
|
||||||
.start(this)
|
.start(this)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.login_debug -> {
|
R.id.login_debug -> {
|
||||||
|
@ -14,7 +14,7 @@ class MainActivity : AppCompatActivity() {
|
|||||||
if (PreferenceManager.getDefaultSharedPreferences(baseContext).getBoolean(
|
if (PreferenceManager.getDefaultSharedPreferences(baseContext).getBoolean(
|
||||||
"firstStart",
|
"firstStart",
|
||||||
true
|
true
|
||||||
)) {
|
)) {
|
||||||
val i = Intent(this@MainActivity, IntroActivity::class.java)
|
val i = Intent(this@MainActivity, IntroActivity::class.java)
|
||||||
startActivity(i)
|
startActivity(i)
|
||||||
} else {
|
} else {
|
||||||
|
@ -47,9 +47,9 @@ class MyApp : MultiDexApplication() {
|
|||||||
|
|
||||||
private fun initAmplify() {
|
private fun initAmplify() {
|
||||||
Amplify.initSharedInstance(this)
|
Amplify.initSharedInstance(this)
|
||||||
.setPositiveFeedbackCollectors(GooglePlayStoreFeedbackCollector())
|
.setPositiveFeedbackCollectors(GooglePlayStoreFeedbackCollector())
|
||||||
.setCriticalFeedbackCollectors(DefaultEmailFeedbackCollector(BuildConfig.FEEDBACK_EMAIL))
|
.setCriticalFeedbackCollectors(DefaultEmailFeedbackCollector(BuildConfig.FEEDBACK_EMAIL))
|
||||||
.applyAllDefaultRules()
|
.applyAllDefaultRules()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initCache() {
|
private fun initCache() {
|
||||||
@ -63,15 +63,15 @@ 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?,
|
imageView: ImageView?,
|
||||||
uri: Uri?,
|
uri: Uri?,
|
||||||
placeholder: Drawable?,
|
placeholder: Drawable?,
|
||||||
tag: String?
|
tag: String?
|
||||||
) {
|
) {
|
||||||
Glide.with(imageView?.context)
|
Glide.with(imageView?.context)
|
||||||
.load(uri)
|
.load(uri)
|
||||||
.apply(RequestOptions.fitCenterTransform().placeholder(placeholder))
|
.apply(RequestOptions.fitCenterTransform().placeholder(placeholder))
|
||||||
.into(imageView)
|
.into(imageView)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun cancel(imageView: ImageView?) {
|
override fun cancel(imageView: ImageView?) {
|
||||||
@ -86,22 +86,34 @@ class MyApp : MultiDexApplication() {
|
|||||||
|
|
||||||
private fun initTheme() {
|
private fun initTheme() {
|
||||||
Scoop.waffleCone()
|
Scoop.waffleCone()
|
||||||
.addFlavor(getString(R.string.default_theme), R.style.NoBar, true)
|
.addFlavor(getString(R.string.default_theme), R.style.NoBar, true)
|
||||||
.addDayNightFlavor(getString(R.string.default_dark_theme), R.style.NoBarDark)
|
.addDayNightFlavor(getString(R.string.default_dark_theme), R.style.NoBarDark)
|
||||||
.addFlavor(getString(R.string.teal_orange_theme), R.style.NoBarTealOrange)
|
.addFlavor(getString(R.string.teal_orange_theme), R.style.NoBarTealOrange)
|
||||||
.addDayNightFlavor(getString(R.string.teal_orange_dark_theme), R.style.NoBarTealOrangeDark)
|
.addDayNightFlavor(
|
||||||
.addFlavor(getString(R.string.cyan_pink_theme), R.style.NoBarCyanPink)
|
getString(R.string.teal_orange_dark_theme),
|
||||||
.addDayNightFlavor(getString(R.string.cyan_pink_dark_theme), R.style.NoBarCyanPinkDark)
|
R.style.NoBarTealOrangeDark
|
||||||
.addFlavor(getString(R.string.grey_orange_theme), R.style.NoBarGreyOrange)
|
)
|
||||||
.addDayNightFlavor(getString(R.string.grey_orange_dark_theme), R.style.NoBarGreyOrangeDark)
|
.addFlavor(getString(R.string.cyan_pink_theme), R.style.NoBarCyanPink)
|
||||||
.addFlavor(getString(R.string.blue_amber_theme), R.style.NoBarBlueAmber)
|
.addDayNightFlavor(getString(R.string.cyan_pink_dark_theme), R.style.NoBarCyanPinkDark)
|
||||||
.addDayNightFlavor(getString(R.string.blue_amber_dark_theme), R.style.NoBarBlueAmberDark)
|
.addFlavor(getString(R.string.grey_orange_theme), R.style.NoBarGreyOrange)
|
||||||
.addFlavor(getString(R.string.indigo_pink_theme), R.style.NoBarIndigoPink)
|
.addDayNightFlavor(
|
||||||
.addDayNightFlavor(getString(R.string.indigo_pink_dark_theme), R.style.NoBarIndigoPinkDark)
|
getString(R.string.grey_orange_dark_theme),
|
||||||
.addFlavor(getString(R.string.red_teal_theme), R.style.NoBarRedTeal)
|
R.style.NoBarGreyOrangeDark
|
||||||
.addDayNightFlavor(getString(R.string.red_teal_dark_theme), R.style.NoBarRedTealDark)
|
)
|
||||||
.setSharedPreferences(PreferenceManager.getDefaultSharedPreferences(this))
|
.addFlavor(getString(R.string.blue_amber_theme), R.style.NoBarBlueAmber)
|
||||||
.initialize()
|
.addDayNightFlavor(
|
||||||
|
getString(R.string.blue_amber_dark_theme),
|
||||||
|
R.style.NoBarBlueAmberDark
|
||||||
|
)
|
||||||
|
.addFlavor(getString(R.string.indigo_pink_theme), R.style.NoBarIndigoPink)
|
||||||
|
.addDayNightFlavor(
|
||||||
|
getString(R.string.indigo_pink_dark_theme),
|
||||||
|
R.style.NoBarIndigoPinkDark
|
||||||
|
)
|
||||||
|
.addFlavor(getString(R.string.red_teal_theme), R.style.NoBarRedTeal)
|
||||||
|
.addDayNightFlavor(getString(R.string.red_teal_dark_theme), R.style.NoBarRedTealDark)
|
||||||
|
.setSharedPreferences(PreferenceManager.getDefaultSharedPreferences(this))
|
||||||
|
.initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryToHandleBug() {
|
private fun tryToHandleBug() {
|
||||||
@ -109,8 +121,8 @@ class MyApp : MultiDexApplication() {
|
|||||||
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler { thread, e ->
|
Thread.setDefaultUncaughtExceptionHandler { thread, e ->
|
||||||
if (e is java.lang.NoClassDefFoundError && e.stackTrace.asList().any {
|
if (e is java.lang.NoClassDefFoundError && e.stackTrace.asList().any {
|
||||||
it.toString().contains("android.view.ViewDebug")
|
it.toString().contains("android.view.ViewDebug")
|
||||||
}) {
|
}) {
|
||||||
Unit
|
Unit
|
||||||
} else {
|
} else {
|
||||||
oldHandler.uncaughtException(thread, e)
|
oldHandler.uncaughtException(thread, e)
|
||||||
|
@ -69,9 +69,9 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
if (allItems.isEmpty()) {
|
if (allItems.isEmpty()) {
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
Crashlytics.log(
|
Crashlytics.log(
|
||||||
100,
|
100,
|
||||||
"READER_ITEMS_EMPTY",
|
"READER_ITEMS_EMPTY",
|
||||||
"Items empty when trying to open the Article Reader. Was (static) companion object field set ?"
|
"Items empty when trying to open the Article Reader. Was (static) companion object field set ?"
|
||||||
)
|
)
|
||||||
Crashlytics.logException(Exception("Empty items on Reader Activity."))
|
Crashlytics.logException(Exception("Empty items on Reader Activity."))
|
||||||
|
|
||||||
@ -79,10 +79,10 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
api = SelfossApi(
|
api = SelfossApi(
|
||||||
this,
|
this,
|
||||||
this@ReaderActivity,
|
this@ReaderActivity,
|
||||||
settings.getBoolean("isSelfSignedCert", false),
|
settings.getBoolean("isSelfSignedCert", false),
|
||||||
sharedPref.getBoolean("should_log_everything", false)
|
sharedPref.getBoolean("should_log_everything", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
currentItem = intent.getIntExtra("currentItem", 0)
|
currentItem = intent.getIntExtra("currentItem", 0)
|
||||||
@ -101,65 +101,65 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
(indicator as CircleIndicator).setViewPager(pager)
|
(indicator as CircleIndicator).setViewPager(pager)
|
||||||
|
|
||||||
pager.addOnPageChangeListener(
|
pager.addOnPageChangeListener(
|
||||||
object : ViewPager.SimpleOnPageChangeListener() {
|
object : ViewPager.SimpleOnPageChangeListener() {
|
||||||
var isLastItem = false
|
var isLastItem = false
|
||||||
|
|
||||||
override fun onPageSelected(position: Int) {
|
override fun onPageSelected(position: Int) {
|
||||||
isLastItem = (position === (allItems.size - 1))
|
isLastItem = (position === (allItems.size - 1))
|
||||||
|
|
||||||
if (allItems[position].starred) {
|
if (allItems[position].starred) {
|
||||||
canRemoveFromFavorite()
|
canRemoveFromFavorite()
|
||||||
} else {
|
} else {
|
||||||
canFavorite()
|
canFavorite()
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onPageScrollStateChanged(state: Int) {
|
|
||||||
if (markOnScroll && (state === ViewPager.SCROLL_STATE_DRAGGING || (state === ViewPager.SCROLL_STATE_IDLE && isLastItem))) {
|
|
||||||
api.markItem(allItems[pager.currentItem].id).enqueue(
|
|
||||||
object : Callback<SuccessResponse> {
|
|
||||||
override fun onResponse(
|
|
||||||
call: Call<SuccessResponse>,
|
|
||||||
response: Response<SuccessResponse>
|
|
||||||
) {
|
|
||||||
if (!response.succeeded() && debugReadingItems) {
|
|
||||||
val message =
|
|
||||||
"message: ${response.message()} " +
|
|
||||||
"response isSuccess: ${response.isSuccessful} " +
|
|
||||||
"response code: ${response.code()} " +
|
|
||||||
"response message: ${response.message()} " +
|
|
||||||
"response errorBody: ${response.errorBody()?.string()} " +
|
|
||||||
"body success: ${response.body()?.success} " +
|
|
||||||
"body isSuccess: ${response.body()?.isSuccess}"
|
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
|
||||||
Crashlytics.log(
|
|
||||||
100,
|
|
||||||
"READ_DEBUG_SUCCESS",
|
|
||||||
message
|
|
||||||
)
|
|
||||||
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(
|
|
||||||
call: Call<SuccessResponse>,
|
|
||||||
t: Throwable
|
|
||||||
) {
|
|
||||||
if (debugReadingItems) {
|
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
|
||||||
Crashlytics.log(
|
|
||||||
100,
|
|
||||||
"READ_DEBUG_ERROR",
|
|
||||||
t.message
|
|
||||||
)
|
|
||||||
Crashlytics.logException(t)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onPageScrollStateChanged(state: Int) {
|
||||||
|
if (markOnScroll && (state === ViewPager.SCROLL_STATE_DRAGGING || (state === ViewPager.SCROLL_STATE_IDLE && isLastItem))) {
|
||||||
|
api.markItem(allItems[pager.currentItem].id).enqueue(
|
||||||
|
object : Callback<SuccessResponse> {
|
||||||
|
override fun onResponse(
|
||||||
|
call: Call<SuccessResponse>,
|
||||||
|
response: Response<SuccessResponse>
|
||||||
|
) {
|
||||||
|
if (!response.succeeded() && debugReadingItems) {
|
||||||
|
val message =
|
||||||
|
"message: ${response.message()} " +
|
||||||
|
"response isSuccess: ${response.isSuccessful} " +
|
||||||
|
"response code: ${response.code()} " +
|
||||||
|
"response message: ${response.message()} " +
|
||||||
|
"response errorBody: ${response.errorBody()?.string()} " +
|
||||||
|
"body success: ${response.body()?.success} " +
|
||||||
|
"body isSuccess: ${response.body()?.isSuccess}"
|
||||||
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"READ_DEBUG_SUCCESS",
|
||||||
|
message
|
||||||
|
)
|
||||||
|
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(
|
||||||
|
call: Call<SuccessResponse>,
|
||||||
|
t: Throwable
|
||||||
|
) {
|
||||||
|
if (debugReadingItems) {
|
||||||
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"READ_DEBUG_ERROR",
|
||||||
|
t.message
|
||||||
|
)
|
||||||
|
Crashlytics.logException(t)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,8 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
oldInstanceState!!.clear()
|
oldInstanceState!!.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class ScreenSlidePagerAdapter(fm: FragmentManager) : FragmentStatePagerAdapter(fm) {
|
private inner class ScreenSlidePagerAdapter(fm: FragmentManager) :
|
||||||
|
FragmentStatePagerAdapter(fm) {
|
||||||
override fun getCount(): Int {
|
override fun getCount(): Int {
|
||||||
return allItems.size
|
return allItems.size
|
||||||
}
|
}
|
||||||
@ -206,48 +207,50 @@ class ReaderActivity : AppCompatActivity() {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.save -> {
|
R.id.save -> {
|
||||||
api.starrItem(allItems[pager.currentItem].id).enqueue(object : Callback<SuccessResponse> {
|
api.starrItem(allItems[pager.currentItem].id)
|
||||||
override fun onResponse(
|
.enqueue(object : Callback<SuccessResponse> {
|
||||||
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar()
|
allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar()
|
||||||
canRemoveFromFavorite()
|
canRemoveFromFavorite()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(
|
override fun onFailure(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
t: Throwable
|
t: Throwable
|
||||||
) {
|
) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
baseContext,
|
baseContext,
|
||||||
R.string.cant_mark_favortie,
|
R.string.cant_mark_favortie,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
R.id.unsave -> {
|
R.id.unsave -> {
|
||||||
api.unstarrItem(allItems[pager.currentItem].id).enqueue(object : Callback<SuccessResponse> {
|
api.unstarrItem(allItems[pager.currentItem].id)
|
||||||
override fun onResponse(
|
.enqueue(object : Callback<SuccessResponse> {
|
||||||
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar()
|
allItems[pager.currentItem] = allItems[pager.currentItem].toggleStar()
|
||||||
canFavorite()
|
canFavorite()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(
|
override fun onFailure(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
t: Throwable
|
t: Throwable
|
||||||
) {
|
) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
baseContext,
|
baseContext,
|
||||||
R.string.cant_unmark_favortie,
|
R.string.cant_unmark_favortie,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item)
|
return super.onOptionsItemSelected(item)
|
||||||
|
@ -39,10 +39,10 @@ class SourcesActivity : AppCompatActivity() {
|
|||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
val api = SelfossApi(
|
val api = SelfossApi(
|
||||||
this,
|
this,
|
||||||
this@SourcesActivity,
|
this@SourcesActivity,
|
||||||
prefs.getBoolean("isSelfSignedCert", false),
|
prefs.getBoolean("isSelfSignedCert", false),
|
||||||
prefs.getBoolean("should_log_everything", false)
|
prefs.getBoolean("should_log_everything", false)
|
||||||
)
|
)
|
||||||
var items: ArrayList<Sources> = ArrayList()
|
var items: ArrayList<Sources> = ArrayList()
|
||||||
|
|
||||||
@ -51,8 +51,8 @@ class SourcesActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
api.sources.enqueue(object : Callback<List<Sources>> {
|
api.sources.enqueue(object : Callback<List<Sources>> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<List<Sources>>,
|
call: Call<List<Sources>>,
|
||||||
response: Response<List<Sources>>
|
response: Response<List<Sources>>
|
||||||
) {
|
) {
|
||||||
if (response.body() != null && response.body()!!.isNotEmpty()) {
|
if (response.body() != null && response.body()!!.isNotEmpty()) {
|
||||||
items = response.body() as ArrayList<Sources>
|
items = response.body() as ArrayList<Sources>
|
||||||
@ -62,18 +62,18 @@ class SourcesActivity : AppCompatActivity() {
|
|||||||
mAdapter.notifyDataSetChanged()
|
mAdapter.notifyDataSetChanged()
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@SourcesActivity,
|
this@SourcesActivity,
|
||||||
R.string.nothing_here,
|
R.string.nothing_here,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<List<Sources>>, t: Throwable) {
|
override fun onFailure(call: Call<List<Sources>>, t: Throwable) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@SourcesActivity,
|
this@SourcesActivity,
|
||||||
R.string.cant_get_sources,
|
R.string.cant_get_sources,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -2,8 +2,6 @@ package apps.amine.bou.readerforselfoss.adapters
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
|
||||||
import android.support.design.widget.Snackbar
|
|
||||||
import android.support.v7.widget.CardView
|
import android.support.v7.widget.CardView
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
@ -11,7 +9,6 @@ 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.TextView
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import apps.amine.bou.readerforselfoss.R
|
import apps.amine.bou.readerforselfoss.R
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.Item
|
import apps.amine.bou.readerforselfoss.api.selfoss.Item
|
||||||
@ -26,12 +23,10 @@ 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
|
||||||
import apps.amine.bou.readerforselfoss.utils.sourceAndDateText
|
import apps.amine.bou.readerforselfoss.utils.sourceAndDateText
|
||||||
import apps.amine.bou.readerforselfoss.utils.succeeded
|
|
||||||
import apps.amine.bou.readerforselfoss.utils.toTextDrawableString
|
import apps.amine.bou.readerforselfoss.utils.toTextDrawableString
|
||||||
import com.amulyakhare.textdrawable.TextDrawable
|
import com.amulyakhare.textdrawable.TextDrawable
|
||||||
import com.amulyakhare.textdrawable.util.ColorGenerator
|
import com.amulyakhare.textdrawable.util.ColorGenerator
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.crashlytics.android.Crashlytics
|
|
||||||
import com.like.LikeButton
|
import com.like.LikeButton
|
||||||
import com.like.OnLikeListener
|
import com.like.OnLikeListener
|
||||||
import kotlinx.android.synthetic.main.card_item.view.*
|
import kotlinx.android.synthetic.main.card_item.view.*
|
||||||
@ -40,20 +35,21 @@ import retrofit2.Callback
|
|||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
|
||||||
class ItemCardAdapter(
|
class ItemCardAdapter(
|
||||||
override val app: Activity,
|
override val app: Activity,
|
||||||
override var items: ArrayList<Item>,
|
override var items: ArrayList<Item>,
|
||||||
override val api: SelfossApi,
|
override val api: SelfossApi,
|
||||||
private val helper: CustomTabActivityHelper,
|
private val helper: CustomTabActivityHelper,
|
||||||
private val internalBrowser: Boolean,
|
private val internalBrowser: Boolean,
|
||||||
private val articleViewer: Boolean,
|
private val articleViewer: Boolean,
|
||||||
private val fullHeightCards: Boolean,
|
private val fullHeightCards: Boolean,
|
||||||
private val appColors: AppColors,
|
private val appColors: AppColors,
|
||||||
override val debugReadingItems: Boolean,
|
override val debugReadingItems: Boolean,
|
||||||
override val userIdentifier: String
|
override val userIdentifier: String
|
||||||
) : ItemsAdapter<ItemCardAdapter.ViewHolder>() {
|
) : ItemsAdapter<ItemCardAdapter.ViewHolder>() {
|
||||||
private val c: Context = app.baseContext
|
private val c: Context = app.baseContext
|
||||||
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
||||||
private val imageMaxHeight: Int = c.resources.getDimension(R.dimen.card_image_max_height).toInt()
|
private val imageMaxHeight: Int =
|
||||||
|
c.resources.getDimension(R.dimen.card_image_max_height).toInt()
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
val v = LayoutInflater.from(c).inflate(R.layout.card_item, parent, false) as CardView
|
val v = LayoutInflater.from(c).inflate(R.layout.card_item, parent, false) as CardView
|
||||||
@ -87,10 +83,10 @@ class ItemCardAdapter(
|
|||||||
val color = generator.getColor(itm.sourcetitle)
|
val color = generator.getColor(itm.sourcetitle)
|
||||||
|
|
||||||
val drawable =
|
val drawable =
|
||||||
TextDrawable
|
TextDrawable
|
||||||
.builder()
|
.builder()
|
||||||
.round()
|
.round()
|
||||||
.build(itm.sourcetitle.toTextDrawableString(), color)
|
.build(itm.sourcetitle.toTextDrawableString(), color)
|
||||||
holder.mView.sourceImage.setImageDrawable(drawable)
|
holder.mView.sourceImage.setImageDrawable(drawable)
|
||||||
} else {
|
} else {
|
||||||
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.sourceImage)
|
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.sourceImage)
|
||||||
@ -117,20 +113,20 @@ class ItemCardAdapter(
|
|||||||
val (id) = items[adapterPosition]
|
val (id) = items[adapterPosition]
|
||||||
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(
|
override fun onFailure(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
t: Throwable
|
t: Throwable
|
||||||
) {
|
) {
|
||||||
mView.favButton.isLiked = false
|
mView.favButton.isLiked = false
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
c,
|
c,
|
||||||
R.string.cant_mark_favortie,
|
R.string.cant_mark_favortie,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -140,20 +136,20 @@ class ItemCardAdapter(
|
|||||||
val (id) = items[adapterPosition]
|
val (id) = items[adapterPosition]
|
||||||
api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> {
|
api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(
|
override fun onFailure(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
t: Throwable
|
t: Throwable
|
||||||
) {
|
) {
|
||||||
mView.favButton.isLiked = true
|
mView.favButton.isLiked = true
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
c,
|
c,
|
||||||
R.string.cant_unmark_favortie,
|
R.string.cant_unmark_favortie,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -175,13 +171,13 @@ class ItemCardAdapter(
|
|||||||
|
|
||||||
mView.setOnClickListener {
|
mView.setOnClickListener {
|
||||||
c.openItemUrl(
|
c.openItemUrl(
|
||||||
items,
|
items,
|
||||||
adapterPosition,
|
adapterPosition,
|
||||||
items[adapterPosition].getLinkDecoded(),
|
items[adapterPosition].getLinkDecoded(),
|
||||||
customTabsIntent,
|
customTabsIntent,
|
||||||
internalBrowser,
|
internalBrowser,
|
||||||
articleViewer,
|
articleViewer,
|
||||||
app
|
app
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,13 @@ package apps.amine.bou.readerforselfoss.adapters
|
|||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
|
||||||
import android.support.constraint.ConstraintLayout
|
import android.support.constraint.ConstraintLayout
|
||||||
import android.support.design.widget.Snackbar
|
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
import android.text.Html
|
import android.text.Html
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import apps.amine.bou.readerforselfoss.R
|
import apps.amine.bou.readerforselfoss.R
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.Item
|
import apps.amine.bou.readerforselfoss.api.selfoss.Item
|
||||||
@ -25,11 +22,9 @@ 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
|
||||||
import apps.amine.bou.readerforselfoss.utils.sourceAndDateText
|
import apps.amine.bou.readerforselfoss.utils.sourceAndDateText
|
||||||
import apps.amine.bou.readerforselfoss.utils.succeeded
|
|
||||||
import apps.amine.bou.readerforselfoss.utils.toTextDrawableString
|
import apps.amine.bou.readerforselfoss.utils.toTextDrawableString
|
||||||
import com.amulyakhare.textdrawable.TextDrawable
|
import com.amulyakhare.textdrawable.TextDrawable
|
||||||
import com.amulyakhare.textdrawable.util.ColorGenerator
|
import com.amulyakhare.textdrawable.util.ColorGenerator
|
||||||
import com.crashlytics.android.Crashlytics
|
|
||||||
import com.like.LikeButton
|
import com.like.LikeButton
|
||||||
import com.like.OnLikeListener
|
import com.like.OnLikeListener
|
||||||
import kotlinx.android.synthetic.main.list_item.view.*
|
import kotlinx.android.synthetic.main.list_item.view.*
|
||||||
@ -40,15 +35,15 @@ import java.util.*
|
|||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
|
||||||
class ItemListAdapter(
|
class ItemListAdapter(
|
||||||
override val app: Activity,
|
override val app: Activity,
|
||||||
override var items: ArrayList<Item>,
|
override var items: ArrayList<Item>,
|
||||||
override val api: SelfossApi,
|
override val api: SelfossApi,
|
||||||
private val helper: CustomTabActivityHelper,
|
private val helper: CustomTabActivityHelper,
|
||||||
private val clickBehavior: Boolean,
|
private val clickBehavior: Boolean,
|
||||||
private val internalBrowser: Boolean,
|
private val internalBrowser: Boolean,
|
||||||
private val articleViewer: Boolean,
|
private val articleViewer: Boolean,
|
||||||
override val debugReadingItems: Boolean,
|
override val debugReadingItems: Boolean,
|
||||||
override val userIdentifier: String
|
override val userIdentifier: String
|
||||||
) : ItemsAdapter<ItemListAdapter.ViewHolder>() {
|
) : ItemsAdapter<ItemListAdapter.ViewHolder>() {
|
||||||
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
||||||
private val c: Context = app.baseContext
|
private val c: Context = app.baseContext
|
||||||
@ -56,9 +51,9 @@ class ItemListAdapter(
|
|||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
val v = LayoutInflater.from(c).inflate(
|
val v = LayoutInflater.from(c).inflate(
|
||||||
R.layout.list_item,
|
R.layout.list_item,
|
||||||
parent,
|
parent,
|
||||||
false
|
false
|
||||||
) as ConstraintLayout
|
) as ConstraintLayout
|
||||||
return ViewHolder(v)
|
return ViewHolder(v)
|
||||||
}
|
}
|
||||||
@ -74,13 +69,13 @@ class ItemListAdapter(
|
|||||||
if (itm.getThumbnail(c).isEmpty()) {
|
if (itm.getThumbnail(c).isEmpty()) {
|
||||||
val sizeInInt = 46
|
val sizeInInt = 46
|
||||||
val sizeInDp = TypedValue.applyDimension(
|
val sizeInDp = TypedValue.applyDimension(
|
||||||
TypedValue.COMPLEX_UNIT_DIP, sizeInInt.toFloat(), c.resources
|
TypedValue.COMPLEX_UNIT_DIP, sizeInInt.toFloat(), c.resources
|
||||||
.displayMetrics
|
.displayMetrics
|
||||||
).toInt()
|
).toInt()
|
||||||
|
|
||||||
val marginInInt = 16
|
val marginInInt = 16
|
||||||
val marginInDp = TypedValue.applyDimension(
|
val marginInDp = TypedValue.applyDimension(
|
||||||
TypedValue.COMPLEX_UNIT_DIP, marginInInt.toFloat(), c.resources
|
TypedValue.COMPLEX_UNIT_DIP, marginInInt.toFloat(), c.resources
|
||||||
.displayMetrics
|
.displayMetrics
|
||||||
).toInt()
|
).toInt()
|
||||||
|
|
||||||
@ -94,10 +89,10 @@ class ItemListAdapter(
|
|||||||
val color = generator.getColor(itm.sourcetitle)
|
val color = generator.getColor(itm.sourcetitle)
|
||||||
|
|
||||||
val drawable =
|
val drawable =
|
||||||
TextDrawable
|
TextDrawable
|
||||||
.builder()
|
.builder()
|
||||||
.round()
|
.round()
|
||||||
.build(itm.sourcetitle.toTextDrawableString(), color)
|
.build(itm.sourcetitle.toTextDrawableString(), color)
|
||||||
|
|
||||||
holder.mView.itemImage.setImageDrawable(drawable)
|
holder.mView.itemImage.setImageDrawable(drawable)
|
||||||
} else {
|
} else {
|
||||||
@ -123,8 +118,6 @@ class ItemListAdapter(
|
|||||||
|
|
||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
|
inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -139,20 +132,20 @@ class ItemListAdapter(
|
|||||||
val (id) = items[adapterPosition]
|
val (id) = items[adapterPosition]
|
||||||
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(
|
override fun onFailure(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
t: Throwable
|
t: Throwable
|
||||||
) {
|
) {
|
||||||
mView.favButton.isLiked = false
|
mView.favButton.isLiked = false
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
c,
|
c,
|
||||||
R.string.cant_mark_favortie,
|
R.string.cant_mark_favortie,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -162,20 +155,20 @@ class ItemListAdapter(
|
|||||||
val (id) = items[adapterPosition]
|
val (id) = items[adapterPosition]
|
||||||
api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> {
|
api.unstarrItem(id).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(
|
override fun onFailure(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
t: Throwable
|
t: Throwable
|
||||||
) {
|
) {
|
||||||
mView.favButton.isLiked = true
|
mView.favButton.isLiked = true
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
c,
|
c,
|
||||||
R.string.cant_unmark_favortie,
|
R.string.cant_unmark_favortie,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -200,13 +193,13 @@ class ItemListAdapter(
|
|||||||
if (!clickBehavior) {
|
if (!clickBehavior) {
|
||||||
mView.setOnClickListener {
|
mView.setOnClickListener {
|
||||||
c.openItemUrl(
|
c.openItemUrl(
|
||||||
items,
|
items,
|
||||||
adapterPosition,
|
adapterPosition,
|
||||||
items[adapterPosition].getLinkDecoded(),
|
items[adapterPosition].getLinkDecoded(),
|
||||||
customTabsIntent,
|
customTabsIntent,
|
||||||
internalBrowser,
|
internalBrowser,
|
||||||
articleViewer,
|
articleViewer,
|
||||||
app
|
app
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
mView.setOnLongClickListener {
|
mView.setOnLongClickListener {
|
||||||
@ -217,13 +210,13 @@ class ItemListAdapter(
|
|||||||
mView.setOnClickListener { actionBarShowHide() }
|
mView.setOnClickListener { actionBarShowHide() }
|
||||||
mView.setOnLongClickListener {
|
mView.setOnLongClickListener {
|
||||||
c.openItemUrl(
|
c.openItemUrl(
|
||||||
items,
|
items,
|
||||||
adapterPosition,
|
adapterPosition,
|
||||||
items[adapterPosition].getLinkDecoded(),
|
items[adapterPosition].getLinkDecoded(),
|
||||||
customTabsIntent,
|
customTabsIntent,
|
||||||
internalBrowser,
|
internalBrowser,
|
||||||
articleViewer,
|
articleViewer,
|
||||||
app
|
app
|
||||||
)
|
)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -239,6 +232,4 @@ class ItemListAdapter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -30,29 +30,29 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
|||||||
|
|
||||||
private fun doUnmark(i: Item, position: Int) {
|
private fun doUnmark(i: Item, position: Int) {
|
||||||
val s = Snackbar
|
val s = Snackbar
|
||||||
.make(
|
.make(
|
||||||
app.findViewById(R.id.coordLayout),
|
app.findViewById(R.id.coordLayout),
|
||||||
R.string.marked_as_read,
|
R.string.marked_as_read,
|
||||||
Snackbar.LENGTH_LONG
|
Snackbar.LENGTH_LONG
|
||||||
)
|
)
|
||||||
.setAction(R.string.undo_string) {
|
.setAction(R.string.undo_string) {
|
||||||
items.add(position, i)
|
items.add(position, i)
|
||||||
notifyItemInserted(position)
|
notifyItemInserted(position)
|
||||||
|
|
||||||
api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
api.unmarkItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
items.remove(i)
|
items.remove(i)
|
||||||
notifyItemRemoved(position)
|
notifyItemRemoved(position)
|
||||||
doUnmark(i, position)
|
doUnmark(i, position)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
val view = s.view
|
val view = s.view
|
||||||
val tv: TextView = view.findViewById(android.support.design.R.id.snackbar_text)
|
val tv: TextView = view.findViewById(android.support.design.R.id.snackbar_text)
|
||||||
@ -69,18 +69,18 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
|||||||
|
|
||||||
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
if (!response.succeeded() && debugReadingItems) {
|
if (!response.succeeded() && debugReadingItems) {
|
||||||
val message =
|
val message =
|
||||||
"message: ${response.message()} " +
|
"message: ${response.message()} " +
|
||||||
"response isSuccess: ${response.isSuccessful} " +
|
"response isSuccess: ${response.isSuccessful} " +
|
||||||
"response code: ${response.code()} " +
|
"response code: ${response.code()} " +
|
||||||
"response message: ${response.message()} " +
|
"response message: ${response.message()} " +
|
||||||
"response errorBody: ${response.errorBody()?.string()} " +
|
"response errorBody: ${response.errorBody()?.string()} " +
|
||||||
"body success: ${response.body()?.success} " +
|
"body success: ${response.body()?.success} " +
|
||||||
"body isSuccess: ${response.body()?.isSuccess}"
|
"body isSuccess: ${response.body()?.isSuccess}"
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
||||||
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
||||||
@ -98,9 +98,9 @@ abstract class ItemsAdapter<VH : RecyclerView.ViewHolder?> : RecyclerView.Adapte
|
|||||||
Toast.makeText(app.baseContext, t.message, Toast.LENGTH_LONG).show()
|
Toast.makeText(app.baseContext, t.message, Toast.LENGTH_LONG).show()
|
||||||
}
|
}
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
app,
|
app,
|
||||||
app.getString(R.string.cant_mark_read),
|
app.getString(R.string.cant_mark_read),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
items.add(i)
|
items.add(i)
|
||||||
notifyItemInserted(position)
|
notifyItemInserted(position)
|
||||||
|
@ -22,18 +22,18 @@ import retrofit2.Callback
|
|||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
|
||||||
class SourcesListAdapter(
|
class SourcesListAdapter(
|
||||||
private val app: Activity,
|
private val app: Activity,
|
||||||
private val items: ArrayList<Sources>,
|
private val items: ArrayList<Sources>,
|
||||||
private val api: SelfossApi
|
private val api: SelfossApi
|
||||||
) : RecyclerView.Adapter<SourcesListAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<SourcesListAdapter.ViewHolder>() {
|
||||||
private val c: Context = app.baseContext
|
private val c: Context = app.baseContext
|
||||||
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
private val generator: ColorGenerator = ColorGenerator.MATERIAL
|
||||||
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||||
val v = LayoutInflater.from(c).inflate(
|
val v = LayoutInflater.from(c).inflate(
|
||||||
R.layout.source_list_item,
|
R.layout.source_list_item,
|
||||||
parent,
|
parent,
|
||||||
false
|
false
|
||||||
) as ConstraintLayout
|
) as ConstraintLayout
|
||||||
return ViewHolder(v)
|
return ViewHolder(v)
|
||||||
}
|
}
|
||||||
@ -45,10 +45,10 @@ class SourcesListAdapter(
|
|||||||
val color = generator.getColor(itm.title)
|
val color = generator.getColor(itm.title)
|
||||||
|
|
||||||
val drawable =
|
val drawable =
|
||||||
TextDrawable
|
TextDrawable
|
||||||
.builder()
|
.builder()
|
||||||
.round()
|
.round()
|
||||||
.build(itm.title.toTextDrawableString(), color)
|
.build(itm.title.toTextDrawableString(), color)
|
||||||
holder.mView.itemImage.setImageDrawable(drawable)
|
holder.mView.itemImage.setImageDrawable(drawable)
|
||||||
} else {
|
} else {
|
||||||
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.itemImage)
|
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.itemImage)
|
||||||
@ -73,8 +73,8 @@ class SourcesListAdapter(
|
|||||||
val (id) = items[adapterPosition]
|
val (id) = items[adapterPosition]
|
||||||
api.deleteSource(id).enqueue(object : Callback<SuccessResponse> {
|
api.deleteSource(id).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<SuccessResponse>,
|
call: Call<SuccessResponse>,
|
||||||
response: Response<SuccessResponse>
|
response: Response<SuccessResponse>
|
||||||
) {
|
) {
|
||||||
if (response.body() != null && response.body()!!.isSuccess) {
|
if (response.body() != null && response.body()!!.isSuccess) {
|
||||||
items.removeAt(adapterPosition)
|
items.removeAt(adapterPosition)
|
||||||
@ -82,18 +82,18 @@ class SourcesListAdapter(
|
|||||||
notifyItemRangeChanged(adapterPosition, itemCount)
|
notifyItemRangeChanged(adapterPosition, itemCount)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
app,
|
app,
|
||||||
R.string.can_delete_source,
|
R.string.can_delete_source,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
app,
|
app,
|
||||||
R.string.can_delete_source,
|
R.string.can_delete_source,
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -21,15 +21,15 @@ class MercuryApi(private val key: String, shouldLog: Boolean) {
|
|||||||
val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
|
val client = OkHttpClient.Builder().addInterceptor(interceptor).build()
|
||||||
|
|
||||||
val gson = GsonBuilder()
|
val gson = GsonBuilder()
|
||||||
.setLenient()
|
.setLenient()
|
||||||
.create()
|
.create()
|
||||||
val retrofit =
|
val retrofit =
|
||||||
Retrofit
|
Retrofit
|
||||||
.Builder()
|
.Builder()
|
||||||
.baseUrl("https://mercury.postlight.com")
|
.baseUrl("https://mercury.postlight.com")
|
||||||
.client(client)
|
.client(client)
|
||||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||||
.build()
|
.build()
|
||||||
service = retrofit.create(MercuryService::class.java)
|
service = retrofit.create(MercuryService::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,39 +5,40 @@ import android.os.Parcelable
|
|||||||
import com.google.gson.annotations.SerializedName
|
import com.google.gson.annotations.SerializedName
|
||||||
|
|
||||||
class ParsedContent(
|
class ParsedContent(
|
||||||
@SerializedName("title") val title: String,
|
@SerializedName("title") val title: String,
|
||||||
@SerializedName("content") val content: String?,
|
@SerializedName("content") val content: String?,
|
||||||
@SerializedName("date_published") val date_published: String,
|
@SerializedName("date_published") val date_published: String,
|
||||||
@SerializedName("lead_image_url") val lead_image_url: String?,
|
@SerializedName("lead_image_url") val lead_image_url: String?,
|
||||||
@SerializedName("dek") val dek: String,
|
@SerializedName("dek") val dek: String,
|
||||||
@SerializedName("url") val url: String,
|
@SerializedName("url") val url: String,
|
||||||
@SerializedName("domain") val domain: String,
|
@SerializedName("domain") val domain: String,
|
||||||
@SerializedName("excerpt") val excerpt: String,
|
@SerializedName("excerpt") val excerpt: String,
|
||||||
@SerializedName("total_pages") val total_pages: Int,
|
@SerializedName("total_pages") val total_pages: Int,
|
||||||
@SerializedName("rendered_pages") val rendered_pages: Int,
|
@SerializedName("rendered_pages") val rendered_pages: Int,
|
||||||
@SerializedName("next_page_url") val next_page_url: String
|
@SerializedName("next_page_url") val next_page_url: String
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmField
|
@JvmField
|
||||||
val CREATOR: Parcelable.Creator<ParsedContent> = object : Parcelable.Creator<ParsedContent> {
|
val CREATOR: Parcelable.Creator<ParsedContent> =
|
||||||
override fun createFromParcel(source: Parcel): ParsedContent = ParsedContent(source)
|
object : Parcelable.Creator<ParsedContent> {
|
||||||
override fun newArray(size: Int): Array<ParsedContent?> = arrayOfNulls(size)
|
override fun createFromParcel(source: Parcel): ParsedContent = ParsedContent(source)
|
||||||
}
|
override fun newArray(size: Int): Array<ParsedContent?> = arrayOfNulls(size)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(source: Parcel) : this(
|
constructor(source: Parcel) : this(
|
||||||
title = source.readString(),
|
title = source.readString(),
|
||||||
content = source.readString(),
|
content = source.readString(),
|
||||||
date_published = source.readString(),
|
date_published = source.readString(),
|
||||||
lead_image_url = source.readString(),
|
lead_image_url = source.readString(),
|
||||||
dek = source.readString(),
|
dek = source.readString(),
|
||||||
url = source.readString(),
|
url = source.readString(),
|
||||||
domain = source.readString(),
|
domain = source.readString(),
|
||||||
excerpt = source.readString(),
|
excerpt = source.readString(),
|
||||||
total_pages = source.readInt(),
|
total_pages = source.readInt(),
|
||||||
rendered_pages = source.readInt(),
|
rendered_pages = source.readInt(),
|
||||||
next_page_url = source.readString()
|
next_page_url = source.readString()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun describeContents() = 0
|
override fun describeContents() = 0
|
||||||
|
@ -10,13 +10,13 @@ internal class BooleanTypeAdapter : JsonDeserializer<Boolean> {
|
|||||||
|
|
||||||
@Throws(JsonParseException::class)
|
@Throws(JsonParseException::class)
|
||||||
override fun deserialize(
|
override fun deserialize(
|
||||||
json: JsonElement,
|
json: JsonElement,
|
||||||
typeOfT: Type,
|
typeOfT: Type,
|
||||||
context: JsonDeserializationContext
|
context: JsonDeserializationContext
|
||||||
): Boolean? =
|
): Boolean? =
|
||||||
try {
|
try {
|
||||||
json.asInt == 1
|
json.asInt == 1
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
json.asBoolean
|
json.asBoolean
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,10 +20,10 @@ import retrofit2.converter.gson.GsonConverterFactory
|
|||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
|
||||||
class SelfossApi(
|
class SelfossApi(
|
||||||
c: Context,
|
c: Context,
|
||||||
callingActivity: Activity,
|
callingActivity: Activity,
|
||||||
isWithSelfSignedCert: Boolean,
|
isWithSelfSignedCert: Boolean,
|
||||||
shouldLog: Boolean
|
shouldLog: Boolean
|
||||||
) {
|
) {
|
||||||
|
|
||||||
private lateinit var service: SelfossService
|
private lateinit var service: SelfossService
|
||||||
@ -32,25 +32,25 @@ class SelfossApi(
|
|||||||
private val password: String
|
private val password: String
|
||||||
|
|
||||||
fun OkHttpClient.Builder.maybeWithSelfSigned(isWithSelfSignedCert: Boolean): OkHttpClient.Builder =
|
fun OkHttpClient.Builder.maybeWithSelfSigned(isWithSelfSignedCert: Boolean): OkHttpClient.Builder =
|
||||||
if (isWithSelfSignedCert) {
|
if (isWithSelfSignedCert) {
|
||||||
getUnsafeHttpClient()
|
getUnsafeHttpClient()
|
||||||
} else {
|
} else {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Credentials.createAuthenticator(): DispatchingAuthenticator =
|
fun Credentials.createAuthenticator(): DispatchingAuthenticator =
|
||||||
DispatchingAuthenticator.Builder()
|
DispatchingAuthenticator.Builder()
|
||||||
.with("digest", DigestAuthenticator(this))
|
.with("digest", DigestAuthenticator(this))
|
||||||
.with("basic", BasicAuthenticator(this))
|
.with("basic", BasicAuthenticator(this))
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
fun DispatchingAuthenticator.getHttpClien(isWithSelfSignedCert: Boolean): OkHttpClient.Builder {
|
fun DispatchingAuthenticator.getHttpClien(isWithSelfSignedCert: Boolean): OkHttpClient.Builder {
|
||||||
val authCache = ConcurrentHashMap<String, CachingAuthenticator>()
|
val authCache = ConcurrentHashMap<String, CachingAuthenticator>()
|
||||||
return OkHttpClient
|
return OkHttpClient
|
||||||
.Builder()
|
.Builder()
|
||||||
.maybeWithSelfSigned(isWithSelfSignedCert)
|
.maybeWithSelfSigned(isWithSelfSignedCert)
|
||||||
.authenticator(CachingAuthenticatorDecorator(this, authCache))
|
.authenticator(CachingAuthenticatorDecorator(this, authCache))
|
||||||
.addInterceptor(AuthenticationCacheInterceptor(authCache))
|
.addInterceptor(AuthenticationCacheInterceptor(authCache))
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -58,16 +58,16 @@ class SelfossApi(
|
|||||||
password = config.userPassword
|
password = config.userPassword
|
||||||
|
|
||||||
val authenticator =
|
val authenticator =
|
||||||
Credentials(
|
Credentials(
|
||||||
config.httpUserLogin,
|
config.httpUserLogin,
|
||||||
config.httpUserPassword
|
config.httpUserPassword
|
||||||
).createAuthenticator()
|
).createAuthenticator()
|
||||||
|
|
||||||
val gson =
|
val gson =
|
||||||
GsonBuilder()
|
GsonBuilder()
|
||||||
.registerTypeAdapter(Boolean::class.javaPrimitiveType, BooleanTypeAdapter())
|
.registerTypeAdapter(Boolean::class.javaPrimitiveType, BooleanTypeAdapter())
|
||||||
.setLenient()
|
.setLenient()
|
||||||
.create()
|
.create()
|
||||||
|
|
||||||
val logging = HttpLoggingInterceptor()
|
val logging = HttpLoggingInterceptor()
|
||||||
|
|
||||||
@ -83,12 +83,12 @@ class SelfossApi(
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
val retrofit =
|
val retrofit =
|
||||||
Retrofit
|
Retrofit
|
||||||
.Builder()
|
.Builder()
|
||||||
.baseUrl(config.baseUrl)
|
.baseUrl(config.baseUrl)
|
||||||
.client(httpClient.build())
|
.client(httpClient.build())
|
||||||
.addConverterFactory(GsonConverterFactory.create(gson))
|
.addConverterFactory(GsonConverterFactory.create(gson))
|
||||||
.build()
|
.build()
|
||||||
service = retrofit.create(SelfossService::class.java)
|
service = retrofit.create(SelfossService::class.java)
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
Config.logoutAndRedirect(c, callingActivity, config.settings.edit(), baseUrlFail = true)
|
Config.logoutAndRedirect(c, callingActivity, config.settings.edit(), baseUrlFail = true)
|
||||||
@ -96,59 +96,59 @@ class SelfossApi(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun login(): Call<SuccessResponse> =
|
fun login(): Call<SuccessResponse> =
|
||||||
service.loginToSelfoss(config.userLogin, config.userPassword)
|
service.loginToSelfoss(config.userLogin, config.userPassword)
|
||||||
|
|
||||||
fun readItems(
|
fun readItems(
|
||||||
tag: String?,
|
tag: String?,
|
||||||
sourceId: Long?,
|
sourceId: Long?,
|
||||||
search: String?,
|
search: String?,
|
||||||
itemsNumber: Int,
|
itemsNumber: Int,
|
||||||
offset: Int
|
offset: Int
|
||||||
): Call<List<Item>> =
|
): Call<List<Item>> =
|
||||||
getItems("read", tag, sourceId, search, itemsNumber, offset)
|
getItems("read", tag, sourceId, search, itemsNumber, offset)
|
||||||
|
|
||||||
fun newItems(
|
fun newItems(
|
||||||
tag: String?,
|
tag: String?,
|
||||||
sourceId: Long?,
|
sourceId: Long?,
|
||||||
search: String?,
|
search: String?,
|
||||||
itemsNumber: Int,
|
itemsNumber: Int,
|
||||||
offset: Int
|
offset: Int
|
||||||
): Call<List<Item>> =
|
): Call<List<Item>> =
|
||||||
getItems("unread", tag, sourceId, search, itemsNumber, offset)
|
getItems("unread", tag, sourceId, search, itemsNumber, offset)
|
||||||
|
|
||||||
fun starredItems(
|
fun starredItems(
|
||||||
tag: String?,
|
tag: String?,
|
||||||
sourceId: Long?,
|
sourceId: Long?,
|
||||||
search: String?,
|
search: String?,
|
||||||
itemsNumber: Int,
|
itemsNumber: Int,
|
||||||
offset: Int
|
offset: Int
|
||||||
): Call<List<Item>> =
|
): Call<List<Item>> =
|
||||||
getItems("starred", tag, sourceId, search, itemsNumber, offset)
|
getItems("starred", tag, sourceId, search, itemsNumber, offset)
|
||||||
|
|
||||||
private fun getItems(
|
private fun getItems(
|
||||||
type: String,
|
type: String,
|
||||||
tag: String?,
|
tag: String?,
|
||||||
sourceId: Long?,
|
sourceId: Long?,
|
||||||
search: String?,
|
search: String?,
|
||||||
items: Int,
|
items: Int,
|
||||||
offset: Int
|
offset: Int
|
||||||
): Call<List<Item>> =
|
): Call<List<Item>> =
|
||||||
service.getItems(type, tag, sourceId, search, userName, password, items, offset)
|
service.getItems(type, tag, sourceId, search, userName, password, items, offset)
|
||||||
|
|
||||||
fun markItem(itemId: String): Call<SuccessResponse> =
|
fun markItem(itemId: String): Call<SuccessResponse> =
|
||||||
service.markAsRead(itemId, userName, password)
|
service.markAsRead(itemId, userName, password)
|
||||||
|
|
||||||
fun unmarkItem(itemId: String): Call<SuccessResponse> =
|
fun unmarkItem(itemId: String): Call<SuccessResponse> =
|
||||||
service.unmarkAsRead(itemId, userName, password)
|
service.unmarkAsRead(itemId, userName, password)
|
||||||
|
|
||||||
fun readAll(ids: List<String>): Call<SuccessResponse> =
|
fun readAll(ids: List<String>): Call<SuccessResponse> =
|
||||||
service.markAllAsRead(ids, userName, password)
|
service.markAllAsRead(ids, userName, password)
|
||||||
|
|
||||||
fun starrItem(itemId: String): Call<SuccessResponse> =
|
fun starrItem(itemId: String): Call<SuccessResponse> =
|
||||||
service.starr(itemId, userName, password)
|
service.starr(itemId, userName, password)
|
||||||
|
|
||||||
fun unstarrItem(itemId: String): Call<SuccessResponse> =
|
fun unstarrItem(itemId: String): Call<SuccessResponse> =
|
||||||
service.unstarr(itemId, userName, password)
|
service.unstarr(itemId, userName, password)
|
||||||
|
|
||||||
val stats: Call<Stats>
|
val stats: Call<Stats>
|
||||||
get() = service.stats(userName, password)
|
get() = service.stats(userName, password)
|
||||||
@ -157,23 +157,23 @@ class SelfossApi(
|
|||||||
get() = service.tags(userName, password)
|
get() = service.tags(userName, password)
|
||||||
|
|
||||||
fun update(): Call<String> =
|
fun update(): Call<String> =
|
||||||
service.update(userName, password)
|
service.update(userName, password)
|
||||||
|
|
||||||
val sources: Call<List<Sources>>
|
val sources: Call<List<Sources>>
|
||||||
get() = service.sources(userName, password)
|
get() = service.sources(userName, password)
|
||||||
|
|
||||||
fun deleteSource(id: String): Call<SuccessResponse> =
|
fun deleteSource(id: String): Call<SuccessResponse> =
|
||||||
service.deleteSource(id, userName, password)
|
service.deleteSource(id, userName, password)
|
||||||
|
|
||||||
fun spouts(): Call<Map<String, Spout>> =
|
fun spouts(): Call<Map<String, Spout>> =
|
||||||
service.spouts(userName, password)
|
service.spouts(userName, password)
|
||||||
|
|
||||||
fun createSource(
|
fun createSource(
|
||||||
title: String,
|
title: String,
|
||||||
url: String,
|
url: String,
|
||||||
spout: String,
|
spout: String,
|
||||||
tags: String,
|
tags: String,
|
||||||
filter: String
|
filter: String
|
||||||
): Call<SuccessResponse> =
|
): Call<SuccessResponse> =
|
||||||
service.createSource(title, url, spout, tags, filter, userName, password)
|
service.createSource(title, url, spout, tags, filter, userName, password)
|
||||||
}
|
}
|
||||||
|
@ -21,9 +21,9 @@ private fun constructUrl(config: Config?, path: String, file: String): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class Tag(
|
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
|
||||||
)
|
)
|
||||||
|
|
||||||
class SuccessResponse(@SerializedName("success") val success: Boolean) {
|
class SuccessResponse(@SerializedName("success") val success: Boolean) {
|
||||||
@ -32,23 +32,23 @@ class SuccessResponse(@SerializedName("success") val success: Boolean) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class Stats(
|
class Stats(
|
||||||
@SerializedName("total") val total: Int,
|
@SerializedName("total") val total: Int,
|
||||||
@SerializedName("unread") val unread: Int,
|
@SerializedName("unread") val unread: Int,
|
||||||
@SerializedName("starred") val starred: Int
|
@SerializedName("starred") val starred: Int
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Spout(
|
data class Spout(
|
||||||
@SerializedName("name") val name: String,
|
@SerializedName("name") val name: String,
|
||||||
@SerializedName("description") val description: String
|
@SerializedName("description") val description: String
|
||||||
)
|
)
|
||||||
|
|
||||||
data class Sources(
|
data class Sources(
|
||||||
@SerializedName("id") val id: String,
|
@SerializedName("id") val id: String,
|
||||||
@SerializedName("title") val title: String,
|
@SerializedName("title") val title: String,
|
||||||
@SerializedName("tags") val tags: String,
|
@SerializedName("tags") val tags: String,
|
||||||
@SerializedName("spout") val spout: String,
|
@SerializedName("spout") val spout: String,
|
||||||
@SerializedName("error") val error: String,
|
@SerializedName("error") val error: String,
|
||||||
@SerializedName("icon") val icon: String
|
@SerializedName("icon") val icon: String
|
||||||
) {
|
) {
|
||||||
var config: Config? = null
|
var config: Config? = null
|
||||||
|
|
||||||
@ -61,16 +61,16 @@ data class Sources(
|
|||||||
}
|
}
|
||||||
|
|
||||||
data class Item(
|
data class Item(
|
||||||
@SerializedName("id") val id: String,
|
@SerializedName("id") val id: String,
|
||||||
@SerializedName("datetime") val datetime: String,
|
@SerializedName("datetime") val datetime: String,
|
||||||
@SerializedName("title") val title: String,
|
@SerializedName("title") val title: String,
|
||||||
@SerializedName("content") val content: String,
|
@SerializedName("content") val content: String,
|
||||||
@SerializedName("unread") val unread: Boolean,
|
@SerializedName("unread") val unread: Boolean,
|
||||||
@SerializedName("starred") var starred: Boolean,
|
@SerializedName("starred") var starred: Boolean,
|
||||||
@SerializedName("thumbnail") val thumbnail: String,
|
@SerializedName("thumbnail") val thumbnail: String,
|
||||||
@SerializedName("icon") val icon: String,
|
@SerializedName("icon") val icon: String,
|
||||||
@SerializedName("link") val link: String,
|
@SerializedName("link") val link: String,
|
||||||
@SerializedName("sourcetitle") val sourcetitle: String
|
@SerializedName("sourcetitle") val sourcetitle: String
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
|
|
||||||
var config: Config? = null
|
var config: Config? = null
|
||||||
@ -83,16 +83,16 @@ data class Item(
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(source: Parcel) : this(
|
constructor(source: Parcel) : this(
|
||||||
id = source.readString(),
|
id = source.readString(),
|
||||||
datetime = source.readString(),
|
datetime = source.readString(),
|
||||||
title = source.readString(),
|
title = source.readString(),
|
||||||
content = source.readString(),
|
content = source.readString(),
|
||||||
unread = 0.toByte() != source.readByte(),
|
unread = 0.toByte() != source.readByte(),
|
||||||
starred = 0.toByte() != source.readByte(),
|
starred = 0.toByte() != source.readByte(),
|
||||||
thumbnail = source.readString(),
|
thumbnail = source.readString(),
|
||||||
icon = source.readString(),
|
icon = source.readString(),
|
||||||
link = source.readString(),
|
link = source.readString(),
|
||||||
sourcetitle = source.readString()
|
sourcetitle = source.readString()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun describeContents() = 0
|
override fun describeContents() = 0
|
||||||
@ -127,15 +127,16 @@ data class Item(
|
|||||||
// TODO: maybe find a better way to handle these kind of urls
|
// TODO: maybe find a better way to handle these kind of urls
|
||||||
fun getLinkDecoded(): String {
|
fun getLinkDecoded(): String {
|
||||||
var stringUrl: String
|
var stringUrl: String
|
||||||
stringUrl = if (link.startsWith("http://news.google.com/news/") || link.startsWith("https://news.google.com/news/")) {
|
stringUrl =
|
||||||
if (link.contains("&url=")) {
|
if (link.startsWith("http://news.google.com/news/") || link.startsWith("https://news.google.com/news/")) {
|
||||||
link.substringAfter("&url=")
|
if (link.contains("&url=")) {
|
||||||
} else {
|
link.substringAfter("&url=")
|
||||||
this.link.replace("&", "&")
|
} else {
|
||||||
}
|
this.link.replace("&", "&")
|
||||||
} else {
|
}
|
||||||
this.link.replace("&", "&")
|
} else {
|
||||||
}
|
this.link.replace("&", "&")
|
||||||
|
}
|
||||||
|
|
||||||
// handle :443 => https
|
// handle :443 => https
|
||||||
if (stringUrl.contains(":443")) {
|
if (stringUrl.contains(":443")) {
|
||||||
|
@ -17,102 +17,102 @@ internal interface SelfossService {
|
|||||||
|
|
||||||
@GET("items")
|
@GET("items")
|
||||||
fun getItems(
|
fun getItems(
|
||||||
@Query("type") type: String,
|
@Query("type") type: String,
|
||||||
@Query("tag") tag: String?,
|
@Query("tag") tag: String?,
|
||||||
@Query("source") source: Long?,
|
@Query("source") source: Long?,
|
||||||
@Query("search") search: String?,
|
@Query("search") search: String?,
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String,
|
@Query("password") password: String,
|
||||||
@Query("items") items: Int,
|
@Query("items") items: Int,
|
||||||
@Query("offset") offset: Int
|
@Query("offset") offset: Int
|
||||||
): Call<List<Item>>
|
): Call<List<Item>>
|
||||||
|
|
||||||
@Headers("Content-Type: application/x-www-form-urlencoded")
|
@Headers("Content-Type: application/x-www-form-urlencoded")
|
||||||
@POST("mark/{id}")
|
@POST("mark/{id}")
|
||||||
fun markAsRead(
|
fun markAsRead(
|
||||||
@Path("id") id: String,
|
@Path("id") id: String,
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<SuccessResponse>
|
): Call<SuccessResponse>
|
||||||
|
|
||||||
@Headers("Content-Type: application/x-www-form-urlencoded")
|
@Headers("Content-Type: application/x-www-form-urlencoded")
|
||||||
@POST("unmark/{id}")
|
@POST("unmark/{id}")
|
||||||
fun unmarkAsRead(
|
fun unmarkAsRead(
|
||||||
@Path("id") id: String,
|
@Path("id") id: String,
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<SuccessResponse>
|
): Call<SuccessResponse>
|
||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("mark")
|
@POST("mark")
|
||||||
fun markAllAsRead(
|
fun markAllAsRead(
|
||||||
@Field("ids[]") ids: List<String>,
|
@Field("ids[]") ids: List<String>,
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<SuccessResponse>
|
): Call<SuccessResponse>
|
||||||
|
|
||||||
@Headers("Content-Type: application/x-www-form-urlencoded")
|
@Headers("Content-Type: application/x-www-form-urlencoded")
|
||||||
@POST("starr/{id}")
|
@POST("starr/{id}")
|
||||||
fun starr(
|
fun starr(
|
||||||
@Path("id") id: String,
|
@Path("id") id: String,
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<SuccessResponse>
|
): Call<SuccessResponse>
|
||||||
|
|
||||||
@Headers("Content-Type: application/x-www-form-urlencoded")
|
@Headers("Content-Type: application/x-www-form-urlencoded")
|
||||||
@POST("unstarr/{id}")
|
@POST("unstarr/{id}")
|
||||||
fun unstarr(
|
fun unstarr(
|
||||||
@Path("id") id: String,
|
@Path("id") id: String,
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<SuccessResponse>
|
): Call<SuccessResponse>
|
||||||
|
|
||||||
@GET("stats")
|
@GET("stats")
|
||||||
fun stats(
|
fun stats(
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<Stats>
|
): Call<Stats>
|
||||||
|
|
||||||
@GET("tags")
|
@GET("tags")
|
||||||
fun tags(
|
fun tags(
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<List<Tag>>
|
): Call<List<Tag>>
|
||||||
|
|
||||||
@GET("update")
|
@GET("update")
|
||||||
fun update(
|
fun update(
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<String>
|
): Call<String>
|
||||||
|
|
||||||
@GET("sources/spouts")
|
@GET("sources/spouts")
|
||||||
fun spouts(
|
fun spouts(
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<Map<String, Spout>>
|
): Call<Map<String, Spout>>
|
||||||
|
|
||||||
@GET("sources/list")
|
@GET("sources/list")
|
||||||
fun sources(
|
fun sources(
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<List<Sources>>
|
): Call<List<Sources>>
|
||||||
|
|
||||||
@DELETE("source/{id}")
|
@DELETE("source/{id}")
|
||||||
fun deleteSource(
|
fun deleteSource(
|
||||||
@Path("id") id: String,
|
@Path("id") id: String,
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<SuccessResponse>
|
): Call<SuccessResponse>
|
||||||
|
|
||||||
@FormUrlEncoded
|
@FormUrlEncoded
|
||||||
@POST("source")
|
@POST("source")
|
||||||
fun createSource(
|
fun createSource(
|
||||||
@Field("title") title: String,
|
@Field("title") title: String,
|
||||||
@Field("url") url: String,
|
@Field("url") url: String,
|
||||||
@Field("spout") spout: String,
|
@Field("spout") spout: String,
|
||||||
@Field("tags") tags: String,
|
@Field("tags") tags: String,
|
||||||
@Field("filter") filter: String,
|
@Field("filter") filter: String,
|
||||||
@Query("username") username: String,
|
@Query("username") username: String,
|
||||||
@Query("password") password: String
|
@Query("password") password: String
|
||||||
): Call<SuccessResponse>
|
): Call<SuccessResponse>
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@ import android.support.design.widget.FloatingActionButton
|
|||||||
import android.support.v4.app.Fragment
|
import android.support.v4.app.Fragment
|
||||||
import android.support.v4.content.ContextCompat
|
import android.support.v4.content.ContextCompat
|
||||||
import android.support.v4.widget.NestedScrollView
|
import android.support.v4.widget.NestedScrollView
|
||||||
import android.text.Html
|
|
||||||
import android.text.method.LinkMovementMethod
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@ -33,7 +31,6 @@ import com.crashlytics.android.Crashlytics
|
|||||||
import com.ftinc.scoop.Scoop
|
import com.ftinc.scoop.Scoop
|
||||||
import com.github.rubensousa.floatingtoolbar.FloatingToolbar
|
import com.github.rubensousa.floatingtoolbar.FloatingToolbar
|
||||||
import kotlinx.android.synthetic.main.fragment_article.view.*
|
import kotlinx.android.synthetic.main.fragment_article.view.*
|
||||||
import org.sufficientlysecure.htmltextview.HtmlHttpImageGetter
|
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
@ -65,12 +62,12 @@ class ArticleFragment : Fragment() {
|
|||||||
private lateinit var rootView: ViewGroup
|
private lateinit var rootView: ViewGroup
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
container: ViewGroup?,
|
container: ViewGroup?,
|
||||||
savedInstanceState: Bundle?
|
savedInstanceState: Bundle?
|
||||||
): View? {
|
): View? {
|
||||||
rootView = inflater
|
rootView = inflater
|
||||||
.inflate(R.layout.fragment_article, container, false) as ViewGroup
|
.inflate(R.layout.fragment_article, container, false) as ViewGroup
|
||||||
|
|
||||||
url = allItems[pageNumber.toInt()].getLinkDecoded()
|
url = allItems[pageNumber.toInt()].getLinkDecoded()
|
||||||
contentText = allItems[pageNumber.toInt()].content
|
contentText = allItems[pageNumber.toInt()].content
|
||||||
@ -89,27 +86,27 @@ class ArticleFragment : Fragment() {
|
|||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(activity)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(activity)
|
||||||
|
|
||||||
mFloatingToolbar.setClickListener(
|
mFloatingToolbar.setClickListener(
|
||||||
object : FloatingToolbar.ItemClickListener {
|
object : FloatingToolbar.ItemClickListener {
|
||||||
override fun onItemClick(item: MenuItem) {
|
override fun onItemClick(item: MenuItem) {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.more_action -> getContentFromMercury(customTabsIntent, prefs)
|
R.id.more_action -> getContentFromMercury(customTabsIntent, prefs)
|
||||||
R.id.share_action -> activity!!.shareLink(url)
|
R.id.share_action -> activity!!.shareLink(url)
|
||||||
R.id.open_action -> activity!!.openItemUrl(
|
R.id.open_action -> activity!!.openItemUrl(
|
||||||
allItems,
|
allItems,
|
||||||
pageNumber.toInt(),
|
pageNumber.toInt(),
|
||||||
url,
|
url,
|
||||||
customTabsIntent,
|
customTabsIntent,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
activity!!
|
activity!!
|
||||||
)
|
)
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onItemLongClick(item: MenuItem?) {
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onItemLongClick(item: MenuItem?) {
|
||||||
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -124,149 +121,153 @@ class ArticleFragment : Fragment() {
|
|||||||
if (!contentImage.isEmptyOrNullOrNullString()) {
|
if (!contentImage.isEmptyOrNullOrNullString()) {
|
||||||
rootView.imageView.visibility = View.VISIBLE
|
rootView.imageView.visibility = View.VISIBLE
|
||||||
Glide
|
Glide
|
||||||
.with(activity!!.baseContext)
|
.with(activity!!.baseContext)
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.load(contentImage)
|
.load(contentImage)
|
||||||
.apply(RequestOptions.fitCenterTransform())
|
.apply(RequestOptions.fitCenterTransform())
|
||||||
.into(rootView.imageView)
|
.into(rootView.imageView)
|
||||||
} else {
|
} else {
|
||||||
rootView.imageView.visibility = View.GONE
|
rootView.imageView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rootView.nestedScrollView.setOnScrollChangeListener(
|
rootView.nestedScrollView.setOnScrollChangeListener(
|
||||||
NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
|
NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
|
||||||
if (scrollY > oldScrollY) {
|
if (scrollY > oldScrollY) {
|
||||||
fab.hide()
|
fab.hide()
|
||||||
} else {
|
} else {
|
||||||
if (mFloatingToolbar.isShowing) mFloatingToolbar.hide() else fab.show()
|
if (mFloatingToolbar.isShowing) mFloatingToolbar.hide() else fab.show()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
return rootView
|
return rootView
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getContentFromMercury(
|
private fun getContentFromMercury(
|
||||||
customTabsIntent: CustomTabsIntent,
|
customTabsIntent: CustomTabsIntent,
|
||||||
prefs: SharedPreferences
|
prefs: SharedPreferences
|
||||||
) {
|
) {
|
||||||
rootView.progressBar.visibility = View.VISIBLE
|
rootView.progressBar.visibility = View.VISIBLE
|
||||||
val parser = MercuryApi(
|
val parser = MercuryApi(
|
||||||
BuildConfig.MERCURY_KEY,
|
BuildConfig.MERCURY_KEY,
|
||||||
prefs.getBoolean("should_log_everything", false)
|
prefs.getBoolean("should_log_everything", false)
|
||||||
)
|
)
|
||||||
|
|
||||||
parser.parseUrl(url).enqueue(
|
parser.parseUrl(url).enqueue(
|
||||||
object : Callback<ParsedContent> {
|
object : Callback<ParsedContent> {
|
||||||
override fun onResponse(
|
override fun onResponse(
|
||||||
call: Call<ParsedContent>,
|
call: Call<ParsedContent>,
|
||||||
response: Response<ParsedContent>
|
response: Response<ParsedContent>
|
||||||
) {
|
) {
|
||||||
// TODO: clean all the following after finding the mercury content issue
|
// TODO: clean all the following after finding the mercury content issue
|
||||||
try {
|
try {
|
||||||
if (response.body() != null && response.body()!!.content != null && !response.body()!!.content.isNullOrEmpty()) {
|
if (response.body() != null && response.body()!!.content != null && !response.body()!!.content.isNullOrEmpty()) {
|
||||||
try {
|
try {
|
||||||
rootView.source.text = response.body()!!.domain
|
rootView.source.text = response.body()!!.domain
|
||||||
rootView.titleView.text = response.body()!!.title
|
rootView.titleView.text = response.body()!!.title
|
||||||
url = response.body()!!.url
|
url = response.body()!!.url
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
||||||
Crashlytics.log(
|
Crashlytics.log(
|
||||||
100,
|
|
||||||
"MERCURY_CONTENT_EXCEPTION",
|
|
||||||
"source titleView or url issues"
|
|
||||||
)
|
|
||||||
Crashlytics.logException(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
htmlToWebview(response.body()!!.content.orEmpty(), prefs)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
|
||||||
Crashlytics.log(
|
|
||||||
100,
|
|
||||||
"MERCURY_CONTENT_EXCEPTION",
|
|
||||||
"Webview issue"
|
|
||||||
)
|
|
||||||
Crashlytics.logException(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isNullOrEmpty()) {
|
|
||||||
rootView.imageView.visibility = View.VISIBLE
|
|
||||||
try {
|
|
||||||
Glide
|
|
||||||
.with(activity!!.baseContext)
|
|
||||||
.asBitmap()
|
|
||||||
.load(response.body()!!.lead_image_url)
|
|
||||||
.apply(RequestOptions.fitCenterTransform())
|
|
||||||
.into(rootView.imageView)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
|
||||||
Crashlytics.log(
|
|
||||||
100,
|
|
||||||
"MERCURY_CONTENT_EXCEPTION",
|
|
||||||
"Glide issue"
|
|
||||||
)
|
|
||||||
Crashlytics.logException(e)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
rootView.imageView.visibility = View.GONE
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
|
||||||
Crashlytics.log(
|
|
||||||
100,
|
|
||||||
"MERCURY_CONTENT_EXCEPTION",
|
|
||||||
"Glide or image issue"
|
|
||||||
)
|
|
||||||
Crashlytics.logException(e)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
rootView.nestedScrollView.scrollTo(0, 0)
|
|
||||||
|
|
||||||
rootView.progressBar.visibility = View.GONE
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
|
||||||
Crashlytics.log(
|
|
||||||
100,
|
|
||||||
"MERCURY_CONTENT_EXCEPTION",
|
|
||||||
"Scroll or visibility issues"
|
|
||||||
)
|
|
||||||
Crashlytics.logException(e)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
openInBrowserAfterFailing(customTabsIntent)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
|
||||||
Crashlytics.log(
|
|
||||||
100,
|
|
||||||
"MERCURY_CONTENT_EXCEPTION",
|
|
||||||
"Browser after failing issue"
|
|
||||||
)
|
|
||||||
Crashlytics.logException(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
|
||||||
Crashlytics.log(
|
|
||||||
100,
|
100,
|
||||||
"MERCURY_CONTENT_EXCEPTION",
|
"MERCURY_CONTENT_EXCEPTION",
|
||||||
"UNCAUGHT (?) Fatal Exception on mercury response"
|
"source titleView or url issues"
|
||||||
)
|
)
|
||||||
Crashlytics.logException(e)
|
Crashlytics.logException(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
htmlToWebview(response.body()!!.content.orEmpty(), prefs)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
||||||
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"MERCURY_CONTENT_EXCEPTION",
|
||||||
|
"Webview issue"
|
||||||
|
)
|
||||||
|
Crashlytics.logException(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isNullOrEmpty()) {
|
||||||
|
rootView.imageView.visibility = View.VISIBLE
|
||||||
|
try {
|
||||||
|
Glide
|
||||||
|
.with(activity!!.baseContext)
|
||||||
|
.asBitmap()
|
||||||
|
.load(response.body()!!.lead_image_url)
|
||||||
|
.apply(RequestOptions.fitCenterTransform())
|
||||||
|
.into(rootView.imageView)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Crashlytics.setUserIdentifier(
|
||||||
|
prefs.getString(
|
||||||
|
"unique_id",
|
||||||
|
""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"MERCURY_CONTENT_EXCEPTION",
|
||||||
|
"Glide issue"
|
||||||
|
)
|
||||||
|
Crashlytics.logException(e)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
rootView.imageView.visibility = View.GONE
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
||||||
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"MERCURY_CONTENT_EXCEPTION",
|
||||||
|
"Glide or image issue"
|
||||||
|
)
|
||||||
|
Crashlytics.logException(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
rootView.nestedScrollView.scrollTo(0, 0)
|
||||||
|
|
||||||
|
rootView.progressBar.visibility = View.GONE
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
||||||
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"MERCURY_CONTENT_EXCEPTION",
|
||||||
|
"Scroll or visibility issues"
|
||||||
|
)
|
||||||
|
Crashlytics.logException(e)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
openInBrowserAfterFailing(customTabsIntent)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
||||||
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"MERCURY_CONTENT_EXCEPTION",
|
||||||
|
"Browser after failing issue"
|
||||||
|
)
|
||||||
|
Crashlytics.logException(e)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
||||||
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"MERCURY_CONTENT_EXCEPTION",
|
||||||
|
"UNCAUGHT (?) Fatal Exception on mercury response"
|
||||||
|
)
|
||||||
|
Crashlytics.logException(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(
|
|
||||||
call: Call<ParsedContent>,
|
|
||||||
t: Throwable
|
|
||||||
) = openInBrowserAfterFailing(customTabsIntent)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onFailure(
|
||||||
|
call: Call<ParsedContent>,
|
||||||
|
t: Throwable
|
||||||
|
) = openInBrowserAfterFailing(customTabsIntent)
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,10 +278,20 @@ class ArticleFragment : Fragment() {
|
|||||||
|
|
||||||
rootView.webcontent.visibility = View.VISIBLE
|
rootView.webcontent.visibility = View.VISIBLE
|
||||||
val textColor = if (Scoop.getInstance().currentFlavor.isDayNight) {
|
val textColor = if (Scoop.getInstance().currentFlavor.isDayNight) {
|
||||||
rootView.webcontent.setBackgroundColor(ContextCompat.getColor(activity!!.baseContext, R.color.dark_webview))
|
rootView.webcontent.setBackgroundColor(
|
||||||
|
ContextCompat.getColor(
|
||||||
|
activity!!.baseContext,
|
||||||
|
R.color.dark_webview
|
||||||
|
)
|
||||||
|
)
|
||||||
ContextCompat.getColor(activity!!.baseContext, R.color.dark_webview_text)
|
ContextCompat.getColor(activity!!.baseContext, R.color.dark_webview_text)
|
||||||
} else {
|
} else {
|
||||||
rootView.webcontent.setBackgroundColor(ContextCompat.getColor(activity!!.baseContext, R.color.light_webview))
|
rootView.webcontent.setBackgroundColor(
|
||||||
|
ContextCompat.getColor(
|
||||||
|
activity!!.baseContext,
|
||||||
|
R.color.light_webview
|
||||||
|
)
|
||||||
|
)
|
||||||
ContextCompat.getColor(activity!!.baseContext, R.color.light_webview_text)
|
ContextCompat.getColor(activity!!.baseContext, R.color.light_webview_text)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -291,7 +302,8 @@ class ArticleFragment : Fragment() {
|
|||||||
rootView.webcontent.settings.javaScriptEnabled = false
|
rootView.webcontent.settings.javaScriptEnabled = false
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
|
||||||
rootView.webcontent.settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
|
rootView.webcontent.settings.layoutAlgorithm =
|
||||||
|
WebSettings.LayoutAlgorithm.TEXT_AUTOSIZING
|
||||||
} else {
|
} else {
|
||||||
rootView.webcontent.settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
|
rootView.webcontent.settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN
|
||||||
}
|
}
|
||||||
@ -308,24 +320,24 @@ class ArticleFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rootView.webcontent.loadDataWithBaseURL(
|
rootView.webcontent.loadDataWithBaseURL(
|
||||||
baseUrl,
|
baseUrl,
|
||||||
"<style>img{display: inline-block;height: auto; width: 100%; max-width: 100%;} a{color: $stringColor;} *:not(a){color: $stringTextColor;}</style>$c",
|
"<style>img{display: inline-block;height: auto; width: 100%; max-width: 100%;} a{color: $stringColor;} *:not(a){color: $stringTextColor;}</style>$c",
|
||||||
"text/html; charset=utf-8",
|
"text/html; charset=utf-8",
|
||||||
"utf-8",
|
"utf-8",
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun openInBrowserAfterFailing(customTabsIntent: CustomTabsIntent) {
|
private fun openInBrowserAfterFailing(customTabsIntent: CustomTabsIntent) {
|
||||||
rootView.progressBar.visibility = View.GONE
|
rootView.progressBar.visibility = View.GONE
|
||||||
activity!!.openItemUrl(
|
activity!!.openItemUrl(
|
||||||
allItems,
|
allItems,
|
||||||
pageNumber.toInt(),
|
pageNumber.toInt(),
|
||||||
url,
|
url,
|
||||||
customTabsIntent,
|
customTabsIntent,
|
||||||
true,
|
true,
|
||||||
false,
|
false,
|
||||||
activity!!
|
activity!!
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -334,8 +346,8 @@ class ArticleFragment : Fragment() {
|
|||||||
private val ARG_ITEMS = "items"
|
private val ARG_ITEMS = "items"
|
||||||
|
|
||||||
fun newInstance(
|
fun newInstance(
|
||||||
position: Int,
|
position: Int,
|
||||||
allItems: ArrayList<Item>
|
allItems: ArrayList<Item>
|
||||||
): ArticleFragment {
|
): ArticleFragment {
|
||||||
val fragment = ArticleFragment()
|
val fragment = ArticleFragment()
|
||||||
val args = Bundle()
|
val args = Bundle()
|
||||||
|
@ -16,9 +16,10 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
|
|
||||||
import apps.amine.bou.readerforselfoss.R;
|
|
||||||
import com.ftinc.scoop.Scoop;
|
import com.ftinc.scoop.Scoop;
|
||||||
|
|
||||||
|
import apps.amine.bou.readerforselfoss.R;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link PreferenceActivity} which implements and proxies the necessary calls
|
* A {@link PreferenceActivity} which implements and proxies the necessary calls
|
||||||
@ -40,7 +41,7 @@ public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
|
|||||||
protected void onPostCreate(Bundle savedInstanceState) {
|
protected void onPostCreate(Bundle savedInstanceState) {
|
||||||
super.onPostCreate(savedInstanceState);
|
super.onPostCreate(savedInstanceState);
|
||||||
|
|
||||||
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
|
LinearLayout root = (LinearLayout) findViewById(android.R.id.list).getParent().getParent().getParent();
|
||||||
AppBarLayout bar = (AppBarLayout) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
|
AppBarLayout bar = (AppBarLayout) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
|
||||||
Toolbar toolbar = bar.findViewById(R.id.toolbar);
|
Toolbar toolbar = bar.findViewById(R.id.toolbar);
|
||||||
setSupportActionBar(toolbar);
|
setSupportActionBar(toolbar);
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package apps.amine.bou.readerforselfoss.settings;
|
package apps.amine.bou.readerforselfoss.settings;
|
||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
@ -27,10 +25,13 @@ import android.text.Spanned;
|
|||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.ftinc.scoop.ui.ScoopSettingsActivity;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import apps.amine.bou.readerforselfoss.BuildConfig;
|
import apps.amine.bou.readerforselfoss.BuildConfig;
|
||||||
import apps.amine.bou.readerforselfoss.R;
|
import apps.amine.bou.readerforselfoss.R;
|
||||||
import apps.amine.bou.readerforselfoss.utils.Config;
|
import apps.amine.bou.readerforselfoss.utils.Config;
|
||||||
import com.ftinc.scoop.ui.ScoopSettingsActivity;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -150,7 +151,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||||||
final SwitchPreference tabOnTap = (SwitchPreference) findPreference("tab_on_tap");
|
final SwitchPreference tabOnTap = (SwitchPreference) findPreference("tab_on_tap");
|
||||||
tabOnTap.setEnabled(!cardViewActive.isChecked());
|
tabOnTap.setEnabled(!cardViewActive.isChecked());
|
||||||
cardViewActive.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
cardViewActive.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue){
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
boolean isEnabled = (Boolean) newValue;
|
boolean isEnabled = (Boolean) newValue;
|
||||||
tabOnTap.setEnabled(!isEnabled);
|
tabOnTap.setEnabled(!isEnabled);
|
||||||
return true;
|
return true;
|
||||||
@ -159,20 +160,20 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||||||
|
|
||||||
EditTextPreference itemsNumber = (EditTextPreference) findPreference("prefer_api_items_number");
|
EditTextPreference itemsNumber = (EditTextPreference) findPreference("prefer_api_items_number");
|
||||||
itemsNumber.getEditText().setFilters(new InputFilter[]{
|
itemsNumber.getEditText().setFilters(new InputFilter[]{
|
||||||
new InputFilter (){
|
new InputFilter() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
|
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
|
||||||
try {
|
try {
|
||||||
int input = Integer.parseInt(dest.toString() + source.toString());
|
int input = Integer.parseInt(dest.toString() + source.toString());
|
||||||
if (input <= 200 && input >0)
|
if (input <= 200 && input > 0)
|
||||||
return null;
|
return null;
|
||||||
} catch (NumberFormatException nfe) {
|
} catch (NumberFormatException nfe) {
|
||||||
Toast.makeText(getActivity(), R.string.items_number_should_be_number, Toast.LENGTH_LONG).show();
|
Toast.makeText(getActivity(), R.string.items_number_should_be_number, Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +244,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
|||||||
addPreferencesFromResource(R.xml.pref_links);
|
addPreferencesFromResource(R.xml.pref_links);
|
||||||
setHasOptionsMenu(true);
|
setHasOptionsMenu(true);
|
||||||
|
|
||||||
findPreference( "trackerLink" ).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
findPreference("trackerLink").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceClick(Preference preference) {
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
openUrl(Uri.parse(BuildConfig.TRACKER_URL));
|
openUrl(Uri.parse(BuildConfig.TRACKER_URL));
|
||||||
|
@ -4,4 +4,4 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
|
|||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
|
||||||
fun Response<SuccessResponse>.succeeded(): Boolean =
|
fun Response<SuccessResponse>.succeeded(): Boolean =
|
||||||
this.code() === 200 && this.body() != null && this.body()!!.isSuccess
|
this.code() === 200 && this.body() != null && this.body()!!.isSuccess
|
@ -9,12 +9,12 @@ import apps.amine.bou.readerforselfoss.R
|
|||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
|
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
|
||||||
|
|
||||||
fun String?.isEmptyOrNullOrNullString(): Boolean =
|
fun String?.isEmptyOrNullOrNullString(): Boolean =
|
||||||
this == null || this == "null" || this.isEmpty()
|
this == null || this == "null" || this.isEmpty()
|
||||||
|
|
||||||
fun Context.checkApkVersion(
|
fun Context.checkApkVersion(
|
||||||
settings: SharedPreferences,
|
settings: SharedPreferences,
|
||||||
editor: SharedPreferences.Editor,
|
editor: SharedPreferences.Editor,
|
||||||
mFirebaseRemoteConfig: FirebaseRemoteConfig
|
mFirebaseRemoteConfig: FirebaseRemoteConfig
|
||||||
) = {
|
) = {
|
||||||
fun isThereAnUpdate() {
|
fun isThereAnUpdate() {
|
||||||
val APK_LINK = "github_apk"
|
val APK_LINK = "github_apk"
|
||||||
@ -26,8 +26,8 @@ fun Context.checkApkVersion(
|
|||||||
alertDialog.setTitle(getString(R.string.new_apk_available_title))
|
alertDialog.setTitle(getString(R.string.new_apk_available_title))
|
||||||
alertDialog.setMessage(getString(R.string.new_apk_available_message))
|
alertDialog.setMessage(getString(R.string.new_apk_available_message))
|
||||||
alertDialog.setButton(
|
alertDialog.setButton(
|
||||||
AlertDialog.BUTTON_POSITIVE,
|
AlertDialog.BUTTON_POSITIVE,
|
||||||
getString(R.string.new_apk_available_get)
|
getString(R.string.new_apk_available_get)
|
||||||
) { _, _ ->
|
) { _, _ ->
|
||||||
editor.putString(APK_LINK, apkLink)
|
editor.putString(APK_LINK, apkLink)
|
||||||
editor.apply()
|
editor.apply()
|
||||||
@ -35,25 +35,25 @@ fun Context.checkApkVersion(
|
|||||||
startActivity(browserIntent)
|
startActivity(browserIntent)
|
||||||
}
|
}
|
||||||
alertDialog.setButton(
|
alertDialog.setButton(
|
||||||
AlertDialog.BUTTON_NEUTRAL, getString(R.string.new_apk_available_no),
|
AlertDialog.BUTTON_NEUTRAL, getString(R.string.new_apk_available_no),
|
||||||
{ dialog, _ ->
|
{ dialog, _ ->
|
||||||
editor.putString(APK_LINK, apkLink)
|
editor.putString(APK_LINK, apkLink)
|
||||||
editor.apply()
|
editor.apply()
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
alertDialog.show()
|
alertDialog.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mFirebaseRemoteConfig.fetch(43200)
|
mFirebaseRemoteConfig.fetch(43200)
|
||||||
.addOnCompleteListener { task ->
|
.addOnCompleteListener { task ->
|
||||||
if (task.isSuccessful) {
|
if (task.isSuccessful) {
|
||||||
mFirebaseRemoteConfig.activateFetched()
|
mFirebaseRemoteConfig.activateFetched()
|
||||||
}
|
|
||||||
|
|
||||||
isThereAnUpdate()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isThereAnUpdate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun String.longHash(): Long {
|
fun String.longHash(): Long {
|
||||||
@ -68,11 +68,11 @@ fun String.longHash(): Long {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun String.toStringUriWithHttp(): String =
|
fun String.toStringUriWithHttp(): String =
|
||||||
if (!this.startsWith("https://") && !this.startsWith("http://")) {
|
if (!this.startsWith("https://") && !this.startsWith("http://")) {
|
||||||
"http://" + this
|
"http://" + this
|
||||||
} else {
|
} else {
|
||||||
this
|
this
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Context.shareLink(itemUrl: String) {
|
fun Context.shareLink(itemUrl: String) {
|
||||||
val sendIntent = Intent()
|
val sendIntent = Intent()
|
||||||
@ -81,9 +81,9 @@ fun Context.shareLink(itemUrl: String) {
|
|||||||
sendIntent.putExtra(Intent.EXTRA_TEXT, itemUrl.toStringUriWithHttp())
|
sendIntent.putExtra(Intent.EXTRA_TEXT, itemUrl.toStringUriWithHttp())
|
||||||
sendIntent.type = "text/plain"
|
sendIntent.type = "text/plain"
|
||||||
startActivity(
|
startActivity(
|
||||||
Intent.createChooser(
|
Intent.createChooser(
|
||||||
sendIntent,
|
sendIntent,
|
||||||
getString(R.string.share)
|
getString(R.string.share)
|
||||||
).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -29,10 +29,10 @@ class Config(c: Context) {
|
|||||||
val settingsName = "paramsselfoss"
|
val settingsName = "paramsselfoss"
|
||||||
|
|
||||||
fun logoutAndRedirect(
|
fun logoutAndRedirect(
|
||||||
c: Context,
|
c: Context,
|
||||||
callingActivity: Activity,
|
callingActivity: Activity,
|
||||||
editor: SharedPreferences.Editor,
|
editor: SharedPreferences.Editor,
|
||||||
baseUrlFail: Boolean = false
|
baseUrlFail: Boolean = false
|
||||||
): Boolean {
|
): Boolean {
|
||||||
editor.remove("url")
|
editor.remove("url")
|
||||||
editor.remove("login")
|
editor.remove("login")
|
||||||
|
@ -8,36 +8,36 @@ import javax.net.ssl.TrustManager
|
|||||||
import javax.net.ssl.X509TrustManager
|
import javax.net.ssl.X509TrustManager
|
||||||
|
|
||||||
fun getUnsafeHttpClient() =
|
fun getUnsafeHttpClient() =
|
||||||
try {
|
try {
|
||||||
// Create a trust manager that does not validate certificate chains
|
// Create a trust manager that does not validate certificate chains
|
||||||
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
|
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
|
||||||
override fun getAcceptedIssuers(): Array<X509Certificate> =
|
override fun getAcceptedIssuers(): Array<X509Certificate> =
|
||||||
arrayOf()
|
arrayOf()
|
||||||
|
|
||||||
@Throws(CertificateException::class)
|
@Throws(CertificateException::class)
|
||||||
override fun checkClientTrusted(
|
override fun checkClientTrusted(
|
||||||
chain: Array<java.security.cert.X509Certificate>,
|
chain: Array<java.security.cert.X509Certificate>,
|
||||||
authType: String
|
authType: String
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(CertificateException::class)
|
@Throws(CertificateException::class)
|
||||||
override fun checkServerTrusted(
|
override fun checkServerTrusted(
|
||||||
chain: Array<java.security.cert.X509Certificate>,
|
chain: Array<java.security.cert.X509Certificate>,
|
||||||
authType: String
|
authType: String
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// Install the all-trusting trust manager
|
// Install the all-trusting trust manager
|
||||||
val sslContext = SSLContext.getInstance("SSL")
|
val sslContext = SSLContext.getInstance("SSL")
|
||||||
sslContext.init(null, trustAllCerts, java.security.SecureRandom())
|
sslContext.init(null, trustAllCerts, java.security.SecureRandom())
|
||||||
|
|
||||||
val sslSocketFactory = sslContext.socketFactory
|
val sslSocketFactory = sslContext.socketFactory
|
||||||
|
|
||||||
OkHttpClient.Builder()
|
OkHttpClient.Builder()
|
||||||
.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
|
.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
|
||||||
.hostnameVerifier { _, _ -> true }
|
.hostnameVerifier { _, _ -> true }
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw RuntimeException(e)
|
throw RuntimeException(e)
|
||||||
}
|
}
|
@ -13,7 +13,11 @@ fun String.toTextDrawableString(): String {
|
|||||||
try {
|
try {
|
||||||
textDrawable.append(s[0])
|
textDrawable.append(s[0])
|
||||||
} catch (e: StringIndexOutOfBoundsException) {
|
} catch (e: StringIndexOutOfBoundsException) {
|
||||||
Crashlytics.log(100, "TEXT_DRAWABLE_INDEX_OUT_OF_BOUND", this + " produces ${e.message}")
|
Crashlytics.log(
|
||||||
|
100,
|
||||||
|
"TEXT_DRAWABLE_INDEX_OUT_OF_BOUND",
|
||||||
|
this + " produces ${e.message}"
|
||||||
|
)
|
||||||
Crashlytics.logException(e)
|
Crashlytics.logException(e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -23,10 +27,10 @@ fun String.toTextDrawableString(): String {
|
|||||||
fun Item.sourceAndDateText(): String {
|
fun Item.sourceAndDateText(): String {
|
||||||
val formattedDate: String = try {
|
val formattedDate: String = try {
|
||||||
" " + DateUtils.getRelativeTimeSpanString(
|
" " + DateUtils.getRelativeTimeSpanString(
|
||||||
SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(this.datetime).time,
|
SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(this.datetime).time,
|
||||||
Date().time,
|
Date().time,
|
||||||
DateUtils.MINUTE_IN_MILLIS,
|
DateUtils.MINUTE_IN_MILLIS,
|
||||||
DateUtils.FORMAT_ABBREV_RELATIVE
|
DateUtils.FORMAT_ABBREV_RELATIVE
|
||||||
)
|
)
|
||||||
} catch (e: ParseException) {
|
} catch (e: ParseException) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
@ -20,10 +20,10 @@ 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 createPendingShareIntent: PendingIntent = PendingIntent.getActivity(
|
||||||
this,
|
this,
|
||||||
0,
|
0,
|
||||||
actionIntent,
|
actionIntent,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
|
|
||||||
val intentBuilder = CustomTabsIntent.Builder()
|
val intentBuilder = CustomTabsIntent.Builder()
|
||||||
@ -35,14 +35,14 @@ fun Context.buildCustomTabsIntent(): CustomTabsIntent {
|
|||||||
|
|
||||||
|
|
||||||
intentBuilder.setStartAnimations(
|
intentBuilder.setStartAnimations(
|
||||||
this,
|
this,
|
||||||
R.anim.slide_in_right,
|
R.anim.slide_in_right,
|
||||||
R.anim.slide_out_left
|
R.anim.slide_out_left
|
||||||
)
|
)
|
||||||
intentBuilder.setExitAnimations(
|
intentBuilder.setExitAnimations(
|
||||||
this,
|
this,
|
||||||
android.R.anim.slide_in_left,
|
android.R.anim.slide_in_left,
|
||||||
android.R.anim.slide_out_right
|
android.R.anim.slide_out_right
|
||||||
)
|
)
|
||||||
|
|
||||||
val closeicon = BitmapFactory.decodeResource(resources, R.drawable.ic_close_white_24dp)
|
val closeicon = BitmapFactory.decodeResource(resources, R.drawable.ic_close_white_24dp)
|
||||||
@ -50,8 +50,8 @@ fun Context.buildCustomTabsIntent(): CustomTabsIntent {
|
|||||||
|
|
||||||
val shareLabel = this.getString(R.string.label_share)
|
val shareLabel = this.getString(R.string.label_share)
|
||||||
val icon = BitmapFactory.decodeResource(
|
val icon = BitmapFactory.decodeResource(
|
||||||
resources,
|
resources,
|
||||||
R.drawable.ic_share_white_24dp
|
R.drawable.ic_share_white_24dp
|
||||||
)
|
)
|
||||||
intentBuilder.setActionButton(icon, shareLabel, createPendingShareIntent)
|
intentBuilder.setActionButton(icon, shareLabel, createPendingShareIntent)
|
||||||
|
|
||||||
@ -59,12 +59,12 @@ fun Context.buildCustomTabsIntent(): CustomTabsIntent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Context.openItemUrlInternally(
|
fun Context.openItemUrlInternally(
|
||||||
allItems: ArrayList<Item>,
|
allItems: ArrayList<Item>,
|
||||||
currentItem: Int,
|
currentItem: Int,
|
||||||
linkDecoded: String,
|
linkDecoded: String,
|
||||||
customTabsIntent: CustomTabsIntent,
|
customTabsIntent: CustomTabsIntent,
|
||||||
articleViewer: Boolean,
|
articleViewer: Boolean,
|
||||||
app: Activity
|
app: Activity
|
||||||
) {
|
) {
|
||||||
if (articleViewer) {
|
if (articleViewer) {
|
||||||
ReaderActivity.allItems = allItems
|
ReaderActivity.allItems = allItems
|
||||||
@ -74,9 +74,9 @@ fun Context.openItemUrlInternally(
|
|||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
CustomTabActivityHelper.openCustomTab(
|
CustomTabActivityHelper.openCustomTab(
|
||||||
app,
|
app,
|
||||||
customTabsIntent,
|
customTabsIntent,
|
||||||
Uri.parse(linkDecoded)
|
Uri.parse(linkDecoded)
|
||||||
) { _, uri ->
|
) { _, uri ->
|
||||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
@ -89,32 +89,32 @@ fun Context.openItemUrlInternally(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Context.openItemUrl(
|
fun Context.openItemUrl(
|
||||||
allItems: ArrayList<Item>,
|
allItems: ArrayList<Item>,
|
||||||
currentItem: Int,
|
currentItem: Int,
|
||||||
linkDecoded: String,
|
linkDecoded: String,
|
||||||
customTabsIntent: CustomTabsIntent,
|
customTabsIntent: CustomTabsIntent,
|
||||||
internalBrowser: Boolean,
|
internalBrowser: Boolean,
|
||||||
articleViewer: Boolean,
|
articleViewer: Boolean,
|
||||||
app: Activity
|
app: Activity
|
||||||
) {
|
) {
|
||||||
|
|
||||||
if (!linkDecoded.isUrlValid()) {
|
if (!linkDecoded.isUrlValid()) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this,
|
this,
|
||||||
this.getString(R.string.cant_open_invalid_url),
|
this.getString(R.string.cant_open_invalid_url),
|
||||||
Toast.LENGTH_LONG
|
Toast.LENGTH_LONG
|
||||||
).show()
|
).show()
|
||||||
} else {
|
} else {
|
||||||
if (!internalBrowser) {
|
if (!internalBrowser) {
|
||||||
openInBrowser(linkDecoded, app)
|
openInBrowser(linkDecoded, app)
|
||||||
} else {
|
} else {
|
||||||
this.openItemUrlInternally(
|
this.openItemUrlInternally(
|
||||||
allItems,
|
allItems,
|
||||||
currentItem,
|
currentItem,
|
||||||
linkDecoded,
|
linkDecoded,
|
||||||
customTabsIntent,
|
customTabsIntent,
|
||||||
articleViewer,
|
articleViewer,
|
||||||
app
|
app
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,7 +127,7 @@ private fun openInBrowser(linkDecoded: String, app: Activity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun String.isUrlValid(): Boolean =
|
fun String.isUrlValid(): Boolean =
|
||||||
HttpUrl.parse(this) != null && Patterns.WEB_URL.matcher(this).matches()
|
HttpUrl.parse(this) != null && Patterns.WEB_URL.matcher(this).matches()
|
||||||
|
|
||||||
fun String.isBaseUrlValid(): Boolean {
|
fun String.isBaseUrlValid(): Boolean {
|
||||||
val baseUrl = HttpUrl.parse(this)
|
val baseUrl = HttpUrl.parse(this)
|
||||||
|
@ -7,37 +7,37 @@ import android.util.AttributeSet
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
|
|
||||||
class ScrollAwareFABBehavior(
|
class ScrollAwareFABBehavior(
|
||||||
context: Context,
|
context: Context,
|
||||||
attrs: AttributeSet
|
attrs: AttributeSet
|
||||||
) : CoordinatorLayout.Behavior<FloatingActionButton>() {
|
) : CoordinatorLayout.Behavior<FloatingActionButton>() {
|
||||||
|
|
||||||
override fun onStartNestedScroll(
|
override fun onStartNestedScroll(
|
||||||
coordinatorLayout: CoordinatorLayout,
|
coordinatorLayout: CoordinatorLayout,
|
||||||
child: FloatingActionButton,
|
child: FloatingActionButton,
|
||||||
directTargetChild: View,
|
directTargetChild: View,
|
||||||
target: View,
|
target: View,
|
||||||
nestedScrollAxes: Int
|
nestedScrollAxes: Int
|
||||||
): Boolean {
|
): Boolean {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNestedScroll(
|
override fun onNestedScroll(
|
||||||
coordinatorLayout: CoordinatorLayout,
|
coordinatorLayout: CoordinatorLayout,
|
||||||
child: FloatingActionButton,
|
child: FloatingActionButton,
|
||||||
target: View,
|
target: View,
|
||||||
dxConsumed: Int,
|
dxConsumed: Int,
|
||||||
dyConsumed: Int,
|
dyConsumed: Int,
|
||||||
dxUnconsumed: Int,
|
dxUnconsumed: Int,
|
||||||
dyUnconsumed: Int
|
dyUnconsumed: Int
|
||||||
) {
|
) {
|
||||||
super.onNestedScroll(
|
super.onNestedScroll(
|
||||||
coordinatorLayout,
|
coordinatorLayout,
|
||||||
child,
|
child,
|
||||||
target,
|
target,
|
||||||
dxConsumed,
|
dxConsumed,
|
||||||
dyConsumed,
|
dyConsumed,
|
||||||
dxUnconsumed,
|
dxUnconsumed,
|
||||||
dyUnconsumed
|
dyUnconsumed
|
||||||
)
|
)
|
||||||
if (dyConsumed > 0 && child.visibility == View.VISIBLE) {
|
if (dyConsumed > 0 && child.visibility == View.VISIBLE) {
|
||||||
child.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
|
child.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
|
||||||
|
@ -9,4 +9,4 @@ fun TextBadgeItem.removeBadge(): TextBadgeItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun TextBadgeItem.maybeShow(): TextBadgeItem =
|
fun TextBadgeItem.maybeShow(): TextBadgeItem =
|
||||||
if (this.isHidden) this.show() else this
|
if (this.isHidden) this.show() else this
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
||||||
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -11,6 +9,8 @@ import android.support.customtabs.CustomTabsIntent;
|
|||||||
import android.support.customtabs.CustomTabsServiceConnection;
|
import android.support.customtabs.CustomTabsServiceConnection;
|
||||||
import android.support.customtabs.CustomTabsSession;
|
import android.support.customtabs.CustomTabsSession;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a helper class to manage the connection to the Custom Tabs Service.
|
* This is a helper class to manage the connection to the Custom Tabs Service.
|
||||||
*/
|
*/
|
||||||
@ -23,15 +23,15 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||||||
/**
|
/**
|
||||||
* Opens the URL on a Custom Tab if possible. Otherwise fallsback to opening it on a WebView.
|
* Opens the URL on a Custom Tab if possible. Otherwise fallsback to opening it on a WebView.
|
||||||
*
|
*
|
||||||
* @param activity The host activity.
|
* @param activity The host activity.
|
||||||
* @param customTabsIntent a CustomTabsIntent to be used if Custom Tabs is available.
|
* @param customTabsIntent a CustomTabsIntent to be used if Custom Tabs is available.
|
||||||
* @param uri the Uri to be opened.
|
* @param uri the Uri to be opened.
|
||||||
* @param fallback a CustomTabFallback to be used if Custom Tabs is not available.
|
* @param fallback a CustomTabFallback to be used if Custom Tabs is not available.
|
||||||
*/
|
*/
|
||||||
public static void openCustomTab(Activity activity,
|
public static void openCustomTab(Activity activity,
|
||||||
CustomTabsIntent customTabsIntent,
|
CustomTabsIntent customTabsIntent,
|
||||||
Uri uri,
|
Uri uri,
|
||||||
CustomTabFallback fallback) {
|
CustomTabFallback fallback) {
|
||||||
String packageName = CustomTabsHelper.getPackageNameToUse(activity);
|
String packageName = CustomTabsHelper.getPackageNameToUse(activity);
|
||||||
|
|
||||||
//If we cant find a package name, it means theres no browser that supports
|
//If we cant find a package name, it means theres no browser that supports
|
||||||
@ -48,6 +48,7 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Unbinds the Activity from the Custom Tabs Service.
|
* Unbinds the Activity from the Custom Tabs Service.
|
||||||
|
*
|
||||||
* @param activity the activity that is connected to the service.
|
* @param activity the activity that is connected to the service.
|
||||||
*/
|
*/
|
||||||
public void unbindCustomTabsService(Activity activity) {
|
public void unbindCustomTabsService(Activity activity) {
|
||||||
@ -74,6 +75,7 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a Callback to be called when connected or disconnected from the Custom Tabs Service.
|
* Register a Callback to be called when connected or disconnected from the Custom Tabs Service.
|
||||||
|
*
|
||||||
* @param connectionCallback
|
* @param connectionCallback
|
||||||
*/
|
*/
|
||||||
public void setConnectionCallback(ConnectionCallback connectionCallback) {
|
public void setConnectionCallback(ConnectionCallback connectionCallback) {
|
||||||
@ -82,6 +84,7 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Binds the Activity to the Custom Tabs Service.
|
* Binds the Activity to the Custom Tabs Service.
|
||||||
|
*
|
||||||
* @param activity the activity to be binded to the service.
|
* @param activity the activity to be binded to the service.
|
||||||
*/
|
*/
|
||||||
public void bindCustomTabsService(Activity activity) {
|
public void bindCustomTabsService(Activity activity) {
|
||||||
@ -95,8 +98,8 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see {@link CustomTabsSession#mayLaunchUrl(Uri, Bundle, List)}.
|
|
||||||
* @return true if call to mayLaunchUrl was accepted.
|
* @return true if call to mayLaunchUrl was accepted.
|
||||||
|
* @see {@link CustomTabsSession#mayLaunchUrl(Uri, Bundle, List)}.
|
||||||
*/
|
*/
|
||||||
public boolean mayLaunchUrl(Uri uri, Bundle extras, List<Bundle> otherLikelyBundles) {
|
public boolean mayLaunchUrl(Uri uri, Bundle extras, List<Bundle> otherLikelyBundles) {
|
||||||
if (mClient == null) return false;
|
if (mClient == null) return false;
|
||||||
@ -142,9 +145,8 @@ public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
|||||||
*/
|
*/
|
||||||
public interface CustomTabFallback {
|
public interface CustomTabFallback {
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param activity The Activity that wants to open the Uri.
|
* @param activity The Activity that wants to open the Uri.
|
||||||
* @param uri The uri to be opened by the fallback.
|
* @param uri The uri to be opened by the fallback.
|
||||||
*/
|
*/
|
||||||
void openUri(Activity activity, Uri uri);
|
void openUri(Activity activity, Uri uri);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
||||||
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
@ -14,6 +11,9 @@ import android.support.customtabs.CustomTabsService;
|
|||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import apps.amine.bou.readerforselfoss.utils.customtabs.helpers.KeepAliveService;
|
import apps.amine.bou.readerforselfoss.utils.customtabs.helpers.KeepAliveService;
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
@SuppressWarnings("ALL")
|
||||||
@ -28,7 +28,8 @@ class CustomTabsHelper {
|
|||||||
|
|
||||||
private static String sPackageNameToUse;
|
private static String sPackageNameToUse;
|
||||||
|
|
||||||
private CustomTabsHelper() {}
|
private CustomTabsHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
public static void addKeepAliveExtra(Context context, Intent intent) {
|
public static void addKeepAliveExtra(Context context, Intent intent) {
|
||||||
Intent keepAliveIntent = new Intent().setClassName(
|
Intent keepAliveIntent = new Intent().setClassName(
|
||||||
@ -40,7 +41,7 @@ class CustomTabsHelper {
|
|||||||
* Goes through all apps that handle VIEW intents and have a warmup service. Picks
|
* Goes through all apps that handle VIEW intents and have a warmup service. Picks
|
||||||
* the one chosen by the user if there is one, otherwise makes a best effort to return a
|
* the one chosen by the user if there is one, otherwise makes a best effort to return a
|
||||||
* valid package name.
|
* valid package name.
|
||||||
*
|
* <p>
|
||||||
* This is <strong>not</strong> threadsafe.
|
* This is <strong>not</strong> threadsafe.
|
||||||
*
|
*
|
||||||
* @param context {@link Context} to use for accessing {@link PackageManager}.
|
* @param context {@link Context} to use for accessing {@link PackageManager}.
|
||||||
@ -94,6 +95,7 @@ class CustomTabsHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Used to check whether there is a specialized handler for a given intent.
|
* Used to check whether there is a specialized handler for a given intent.
|
||||||
|
*
|
||||||
* @param intent The intent to check with.
|
* @param intent The intent to check with.
|
||||||
* @return Whether there is a specialized handler for the given intent.
|
* @return Whether there is a specialized handler for the given intent.
|
||||||
*/
|
*/
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
||||||
|
|
||||||
|
|
||||||
import java.lang.ref.WeakReference;
|
|
||||||
|
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.support.customtabs.CustomTabsClient;
|
import android.support.customtabs.CustomTabsClient;
|
||||||
import android.support.customtabs.CustomTabsServiceConnection;
|
import android.support.customtabs.CustomTabsServiceConnection;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation for the CustomTabsServiceConnection that avoids leaking the
|
* Implementation for the CustomTabsServiceConnection that avoids leaking the
|
||||||
* ServiceConnectionCallback
|
* ServiceConnectionCallback
|
||||||
|
@ -7,6 +7,7 @@ import android.support.customtabs.CustomTabsClient;
|
|||||||
public interface ServiceConnectionCallback {
|
public interface ServiceConnectionCallback {
|
||||||
/**
|
/**
|
||||||
* Called when the service is connected.
|
* Called when the service is connected.
|
||||||
|
*
|
||||||
* @param client a CustomTabsClient
|
* @param client a CustomTabsClient
|
||||||
*/
|
*/
|
||||||
void onServiceConnected(CustomTabsClient client);
|
void onServiceConnected(CustomTabsClient client);
|
||||||
|
@ -15,7 +15,8 @@ import com.mikepenz.materialdrawer.util.DrawerImageLoader
|
|||||||
import com.mikepenz.materialdrawer.util.DrawerUIUtils
|
import com.mikepenz.materialdrawer.util.DrawerUIUtils
|
||||||
import com.mikepenz.materialize.util.UIUtils
|
import com.mikepenz.materialize.util.UIUtils
|
||||||
|
|
||||||
abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> : BaseDrawerItem<T, VH>() {
|
abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> :
|
||||||
|
BaseDrawerItem<T, VH>() {
|
||||||
fun withIcon(url: String): T {
|
fun withIcon(url: String): T {
|
||||||
this.icon = ImageHolder(url)
|
this.icon = ImageHolder(url)
|
||||||
return this as T
|
return this as T
|
||||||
@ -76,8 +77,8 @@ abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> :
|
|||||||
|
|
||||||
//set the background for the item
|
//set the background for the item
|
||||||
UIUtils.setBackground(
|
UIUtils.setBackground(
|
||||||
viewHolder.view,
|
viewHolder.view,
|
||||||
UIUtils.getSelectableBackground(ctx, selectedColor, true)
|
UIUtils.getSelectableBackground(ctx, selectedColor, true)
|
||||||
)
|
)
|
||||||
//set the text for the name
|
//set the text for the name
|
||||||
StringHolder.applyTo(this.getName(), viewHolder.name)
|
StringHolder.applyTo(this.getName(), viewHolder.name)
|
||||||
@ -88,9 +89,9 @@ abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> :
|
|||||||
viewHolder.name.setTextColor(getTextColorStateList(color, selectedTextColor))
|
viewHolder.name.setTextColor(getTextColorStateList(color, selectedTextColor))
|
||||||
//set the description text color
|
//set the description text color
|
||||||
ColorHolder.applyToOr(
|
ColorHolder.applyToOr(
|
||||||
descriptionTextColor,
|
descriptionTextColor,
|
||||||
viewHolder.description,
|
viewHolder.description,
|
||||||
getTextColorStateList(color, selectedTextColor)
|
getTextColorStateList(color, selectedTextColor)
|
||||||
)
|
)
|
||||||
|
|
||||||
//define the typeface for our textViews
|
//define the typeface for our textViews
|
||||||
|
@ -10,7 +10,9 @@ import com.mikepenz.materialdrawer.holder.BadgeStyle
|
|||||||
import com.mikepenz.materialdrawer.holder.StringHolder
|
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||||
import com.mikepenz.materialdrawer.model.interfaces.ColorfulBadgeable
|
import com.mikepenz.materialdrawer.model.interfaces.ColorfulBadgeable
|
||||||
|
|
||||||
class CustomUrlPrimaryDrawerItem : CustomUrlBasePrimaryDrawerItem<CustomUrlPrimaryDrawerItem, CustomUrlPrimaryDrawerItem.ViewHolder>(), ColorfulBadgeable<CustomUrlPrimaryDrawerItem> {
|
class CustomUrlPrimaryDrawerItem :
|
||||||
|
CustomUrlBasePrimaryDrawerItem<CustomUrlPrimaryDrawerItem, CustomUrlPrimaryDrawerItem.ViewHolder>(),
|
||||||
|
ColorfulBadgeable<CustomUrlPrimaryDrawerItem> {
|
||||||
protected var mBadge: StringHolder = StringHolder("")
|
protected var mBadge: StringHolder = StringHolder("")
|
||||||
protected var mBadgeStyle = BadgeStyle()
|
protected var mBadgeStyle = BadgeStyle()
|
||||||
|
|
||||||
@ -64,8 +66,8 @@ class CustomUrlPrimaryDrawerItem : CustomUrlBasePrimaryDrawerItem<CustomUrlPrima
|
|||||||
//style the badge if it is visible
|
//style the badge if it is visible
|
||||||
if (badgeVisible) {
|
if (badgeVisible) {
|
||||||
mBadgeStyle.style(
|
mBadgeStyle.style(
|
||||||
viewHolder.badge,
|
viewHolder.badge,
|
||||||
getTextColorStateList(getColor(ctx), getSelectedTextColor(ctx))
|
getTextColorStateList(getColor(ctx), getSelectedTextColor(ctx))
|
||||||
)
|
)
|
||||||
viewHolder.badgeContainer.visibility = View.VISIBLE
|
viewHolder.badgeContainer.visibility = View.VISIBLE
|
||||||
} else {
|
} else {
|
||||||
|
@ -9,31 +9,31 @@ import com.bumptech.glide.request.RequestOptions
|
|||||||
import com.bumptech.glide.request.target.BitmapImageViewTarget
|
import com.bumptech.glide.request.target.BitmapImageViewTarget
|
||||||
|
|
||||||
fun Context.bitmapCenterCrop(url: String, iv: ImageView) =
|
fun Context.bitmapCenterCrop(url: String, iv: ImageView) =
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.load(url)
|
.load(url)
|
||||||
.apply(RequestOptions.centerCropTransform())
|
.apply(RequestOptions.centerCropTransform())
|
||||||
.into(iv)
|
.into(iv)
|
||||||
|
|
||||||
fun Context.bitmapFitCenter(url: String, iv: ImageView) =
|
fun Context.bitmapFitCenter(url: String, iv: ImageView) =
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.load(url)
|
.load(url)
|
||||||
.apply(RequestOptions.fitCenterTransform())
|
.apply(RequestOptions.fitCenterTransform())
|
||||||
.into(iv)
|
.into(iv)
|
||||||
|
|
||||||
fun Context.circularBitmapDrawable(url: String, iv: ImageView) =
|
fun Context.circularBitmapDrawable(url: String, iv: ImageView) =
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.load(url)
|
.load(url)
|
||||||
.apply(RequestOptions.centerCropTransform())
|
.apply(RequestOptions.centerCropTransform())
|
||||||
.into(object : BitmapImageViewTarget(iv) {
|
.into(object : BitmapImageViewTarget(iv) {
|
||||||
override fun setResource(resource: Bitmap?) {
|
override fun setResource(resource: Bitmap?) {
|
||||||
val circularBitmapDrawable = RoundedBitmapDrawableFactory.create(
|
val circularBitmapDrawable = RoundedBitmapDrawableFactory.create(
|
||||||
resources,
|
resources,
|
||||||
resource
|
resource
|
||||||
)
|
)
|
||||||
circularBitmapDrawable.isCircular = true
|
circularBitmapDrawable.isCircular = true
|
||||||
iv.setImageDrawable(circularBitmapDrawable)
|
iv.setImageDrawable(circularBitmapDrawable)
|
||||||
}
|
}
|
||||||
})
|
})
|
@ -23,9 +23,9 @@ class SelfSignedGlideModule : GlideModule {
|
|||||||
val client = getUnsafeHttpClient().build()
|
val client = getUnsafeHttpClient().build()
|
||||||
|
|
||||||
registry?.append(
|
registry?.append(
|
||||||
GlideUrl::class.java,
|
GlideUrl::class.java,
|
||||||
InputStream::class.java,
|
InputStream::class.java,
|
||||||
com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader.Factory(client)
|
com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader.Factory(client)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user