Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
4565079f29 | |||
3482092cb2 | |||
2df5e52de0 | |||
0ef4fc67fa | |||
e2bfd549d3 | |||
7071af5fa5 | |||
95f267f701 | |||
f363bbcc0c | |||
65a912f271 | |||
758661f5fb | |||
2d3c297726 | |||
ca85e3d3ed | |||
2190ad0387 | |||
0d067e05af | |||
c3305b7523 | |||
fb84b31122 | |||
9d40026ef7 | |||
041a225992 | |||
b42dc7f87c | |||
0283e49c27 | |||
e5e1b2f5a5 | |||
813a0ae475 | |||
f0e036cdd8 |
14
CHANGELOG.md
14
CHANGELOG.md
@ -1,3 +1,17 @@
|
|||||||
|
**1.5.1**
|
||||||
|
|
||||||
|
- Added a drawer for filtering sources and tags.
|
||||||
|
|
||||||
|
- You can now search for items from the toolbar.
|
||||||
|
|
||||||
|
**1.5.0.2**
|
||||||
|
|
||||||
|
- If the content in the article viewer is empty, the article will open in a custom tab.
|
||||||
|
|
||||||
|
- Added a share button, and an "open in browser" button to the bottom of the article viewer.
|
||||||
|
|
||||||
|
- Updated custom tab code.
|
||||||
|
|
||||||
**1.5.0.1**
|
**1.5.0.1**
|
||||||
|
|
||||||
- The release APK wasn't working at all.
|
- The release APK wasn't working at all.
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# ReaderForSelfoss
|
# ReaderForSelfoss
|
||||||
|
|
||||||
|
[](https://circleci.com/gh/aminecmi/ReaderforSelfoss/tree/master)
|
||||||
|
|
||||||
This is the repo of [Reader For Selfoss](https://play.google.com/store/apps/details?id=apps.amine.bou.readerforselfoss&hl=en).
|
This is the repo of [Reader For Selfoss](https://play.google.com/store/apps/details?id=apps.amine.bou.readerforselfoss&hl=en).
|
||||||
|
|
||||||
It's an RSS Reader for Android, that **only** works with [Selfoss](https://selfoss.aditu.de/)
|
It's an RSS Reader for Android, that **only** works with [Selfoss](https://selfoss.aditu.de/)
|
||||||
@ -26,4 +28,3 @@ You'll have to:
|
|||||||
- [Check what changed](https://github.com/aminecmi/ReaderforSelfoss/blob/master/CHANGELOG.md)
|
- [Check what changed](https://github.com/aminecmi/ReaderforSelfoss/blob/master/CHANGELOG.md)
|
||||||
- [See what I'm doing](https://github.com/aminecmi/ReaderforSelfoss/projects/1)
|
- [See what I'm doing](https://github.com/aminecmi/ReaderforSelfoss/projects/1)
|
||||||
- [Create an issue, or request a new feature](https://github.com/aminecmi/ReaderforSelfoss/issues)
|
- [Create an issue, or request a new feature](https://github.com/aminecmi/ReaderforSelfoss/issues)
|
||||||
- [Help me translate the app](https://poeditor.com/join/project/viHr8ujJ7S)
|
|
@ -25,8 +25,8 @@ android {
|
|||||||
applicationId "apps.amine.bou.readerforselfoss"
|
applicationId "apps.amine.bou.readerforselfoss"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 25
|
targetSdkVersion 25
|
||||||
versionCode 1501
|
versionCode 1510
|
||||||
versionName "1.5.0.1"
|
versionName "1.5.1"
|
||||||
|
|
||||||
// Enabling multidex support.
|
// Enabling multidex support.
|
||||||
multiDexEnabled true
|
multiDexEnabled true
|
||||||
@ -98,7 +98,7 @@ dependencies {
|
|||||||
compile 'com.burgstaller:okhttp-digest:1.12'
|
compile 'com.burgstaller:okhttp-digest:1.12'
|
||||||
|
|
||||||
// Material-ish things
|
// Material-ish things
|
||||||
compile 'com.roughike:bottom-bar:2.2.0'
|
compile 'com.roughike:bottom-bar:2.3.1'
|
||||||
compile 'com.melnykov:floatingactionbutton:1.3.0'
|
compile 'com.melnykov:floatingactionbutton:1.3.0'
|
||||||
compile 'com.github.jd-alexander:LikeButton:0.2.1'
|
compile 'com.github.jd-alexander:LikeButton:0.2.1'
|
||||||
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||||
@ -113,12 +113,28 @@ dependencies {
|
|||||||
// For the article reader
|
// For the article reader
|
||||||
compile 'com.klinkerapps:drag-dismiss-activity:1.4.0'
|
compile 'com.klinkerapps:drag-dismiss-activity:1.4.0'
|
||||||
|
|
||||||
|
// Drawer
|
||||||
|
compile('com.mikepenz:materialdrawer:5.9.2@aar') {
|
||||||
|
transitive = true
|
||||||
|
}
|
||||||
|
compile 'com.anupcowkur:reservoir:3.1.0'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
|
||||||
|
|
||||||
|
afterEvaluate {
|
||||||
|
initFabricPropertiesIfNeeded()
|
||||||
|
}
|
||||||
|
|
||||||
|
def initFabricPropertiesIfNeeded() {
|
||||||
|
def propertiesFile = file('fabric.properties')
|
||||||
|
if (!propertiesFile.exists()) {
|
||||||
|
def commentMessage = "This is autogenerated fabric property from system environment to prevent key to be committed to source control."
|
||||||
|
ant.propertyfile(file: "fabric.properties", comment: commentMessage) {
|
||||||
|
entry(key: "apiSecret", value: crashlyticsdemoApisecret)
|
||||||
|
entry(key: "apiKey", value: crashlyticsdemoApikey)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -31,7 +31,8 @@
|
|||||||
<activity android:name=".LoginActivity"
|
<activity android:name=".LoginActivity"
|
||||||
android:label="@string/title_activity_login">
|
android:label="@string/title_activity_login">
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".HomeActivity">
|
<activity android:name=".HomeActivity"
|
||||||
|
android:theme="@style/NoBar">
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".settings.SettingsActivity"
|
android:name=".settings.SettingsActivity"
|
||||||
|
@ -4,30 +4,34 @@ import android.app.Activity
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
import android.support.design.widget.CoordinatorLayout
|
import android.support.design.widget.CoordinatorLayout
|
||||||
|
import android.support.v4.view.MenuItemCompat
|
||||||
import android.support.v4.widget.SwipeRefreshLayout
|
import android.support.v4.widget.SwipeRefreshLayout
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.widget.GridLayoutManager
|
import android.support.v7.widget.*
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.support.v7.widget.StaggeredGridLayoutManager
|
|
||||||
import android.support.v7.widget.helper.ItemTouchHelper
|
import android.support.v7.widget.helper.ItemTouchHelper
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
|
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
|
||||||
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
|
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.Item
|
import apps.amine.bou.readerforselfoss.api.selfoss.*
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.Stats
|
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
|
|
||||||
import apps.amine.bou.readerforselfoss.settings.SettingsActivity
|
import apps.amine.bou.readerforselfoss.settings.SettingsActivity
|
||||||
import apps.amine.bou.readerforselfoss.utils.Config
|
import apps.amine.bou.readerforselfoss.utils.Config
|
||||||
import apps.amine.bou.readerforselfoss.utils.checkAndDisplayStoreApk
|
import apps.amine.bou.readerforselfoss.utils.checkAndDisplayStoreApk
|
||||||
import apps.amine.bou.readerforselfoss.utils.checkApkVersion
|
import apps.amine.bou.readerforselfoss.utils.checkApkVersion
|
||||||
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
|
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
|
||||||
|
import apps.amine.bou.readerforselfoss.utils.drawer.CustomUrlPrimaryDrawerItem
|
||||||
|
import apps.amine.bou.readerforselfoss.utils.longHash
|
||||||
|
import com.anupcowkur.reservoir.Reservoir
|
||||||
|
import com.anupcowkur.reservoir.ReservoirGetCallback
|
||||||
|
import com.anupcowkur.reservoir.ReservoirPutCallback
|
||||||
import com.crashlytics.android.answers.Answers
|
import com.crashlytics.android.answers.Answers
|
||||||
import com.crashlytics.android.answers.InviteEvent
|
import com.crashlytics.android.answers.InviteEvent
|
||||||
import com.github.stkent.amplify.prompt.DefaultLayoutPromptView
|
import com.github.stkent.amplify.prompt.DefaultLayoutPromptView
|
||||||
@ -36,21 +40,30 @@ import com.google.android.gms.appinvite.AppInviteInvitation
|
|||||||
import com.google.android.gms.common.ConnectionResult
|
import com.google.android.gms.common.ConnectionResult
|
||||||
import com.google.android.gms.common.GoogleApiAvailability
|
import com.google.android.gms.common.GoogleApiAvailability
|
||||||
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
|
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
|
||||||
|
import com.google.gson.reflect.TypeToken
|
||||||
import com.mikepenz.aboutlibraries.Libs
|
import com.mikepenz.aboutlibraries.Libs
|
||||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
import com.mikepenz.aboutlibraries.LibsBuilder
|
||||||
|
import com.mikepenz.materialdrawer.Drawer
|
||||||
|
import com.mikepenz.materialdrawer.DrawerBuilder
|
||||||
|
import com.mikepenz.materialdrawer.holder.BadgeStyle
|
||||||
|
import com.mikepenz.materialdrawer.model.DividerDrawerItem
|
||||||
|
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
|
||||||
|
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
|
||||||
import com.roughike.bottombar.BottomBar
|
import com.roughike.bottombar.BottomBar
|
||||||
import com.roughike.bottombar.BottomBarTab
|
import com.roughike.bottombar.BottomBarTab
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
import java.lang.Exception
|
||||||
|
|
||||||
|
class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||||
class HomeActivity : AppCompatActivity() {
|
|
||||||
|
|
||||||
|
|
||||||
private val MENU_PREFERENCES = 12302
|
private val MENU_PREFERENCES = 12302
|
||||||
private val REQUEST_INVITE = 13231
|
private val REQUEST_INVITE = 13231
|
||||||
private val REQUEST_INVITE_BYMAIL = 13232
|
private val REQUEST_INVITE_BYMAIL = 13232
|
||||||
|
private val DRAWER_ID_TAGS = 100101L
|
||||||
|
private val DRAWER_ID_SOURCES = 100110L
|
||||||
|
private val DRAWER_ID_FILTERS = 100111L
|
||||||
private var mRecyclerView: RecyclerView? = null
|
private var mRecyclerView: RecyclerView? = null
|
||||||
private var api: SelfossApi? = null
|
private var api: SelfossApi? = null
|
||||||
private var items: ArrayList<Item> = ArrayList()
|
private var items: ArrayList<Item> = ArrayList()
|
||||||
@ -77,6 +90,13 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
private var tabStarred: BottomBarTab? = null
|
private var tabStarred: BottomBarTab? = null
|
||||||
private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null
|
private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null
|
||||||
private var fullHeightCards: Boolean = false
|
private var fullHeightCards: Boolean = false
|
||||||
|
private var toolbar: Toolbar? = null
|
||||||
|
private var drawer: Drawer? = null
|
||||||
|
private var maybeTagFilter: Tag? = null
|
||||||
|
private var maybeSourceFilter: Sources? = null
|
||||||
|
private var maybeSearchFilter: String? = null
|
||||||
|
|
||||||
|
data class DrawerData(val tags: List<Tag>?, val sources: List<Sources>?)
|
||||||
|
|
||||||
private fun handleSharedPrefs() {
|
private fun handleSharedPrefs() {
|
||||||
clickBehavior = this.sharedPref!!.getBoolean("tab_on_tap", false)
|
clickBehavior = this.sharedPref!!.getBoolean("tab_on_tap", false)
|
||||||
@ -91,6 +111,8 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
|
handleDrawerItems()
|
||||||
|
|
||||||
sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
|
sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
val settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
|
val settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
|
||||||
@ -110,13 +132,219 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun handleDrawer() {
|
||||||
|
|
||||||
|
drawer = DrawerBuilder()
|
||||||
|
.withActivity(this)
|
||||||
|
.withRootView(R.id.drawer_layout)
|
||||||
|
.withToolbar(toolbar!!)
|
||||||
|
.withActionBarDrawerToggle(true)
|
||||||
|
.withActionBarDrawerToggleAnimated(true)
|
||||||
|
.withShowDrawerOnFirstLaunch(true)
|
||||||
|
.withOnDrawerListener(object: Drawer.OnDrawerListener {
|
||||||
|
override fun onDrawerSlide(p0: View?, p1: Float) {
|
||||||
|
mBottomBar!!.alpha = (1 - p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDrawerClosed(p0: View?) {
|
||||||
|
mBottomBar!!.shySettings.showBar()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDrawerOpened(p0: View?) {
|
||||||
|
mBottomBar!!.shySettings.hideBar()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.build()
|
||||||
|
|
||||||
|
drawer!!.addStickyFooterItem(
|
||||||
|
PrimaryDrawerItem()
|
||||||
|
.withName(R.string.action_about)
|
||||||
|
.withSelectable(false)
|
||||||
|
.withIcon(R.drawable.ic_info_outline)
|
||||||
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
|
LibsBuilder()
|
||||||
|
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
|
||||||
|
.withAboutIconShown(true)
|
||||||
|
.withAboutVersionShown(true)
|
||||||
|
.start(this@HomeActivity)
|
||||||
|
false
|
||||||
|
})
|
||||||
|
drawer!!.addStickyFooterItem(
|
||||||
|
PrimaryDrawerItem()
|
||||||
|
.withName(R.string.title_activity_settings)
|
||||||
|
.withIcon(R.drawable.ic_settings)
|
||||||
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
|
startActivityForResult(Intent(this@HomeActivity, SettingsActivity::class.java), MENU_PREFERENCES)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleDrawerItems() {
|
||||||
|
fun handleDrawerData(maybeDrawerData: DrawerData?, loadedFromCache: Boolean = false) {
|
||||||
|
fun handleTags(maybeTags: List<Tag>?) {
|
||||||
|
if (maybeTags == null) {
|
||||||
|
if (loadedFromCache)
|
||||||
|
drawer!!.addItem(SecondaryDrawerItem().withName(getString(R.string.drawer_error_loading_tags)).withSelectable(false))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (tag in maybeTags) {
|
||||||
|
val gd: GradientDrawable = GradientDrawable()
|
||||||
|
gd.setColor(Color.parseColor(tag.color))
|
||||||
|
gd.shape = GradientDrawable.RECTANGLE
|
||||||
|
gd.setSize(30, 30)
|
||||||
|
gd.cornerRadius = 30F
|
||||||
|
drawer!!.addItem(
|
||||||
|
PrimaryDrawerItem()
|
||||||
|
.withName(tag.tag)
|
||||||
|
.withIdentifier(longHash(tag.tag))
|
||||||
|
.withIcon(gd)
|
||||||
|
.withBadge("${tag.unread}")
|
||||||
|
.withBadgeStyle(
|
||||||
|
BadgeStyle().withTextColor(Color.WHITE)
|
||||||
|
.withColorRes(R.color.colorAccent)
|
||||||
|
)
|
||||||
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
|
maybeTagFilter = tag
|
||||||
|
getElementsAccordingToTab()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun handleSources(maybeSources: List<Sources>?) {
|
||||||
|
if (maybeSources == null) {
|
||||||
|
if (loadedFromCache)
|
||||||
|
drawer!!.addItem(SecondaryDrawerItem().withName(getString(R.string.drawer_error_loading_sources)).withSelectable(false))
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (tag in maybeSources)
|
||||||
|
drawer!!.addItem(
|
||||||
|
CustomUrlPrimaryDrawerItem()
|
||||||
|
.withName(tag.title)
|
||||||
|
.withIdentifier(tag.id.toLong())
|
||||||
|
.withIcon(tag.getIcon(this@HomeActivity))
|
||||||
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
|
maybeSourceFilter = tag
|
||||||
|
getElementsAccordingToTab()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
drawer!!.removeAllItems()
|
||||||
|
if (maybeDrawerData != null) {
|
||||||
|
drawer!!.addItem(
|
||||||
|
SecondaryDrawerItem()
|
||||||
|
.withName(getString(R.string.drawer_item_filters))
|
||||||
|
.withSelectable(false)
|
||||||
|
.withIdentifier(DRAWER_ID_FILTERS)
|
||||||
|
.withBadge(getString(R.string.drawer_action_clear))
|
||||||
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
|
maybeSourceFilter = null
|
||||||
|
maybeTagFilter = null
|
||||||
|
getElementsAccordingToTab()
|
||||||
|
false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
drawer!!.addItem(DividerDrawerItem())
|
||||||
|
drawer!!.addItem(SecondaryDrawerItem().withName(getString(R.string.drawer_item_tags)).withIdentifier(DRAWER_ID_TAGS).withSelectable(false))
|
||||||
|
handleTags(maybeDrawerData.tags)
|
||||||
|
drawer!!.addItem(
|
||||||
|
SecondaryDrawerItem()
|
||||||
|
.withName(getString(R.string.drawer_item_sources))
|
||||||
|
.withIdentifier(DRAWER_ID_TAGS)
|
||||||
|
.withBadge(getString(R.string.drawer_action_edit))
|
||||||
|
.withSelectable(false)
|
||||||
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
|
startActivity(Intent(this, SourcesActivity::class.java))
|
||||||
|
false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
handleSources(maybeDrawerData.sources)
|
||||||
|
|
||||||
|
|
||||||
|
if (!loadedFromCache)
|
||||||
|
Reservoir.putAsync("drawerData", maybeDrawerData, object : ReservoirPutCallback {
|
||||||
|
override fun onSuccess() {}
|
||||||
|
|
||||||
|
override fun onFailure(p0: Exception?) {
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (!loadedFromCache) {
|
||||||
|
drawer!!.addItem(PrimaryDrawerItem().withName(getString(R.string.no_tags_loaded)).withIdentifier(DRAWER_ID_TAGS).withSelectable(false))
|
||||||
|
drawer!!.addItem(PrimaryDrawerItem().withName(getString(R.string.no_sources_loaded)).withIdentifier(DRAWER_ID_SOURCES).withSelectable(false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun drawerApiCalls(maybeDrawerData: DrawerData?) {
|
||||||
|
var tags: List<Tag>? = null
|
||||||
|
var sources: List<Sources>?
|
||||||
|
|
||||||
|
fun sourcesApiCall() {
|
||||||
|
api!!.sources.enqueue(object: Callback<List<Sources>> {
|
||||||
|
override fun onResponse(call: Call<List<Sources>>?, response: Response<List<Sources>>) {
|
||||||
|
sources = response.body()
|
||||||
|
val apiDrawerData = DrawerData(tags, sources)
|
||||||
|
if (maybeDrawerData == null || (maybeDrawerData != null && maybeDrawerData != apiDrawerData))
|
||||||
|
handleDrawerData(apiDrawerData)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<List<Sources>>?, t: Throwable?) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
api!!.tags.enqueue(object: Callback<List<Tag>> {
|
||||||
|
override fun onResponse(call: Call<List<Tag>>, response: Response<List<Tag>>) {
|
||||||
|
tags = response.body()
|
||||||
|
sourcesApiCall()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call<List<Tag>>?, t: Throwable?) {
|
||||||
|
sourcesApiCall()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
drawer!!.addItem(PrimaryDrawerItem().withName(getString(R.string.drawer_loading)).withSelectable(false))
|
||||||
|
|
||||||
|
val resultType = object : TypeToken<DrawerData>() {}.type
|
||||||
|
Reservoir.getAsync("drawerData", resultType, object: ReservoirGetCallback<DrawerData> {
|
||||||
|
override fun onSuccess(maybeDrawerData: DrawerData?) {
|
||||||
|
handleDrawerData(maybeDrawerData, loadedFromCache = true)
|
||||||
|
drawerApiCalls(maybeDrawerData)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(p0: Exception?) {
|
||||||
|
drawerApiCalls(null)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_home)
|
setContentView(R.layout.activity_home)
|
||||||
|
|
||||||
|
toolbar = findViewById(R.id.toolbar) as Toolbar?
|
||||||
|
setSupportActionBar(toolbar)
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
val promptView = findViewById(R.id.prompt_view) as DefaultLayoutPromptView
|
val promptView = findViewById(R.id.prompt_view) as DefaultLayoutPromptView
|
||||||
|
|
||||||
Amplify.getSharedInstance().promptIfReady(promptView)
|
Amplify.getSharedInstance().promptIfReady(promptView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +358,8 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
mBottomBar = findViewById(R.id.bottomBar) as BottomBar
|
mBottomBar = findViewById(R.id.bottomBar) as BottomBar
|
||||||
|
|
||||||
|
handleDrawer()
|
||||||
|
|
||||||
// TODO: clean this hack
|
// TODO: clean this hack
|
||||||
val listenerAlreadySet = booleanArrayOf(false)
|
val listenerAlreadySet = booleanArrayOf(false)
|
||||||
mBottomBar!!.setOnTabSelectListener { tabId ->
|
mBottomBar!!.setOnTabSelectListener { tabId ->
|
||||||
@ -229,7 +459,6 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getElementsAccordingToTab() {
|
private fun getElementsAccordingToTab() {
|
||||||
items = ArrayList()
|
|
||||||
|
|
||||||
when (elementsShown) {
|
when (elementsShown) {
|
||||||
UNREAD_SHOWN -> getUnRead()
|
UNREAD_SHOWN -> getUnRead()
|
||||||
@ -241,15 +470,9 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun getUnRead() {
|
private fun getUnRead() {
|
||||||
elementsShown = UNREAD_SHOWN
|
elementsShown = UNREAD_SHOWN
|
||||||
api!!.unreadItems.enqueue(object : Callback<List<Item>> {
|
api!!.unreadItems(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter).enqueue(object : Callback<List<Item>> {
|
||||||
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
||||||
if (response.body() != null && response.body()!!.isNotEmpty()) {
|
handleItemsResponse(response)
|
||||||
items = response.body() as ArrayList<Item>
|
|
||||||
} else {
|
|
||||||
items = ArrayList()
|
|
||||||
}
|
|
||||||
handleListResult()
|
|
||||||
mSwipeRefreshLayout!!.isRefreshing = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
||||||
@ -259,17 +482,26 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun handleItemsResponse(response: Response<List<Item>>) {
|
||||||
|
val didUpdate = (response.body() != items)
|
||||||
|
if (response.body() != null) {
|
||||||
|
if (response.body() != items) {
|
||||||
|
items = response.body() as ArrayList<Item>
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
items = ArrayList()
|
||||||
|
}
|
||||||
|
if (didUpdate)
|
||||||
|
handleListResult()
|
||||||
|
if (items.isEmpty()) Toast.makeText(this@HomeActivity, R.string.nothing_here, Toast.LENGTH_SHORT).show()
|
||||||
|
mSwipeRefreshLayout!!.isRefreshing = false
|
||||||
|
}
|
||||||
|
|
||||||
private fun getRead() {
|
private fun getRead() {
|
||||||
elementsShown = READ_SHOWN
|
elementsShown = READ_SHOWN
|
||||||
api!!.readItems.enqueue(object : Callback<List<Item>> {
|
api!!.readItems(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter).enqueue(object : Callback<List<Item>> {
|
||||||
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
||||||
if (response.body() != null && response.body()!!.isNotEmpty()) {
|
handleItemsResponse(response)
|
||||||
items = response.body() as ArrayList<Item>
|
|
||||||
} else {
|
|
||||||
items = ArrayList()
|
|
||||||
}
|
|
||||||
handleListResult()
|
|
||||||
mSwipeRefreshLayout!!.isRefreshing = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
||||||
@ -281,15 +513,9 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private fun getStarred() {
|
private fun getStarred() {
|
||||||
elementsShown = FAV_SHOWN
|
elementsShown = FAV_SHOWN
|
||||||
api!!.starredItems.enqueue(object : Callback<List<Item>> {
|
api!!.starredItems(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter).enqueue(object : Callback<List<Item>> {
|
||||||
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
||||||
if (response.body() != null && response.body()!!.isNotEmpty()) {
|
handleItemsResponse(response)
|
||||||
items = response.body() as ArrayList<Item>
|
|
||||||
} else {
|
|
||||||
items = ArrayList()
|
|
||||||
}
|
|
||||||
handleListResult()
|
|
||||||
mSwipeRefreshLayout!!.isRefreshing = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
||||||
@ -311,8 +537,6 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
mRecyclerView!!.adapter = mAdapter
|
mRecyclerView!!.adapter = mAdapter
|
||||||
mAdapter.notifyDataSetChanged()
|
mAdapter.notifyDataSetChanged()
|
||||||
|
|
||||||
if (items.isEmpty()) Toast.makeText(this@HomeActivity, R.string.nothing_here, Toast.LENGTH_SHORT).show()
|
|
||||||
|
|
||||||
reloadBadges()
|
reloadBadges()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,6 +553,11 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
val inflater = menuInflater
|
val inflater = menuInflater
|
||||||
inflater.inflate(R.menu.home_menu, menu)
|
inflater.inflate(R.menu.home_menu, menu)
|
||||||
|
|
||||||
|
val searchItem = menu.findItem(R.id.action_search)
|
||||||
|
val searchView = MenuItemCompat.getActionView(searchItem) as SearchView
|
||||||
|
searchView.setOnQueryTextListener(this)
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -370,6 +599,7 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
items = ArrayList()
|
items = ArrayList()
|
||||||
|
if (items.isEmpty()) Toast.makeText(this@HomeActivity, R.string.nothing_here, Toast.LENGTH_SHORT).show()
|
||||||
handleListResult()
|
handleListResult()
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
@ -384,24 +614,6 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
finish()
|
finish()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.action_sources -> {
|
|
||||||
val intent2 = Intent(this, SourcesActivity::class.java)
|
|
||||||
startActivity(intent2)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
R.id.action_settings -> {
|
|
||||||
val intent3 = Intent(this, SettingsActivity::class.java)
|
|
||||||
startActivityForResult(intent3, MENU_PREFERENCES)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
R.id.about -> {
|
|
||||||
LibsBuilder()
|
|
||||||
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
|
|
||||||
.withAboutIconShown(true)
|
|
||||||
.withAboutVersionShown(true)
|
|
||||||
.start(this)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
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))
|
||||||
@ -452,7 +664,10 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
override fun onActivityResult(req: Int, result: Int, data: Intent?) {
|
override fun onActivityResult(req: Int, result: Int, data: Intent?) {
|
||||||
when (req) {
|
when (req) {
|
||||||
MENU_PREFERENCES -> recreate()
|
MENU_PREFERENCES -> {
|
||||||
|
drawer!!.closeDrawer()
|
||||||
|
recreate()
|
||||||
|
}
|
||||||
REQUEST_INVITE -> if (result == Activity.RESULT_OK) {
|
REQUEST_INVITE -> if (result == Activity.RESULT_OK) {
|
||||||
Answers.getInstance().logInvite(InviteEvent())
|
Answers.getInstance().logInvite(InviteEvent())
|
||||||
}
|
}
|
||||||
@ -470,4 +685,18 @@ class HomeActivity : AppCompatActivity() {
|
|||||||
val dpWidth = displayMetrics.widthPixels / displayMetrics.density
|
val dpWidth = displayMetrics.widthPixels / displayMetrics.density
|
||||||
return (dpWidth / 300).toInt()
|
return (dpWidth / 300).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onQueryTextChange(p0: String?): Boolean {
|
||||||
|
if (p0.isNullOrBlank()) {
|
||||||
|
maybeSearchFilter = null
|
||||||
|
getElementsAccordingToTab()
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQueryTextSubmit(p0: String?): Boolean {
|
||||||
|
maybeSearchFilter = p0
|
||||||
|
getElementsAccordingToTab()
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
package apps.amine.bou.readerforselfoss
|
package apps.amine.bou.readerforselfoss
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.net.Uri
|
||||||
import android.support.multidex.MultiDexApplication
|
import android.support.multidex.MultiDexApplication
|
||||||
|
import android.widget.ImageView
|
||||||
import com.crashlytics.android.Crashlytics
|
import com.crashlytics.android.Crashlytics
|
||||||
import com.github.stkent.amplify.tracking.Amplify
|
import com.github.stkent.amplify.tracking.Amplify
|
||||||
import io.fabric.sdk.android.Fabric
|
import io.fabric.sdk.android.Fabric
|
||||||
|
import com.anupcowkur.reservoir.Reservoir
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.mikepenz.iconics.IconicsDrawable
|
||||||
|
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
|
||||||
|
import com.mikepenz.materialdrawer.util.DrawerImageLoader
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
|
||||||
class MyApp : MultiDexApplication() {
|
class MyApp : MultiDexApplication() {
|
||||||
@ -16,5 +26,25 @@ class MyApp : MultiDexApplication() {
|
|||||||
.setFeedbackEmailAddress(getString(R.string.feedback_email))
|
.setFeedbackEmailAddress(getString(R.string.feedback_email))
|
||||||
.setAlwaysShow(BuildConfig.DEBUG)
|
.setAlwaysShow(BuildConfig.DEBUG)
|
||||||
.applyAllDefaultRules()
|
.applyAllDefaultRules()
|
||||||
|
|
||||||
|
try {
|
||||||
|
Reservoir.init(this, 8192) //in bytes
|
||||||
|
} catch (e: IOException) {
|
||||||
|
//failure
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawerImageLoader.init(object : AbstractDrawerImageLoader() {
|
||||||
|
override fun set(imageView: ImageView?, uri: Uri?, placeholder: Drawable?, tag: String?) {
|
||||||
|
Glide.with(imageView?.context).load(uri).placeholder(placeholder).into(imageView)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun cancel(imageView: ImageView?) {
|
||||||
|
Glide.clear(imageView)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun placeholder(ctx: Context?, tag: String?): Drawable {
|
||||||
|
return applicationContext.resources.getDrawable(R.mipmap.ic_launcher)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ import android.os.Bundle
|
|||||||
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.ImageButton
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
|
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
|
||||||
@ -44,6 +45,9 @@ class ReaderActivity : DragDismissActivity() {
|
|||||||
val content = v.findViewById(R.id.content) as HtmlTextView
|
val content = v.findViewById(R.id.content) as HtmlTextView
|
||||||
val url = intent.getStringExtra("url")
|
val url = intent.getStringExtra("url")
|
||||||
val parser = MercuryApi(getString(R.string.mercury))
|
val parser = MercuryApi(getString(R.string.mercury))
|
||||||
|
val browserBtn: ImageButton = v.findViewById(R.id.browserBtn) as ImageButton
|
||||||
|
val shareBtn: ImageButton = v.findViewById(R.id.shareBtn) as ImageButton
|
||||||
|
|
||||||
|
|
||||||
val customTabsIntent = buildCustomTabsIntent(this@ReaderActivity)
|
val customTabsIntent = buildCustomTabsIntent(this@ReaderActivity)
|
||||||
mCustomTabActivityHelper = CustomTabActivityHelper()
|
mCustomTabActivityHelper = CustomTabActivityHelper()
|
||||||
@ -52,13 +56,30 @@ class ReaderActivity : DragDismissActivity() {
|
|||||||
|
|
||||||
parser.parseUrl(url).enqueue(object : Callback<ParsedContent> {
|
parser.parseUrl(url).enqueue(object : Callback<ParsedContent> {
|
||||||
override fun onResponse(call: Call<ParsedContent>, response: Response<ParsedContent>) {
|
override fun onResponse(call: Call<ParsedContent>, response: Response<ParsedContent>) {
|
||||||
if (response.body() != null) {
|
if (response.body() != null && response.body()!!.content != null && response.body()!!.content.isNotEmpty()) {
|
||||||
source.text = response.body()!!.domain
|
source.text = response.body()!!.domain
|
||||||
title.text = response.body()!!.title
|
title.text = response.body()!!.title
|
||||||
if (response.body()!!.content != null && !response.body()!!.content.isEmpty())
|
if (response.body()!!.content != null && !response.body()!!.content.isEmpty())
|
||||||
content.setHtml(response.body()!!.content, HtmlHttpImageGetter(content, null, true))
|
content.setHtml(response.body()!!.content, HtmlHttpImageGetter(content, null, true))
|
||||||
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isEmpty())
|
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isEmpty())
|
||||||
Glide.with(applicationContext).load(response.body()!!.lead_image_url).asBitmap().fitCenter().into(image)
|
Glide.with(applicationContext).load(response.body()!!.lead_image_url).asBitmap().fitCenter().into(image)
|
||||||
|
|
||||||
|
shareBtn.setOnClickListener {
|
||||||
|
val sendIntent = Intent()
|
||||||
|
sendIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
sendIntent.action = Intent.ACTION_SEND
|
||||||
|
sendIntent.putExtra(Intent.EXTRA_TEXT, response.body()!!.url)
|
||||||
|
sendIntent.type = "text/plain"
|
||||||
|
startActivity(Intent.createChooser(sendIntent, getString(R.string.share)).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK))
|
||||||
|
}
|
||||||
|
|
||||||
|
browserBtn.setOnClickListener {
|
||||||
|
val intent = Intent(Intent.ACTION_VIEW)
|
||||||
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
|
intent.data = Uri.parse(response.body()!!.url)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
hideProgressBar()
|
hideProgressBar()
|
||||||
} else {
|
} else {
|
||||||
errorAfterMercuryCall()
|
errorAfterMercuryCall()
|
||||||
|
@ -72,17 +72,17 @@ class SelfossApi(c: Context) {
|
|||||||
return service.loginToSelfoss(config.userLogin, config.userPassword)
|
return service.loginToSelfoss(config.userLogin, config.userPassword)
|
||||||
}
|
}
|
||||||
|
|
||||||
val readItems: Call<List<Item>>
|
fun readItems(tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
|
||||||
get() = getItems("read")
|
getItems("read", tag, sourceId, search)
|
||||||
|
|
||||||
val unreadItems: Call<List<Item>>
|
fun unreadItems(tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
|
||||||
get() = getItems("unread")
|
getItems("unread", tag, sourceId, search)
|
||||||
|
|
||||||
val starredItems: Call<List<Item>>
|
fun starredItems(tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
|
||||||
get() = getItems("starred")
|
getItems("starred", tag, sourceId, search)
|
||||||
|
|
||||||
private fun getItems(type: String): Call<List<Item>> {
|
private fun getItems(type: String, tag: String?, sourceId: Long?, search: String?): Call<List<Item>> {
|
||||||
return service.getItems(type, userName, password)
|
return service.getItems(type, tag, sourceId, search, userName, password)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun markItem(itemId: String): Call<SuccessResponse> {
|
fun markItem(itemId: String): Call<SuccessResponse> {
|
||||||
|
@ -16,7 +16,12 @@ internal interface SelfossService {
|
|||||||
fun loginToSelfoss(@Query("username") username: String, @Query("password") password: String): Call<SuccessResponse>
|
fun loginToSelfoss(@Query("username") username: String, @Query("password") password: String): Call<SuccessResponse>
|
||||||
|
|
||||||
@GET("items")
|
@GET("items")
|
||||||
fun getItems(@Query("type") type: String, @Query("username") username: String, @Query("password") password: String): Call<List<Item>>
|
fun getItems(@Query("type") type: String,
|
||||||
|
@Query("tag") tag: String?,
|
||||||
|
@Query("source") source: Long?,
|
||||||
|
@Query("search") search: String?,
|
||||||
|
@Query("username") username: String,
|
||||||
|
@Query("password") password: String): Call<List<Item>>
|
||||||
|
|
||||||
@POST("mark/{id}")
|
@POST("mark/{id}")
|
||||||
fun markAsRead(@Path("id") id: String, @Query("username") username: String, @Query("password") password: String): Call<SuccessResponse>
|
fun markAsRead(@Path("id") id: String, @Query("username") username: String, @Query("password") password: String): Call<SuccessResponse>
|
||||||
|
@ -86,3 +86,14 @@ private fun isThereAnUpdate(settings: SharedPreferences, editor: SharedPreferenc
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun longHash(string: String): Long {
|
||||||
|
var h = 98764321261L
|
||||||
|
val l = string.length
|
||||||
|
val chars = string.toCharArray()
|
||||||
|
|
||||||
|
for (i in 0..l - 1) {
|
||||||
|
h = 31 * h + chars[i].toLong()
|
||||||
|
}
|
||||||
|
return h
|
||||||
|
}
|
@ -1,7 +1,6 @@
|
|||||||
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.customtabs.CustomTabsClient;
|
import android.support.customtabs.CustomTabsClient;
|
||||||
@ -11,28 +10,30 @@ import android.support.customtabs.CustomTabsSession;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@SuppressWarnings("ALL")
|
/**
|
||||||
public class CustomTabActivityHelper {
|
* This is a helper class to manage the connection to the Custom Tabs Service.
|
||||||
|
*/
|
||||||
|
public class CustomTabActivityHelper implements ServiceConnectionCallback {
|
||||||
private CustomTabsSession mCustomTabsSession;
|
private CustomTabsSession mCustomTabsSession;
|
||||||
private CustomTabsClient mClient;
|
private CustomTabsClient mClient;
|
||||||
private CustomTabsServiceConnection mConnection;
|
private CustomTabsServiceConnection mConnection;
|
||||||
private ConnectionCallback mConnectionCallback;
|
private ConnectionCallback mConnectionCallback;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 there's no browser that supports
|
//If we cant find a package name, it means theres no browser that supports
|
||||||
//Chrome Custom Tabs installed. So, we fallback to the webview
|
//Chrome Custom Tabs installed. So, we fallback to the webview
|
||||||
if (packageName == null) {
|
if (packageName == null) {
|
||||||
if (fallback != null) {
|
if (fallback != null) {
|
||||||
@ -45,22 +46,21 @@ public class CustomTabActivityHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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) {
|
||||||
try {
|
if (mConnection == null) return;
|
||||||
if (mConnection == null) return;
|
activity.unbindService(mConnection);
|
||||||
activity.unbindService(mConnection);
|
mClient = null;
|
||||||
mClient = null;
|
mCustomTabsSession = null;
|
||||||
mCustomTabsSession = null;
|
mConnection = null;
|
||||||
} catch (RuntimeException e) {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates or retrieves an exiting CustomTabsSession
|
* Creates or retrieves an exiting CustomTabsSession.
|
||||||
*
|
*
|
||||||
* @return a CustomTabsSession
|
* @return a CustomTabsSession.
|
||||||
*/
|
*/
|
||||||
public CustomTabsSession getSession() {
|
public CustomTabsSession getSession() {
|
||||||
if (mClient == null) {
|
if (mClient == null) {
|
||||||
@ -72,7 +72,7 @@ public class CustomTabActivityHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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) {
|
||||||
@ -80,65 +80,70 @@ public class CustomTabActivityHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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) {
|
||||||
if (mClient != null) return;
|
if (mClient != null) return;
|
||||||
|
|
||||||
String packageName = CustomTabsHelper.getPackageNameToUse(activity);
|
String packageName = CustomTabsHelper.getPackageNameToUse(activity);
|
||||||
if (packageName == null) return;
|
if (packageName == null) return;
|
||||||
mConnection = new CustomTabsServiceConnection() {
|
|
||||||
@Override
|
|
||||||
public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
|
|
||||||
mClient = client;
|
|
||||||
mClient.warmup(0L);
|
|
||||||
if (mConnectionCallback != null) mConnectionCallback.onCustomTabsConnected();
|
|
||||||
//Initialize a session as soon as possible.
|
|
||||||
getSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
mConnection = new ServiceConnection(this);
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
|
||||||
mClient = null;
|
|
||||||
if (mConnectionCallback != null) mConnectionCallback.onCustomTabsDisconnected();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
CustomTabsClient.bindCustomTabsService(activity, packageName, mConnection);
|
CustomTabsClient.bindCustomTabsService(activity, packageName, mConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see {@link CustomTabsSession#mayLaunchUrl(Uri, Bundle, List)}.
|
||||||
|
* @return true if call to mayLaunchUrl was accepted.
|
||||||
|
*/
|
||||||
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;
|
||||||
|
|
||||||
CustomTabsSession session = getSession();
|
CustomTabsSession session = getSession();
|
||||||
return session != null && session.mayLaunchUrl(uri, extras, otherLikelyBundles);
|
if (session == null) return false;
|
||||||
|
|
||||||
|
return session.mayLaunchUrl(uri, extras, otherLikelyBundles);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(CustomTabsClient client) {
|
||||||
|
mClient = client;
|
||||||
|
mClient.warmup(0L);
|
||||||
|
if (mConnectionCallback != null) mConnectionCallback.onCustomTabsConnected();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected() {
|
||||||
|
mClient = null;
|
||||||
|
mCustomTabsSession = null;
|
||||||
|
if (mConnectionCallback != null) mConnectionCallback.onCustomTabsDisconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Callback for when the service is connected or disconnected. Use those callbacks to
|
* A Callback for when the service is connected or disconnected. Use those callbacks to
|
||||||
* handle UI changes when the service is connected or disconnected
|
* handle UI changes when the service is connected or disconnected.
|
||||||
*/
|
*/
|
||||||
public interface ConnectionCallback {
|
public interface ConnectionCallback {
|
||||||
/**
|
/**
|
||||||
* Called when the service is connected
|
* Called when the service is connected.
|
||||||
*/
|
*/
|
||||||
void onCustomTabsConnected();
|
void onCustomTabsConnected();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Called when the service is disconnected
|
* Called when the service is disconnected.
|
||||||
*/
|
*/
|
||||||
void onCustomTabsDisconnected();
|
void onCustomTabsDisconnected();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To be used as a fallback to open the Uri when Custom Tabs is not available
|
* To be used as a fallback to open the Uri when Custom Tabs is not available.
|
||||||
*/
|
*/
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,32 @@
|
|||||||
|
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.support.customtabs.CustomTabsClient;
|
||||||
|
import android.support.customtabs.CustomTabsServiceConnection;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation for the CustomTabsServiceConnection that avoids leaking the
|
||||||
|
* ServiceConnectionCallback
|
||||||
|
*/
|
||||||
|
public class ServiceConnection extends CustomTabsServiceConnection {
|
||||||
|
// A weak reference to the ServiceConnectionCallback to avoid leaking it.
|
||||||
|
private WeakReference<ServiceConnectionCallback> mConnectionCallback;
|
||||||
|
|
||||||
|
public ServiceConnection(ServiceConnectionCallback connectionCallback) {
|
||||||
|
mConnectionCallback = new WeakReference<>(connectionCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCustomTabsServiceConnected(ComponentName name, CustomTabsClient client) {
|
||||||
|
ServiceConnectionCallback connectionCallback = mConnectionCallback.get();
|
||||||
|
if (connectionCallback != null) connectionCallback.onServiceConnected(client);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
ServiceConnectionCallback connectionCallback = mConnectionCallback.get();
|
||||||
|
if (connectionCallback != null) connectionCallback.onServiceDisconnected();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
package apps.amine.bou.readerforselfoss.utils.customtabs;
|
||||||
|
|
||||||
|
|
||||||
|
import android.support.customtabs.CustomTabsClient;
|
||||||
|
|
||||||
|
|
||||||
|
public interface ServiceConnectionCallback {
|
||||||
|
/**
|
||||||
|
* Called when the service is connected.
|
||||||
|
* @param client a CustomTabsClient
|
||||||
|
*/
|
||||||
|
void onServiceConnected(CustomTabsClient client);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when the service is disconnected.
|
||||||
|
*/
|
||||||
|
void onServiceDisconnected();
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
/* From https://github.com/mikepenz/MaterialDrawer/blob/develop/app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomBaseViewHolder.java */
|
||||||
|
package apps.amine.bou.readerforselfoss.utils.drawer
|
||||||
|
|
||||||
|
|
||||||
|
import android.support.v7.widget.RecyclerView
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
|
||||||
|
import apps.amine.bou.readerforselfoss.R
|
||||||
|
|
||||||
|
|
||||||
|
open class CustomBaseViewHolder(var view: View) : RecyclerView.ViewHolder(view) {
|
||||||
|
var icon: ImageView = view.findViewById(R.id.material_drawer_icon) as ImageView
|
||||||
|
var name: TextView = view.findViewById(R.id.material_drawer_name) as TextView
|
||||||
|
var description: TextView = view.findViewById(R.id.material_drawer_description) as TextView
|
||||||
|
}
|
@ -0,0 +1,108 @@
|
|||||||
|
/* From https://github.com/mikepenz/MaterialDrawer/blob/develop/app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomUrlBasePrimaryDrawerItem.java */
|
||||||
|
package apps.amine.bou.readerforselfoss.utils.drawer
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.net.Uri
|
||||||
|
import android.support.annotation.ColorInt
|
||||||
|
import android.support.annotation.ColorRes
|
||||||
|
import android.support.annotation.StringRes
|
||||||
|
import android.support.v7.widget.RecyclerView
|
||||||
|
|
||||||
|
import com.mikepenz.materialdrawer.holder.ColorHolder
|
||||||
|
import com.mikepenz.materialdrawer.holder.ImageHolder
|
||||||
|
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||||
|
import com.mikepenz.materialdrawer.model.BaseDrawerItem
|
||||||
|
import com.mikepenz.materialdrawer.util.DrawerImageLoader
|
||||||
|
import com.mikepenz.materialdrawer.util.DrawerUIUtils
|
||||||
|
import com.mikepenz.materialize.util.UIUtils
|
||||||
|
|
||||||
|
|
||||||
|
abstract class CustomUrlBasePrimaryDrawerItem<T, VH : RecyclerView.ViewHolder> : BaseDrawerItem<T, VH>() {
|
||||||
|
fun withIcon(url: String): T {
|
||||||
|
this.icon = ImageHolder(url)
|
||||||
|
return this as T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withIcon(uri: Uri): T {
|
||||||
|
this.icon = ImageHolder(uri)
|
||||||
|
return this as T
|
||||||
|
}
|
||||||
|
|
||||||
|
var description: StringHolder? = null
|
||||||
|
private set
|
||||||
|
var descriptionTextColor: ColorHolder? = null
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun withDescription(description: String): T {
|
||||||
|
this.description = StringHolder(description)
|
||||||
|
return this as T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withDescription(@StringRes descriptionRes: Int): T {
|
||||||
|
this.description = StringHolder(descriptionRes)
|
||||||
|
return this as T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withDescriptionTextColor(@ColorInt color: Int): T {
|
||||||
|
this.descriptionTextColor = ColorHolder.fromColor(color)
|
||||||
|
return this as T
|
||||||
|
}
|
||||||
|
|
||||||
|
fun withDescriptionTextColorRes(@ColorRes colorRes: Int): T {
|
||||||
|
this.descriptionTextColor = ColorHolder.fromColorRes(colorRes)
|
||||||
|
return this as T
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* a helper method to have the logic for all secondaryDrawerItems only once
|
||||||
|
|
||||||
|
* @param viewHolder
|
||||||
|
*/
|
||||||
|
protected fun bindViewHelper(viewHolder: CustomBaseViewHolder) {
|
||||||
|
val ctx = viewHolder.itemView.context
|
||||||
|
|
||||||
|
//set the identifier from the drawerItem here. It can be used to run tests
|
||||||
|
viewHolder.itemView.id = hashCode()
|
||||||
|
|
||||||
|
//set the item selected if it is
|
||||||
|
viewHolder.itemView.isSelected = isSelected
|
||||||
|
|
||||||
|
//get the correct color for the background
|
||||||
|
val selectedColor = getSelectedColor(ctx)
|
||||||
|
//get the correct color for the text
|
||||||
|
val color = getColor(ctx)
|
||||||
|
val selectedTextColor = getSelectedTextColor(ctx)
|
||||||
|
//get the correct color for the icon
|
||||||
|
val iconColor = getIconColor(ctx)
|
||||||
|
val selectedIconColor = getSelectedIconColor(ctx)
|
||||||
|
|
||||||
|
//set the background for the item
|
||||||
|
UIUtils.setBackground(viewHolder.view, UIUtils.getSelectableBackground(ctx, selectedColor, true))
|
||||||
|
//set the text for the name
|
||||||
|
StringHolder.applyTo(this.getName(), viewHolder.name)
|
||||||
|
//set the text for the description or hide
|
||||||
|
StringHolder.applyToOrHide(this.description, viewHolder.description)
|
||||||
|
|
||||||
|
//set the colors for textViews
|
||||||
|
viewHolder.name.setTextColor(getTextColorStateList(color, selectedTextColor))
|
||||||
|
//set the description text color
|
||||||
|
ColorHolder.applyToOr(descriptionTextColor,
|
||||||
|
viewHolder.description, getTextColorStateList(color, selectedTextColor))
|
||||||
|
|
||||||
|
//define the typeface for our textViews
|
||||||
|
if (getTypeface() != null) {
|
||||||
|
viewHolder.name.typeface = getTypeface()
|
||||||
|
viewHolder.description.typeface = getTypeface()
|
||||||
|
}
|
||||||
|
|
||||||
|
//we make sure we reset the image first before setting the new one in case there is an empty one
|
||||||
|
DrawerImageLoader.getInstance().cancelImage(viewHolder.icon)
|
||||||
|
viewHolder.icon.setImageBitmap(null)
|
||||||
|
//get the drawables for our icon and set it
|
||||||
|
ImageHolder.applyTo(icon, viewHolder.icon, "customUrlItem")
|
||||||
|
|
||||||
|
//for android API 17 --> Padding not applied via xml
|
||||||
|
DrawerUIUtils.setDrawerVerticalPadding(viewHolder.view)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
/* From https://github.com/mikepenz/MaterialDrawer/blob/develop/app/src/main/java/com/mikepenz/materialdrawer/app/drawerItems/CustomUrlPrimaryDrawerItem.java */
|
||||||
|
package apps.amine.bou.readerforselfoss.utils.drawer
|
||||||
|
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.support.annotation.LayoutRes
|
||||||
|
import android.support.annotation.StringRes
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.TextView
|
||||||
|
|
||||||
|
import apps.amine.bou.readerforselfoss.R
|
||||||
|
import com.mikepenz.materialdrawer.holder.BadgeStyle
|
||||||
|
import com.mikepenz.materialdrawer.holder.StringHolder
|
||||||
|
import com.mikepenz.materialdrawer.model.interfaces.ColorfulBadgeable
|
||||||
|
|
||||||
|
|
||||||
|
class CustomUrlPrimaryDrawerItem : CustomUrlBasePrimaryDrawerItem<CustomUrlPrimaryDrawerItem, CustomUrlPrimaryDrawerItem.ViewHolder>(), ColorfulBadgeable<CustomUrlPrimaryDrawerItem> {
|
||||||
|
protected var mBadge: StringHolder = StringHolder("")
|
||||||
|
protected var mBadgeStyle = BadgeStyle()
|
||||||
|
|
||||||
|
override fun withBadge(badge: StringHolder): CustomUrlPrimaryDrawerItem {
|
||||||
|
this.mBadge = badge
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun withBadge(badge: String): CustomUrlPrimaryDrawerItem {
|
||||||
|
this.mBadge = StringHolder(badge)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun withBadge(@StringRes badgeRes: Int): CustomUrlPrimaryDrawerItem {
|
||||||
|
this.mBadge = StringHolder(badgeRes)
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun withBadgeStyle(badgeStyle: BadgeStyle): CustomUrlPrimaryDrawerItem {
|
||||||
|
this.mBadgeStyle = badgeStyle
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBadge(): StringHolder {
|
||||||
|
return mBadge
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getBadgeStyle(): BadgeStyle {
|
||||||
|
return mBadgeStyle
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getType(): Int {
|
||||||
|
return R.id.material_drawer_item_custom_url_item
|
||||||
|
}
|
||||||
|
|
||||||
|
@LayoutRes
|
||||||
|
override fun getLayoutRes(): Int {
|
||||||
|
return R.layout.material_drawer_item_primary
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun bindView(viewHolder: ViewHolder, payloads: List<*>?) {
|
||||||
|
super.bindView(viewHolder, payloads)
|
||||||
|
|
||||||
|
val ctx = viewHolder.itemView.context
|
||||||
|
|
||||||
|
//bind the basic view parts
|
||||||
|
bindViewHelper(viewHolder)
|
||||||
|
|
||||||
|
//set the text for the badge or hide
|
||||||
|
val badgeVisible = StringHolder.applyToOrHide(mBadge, viewHolder.badge)
|
||||||
|
//style the badge if it is visible
|
||||||
|
if (badgeVisible) {
|
||||||
|
mBadgeStyle.style(viewHolder.badge, getTextColorStateList(getColor(ctx), getSelectedTextColor(ctx)))
|
||||||
|
viewHolder.badgeContainer.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
viewHolder.badgeContainer.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
//define the typeface for our textViews
|
||||||
|
if (getTypeface() != null) {
|
||||||
|
viewHolder.badge.typeface = getTypeface()
|
||||||
|
}
|
||||||
|
|
||||||
|
//call the onPostBindView method to trigger post bind view actions (like the listener to modify the item if required)
|
||||||
|
onPostBindView(this, viewHolder.itemView)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getViewHolder(v: View): ViewHolder {
|
||||||
|
return ViewHolder(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
class ViewHolder(view: View) : CustomBaseViewHolder(view) {
|
||||||
|
val badgeContainer: View = view.findViewById(R.id.material_drawer_badge_container)
|
||||||
|
val badge: TextView = view.findViewById(R.id.material_drawer_badge) as TextView
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
9
app/src/main/res/drawable-anydpi/ic_info_outline.xml
Normal file
9
app/src/main/res/drawable-anydpi/ic_info_outline.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M11,17h2v-6h-2v6zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8zM11,9h2L13,7h-2v2z"/>
|
||||||
|
</vector>
|
9
app/src/main/res/drawable-anydpi/ic_settings.xml
Normal file
9
app/src/main/res/drawable-anydpi/ic_settings.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24.0"
|
||||||
|
android:viewportHeight="24.0">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FF000000"
|
||||||
|
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
||||||
|
</vector>
|
BIN
app/src/main/res/drawable-hdpi/ic_action_search.png
Normal file
BIN
app/src/main/res/drawable-hdpi/ic_action_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 680 B |
BIN
app/src/main/res/drawable-mdpi/ic_action_search.png
Normal file
BIN
app/src/main/res/drawable-mdpi/ic_action_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 442 B |
BIN
app/src/main/res/drawable-xhdpi/ic_action_search.png
Normal file
BIN
app/src/main/res/drawable-xhdpi/ic_action_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 634 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_action_search.png
Normal file
BIN
app/src/main/res/drawable-xxhdpi/ic_action_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
app/src/main/res/drawable-xxxhdpi/ic_action_search.png
Normal file
BIN
app/src/main/res/drawable-xxxhdpi/ic_action_search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.3 KiB |
@ -5,6 +5,7 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
tools:context="apps.amine.bou.readerforselfoss.HomeActivity">
|
tools:context="apps.amine.bou.readerforselfoss.HomeActivity">
|
||||||
|
|
||||||
<com.roughike.bottombar.BottomBar
|
<com.roughike.bottombar.BottomBar
|
||||||
@ -54,19 +55,55 @@
|
|||||||
android:layout_toRightOf="@+id/bottomBar"
|
android:layout_toRightOf="@+id/bottomBar"
|
||||||
android:layout_below="@id/prompt_view">
|
android:layout_below="@id/prompt_view">
|
||||||
|
|
||||||
<android.support.v4.widget.SwipeRefreshLayout
|
<android.support.design.widget.CoordinatorLayout
|
||||||
android:id="@+id/swipeRefreshLayout"
|
android:id="@+id/intern_coordLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<LinearLayout
|
||||||
android:id="@+id/my_recycler_view"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/background_grey"
|
android:orientation="vertical">
|
||||||
android:scrollbars="vertical"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
<android.support.design.widget.AppBarLayout
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:theme="@style/ToolBarStyle"
|
||||||
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/drawer_layout"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<android.support.v4.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipeRefreshLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/my_recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/background_grey"
|
||||||
|
android:scrollbars="vertical"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||||
|
</android.support.v4.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context="apps.amine.bou.readerforselfoss.HomeActivity"
|
tools:context="apps.amine.bou.readerforselfoss.HomeActivity"
|
||||||
|
android:fitsSystemWindows="true"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<com.github.stkent.amplify.prompt.DefaultLayoutPromptView
|
<com.github.stkent.amplify.prompt.DefaultLayoutPromptView
|
||||||
@ -34,22 +35,55 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_below="@id/prompt_view">
|
android:layout_below="@id/prompt_view">
|
||||||
|
|
||||||
|
<android.support.design.widget.CoordinatorLayout
|
||||||
<android.support.v4.widget.SwipeRefreshLayout
|
android:id="@+id/intern_coordLayout"
|
||||||
android:id="@+id/swipeRefreshLayout"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<LinearLayout
|
||||||
android:id="@+id/my_recycler_view"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/background_grey"
|
android:orientation="vertical">
|
||||||
android:clipToPadding="false"
|
|
||||||
android:scrollbars="vertical"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
|
||||||
|
|
||||||
|
<android.support.design.widget.AppBarLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<android.support.v7.widget.Toolbar
|
||||||
|
android:id="@+id/toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="?attr/actionBarSize"
|
||||||
|
app:theme="@style/ToolBarStyle"
|
||||||
|
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
|
||||||
|
|
||||||
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/drawer_layout"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<android.support.v4.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipeRefreshLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<android.support.v7.widget.RecyclerView
|
||||||
|
android:id="@+id/my_recycler_view"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:background="@color/background_grey"
|
||||||
|
android:clipToPadding="false"
|
||||||
|
android:scrollbars="vertical"
|
||||||
|
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||||
|
</android.support.v4.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
<com.roughike.bottombar.BottomBar
|
<com.roughike.bottombar.BottomBar
|
||||||
android:id="@+id/bottomBar"
|
android:id="@+id/bottomBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -62,6 +96,5 @@
|
|||||||
app:bb_badgeBackgroundColor="@color/colorPrimary"
|
app:bb_badgeBackgroundColor="@color/colorPrimary"
|
||||||
app:bb_inActiveTabColor="@color/black"
|
app:bb_inActiveTabColor="@color/black"
|
||||||
app:bb_badgesHideWhenActive="false" />
|
app:bb_badgesHideWhenActive="false" />
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
@ -62,5 +62,64 @@
|
|||||||
app:layout_constraintHorizontal_bias="0.0"
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/title" />
|
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||||
|
tools:text="Some text @android:string/fingerprint_icon_content_description" />
|
||||||
|
|
||||||
|
<android.support.constraint.ConstraintLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_marginBottom="0dp"
|
||||||
|
android:layout_marginEnd="0dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:background="#BBBBBB"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/content"
|
||||||
|
app:layout_constraintVertical_bias="1.0">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/browserBtn"
|
||||||
|
android:layout_width="35dp"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_toLeftOf="@+id/shareBtn"
|
||||||
|
android:layout_toStartOf="@+id/shareBtn"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:elevation="5dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/ic_open_in_browser_black_24dp"
|
||||||
|
android:tint="#000000"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/shareBtn"
|
||||||
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/shareBtn"
|
||||||
|
android:layout_width="35dp"
|
||||||
|
android:layout_height="35dp"
|
||||||
|
android:adjustViewBounds="true"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:elevation="5dp"
|
||||||
|
android:padding="4dp"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@drawable/ic_share_black_24dp"
|
||||||
|
android:tint="#000000"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.5"
|
||||||
|
app:layout_constraintStart_toEndOf="@+id/browserBtn"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
@ -54,65 +54,64 @@
|
|||||||
android:gravity="start" />
|
android:gravity="start" />
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
android:id="@+id/actionBar"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="#BBBBBB"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintTop_toBottomOf="@+id/sourceTitleAndDate">
|
||||||
app:layout_constraintTop_toBottomOf="@+id/sourceTitleAndDate"
|
|
||||||
android:id="@+id/actionBar"
|
|
||||||
android:background="#BBBBBB"
|
|
||||||
android:visibility="gone">
|
|
||||||
|
|
||||||
|
|
||||||
<com.like.LikeButton
|
<com.like.LikeButton
|
||||||
app:icon_type="heart"
|
|
||||||
app:icon_size="22dp"
|
|
||||||
android:id="@+id/favButton"
|
android:id="@+id/favButton"
|
||||||
android:layout_width="35dp"
|
android:layout_width="35dp"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_alignParentRight="true"
|
android:layout_marginEnd="8dp"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_marginRight="8dp"
|
||||||
android:elevation="5dp"
|
android:elevation="5dp"
|
||||||
android:padding="4dp"
|
android:padding="4dp"
|
||||||
android:layout_marginEnd="8dp"
|
app:icon_size="22dp"
|
||||||
android:layout_marginRight="8dp"/>
|
app:icon_type="heart" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
|
android:id="@+id/shareBtn"
|
||||||
android:layout_width="35dp"
|
android:layout_width="35dp"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:src="@drawable/ic_share_black_24dp"
|
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
android:layout_toLeftOf="@+id/favButton"
|
android:layout_toLeftOf="@+id/favButton"
|
||||||
android:layout_toStartOf="@+id/favButton"
|
android:layout_toStartOf="@+id/favButton"
|
||||||
android:id="@+id/shareBtn"
|
android:adjustViewBounds="true"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:elevation="5dp"
|
android:elevation="5dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:padding="4dp"
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:tint="#000000"
|
|
||||||
android:adjustViewBounds="true"
|
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:padding="4dp"/>
|
android:src="@drawable/ic_share_black_24dp"
|
||||||
|
android:tint="#000000" />
|
||||||
|
|
||||||
<ImageButton
|
<ImageButton
|
||||||
|
android:id="@+id/browserBtn"
|
||||||
android:layout_width="35dp"
|
android:layout_width="35dp"
|
||||||
android:layout_height="35dp"
|
android:layout_height="35dp"
|
||||||
android:src="@drawable/ic_open_in_browser_black_24dp"
|
|
||||||
android:layout_centerVertical="true"
|
android:layout_centerVertical="true"
|
||||||
android:layout_toLeftOf="@+id/shareBtn"
|
|
||||||
android:layout_toStartOf="@+id/shareBtn"
|
|
||||||
android:id="@+id/browserBtn"
|
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:elevation="5dp"
|
android:layout_toLeftOf="@+id/shareBtn"
|
||||||
android:background="@android:color/transparent"
|
android:layout_toStartOf="@+id/shareBtn"
|
||||||
android:tint="#000000"
|
|
||||||
android:adjustViewBounds="true"
|
android:adjustViewBounds="true"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:elevation="5dp"
|
||||||
|
android:padding="4dp"
|
||||||
android:scaleType="centerCrop"
|
android:scaleType="centerCrop"
|
||||||
android:padding="4dp"/>
|
android:src="@drawable/ic_open_in_browser_black_24dp"
|
||||||
|
android:tint="#000000" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,6 +2,12 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item android:id="@+id/action_search"
|
||||||
|
android:title="@string/menu_home_search"
|
||||||
|
android:icon="@drawable/ic_action_search"
|
||||||
|
app:showAsAction="ifRoom|collapseActionView"
|
||||||
|
app:actionViewClass="android.support.v7.widget.SearchView" />
|
||||||
|
|
||||||
<item android:id="@+id/readAll"
|
<item android:id="@+id/readAll"
|
||||||
android:icon="@drawable/ic_done_all_white_24dp"
|
android:icon="@drawable/ic_done_all_white_24dp"
|
||||||
android:title="@string/readAll"
|
android:title="@string/readAll"
|
||||||
@ -14,24 +20,11 @@
|
|||||||
android:orderInCategory="99"
|
android:orderInCategory="99"
|
||||||
android:title="@string/menu_home_refresh"
|
android:title="@string/menu_home_refresh"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
<item android:id="@+id/action_settings"
|
|
||||||
android:title="@string/title_activity_settings"
|
|
||||||
android:orderInCategory="100"
|
|
||||||
app:showAsAction="never"/>
|
|
||||||
|
|
||||||
<item android:id="@+id/action_sources"
|
|
||||||
android:title="@string/action_source"
|
|
||||||
android:orderInCategory="101"
|
|
||||||
app:showAsAction="never"/>
|
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/action_share_the_app"
|
android:id="@+id/action_share_the_app"
|
||||||
android:orderInCategory="102"
|
android:orderInCategory="102"
|
||||||
android:title="@string/menu_share_the_app" />
|
android:title="@string/menu_share_the_app" />
|
||||||
<item android:id="@+id/about"
|
|
||||||
android:title="@string/action_about"
|
|
||||||
android:orderInCategory="103"
|
|
||||||
app:showAsAction="never"/>
|
|
||||||
|
|
||||||
<item android:id="@+id/action_disconnect"
|
<item android:id="@+id/action_disconnect"
|
||||||
android:title="@string/action_disconnect"
|
android:title="@string/action_disconnect"
|
||||||
|
@ -103,4 +103,16 @@
|
|||||||
<string name="card_height_off" >La taille de la carte sera fixe</string>
|
<string name="card_height_off" >La taille de la carte sera fixe</string>
|
||||||
<string name="source_code">Code source</string>
|
<string name="source_code">Code source</string>
|
||||||
<string name="cant_mark_read">Kan het artikel niet als gelezen markeren</string>
|
<string name="cant_mark_read">Kan het artikel niet als gelezen markeren</string>
|
||||||
|
<string name="drawer_error_loading_tags">Erreur lors du chargement des tags…</string>
|
||||||
|
<string name="drawer_error_loading_sources">Erreur lors du chargement des sources…</string>
|
||||||
|
<string name="drawer_item_filters">Filtres</string>
|
||||||
|
<string name="drawer_action_clear">raz</string>
|
||||||
|
<string name="drawer_item_tags">Tags</string>
|
||||||
|
<string name="drawer_item_sources">Sources</string>
|
||||||
|
<string name="drawer_action_edit">editer</string>
|
||||||
|
<string name="cache_drawer_error">Impossible de mettre en cache les filtres pour le drawer</string>
|
||||||
|
<string name="no_tags_loaded">Pas de tags chargés</string>
|
||||||
|
<string name="no_sources_loaded">Pas de sources chargés</string>
|
||||||
|
<string name="drawer_loading">Chargement …</string>
|
||||||
|
<string name="menu_home_search">Rechercher</string>
|
||||||
</resources>
|
</resources>
|
@ -103,4 +103,16 @@
|
|||||||
<string name="card_height_off" >Vaste hoogte</string>
|
<string name="card_height_off" >Vaste hoogte</string>
|
||||||
<string name="source_code">Source code</string>
|
<string name="source_code">Source code</string>
|
||||||
<string name="cant_mark_read">Impossible de marquer l\'article comme lu</string>
|
<string name="cant_mark_read">Impossible de marquer l\'article comme lu</string>
|
||||||
|
<string name="drawer_error_loading_tags">Error loading tags…</string>
|
||||||
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
|
<string name="drawer_item_filters">Filters</string>
|
||||||
|
<string name="drawer_action_clear">clear</string>
|
||||||
|
<string name="drawer_item_tags">Tags</string>
|
||||||
|
<string name="drawer_item_sources">Sources</string>
|
||||||
|
<string name="drawer_action_edit">edit</string>
|
||||||
|
<string name="cache_drawer_error">Couldn\'t cache your drawer data</string>
|
||||||
|
<string name="no_tags_loaded">No tags loaded</string>
|
||||||
|
<string name="no_sources_loaded">No sources loaded</string>
|
||||||
|
<string name="drawer_loading">Loading …</string>
|
||||||
|
<string name="menu_home_search">Zoeken</string>
|
||||||
</resources>
|
</resources>
|
4
app/src/main/res/values/ids.xml
Normal file
4
app/src/main/res/values/ids.xml
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<resources>
|
||||||
|
<item name="material_drawer_item_custom_url_item" type="id" />
|
||||||
|
</resources>
|
@ -105,4 +105,16 @@
|
|||||||
<string name="card_height_off">Card height will be fixed</string>
|
<string name="card_height_off">Card height will be fixed</string>
|
||||||
<string name="source_code">Source code</string>
|
<string name="source_code">Source code</string>
|
||||||
<string name="cant_mark_read">Can\'t mark article as read</string>
|
<string name="cant_mark_read">Can\'t mark article as read</string>
|
||||||
|
<string name="drawer_error_loading_tags">Error loading tags…</string>
|
||||||
|
<string name="drawer_error_loading_sources">Error loading sources…</string>
|
||||||
|
<string name="drawer_item_filters">Filters</string>
|
||||||
|
<string name="drawer_action_clear">clear</string>
|
||||||
|
<string name="drawer_item_tags">Tags</string>
|
||||||
|
<string name="drawer_item_sources">Sources</string>
|
||||||
|
<string name="drawer_action_edit">edit</string>
|
||||||
|
<string name="cache_drawer_error">Couldn\'t cache your drawer data</string>
|
||||||
|
<string name="no_tags_loaded">No tags loaded</string>
|
||||||
|
<string name="no_sources_loaded">No sources loaded</string>
|
||||||
|
<string name="drawer_loading">Loading …</string>
|
||||||
|
<string name="menu_home_search">Search</string>
|
||||||
</resources>
|
</resources>
|
@ -13,4 +13,20 @@
|
|||||||
<item name="android:windowBackground">@drawable/background_splash</item>
|
<item name="android:windowBackground">@drawable/background_splash</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="NoBar" parent="Theme.AppCompat.Light.NoActionBar">
|
||||||
|
<item name="colorPrimary">@color/colorPrimary</item>
|
||||||
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
|
<item name="colorAccent">@color/colorAccent</item>
|
||||||
|
<item name="android:textColor">#000000</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- ToolBar -->
|
||||||
|
<style name="ToolBarStyle" parent="Theme.AppCompat">
|
||||||
|
<item name="android:textColorPrimary">@color/white</item>
|
||||||
|
<item name="android:textColorSecondary">@color/white</item>
|
||||||
|
<item name="actionMenuTextColor">@color/white</item>
|
||||||
|
<!--<item name="actionOverflowButtonStyle">@style/ActionButtonOverflowStyle</item>
|
||||||
|
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>-->
|
||||||
|
</style>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -7,7 +7,7 @@ buildscript {
|
|||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.0.0-alpha2'
|
classpath 'com.android.tools.build:gradle:3.0.0-alpha3'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
|
43
circle.yml
Normal file
43
circle.yml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
machine:
|
||||||
|
timezone: Europe/Paris
|
||||||
|
java:
|
||||||
|
version: 'oraclejdk8'
|
||||||
|
environment:
|
||||||
|
ANDROID_HOME: /usr/local/android-sdk-linux
|
||||||
|
PATH: ANDROID_HOME:$ANDROID_HOME/platform-tools:$ANDROID_BUUILD:$ANDROID_HOME/tools:$PATH
|
||||||
|
_JAVA_OPTIONS: "-Xms512m -Xmx1024m"
|
||||||
|
GRADLE_OPTS: '-Dorg.gradle.jvmargs="-Xmx2048m -XX:+HeapDumpOnOutOfMemoryError"'
|
||||||
|
|
||||||
|
dependencies:
|
||||||
|
pre:
|
||||||
|
- touch app/google-services.json
|
||||||
|
- echo $GOOGLE_SERVICES_JSON > app/google-services.json
|
||||||
|
- touch app/src/main/res/values/secrets.xml
|
||||||
|
- echo $SECRETS_XML > app/src/main/res/values/secrets.xml
|
||||||
|
- mkdir app/src/main/res/mipmap-hdpi
|
||||||
|
- convert -size 72x72 xc:white app/src/main/res/mipmap-hdpi/ic_launcher.png
|
||||||
|
- mkdir app/src/main/res/mipmap-mdpi
|
||||||
|
- convert -size 48x48 xc:white app/src/main/res/mipmap-mdpi/ic_launcher.png
|
||||||
|
- mkdir app/src/main/res/mipmap-xhdpi
|
||||||
|
- convert -size 96x96 xc:white app/src/main/res/mipmap-xhdpi/ic_launcher.png
|
||||||
|
- mkdir app/src/main/res/mipmap-xxhdpi
|
||||||
|
- convert -size 192x192 xc:white app/src/main/res/mipmap-xxhdpi/ic_launcher.png
|
||||||
|
- mkdir app/src/main/res/mipmap-xxxhdpi
|
||||||
|
- convert -size 512x512 xc:white app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
|
||||||
|
|
||||||
|
cache_directories:
|
||||||
|
- ~/.gradle
|
||||||
|
- ~/.android
|
||||||
|
|
||||||
|
override:
|
||||||
|
- echo y | android update sdk --no-ui --filter "android-25,build-tools-25.0.3"
|
||||||
|
- echo y | android update sdk --no-ui --all --filter "platform-tools, tools"
|
||||||
|
- echo y | android update sdk --no-ui --all --filter "android-25, build-tools-25.0.3"
|
||||||
|
- echo y | android update sdk --no-ui --all --filter "extra-android-m2repository"
|
||||||
|
- echo y | android update sdk --no-ui --all --filter "extra-android-support"
|
||||||
|
- echo y | android update sdk --no-ui --all --filter "extra-google-m2repository"
|
||||||
|
- echo y | android update sdk --no-ui --all --filter "extra-google-google_play_services"
|
||||||
|
|
||||||
|
test:
|
||||||
|
override:
|
||||||
|
- gradlew assemble -P crashlyticsdemoApikey=$FABRIC_API_KEY -P crashlyticsdemoApisecret=$FABRIC_API_SECRET
|
Reference in New Issue
Block a user