Compare commits

..

18 Commits

Author SHA1 Message Date
8ad8b55424 Drawer reloading on slide to refresh. 2017-06-08 20:43:22 +02:00
3da1d431db Fixes #23. 2017-06-08 20:35:50 +02:00
4565079f29 More filtering with the search toolbar. 2017-06-07 08:59:13 +02:00
3482092cb2 Filters not reset on resume. 2017-06-07 07:35:55 +02:00
2df5e52de0 Fixes #6 2017-06-07 07:28:17 +02:00
0ef4fc67fa Fixing cache issue. May need some real solution. 2017-06-06 21:13:46 +02:00
e2bfd549d3 Build and changelog. 2017-06-06 20:04:00 +02:00
7071af5fa5 Added back unread count. 2017-06-06 20:02:05 +02:00
95f267f701 Switched primary <=> secodary items for drawer.
Added source icon fetching.
2017-06-06 20:01:33 +02:00
f363bbcc0c Fixed an issue with the article reader. 2017-06-06 18:54:17 +02:00
65a912f271 Finally fixed #16 and fixed #17. 2017-06-05 21:17:51 +02:00
758661f5fb Fixed #16, fixes #17 and fixes #19 2017-06-05 18:50:19 +02:00
2d3c297726 Fixes #14 and fixes #15 2017-06-04 20:26:05 +02:00
ca85e3d3ed Changelog for previous version. 2017-06-04 18:24:31 +02:00
2190ad0387 Forced nl strings to english. 2017-06-04 18:13:29 +02:00
0d067e05af Fixed drawable on landscape and extracted strings to translation. 2017-06-04 18:09:02 +02:00
c3305b7523 Moved some menu items to the drawable. 2017-06-04 16:44:31 +02:00
fb84b31122 Drawer with caching. 2017-06-04 16:09:42 +02:00
28 changed files with 771 additions and 113 deletions

View File

@ -1,3 +1,9 @@
**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.

View File

@ -25,8 +25,8 @@ android {
applicationId "apps.amine.bou.readerforselfoss"
minSdkVersion 16
targetSdkVersion 25
versionCode 1502
versionName "1.5.0.2"
versionCode 1511
versionName "1.5.1.1"
// Enabling multidex support.
multiDexEnabled true
@ -98,7 +98,7 @@ dependencies {
compile 'com.burgstaller:okhttp-digest:1.12'
// 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.github.jd-alexander:LikeButton:0.2.1'
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
@ -113,6 +113,12 @@ dependencies {
// For the article reader
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'

View File

@ -31,7 +31,8 @@
<activity android:name=".LoginActivity"
android:label="@string/title_activity_login">
</activity>
<activity android:name=".HomeActivity">
<activity android:name=".HomeActivity"
android:theme="@style/NoBar">
</activity>
<activity
android:name=".settings.SettingsActivity"

View File

@ -31,7 +31,14 @@ class AddSourceActivity : AppCompatActivity() {
val mTags = findViewById(R.id.tags) as EditText
val mSpoutsSpinner = findViewById(R.id.spoutsSpinner) as Spinner
val mSaveBtn = findViewById(R.id.saveBtn) as Button
val api = SelfossApi(this)
var api: SelfossApi? = null
try {
api = SelfossApi(this)
} catch (e: IllegalArgumentException) {
mustLoginToAddSource()
}
val intent = intent
@ -40,7 +47,7 @@ class AddSourceActivity : AppCompatActivity() {
mNameInput.setText(intent.getStringExtra(Intent.EXTRA_TITLE))
}
mSaveBtn.setOnClickListener { handleSaveSource(mTags, mNameInput.text.toString(), mSourceUri.text.toString(), api) }
mSaveBtn.setOnClickListener { handleSaveSource(mTags, mNameInput.text.toString(), mSourceUri.text.toString(), api!!) }
val spoutsKV = HashMap<String, String>()
@ -58,14 +65,11 @@ class AddSourceActivity : AppCompatActivity() {
val config = Config(this)
if (config.baseUrl.isEmpty() || !isUrlValid(config.baseUrl)) {
Toast.makeText(this, getString(R.string.addStringNoUrl), Toast.LENGTH_SHORT).show()
val i = Intent(this, LoginActivity::class.java)
startActivity(i)
finish()
mustLoginToAddSource()
} else {
var items: Map<String, Spout>
api.spouts().enqueue(object : Callback<Map<String, Spout>> {
api!!.spouts().enqueue(object : Callback<Map<String, Spout>> {
override fun onResponse(call: Call<Map<String, Spout>>, response: Response<Map<String, Spout>>) {
if (response.body() != null) {
items = response.body()!!
@ -99,6 +103,13 @@ class AddSourceActivity : AppCompatActivity() {
}
}
private fun mustLoginToAddSource() {
Toast.makeText(this, getString(R.string.addStringNoUrl), Toast.LENGTH_SHORT).show()
val i = Intent(this, LoginActivity::class.java)
startActivity(i)
finish()
}
private fun handleSaveSource(mTags: EditText, title: String, url: String, api: SelfossApi) {
if (title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()) {

View File

@ -4,30 +4,34 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.net.Uri
import android.os.Bundle
import android.preference.PreferenceManager
import android.support.design.widget.CoordinatorLayout
import android.support.v4.view.MenuItemCompat
import android.support.v4.widget.SwipeRefreshLayout
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.GridLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.StaggeredGridLayoutManager
import android.support.v7.widget.*
import android.support.v7.widget.helper.ItemTouchHelper
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
import apps.amine.bou.readerforselfoss.api.selfoss.Item
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.api.selfoss.*
import apps.amine.bou.readerforselfoss.settings.SettingsActivity
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.checkAndDisplayStoreApk
import apps.amine.bou.readerforselfoss.utils.checkApkVersion
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.InviteEvent
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.GoogleApiAvailability
import com.google.firebase.remoteconfig.FirebaseRemoteConfig
import com.google.gson.reflect.TypeToken
import com.mikepenz.aboutlibraries.Libs
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.BottomBarTab
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.lang.Exception
class HomeActivity : AppCompatActivity() {
class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
private val MENU_PREFERENCES = 12302
private val REQUEST_INVITE = 13231
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 api: SelfossApi? = null
private var items: ArrayList<Item> = ArrayList()
@ -77,6 +90,13 @@ class HomeActivity : AppCompatActivity() {
private var tabStarred: BottomBarTab? = null
private var mFirebaseRemoteConfig: FirebaseRemoteConfig? = null
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() {
clickBehavior = this.sharedPref!!.getBoolean("tab_on_tap", false)
@ -91,6 +111,8 @@ class HomeActivity : AppCompatActivity() {
override fun onResume() {
super.onResume()
handleDrawerItems()
sharedPref = PreferenceManager.getDefaultSharedPreferences(this)
val settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
@ -110,13 +132,219 @@ class HomeActivity : AppCompatActivity() {
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?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
toolbar = findViewById(R.id.toolbar) as Toolbar?
setSupportActionBar(toolbar)
if (savedInstanceState == null) {
val promptView = findViewById(R.id.prompt_view) as DefaultLayoutPromptView
Amplify.getSharedInstance().promptIfReady(promptView)
}
@ -130,6 +358,8 @@ class HomeActivity : AppCompatActivity() {
mBottomBar = findViewById(R.id.bottomBar) as BottomBar
handleDrawer()
// TODO: clean this hack
val listenerAlreadySet = booleanArrayOf(false)
mBottomBar!!.setOnTabSelectListener { tabId ->
@ -157,7 +387,10 @@ class HomeActivity : AppCompatActivity() {
R.color.refresh_progress_1,
R.color.refresh_progress_2,
R.color.refresh_progress_3)
mSwipeRefreshLayout!!.setOnRefreshListener { getElementsAccordingToTab() }
mSwipeRefreshLayout!!.setOnRefreshListener {
handleDrawerItems()
getElementsAccordingToTab()
}
val simpleItemTouchCallback = object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
@ -229,7 +462,6 @@ class HomeActivity : AppCompatActivity() {
}
private fun getElementsAccordingToTab() {
items = ArrayList()
when (elementsShown) {
UNREAD_SHOWN -> getUnRead()
@ -241,15 +473,9 @@ class HomeActivity : AppCompatActivity() {
private fun getUnRead() {
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>>) {
if (response.body() != null && response.body()!!.isNotEmpty()) {
items = response.body() as ArrayList<Item>
} else {
items = ArrayList()
}
handleListResult()
mSwipeRefreshLayout!!.isRefreshing = false
handleItemsResponse(response)
}
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
@ -259,17 +485,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() {
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>>) {
if (response.body() != null && response.body()!!.isNotEmpty()) {
items = response.body() as ArrayList<Item>
} else {
items = ArrayList()
}
handleListResult()
mSwipeRefreshLayout!!.isRefreshing = false
handleItemsResponse(response)
}
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
@ -281,15 +516,9 @@ class HomeActivity : AppCompatActivity() {
private fun getStarred() {
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>>) {
if (response.body() != null && response.body()!!.isNotEmpty()) {
items = response.body() as ArrayList<Item>
} else {
items = ArrayList()
}
handleListResult()
mSwipeRefreshLayout!!.isRefreshing = false
handleItemsResponse(response)
}
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
@ -311,8 +540,6 @@ class HomeActivity : AppCompatActivity() {
mRecyclerView!!.adapter = mAdapter
mAdapter.notifyDataSetChanged()
if (items.isEmpty()) Toast.makeText(this@HomeActivity, R.string.nothing_here, Toast.LENGTH_SHORT).show()
reloadBadges()
}
@ -329,6 +556,11 @@ class HomeActivity : AppCompatActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
val inflater = menuInflater
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
}
@ -370,6 +602,7 @@ class HomeActivity : AppCompatActivity() {
}
})
items = ArrayList()
if (items.isEmpty()) Toast.makeText(this@HomeActivity, R.string.nothing_here, Toast.LENGTH_SHORT).show()
handleListResult()
}
return true
@ -384,24 +617,6 @@ class HomeActivity : AppCompatActivity() {
finish()
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 -> {
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
val share = AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
@ -452,7 +667,10 @@ class HomeActivity : AppCompatActivity() {
override fun onActivityResult(req: Int, result: Int, data: Intent?) {
when (req) {
MENU_PREFERENCES -> recreate()
MENU_PREFERENCES -> {
drawer!!.closeDrawer()
recreate()
}
REQUEST_INVITE -> if (result == Activity.RESULT_OK) {
Answers.getInstance().logInvite(InviteEvent())
}
@ -470,4 +688,18 @@ class HomeActivity : AppCompatActivity() {
val dpWidth = displayMetrics.widthPixels / displayMetrics.density
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
}
}

View File

@ -1,9 +1,19 @@
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.widget.ImageView
import com.crashlytics.android.Crashlytics
import com.github.stkent.amplify.tracking.Amplify
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() {
@ -16,5 +26,25 @@ class MyApp : MultiDexApplication() {
.setFeedbackEmailAddress(getString(R.string.feedback_email))
.setAlwaysShow(BuildConfig.DEBUG)
.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)
}
})
}
}

View File

@ -56,7 +56,7 @@ class ReaderActivity : DragDismissActivity() {
parser.parseUrl(url).enqueue(object : Callback<ParsedContent> {
override fun onResponse(call: Call<ParsedContent>, response: Response<ParsedContent>) {
if (response.body() != null && response.body()!!.content.isNotEmpty()) {
if (response.body() != null && response.body()!!.content != null && response.body()!!.content.isNotEmpty()) {
source.text = response.body()!!.domain
title.text = response.body()!!.title
if (response.body()!!.content != null && !response.body()!!.content.isEmpty())

View File

@ -72,17 +72,17 @@ class SelfossApi(c: Context) {
return service.loginToSelfoss(config.userLogin, config.userPassword)
}
val readItems: Call<List<Item>>
get() = getItems("read")
fun readItems(tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
getItems("read", tag, sourceId, search)
val unreadItems: Call<List<Item>>
get() = getItems("unread")
fun unreadItems(tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
getItems("unread", tag, sourceId, search)
val starredItems: Call<List<Item>>
get() = getItems("starred")
fun starredItems(tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
getItems("starred", tag, sourceId, search)
private fun getItems(type: String): Call<List<Item>> {
return service.getItems(type, userName, password)
private fun getItems(type: String, tag: String?, sourceId: Long?, search: String?): Call<List<Item>> {
return service.getItems(type, tag, sourceId, search, userName, password)
}
fun markItem(itemId: String): Call<SuccessResponse> {

View File

@ -16,7 +16,12 @@ internal interface SelfossService {
fun loginToSelfoss(@Query("username") username: String, @Query("password") password: String): Call<SuccessResponse>
@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}")
fun markAsRead(@Path("id") id: String, @Query("username") username: String, @Query("password") password: String): Call<SuccessResponse>

View File

@ -85,4 +85,15 @@ private fun isThereAnUpdate(settings: SharedPreferences, editor: SharedPreferenc
alertDialog.show()
}
}
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
}

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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
}
}

View 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>

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 680 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

@ -5,6 +5,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="apps.amine.bou.readerforselfoss.HomeActivity">
<com.roughike.bottombar.BottomBar
@ -54,19 +55,55 @@
android:layout_toRightOf="@+id/bottomBar"
android:layout_below="@id/prompt_view">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
<android.support.design.widget.CoordinatorLayout
android:id="@+id/intern_coordLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
<LinearLayout
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>
android:layout_height="match_parent"
android:orientation="vertical">
<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: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>

View File

@ -5,6 +5,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="apps.amine.bou.readerforselfoss.HomeActivity"
android:fitsSystemWindows="true"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.github.stkent.amplify.prompt.DefaultLayoutPromptView
@ -34,22 +35,55 @@
android:layout_height="match_parent"
android:layout_below="@id/prompt_view">
<android.support.v4.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
<android.support.design.widget.CoordinatorLayout
android:id="@+id/intern_coordLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/my_recycler_view"
<LinearLayout
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>
android:layout_height="match_parent"
android:orientation="vertical">
<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
android:id="@+id/bottomBar"
android:layout_width="match_parent"
@ -62,6 +96,5 @@
app:bb_badgeBackgroundColor="@color/colorPrimary"
app:bb_inActiveTabColor="@color/black"
app:bb_badgesHideWhenActive="false" />
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>

View File

@ -2,6 +2,12 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
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"
android:icon="@drawable/ic_done_all_white_24dp"
android:title="@string/readAll"
@ -14,24 +20,11 @@
android:orderInCategory="99"
android:title="@string/menu_home_refresh"
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
android:id="@+id/action_share_the_app"
android:orderInCategory="102"
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"
android:title="@string/action_disconnect"

View File

@ -103,4 +103,16 @@
<string name="card_height_off" >La taille de la carte sera fixe</string>
<string name="source_code">Code source</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>

View File

@ -103,4 +103,16 @@
<string name="card_height_off" >Vaste hoogte</string>
<string name="source_code">Source code</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>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<item name="material_drawer_item_custom_url_item" type="id" />
</resources>

View File

@ -105,4 +105,16 @@
<string name="card_height_off">Card height will be fixed</string>
<string name="source_code">Source code</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>

View File

@ -13,4 +13,20 @@
<item name="android:windowBackground">@drawable/background_splash</item>
</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>