Compare commits

...

42 Commits

Author SHA1 Message Date
9fa178d513 Closes #71 2017-09-02 17:55:02 +02:00
043b184065 Images are now loading on self signed certs. 2017-09-02 13:58:35 +02:00
10559bb894 Fixed build problem from last commit. 2017-09-02 12:51:11 +02:00
d0000d66b2 Fixes #70. Updated glide for images loading. 2017-09-02 10:02:35 +02:00
b447ac738a Fixes #62. 2017-08-31 20:00:58 +02:00
faebfc238c Closes #69. 2017-08-30 22:11:29 +02:00
c28fbd37cc Fixed issue with last commit. 2017-08-30 07:34:48 +02:00
4b8396959d Needed to add an exception for the log to work. 2017-08-30 07:22:28 +02:00
b39d510e07 Added reading article log. 2017-08-29 22:49:20 +02:00
286dda7f80 Update README.md 2017-08-27 19:33:21 +02:00
7bda896e2d Added the ability to choose the number of items loaded. 2017-08-26 21:36:19 +02:00
ba4feeea87 Trying to fix pre-lolipop svg drawable loading. 2017-08-16 22:15:33 +02:00
6f52eae3c6 Version updates. 2017-08-16 21:18:15 +02:00
40ea8d56e6 Closes #64 2017-08-16 20:18:49 +02:00
72e562e8a8 Reverted back to the old icon. 2017-08-16 07:51:28 +02:00
6fa01bfe19 Added changelog. 2017-08-04 21:44:29 +02:00
0ef59c9b91 Added a quick fix for accepting self signed certificates. 2017-08-04 21:42:35 +02:00
d768d2232b Added login optional debug logs. (#61) 2017-08-04 08:30:21 +02:00
b44a200731 A better icon. 2017-08-03 07:43:00 +02:00
016815e0d1 This test keep failing of firebase test lab. 2017-08-02 21:01:51 +02:00
590534e4a6 Splash screen fix, with some test problem. 2017-08-02 20:53:20 +02:00
7ea9d4e519 Changelog 2017-08-02 20:11:02 +02:00
e0ab09f533 Adaptive icon (#60)
* Removed mipmap folder from gitignore.

* New adaptive icon.

* Removed icon step from build.

* The icon seamed pixelated.
2017-08-02 20:08:31 +02:00
fbe98f1b16 Update CONTRIBUTING.md 2017-08-02 07:32:28 +02:00
d0675b8443 Update build.gradle 2017-07-30 19:01:05 +02:00
3ea1ed02ae Update build.gradle 2017-07-30 18:58:36 +02:00
ba120b1e0b Ignoring annoying bug with Samsung devices on 4.2.2 (#57)
* Updated gradle version.

* Fixed #55. Ignoring annoying non fatal bug on Samsung devices.
2017-07-30 18:37:44 +02:00
acf6995c2d Trying to handle app versionning from git tag. 2017-07-28 05:02:28 -04:00
8306860f90 Fixed #54 2017-07-28 07:33:21 +02:00
65974166be Update README.md 2017-07-27 22:03:57 +02:00
ee8924f986 Removed travis integration. 2017-07-27 22:02:14 +02:00
170e575465 Hiding the badge on reading all. 2017-07-27 22:02:14 +02:00
b7d5317b10 Fixed travis build. 2017-07-25 21:35:57 +02:00
f12e7748c5 Build v1.5.1.8 2017-07-25 21:17:34 +02:00
69a2418afc Fix 51 (#52)
* Some more bug fixes.

* Cleaning travis file.

* Fixes #51
2017-07-22 13:12:13 +02:00
4924ddd172 Changed CI from circle to travis. 2017-07-21 18:48:13 +02:00
1889b43786 Build and changelog. 2017-07-21 11:44:13 +02:00
f2e38a4203 Bug fixes (#49)
* Version updates.

* Fixed 'Calling startActivity() from outside of an Activity'

* Fixes #47

* Anydpi icons causing crashes.
2017-07-14 09:29:25 +02:00
90a8fac8d4 Added back the badges. 2017-07-10 22:18:42 +02:00
04402c5ab9 Build. 2017-07-09 19:26:14 +02:00
f8f710df99 Working themes. Needs some cleaning. Closes #37 . 2017-07-09 19:07:52 +02:00
b8105bb6fb Update README.md 2017-07-05 15:00:31 +02:00
106 changed files with 1588 additions and 757 deletions

View File

@ -22,7 +22,8 @@ Always check if the web version of your instance is working.
### Bug reports/Feature request
* Always search before reporting an issue or asking for a feature to avoid duplicates.
* Include every usefull details (app version, phone model, Android version and screenshots when possible)
* Include your unique user id. It's displayed on the debug settings page. (You can tap it, it'll be copied to your clipboard)
* Include every other useful details (app version, phone model, Android version and screenshots when possible).
* Avoid bumping non-fatal issues, or feature requests. I'll try to fix them as soon as possible, and try to prioritize the requests. (You may wan to use the [reactions](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) for that)
### Pull requests
@ -38,18 +39,19 @@ Always check if the web version of your instance is working.
* Be willing to accept criticism on your PRs (as I am on mine).
* Remember that PR review can take time.
# Build the project
You can directly import this project into IntellIJ/Android Studio.
You'll have to:
- [Create your own launcher icon](https://developer.android.com/studio/write/image-asset-studio.html#creating-launcher)
- Configure Fabric, or [remove it](https://docs.fabric.io/android/fabric/settings/removing.html#).
- Create a firebase project and add the `google-services.json` to the `app/` folder.
- Define the following in `res/values/strings.xml` or create `res/values/secrets.xml`
- mercury: A [Mercury](https://mercury.postlight.com/web-parser/) web parser api key for the internal browser
- feedback_email: An email to receive users feedback.
- source_url: an url to the source code, used in the settings
- tracker_url: an url to the tracker, used in the settings
- To run your app, you'll have to add `-P appLoginUrl="your.selfoss-instance.url" -P appLoginUsername="Username" -P appLoginPassword="password"`. (These are only used to run the espresso tests. You should be able to use empty strings or fake values to build the app)

1
.gitignore vendored
View File

@ -216,5 +216,4 @@ gradle-app.setting
secrets.xml
mipmap-*
release/

View File

@ -1,4 +1,80 @@
**1.5.1.3**
**1.5.2.13**
- Updated glide.
- Loading images from self signed certificate now working.
**1.5.2.12**
- Self signed certificates are now working for loading data. Image are not loading yet.
**1.5.2.11**
- Added a random unique identifier to be used in the logs.
**1.5.2.08/09/10**
- Added settable logs for reading articles problems.
**1.5.2.07**
- Added the ability to choose the number of items loaded (the maximum value is 200 and is imposed by the selfoss api)
**1.5.2.06**
- Fix problem introduced in 1.5.2.04. SVG file not working on older versions of android.
**1.5.2.05**
- Versions updates
**1.5.2.04**
- Reverted to the old icon.
- Better icon for the intro activity.
- Updated gradle version.
**1.5.2.03**
- Added the ability to accept self signed certificates. (Needs more testing)
**1.5.2.02**
- Added optional login option.
**1.5.2.01**
- New (Better) Icon !
**1.5.2.0**
- New Icon !
**1.5.1.9/10/11**
- Hiding the unread badge when marking all items as read.
**1.5.1.8**
- Fixes and libs updates.
**1.5.1.7**
- Bug fixes.
- Code cleaning
**1.5.1.6**
- Added back the badges after it was fixed on the library side.
**1.5.1.5**
- THEMES !!!! For now, the app has predefined themes. You can ask for new ones until I make them dynamic.
**1.5.1.3/4**
- Fixes introduces by the previous alpha (1.5.1.2)

View File

@ -1,6 +1,8 @@
# ReaderForSelfoss
[![CircleCI](https://circleci.com/gh/aminecmi/ReaderforSelfoss/tree/master.svg?style=svg)](https://circleci.com/gh/aminecmi/ReaderforSelfoss/tree/master)
[![Build Status](http://jenkins.amine-bou.fr/job/ReaderForSelfoss/badge/icon)](http://jenkins.amine-bou.fr/job/ReaderForSelfoss/)
[![Gitter chat](https://badges.gitter.im/amine-bou/ReaderForSelfoss.png)](https://gitter.im/amine-bou/ReaderForSelfoss)
[![codebeat badge](https://codebeat.co/badges/bce66c0f-fd28-4341-a159-3b6dd22ac854)](https://codebeat.co/projects/github-com-aminecmi-readerforselfoss-master)

View File

@ -8,6 +8,21 @@ buildscript {
}
}
def gitVersion() {
def process = "git describe --abbrev=0 --tags".execute()
return process.text.substring(1).replaceAll("\\.", "")
}
def versionCodeFromGit() {
println "version code " + gitVersion().toInteger()
return gitVersion().toInteger()
}
def versionNameFromGit() {
println "version code " + gitVersion().trim()
return gitVersion().trim()
}
apply plugin: 'com.android.application'
apply plugin: 'io.fabric'
@ -20,13 +35,13 @@ repositories {
android {
compileSdkVersion 26
buildToolsVersion "26.0.0"
buildToolsVersion "26.0.1"
defaultConfig {
applicationId "apps.amine.bou.readerforselfoss"
minSdkVersion 16
targetSdkVersion 25
versionCode 1513
versionName "1.5.1.3"
targetSdkVersion 26
versionCode versionCodeFromGit()
versionName versionNameFromGit()
// Enabling multidex support.
multiDexEnabled true
@ -68,43 +83,43 @@ android {
dependencies {
// Testing
androidTestCompile 'com.android.support.test.espresso:espresso-core:2.2.2'
androidTestCompile 'com.android.support.test:runner:0.5'
androidTestCompile 'com.android.support.test.espresso:espresso-core:3.0.0'
androidTestCompile 'com.android.support.test:runner:1.0.0'
// Espresso-contrib for DatePicker, RecyclerView, Drawer actions, Accessibility checks, CountingIdlingResource
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:2.2.2'
androidTestCompile 'com.android.support.test.espresso:espresso-contrib:3.0.0'
// Espresso-intents for validation and stubbing of Intents
androidTestCompile 'com.android.support.test.espresso:espresso-intents:2.2.2'
androidTestCompile 'com.android.support.test.espresso:espresso-intents:3.0.0'
compile fileTree(dir: 'libs', include: ['*.jar'])
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
// Android Support
compile 'com.android.support:appcompat-v7:26.0.0-beta2'
compile 'com.android.support:design:26.0.0-beta2'
compile 'com.android.support:recyclerview-v7:26.0.0-beta2'
compile 'com.android.support:support-v4:26.0.0-beta2'
compile 'com.android.support:support-vector-drawable:26.0.0-beta2'
compile 'com.android.support:customtabs:26.0.0-beta2'
compile 'com.android.support:cardview-v7:26.0.0-beta2'
compile 'com.android.support:appcompat-v7:26.0.1'
compile 'com.android.support:design:26.0.1'
compile 'com.android.support:recyclerview-v7:26.0.1'
compile 'com.android.support:support-v4:26.0.1'
compile 'com.android.support:support-vector-drawable:26.0.1'
compile 'com.android.support:customtabs:26.0.1'
compile 'com.android.support:cardview-v7:26.0.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
// Firebase + crashlytics
compile 'com.google.firebase:firebase-core:11.0.1'
compile 'com.google.firebase:firebase-config:11.0.1'
compile 'com.google.firebase:firebase-invites:11.0.1'
compile 'com.google.firebase:firebase-core:11.2.0'
compile 'com.google.firebase:firebase-config:11.2.0'
compile 'com.google.firebase:firebase-invites:11.2.0'
compile('com.crashlytics.sdk.android:crashlytics:2.6.8@aar') {
transitive = true
}
//multidex
compile 'com.android.support:multidex:1.0.1'
compile 'com.android.support:multidex:1.0.2'
// Intro
compile 'agency.tango.android:material-intro-screen:0.0.5'
// About
compile('com.mikepenz:aboutlibraries:5.9.6@aar') {
compile('com.mikepenz:aboutlibraries:5.9.7@aar') {
transitive = true
}
@ -115,27 +130,33 @@ dependencies {
compile 'com.burgstaller:okhttp-digest:1.12'
// Material-ish things
compile 'com.roughike:bottom-bar:2.3.1'
compile 'com.ashokvarma.android:bottom-navigation-bar:2.0.2'
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'
compile 'org.sufficientlysecure:html-textview:3.3'
// glide
compile 'com.github.bumptech.glide:glide:3.7.0'
compile('com.github.bumptech.glide:glide:4.1.0@aar') {
transitive = true;
}
compile('com.github.bumptech.glide:okhttp3-integration:4.1.0@aar')
// Asking politely users to rate the app
compile 'com.github.stkent:amplify:1.5.0'
// For the article reader
compile 'com.klinkerapps:drag-dismiss-activity:1.4.1'
compile 'com.klinkerapps:drag-dismiss-activity:1.4.3'
// Drawer
compile('com.mikepenz:materialdrawer:5.9.3@aar') {
compile('com.mikepenz:materialdrawer:5.9.5@aar') {
transitive = true
}
compile 'com.anupcowkur:reservoir:3.1.0'
// Themes
compile 'com.52inc:scoops:1.0.0'
}
apply plugin: 'com.google.gms.google-services'
@ -167,4 +188,4 @@ def initAppLoginPropertiesIfNeeded() {
entry(key: "appLoginPassword", value: System.getProperty("appLoginPassword"))
}
}
}
}

View File

@ -56,4 +56,8 @@
#Bottom bar lib
-dontwarn com.roughike.bottombar.**
-dontwarn com.roughike.bottombar.**
# self signed glidemodule
-keep public class * implements com.bumptech.glide.module.GlideModule

View File

@ -86,7 +86,7 @@ class HomeActivityEspressoTest {
intended(hasComponent(LoginActivity::class.java.name), times(1))
onView(isRoot()).perform(pressBack())
//onView(isRoot()).perform(pressBack())
}

View File

@ -46,7 +46,7 @@ class IntroActivityEspressoTest {
Intents.init()
}
@Test
/*@Test
fun nextEachTimes() {
rule.launchActivity(Intent())
@ -61,7 +61,7 @@ class IntroActivityEspressoTest {
intended(hasComponent(IntroActivity::class.java.name), times(1))
intended(hasComponent(LoginActivity::class.java.name), times(1))
}
}*/
@Test
fun nextBackRandomTimes() {

View File

@ -14,7 +14,7 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/NoBar">
<activity
android:name=".MainActivity"
android:theme="@style/SplashTheme">
@ -31,8 +31,7 @@
<activity android:name=".LoginActivity"
android:label="@string/title_activity_login">
</activity>
<activity android:name=".HomeActivity"
android:theme="@style/NoBar">
<activity android:name=".HomeActivity">
</activity>
<activity
android:name=".settings.SettingsActivity"
@ -65,6 +64,9 @@
<activity android:name=".ReaderActivity"
android:theme="@style/DragDismissTheme">
</activity>
<meta-data
android:name="apps.amine.bou.readerforselfoss.utils.glide.SelfSignedGlideModule"
android:value="GlideModule" />
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -2,8 +2,10 @@ package apps.amine.bou.readerforselfoss
import android.content.Intent
import android.os.Bundle
import android.preference.PreferenceManager
import android.support.constraint.ConstraintLayout
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.view.View
import android.widget.*
@ -15,8 +17,8 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.Spout
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.isUrlValid
import apps.amine.bou.readerforselfoss.utils.isBaseUrlValid
import com.ftinc.scoop.Scoop
class AddSourceActivity : AppCompatActivity() {
@ -25,7 +27,12 @@ class AddSourceActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Scoop.getInstance().apply(this)
setContentView(R.layout.activity_add_source)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
val mProgress: ProgressBar = findViewById(R.id.progress)
val mForm: ConstraintLayout = findViewById(R.id.formContainer)
@ -37,7 +44,8 @@ class AddSourceActivity : AppCompatActivity() {
var api: SelfossApi? = null
try {
api = SelfossApi(this, this@AddSourceActivity)
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
api = SelfossApi(this, this@AddSourceActivity, prefs.getBoolean("isSelfSignedCert", false))
} catch (e: IllegalArgumentException) {
mustLoginToAddSource()
}
@ -67,7 +75,7 @@ class AddSourceActivity : AppCompatActivity() {
val config = Config(this)
if (config.baseUrl.isEmpty() || !config.baseUrl.isUrlValid()) {
if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid()) {
mustLoginToAddSource()
} else {

View File

@ -43,8 +43,6 @@ 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
@ -53,13 +51,23 @@ import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
import apps.amine.bou.readerforselfoss.api.selfoss.*
import apps.amine.bou.readerforselfoss.settings.SettingsActivity
import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.bottombar.maybeShow
import apps.amine.bou.readerforselfoss.utils.bottombar.removeBadge
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.ashokvarma.bottomnavigation.BottomNavigationBar
import com.ashokvarma.bottomnavigation.BottomNavigationItem
import com.ashokvarma.bottomnavigation.TextBadgeItem
import com.ftinc.scoop.Scoop
import com.mikepenz.materialdrawer.AccountHeader
import com.mikepenz.materialdrawer.AccountHeaderBuilder
import com.mikepenz.materialdrawer.holder.DimenHolder
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
@ -76,32 +84,36 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
private var items: ArrayList<Item> = ArrayList()
private var clickBehavior = false
private var debugReadingItems = false
private var internalBrowser = false
private var articleViewer = false
private var shouldBeCardView = false
private var displayUnreadCount = false
private var displayAllCount = false
private var fullHeightCards: Boolean = false
private var itemsNumber: Int = 200
private var elementsShown: Int = 0
private var maybeTagFilter: Tag? = null
private var maybeSourceFilter: Sources? = null
private var maybeSearchFilter: String? = null
private var userIdentifier: String = ""
private lateinit var emptyText: TextView
private lateinit var mRecyclerView: RecyclerView
private lateinit var mBottomBar: BottomBar
private lateinit var mCoordinatorLayout: CoordinatorLayout
private lateinit var mSwipeRefreshLayout: SwipeRefreshLayout
private lateinit var tabNew: BottomBarTab
private lateinit var tabArchive: BottomBarTab
private lateinit var tabStarred: BottomBarTab
private lateinit var recyclerView: RecyclerView
private lateinit var bottomBar: BottomNavigationBar
private lateinit var coordinatorLayout: CoordinatorLayout
private lateinit var swipeRefreshLayout: SwipeRefreshLayout
private lateinit var tabNewBadge: TextBadgeItem
private lateinit var tabArchiveBadge: TextBadgeItem
private lateinit var tabStarredBadge: TextBadgeItem
private lateinit var toolbar: Toolbar
private lateinit var drawer: Drawer
private lateinit var api: SelfossApi
private lateinit var mCustomTabActivityHelper: CustomTabActivityHelper
private lateinit var customTabActivityHelper: CustomTabActivityHelper
private lateinit var editor: SharedPreferences.Editor
private lateinit var sharedPref: SharedPreferences
private lateinit var mFirebaseRemoteConfig: FirebaseRemoteConfig
private lateinit var firebaseRemoteConfig: FirebaseRemoteConfig
private lateinit var appColors: AppColors
@ -111,11 +123,14 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
override fun onStart() {
super.onStart()
mCustomTabActivityHelper.bindCustomTabsService(this)
customTabActivityHelper.bindCustomTabsService(this)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Scoop.getInstance().apply(this)
setContentView(R.layout.activity_home)
toolbar = findViewById(R.id.toolbar)
@ -126,48 +141,34 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
Amplify.getSharedInstance().promptIfReady(promptView)
}
mFirebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
mFirebaseRemoteConfig.setDefaults(R.xml.default_remote_config)
firebaseRemoteConfig = FirebaseRemoteConfig.getInstance()
firebaseRemoteConfig.setDefaults(R.xml.default_remote_config)
mCustomTabActivityHelper = CustomTabActivityHelper()
customTabActivityHelper = CustomTabActivityHelper()
api = SelfossApi(this, this@HomeActivity)
val dirtyPref = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
api = SelfossApi(this, this@HomeActivity, dirtyPref.getBoolean("isSelfSignedCert", false))
items = ArrayList()
mBottomBar = findViewById(R.id.bottomBar)
appColors = AppColors(this@HomeActivity)
handleDrawer()
handleBottomBar()
// TODO: clean this hack
val listenerAlreadySet = booleanArrayOf(false)
mBottomBar.setOnTabSelectListener { tabId ->
if (listenerAlreadySet[0]) {
if (tabId == R.id.tab_new) {
getUnRead()
} else if (tabId == R.id.tab_archive) {
getRead()
} else if (tabId == R.id.tab_fav) {
getStarred()
}
getElementsAccordingToTab()
} else {
listenerAlreadySet[0] = true
}
}
handleDrawer(dirtyPref)
mCoordinatorLayout = findViewById(R.id.coordLayout)
mSwipeRefreshLayout = findViewById(R.id.swipeRefreshLayout)
mRecyclerView = findViewById(R.id.my_recycler_view)
coordinatorLayout = findViewById(R.id.coordLayout)
swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout)
recyclerView = findViewById(R.id.my_recycler_view)
emptyText = findViewById(R.id.emptyText)
reloadLayoutManager()
mSwipeRefreshLayout.setColorSchemeResources(
swipeRefreshLayout.setColorSchemeResources(
R.color.refresh_progress_1,
R.color.refresh_progress_2,
R.color.refresh_progress_3)
mSwipeRefreshLayout.setOnRefreshListener {
swipeRefreshLayout.setOnRefreshListener {
handleDrawerItems()
getElementsAccordingToTab()
}
@ -188,25 +189,74 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
val position = items.indexOf(i)
if (shouldBeCardView) {
(mRecyclerView.adapter as ItemCardAdapter).removeItemAtIndex(position)
(recyclerView.adapter as ItemCardAdapter).removeItemAtIndex(position)
} else {
(mRecyclerView.adapter as ItemListAdapter).removeItemAtIndex(position)
(recyclerView.adapter as ItemListAdapter).removeItemAtIndex(position)
}
tabNew.setBadgeCount(items.size - 1)
mayBeEmpty()
if (items.size > 0)
tabNewBadge.setText("${items.size}").maybeShow()
else
tabNewBadge.hide()
} catch (e: IndexOutOfBoundsException) {}
}
}
ItemTouchHelper(simpleItemTouchCallback).attachToRecyclerView(mRecyclerView)
ItemTouchHelper(simpleItemTouchCallback).attachToRecyclerView(recyclerView)
this@HomeActivity.checkAndDisplayStoreApk()
}
private fun handleBottomBar() {
bottomBar = findViewById(R.id.bottomBar)
tabNewBadge = TextBadgeItem()
.setText("")
.setHideOnSelect(false).hide(false)
.setBackgroundColor(appColors.primary)
tabArchiveBadge = TextBadgeItem()
.setText("")
.setHideOnSelect(false).hide(false)
.setBackgroundColor(appColors.primary)
tabStarredBadge = TextBadgeItem()
.setText("")
.setHideOnSelect(false).hide(false)
.setBackgroundColor(appColors.primary)
val tabNew =
BottomNavigationItem(
R.drawable.ic_fiber_new_black_24dp,
getString(R.string.tab_new)
).setActiveColor(appColors.accent)
.setBadgeItem(tabNewBadge)
val tabArchive =
BottomNavigationItem(
R.drawable.ic_archive_black_24dp,
getString(R.string.tab_read)
).setActiveColor(appColors.dark)
.setBadgeItem(tabArchiveBadge)
val tabStarred =
BottomNavigationItem(
R.drawable.ic_favorite_black_24dp,
getString(R.string.tab_favs)
).setActiveColorResource(R.color.pink)
.setBadgeItem(tabStarredBadge)
bottomBar
.addItem(tabNew)
.addItem(tabArchive)
.addItem(tabStarred)
.setFirstSelectedPosition(0)
.initialise()
bottomBar.setMode(BottomNavigationBar.MODE_SHIFTING)
bottomBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC)
}
override fun onResume() {
super.onResume()
@ -218,26 +268,22 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
editor = settings.edit()
if (BuildConfig.GITHUB_VERSION) {
this@HomeActivity.checkApkVersion(settings, editor, mFirebaseRemoteConfig)
this@HomeActivity.checkApkVersion(settings, editor, firebaseRemoteConfig)
}
handleSharedPrefs()
tabNew = mBottomBar.getTabWithId(R.id.tab_new)
tabArchive = mBottomBar.getTabWithId(R.id.tab_archive)
tabStarred = mBottomBar.getTabWithId(R.id.tab_fav)
getElementsAccordingToTab()
}
override fun onStop() {
super.onStop()
mCustomTabActivityHelper.unbindCustomTabsService(this)
customTabActivityHelper.unbindCustomTabsService(this)
}
private fun handleSharedPrefs() {
debugReadingItems = sharedPref.getBoolean("read_debug", false)
clickBehavior = sharedPref.getBoolean("tab_on_tap", false)
internalBrowser = sharedPref.getBoolean("prefer_internal_browser", true)
articleViewer = sharedPref.getBoolean("prefer_article_viewer", true)
@ -245,12 +291,29 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
displayUnreadCount = sharedPref.getBoolean("display_unread_count", true)
displayAllCount = sharedPref.getBoolean("display_other_count", false)
fullHeightCards = sharedPref.getBoolean("full_height_cards", false)
itemsNumber = sharedPref.getString("prefer_api_items_number", "200").toInt()
userIdentifier = sharedPref.getString("unique_id", "")
}
private fun handleDrawer() {
private fun handleDrawer(dirtyPref: SharedPreferences) {
val headerResult: AccountHeader = AccountHeaderBuilder()
.withActivity(this)
.withHeaderBackground(R.drawable.bg)
.addProfiles(
ProfileDrawerItem()
.withName(
dirtyPref.getString("url", "")
)
.withIcon(resources.getDrawable(R.mipmap.ic_launcher))
)
.withSelectionListEnabledForSingleProfile(false)
.build()
drawer = DrawerBuilder()
.withActivity(this)
.withAccountHeader(headerResult)
.withHeaderHeight(DimenHolder.fromDp(140))
.withRootView(R.id.drawer_layout)
.withToolbar(toolbar)
.withActionBarDrawerToggle(true)
@ -258,37 +321,25 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
.withShowDrawerOnFirstLaunch(true)
.withOnDrawerListener(object: Drawer.OnDrawerListener {
override fun onDrawerSlide(v: View?, p1: Float) {
mBottomBar.alpha = (1 - p1)
bottomBar.alpha = (1 - p1)
}
override fun onDrawerClosed(v: View?) {
mBottomBar.shySettings.showBar()
bottomBar.show()
}
override fun onDrawerOpened(v: View?) {
mBottomBar.shySettings.hideBar()
bottomBar.hide()
}
})
.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)
.withIconTintingEnabled(true)
.withOnDrawerItemClickListener { _, _, _ ->
startActivityForResult(
Intent(
@ -328,7 +379,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
.withBadge("${tag.unread}")
.withBadgeStyle(
BadgeStyle().withTextColor(Color.WHITE)
.withColorRes(R.color.colorAccent)
.withColor(appColors.accent)
)
.withOnDrawerItemClickListener { _, _, _ ->
maybeTagFilter = tag
@ -387,6 +438,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
.withIdentifier(DRAWER_ID_TAGS)
.withSelectable(false))
handleTags(maybeDrawerData.tags)
drawer.addItem(DividerDrawerItem())
drawer.addItem(
SecondaryDrawerItem()
.withName(getString(R.string.drawer_item_sources))
@ -399,6 +451,26 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
}
)
handleSources(maybeDrawerData.sources)
drawer.addItem(DividerDrawerItem())
drawer.addItem(
PrimaryDrawerItem()
.withName(R.string.action_about)
.withSelectable(false)
.withIcon(R.drawable.ic_info_outline)
.withIconTintingEnabled(true)
.withOnDrawerItemClickListener { _, _, _ ->
LibsBuilder()
.withActivityStyle(
if (appColors.isDarkTheme)
Libs.ActivityStyle.LIGHT_DARK_TOOLBAR
else
Libs.ActivityStyle.DARK
)
.withAboutIconShown(true)
.withAboutVersionShown(true)
.start(this@HomeActivity)
false
})
if (!loadedFromCache)
@ -484,33 +556,45 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
mLayoutManager = GridLayoutManager(this, calculateNoOfColumns())
}
mRecyclerView.layoutManager = mLayoutManager
mRecyclerView.setHasFixedSize(true)
recyclerView.layoutManager = mLayoutManager
recyclerView.setHasFixedSize(true)
mBottomBar.setOnTabReselectListener {
if (shouldBeCardView) {
if ((mLayoutManager as StaggeredGridLayoutManager).findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
getElementsAccordingToTab()
bottomBar.setTabSelectedListener(object: BottomNavigationBar.OnTabSelectedListener {
override fun onTabUnselected(position: Int) = Unit
override fun onTabReselected(position: Int) =
if (shouldBeCardView) {
if ((mLayoutManager as StaggeredGridLayoutManager).findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
getElementsAccordingToTab()
} else {
mLayoutManager.scrollToPositionWithOffset(0, 0)
}
} else {
mLayoutManager.scrollToPositionWithOffset(0, 0)
if ((mLayoutManager as GridLayoutManager).findFirstCompletelyVisibleItemPosition() == 0) {
getElementsAccordingToTab()
} else {
mLayoutManager.scrollToPositionWithOffset(0, 0)
}
}
} else {
if ((mLayoutManager as GridLayoutManager).findFirstCompletelyVisibleItemPosition() == 0) {
getElementsAccordingToTab()
} else {
mLayoutManager.scrollToPositionWithOffset(0, 0)
override fun onTabSelected(position: Int) =
when(position) {
0 -> getUnRead()
1 -> getRead()
2 -> getStarred()
else -> Unit
}
}
}
})
}
fun mayBeEmpty() =
if (items.isEmpty()) {
emptyText.visibility = View.VISIBLE
mRecyclerView.visibility = View.GONE
recyclerView.visibility = View.GONE
} else {
emptyText.visibility = View.GONE
mRecyclerView.visibility = View.VISIBLE
recyclerView.visibility = View.VISIBLE
}
private fun getElementsAccordingToTab() =
@ -534,11 +618,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
if (didUpdate)
handleListResult()
mayBeEmpty()
mSwipeRefreshLayout.isRefreshing = false
swipeRefreshLayout.isRefreshing = false
}
if (!mSwipeRefreshLayout.isRefreshing)
mSwipeRefreshLayout.post { mSwipeRefreshLayout.isRefreshing = true }
if (!swipeRefreshLayout.isRefreshing)
swipeRefreshLayout.post { swipeRefreshLayout.isRefreshing = true }
call(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter)
.enqueue(object : Callback<List<Item>> {
@ -547,7 +631,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
}
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
mSwipeRefreshLayout.isRefreshing = false
swipeRefreshLayout.isRefreshing = false
Toast.makeText(this@HomeActivity, toastMessage, Toast.LENGTH_SHORT).show()
}
})
@ -555,7 +639,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
private fun getUnRead() {
elementsShown = UNREAD_SHOWN
doCallTo(R.string.cant_get_new_elements){t, id, f -> api.newItems(t, id, f)}
doCallTo(R.string.cant_get_new_elements){t, id, f -> api.newItems(t, id, f, itemsNumber)}
}
private fun getRead() {
@ -578,22 +662,27 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
this,
items,
api,
mCustomTabActivityHelper,
customTabActivityHelper,
internalBrowser,
articleViewer,
fullHeightCards)
fullHeightCards,
appColors,
debugReadingItems,
userIdentifier)
} else {
mAdapter =
ItemListAdapter(
this,
items,
api,
mCustomTabActivityHelper,
customTabActivityHelper,
clickBehavior,
internalBrowser,
articleViewer)
articleViewer,
debugReadingItems,
userIdentifier)
}
mRecyclerView.adapter = mAdapter
recyclerView.adapter = mAdapter
mAdapter.notifyDataSetChanged()
reloadBadges()
@ -604,13 +693,20 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
api.stats.enqueue(object : Callback<Stats> {
override fun onResponse(call: Call<Stats>, response: Response<Stats>) {
if (response.body() != null) {
tabNew.setBadgeCount(response.body()!!.unread)
if (displayUnreadCount)
tabNewBadge
.setText(response.body()!!.unread.toString())
.maybeShow()
if (displayAllCount) {
tabArchive.setBadgeCount(response.body()!!.total)
tabStarred.setBadgeCount(response.body()!!.starred)
tabArchiveBadge
.setText(response.body()!!.total.toString())
.maybeShow()
tabStarredBadge
.setText(response.body()!!.starred.toString())
.maybeShow()
} else {
tabArchive.removeBadge()
tabStarred.removeBadge()
tabArchiveBadge.removeBadge()
tabStarredBadge.removeBadge()
}
}
}
@ -618,9 +714,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
override fun onFailure(call: Call<Stats>, t: Throwable) {}
})
} else {
tabNew.removeBadge()
tabArchive.removeBadge()
tabStarred.removeBadge()
tabNewBadge.removeBadge()
tabArchiveBadge.removeBadge()
tabStarredBadge.removeBadge()
}
}
@ -692,22 +788,24 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
}
R.id.readAll -> {
if (elementsShown == UNREAD_SHOWN) {
mSwipeRefreshLayout.isRefreshing = false
swipeRefreshLayout.isRefreshing = false
val ids = items.map { it.id }
api.readAll(ids).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
if (response.body() != null && response.body()!!.isSuccess)
if (response.body() != null && response.body()!!.isSuccess) {
Toast.makeText(this@HomeActivity, R.string.all_posts_read, Toast.LENGTH_SHORT).show()
tabNewBadge.removeBadge()
}
else
Toast.makeText(this@HomeActivity, R.string.all_posts_not_read, Toast.LENGTH_SHORT).show()
mSwipeRefreshLayout.isRefreshing = false
swipeRefreshLayout.isRefreshing = false
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
Toast.makeText(this@HomeActivity, R.string.all_posts_not_read, Toast.LENGTH_SHORT).show()
mSwipeRefreshLayout.isRefreshing = false
swipeRefreshLayout.isRefreshing = false
}
})
items = ArrayList()

View File

@ -9,7 +9,7 @@ import android.view.View
import agency.tango.materialintroscreen.MaterialIntroActivity
import agency.tango.materialintroscreen.MessageButtonBehaviour
import agency.tango.materialintroscreen.SlideFragmentBuilder
import android.support.v7.app.AppCompatDelegate
class IntroActivity : MaterialIntroActivity() {
@ -17,10 +17,12 @@ class IntroActivity : MaterialIntroActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
addSlide(SlideFragmentBuilder()
.backgroundColor(R.color.colorPrimary)
.buttonsColor(R.color.colorAccent)
.image(R.mipmap.ic_launcher)
.image(R.drawable.web_hi_res_512)
.title(getString(R.string.intro_hello_title))
.description(getString(R.string.intro_hello_message))
.build())
@ -28,7 +30,7 @@ class IntroActivity : MaterialIntroActivity() {
addSlide(SlideFragmentBuilder()
.backgroundColor(R.color.colorAccent)
.buttonsColor(R.color.colorPrimary)
.image(R.drawable.ic_info_outline_white_48dp)
.image(R.drawable.ic_info_outline_white_48px)
.title(getString(R.string.intro_needs_selfoss_title))
.description(getString(R.string.intro_needs_selfoss_message))
.build(),
@ -40,7 +42,7 @@ class IntroActivity : MaterialIntroActivity() {
addSlide(SlideFragmentBuilder()
.backgroundColor(R.color.colorPrimaryDark)
.buttonsColor(R.color.colorAccentDark)
.image(R.drawable.ic_thumb_up_white_48dp)
.image(R.drawable.ic_thumb_up_white_48px)
.title(getString(R.string.intro_all_set_title))
.description(getString(R.string.intro_all_set_message))
.build())

View File

@ -9,15 +9,13 @@ import android.os.Bundle
import android.support.design.widget.TextInputLayout
import android.support.v7.app.AlertDialog
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
import android.text.TextUtils
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.inputmethod.EditorInfo
import android.widget.Button
import android.widget.EditText
import android.widget.Switch
import android.widget.TextView
import android.widget.*
import com.google.firebase.analytics.FirebaseAnalytics
import com.mikepenz.aboutlibraries.Libs
@ -30,17 +28,21 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.checkAndDisplayStoreApk
import apps.amine.bou.readerforselfoss.utils.isUrlValid
import apps.amine.bou.readerforselfoss.utils.isBaseUrlValid
import com.crashlytics.android.Crashlytics
import com.ftinc.scoop.Scoop
import io.fabric.sdk.android.Fabric
class LoginActivity : AppCompatActivity() {
private var inValidCount: Int = 0
private var isWithSelfSignedCert = false
private var isWithLogin = false
private var isWithHTTPLogin = false
private lateinit var settings: SharedPreferences
private lateinit var editor: SharedPreferences.Editor
private lateinit var mFirebaseAnalytics: FirebaseAnalytics
private lateinit var mUrlView: EditText
private lateinit var mLoginView: TextView
@ -49,13 +51,19 @@ class LoginActivity : AppCompatActivity() {
private lateinit var mPasswordView: EditText
private lateinit var mHTTPPasswordView: EditText
private lateinit var mLoginFormView: View
private lateinit var userIdentifier: String
private var logErrors: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Scoop.getInstance().apply(this)
setContentView(R.layout.activity_login)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
if (intent.getBooleanExtra("baseUrlFail", false)) {
val alertDialog = AlertDialog.Builder(this).create()
alertDialog.setTitle(getString(R.string.warning_wrong_url))
@ -69,6 +77,11 @@ class LoginActivity : AppCompatActivity() {
settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
userIdentifier = settings.getString("unique_id", "")
logErrors = settings.getBoolean("loging_debug", false)
editor = settings.edit()
if (settings.getString("url", "").isNotEmpty()) {
goToMain()
} else {
@ -91,6 +104,15 @@ class LoginActivity : AppCompatActivity() {
val mPasswordLayout: TextInputLayout = findViewById(R.id.passwordLayout)
val mHTTPPasswordLayout: TextInputLayout = findViewById(R.id.httpPasswordInput)
val mEmailSignInButton: Button = findViewById(R.id.email_sign_in_button)
val selfHostedSwitch: Switch = findViewById(R.id.withSelfhostedCert)
val warningTextview: TextView = findViewById(R.id.warningText)
selfHostedSwitch.setOnCheckedChangeListener {_, b ->
isWithSelfSignedCert = !isWithSelfSignedCert
val visi: Int = if (b) View.VISIBLE else View.GONE
warningTextview.visibility = visi
}
mPasswordView.setOnEditorActionListener(TextView.OnEditorActionListener { _, id, _ ->
if (id == R.id.login || id == EditorInfo.IME_NULL) {
@ -144,7 +166,7 @@ class LoginActivity : AppCompatActivity() {
var cancel = false
var focusView: View? = null
if (!url.isUrlValid()) {
if (!url.isBaseUrlValid()) {
mUrlView.error = getString(R.string.login_url_problem)
focusView = mUrlView
cancel = true
@ -181,17 +203,17 @@ class LoginActivity : AppCompatActivity() {
} else {
showProgress(true)
val editor = settings.edit()
editor.putString("url", url)
editor.putString("login", login)
editor.putString("httpUserName", httpLogin)
editor.putString("password", password)
editor.putString("httpPassword", httpPassword)
editor.putBoolean("isSelfSignedCert", isWithSelfSignedCert)
editor.apply()
val api = SelfossApi(this, this@LoginActivity)
val api = SelfossApi(this, this@LoginActivity, isWithSelfSignedCert)
api.login().enqueue(object : Callback<SuccessResponse> {
private fun preferenceError() {
private fun preferenceError(t: Throwable) {
editor.remove("url")
editor.remove("login")
editor.remove("httpUserName")
@ -203,6 +225,12 @@ class LoginActivity : AppCompatActivity() {
mPasswordView.error = getString(R.string.wrong_infos)
mHTTPLoginView.error = getString(R.string.wrong_infos)
mHTTPPasswordView.error = getString(R.string.wrong_infos)
if (logErrors) {
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "LOGIN_DEBUG_ERRROR", t.message)
Crashlytics.logException(t)
Toast.makeText(this@LoginActivity, t.message, Toast.LENGTH_LONG).show()
}
showProgress(false)
}
@ -211,12 +239,12 @@ class LoginActivity : AppCompatActivity() {
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, Bundle())
goToMain()
} else {
preferenceError()
preferenceError(Exception("No response body..."))
}
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
preferenceError()
preferenceError(t)
}
})
}
@ -255,6 +283,7 @@ class LoginActivity : AppCompatActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
menuInflater.inflate(R.menu.login_menu, menu)
menu.findItem(R.id.loging_debug).isChecked = logErrors
return true
}
@ -268,6 +297,14 @@ class LoginActivity : AppCompatActivity() {
.start(this)
return true
}
R.id.loging_debug -> {
val newState = !item.isChecked
item.isChecked = newState
logErrors = newState
editor.putBoolean("loging_debug", newState)
editor.apply()
return true
}
else -> return super.onOptionsItemSelected(item)
}
}

View File

@ -3,47 +3,113 @@ package apps.amine.bou.readerforselfoss
import android.content.Context
import android.graphics.drawable.Drawable
import android.net.Uri
import android.preference.PreferenceManager
import android.support.multidex.MultiDexApplication
import android.widget.ImageView
import apps.amine.bou.readerforselfoss.utils.Config
import com.anupcowkur.reservoir.Reservoir
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.crashlytics.android.Crashlytics
import com.ftinc.scoop.Scoop
import com.github.stkent.amplify.tracking.Amplify
import com.mikepenz.materialdrawer.util.AbstractDrawerImageLoader
import com.mikepenz.materialdrawer.util.DrawerImageLoader
import io.fabric.sdk.android.Fabric
import java.io.IOException
import java.util.UUID.randomUUID
class MyApp : MultiDexApplication() {
override fun onCreate() {
super.onCreate()
if (!BuildConfig.DEBUG)
Fabric.with(this, Crashlytics())
Fabric.with(this, Crashlytics())
initAmplify()
initCache()
val prefs = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
if (prefs.getString("unique_id", "").isEmpty()) {
val editor = prefs.edit()
editor.putString("unique_id", randomUUID().toString())
editor.apply()
}
initDrawerImageLoader()
initTheme()
tryToHandleBug()
}
private fun initAmplify() {
Amplify.initSharedInstance(this)
.setFeedbackEmailAddress(getString(R.string.feedback_email))
.setAlwaysShow(BuildConfig.DEBUG)
.applyAllDefaultRules()
.setFeedbackEmailAddress(getString(R.string.feedback_email))
.applyAllDefaultRules()
}
private fun initCache() {
try {
Reservoir.init(this, 8192) //in bytes
} catch (e: IOException) {
//failure
}
}
private fun initDrawerImageLoader() {
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)
Glide.with(imageView?.context)
.load(uri)
.apply(RequestOptions.fitCenterTransform()
.placeholder(placeholder))
.into(imageView)
}
override fun cancel(imageView: ImageView?) {
Glide.clear(imageView)
Glide.with(imageView?.context).clear(imageView)
}
override fun placeholder(ctx: Context?, tag: String?): Drawable {
return applicationContext.resources.getDrawable(R.mipmap.ic_launcher)
return baseContext.resources.getDrawable(R.mipmap.ic_launcher)
}
})
}
private fun initTheme() {
Scoop.waffleCone()
.addFlavor(getString(R.string.default_theme), R.style.NoBar, true)
.addFlavor(getString(R.string.default_dark_theme), R.style.NoBarDark)
.addFlavor(getString(R.string.teal_orange_theme), R.style.NoBarTealOrange)
.addFlavor(getString(R.string.teal_orange_dark_theme), R.style.NoBarTealOrangeDark)
.addFlavor(getString(R.string.cyan_pink_theme), R.style.NoBarCyanPink)
.addFlavor(getString(R.string.cyan_pink_dark_theme), R.style.NoBarCyanPinkDark)
.addFlavor(getString(R.string.grey_orange_theme), R.style.NoBarGreyOrange)
.addFlavor(getString(R.string.grey_orange_dark_theme), R.style.NoBarGreyOrangeDark)
.addFlavor(getString(R.string.blue_amber_theme), R.style.NoBarBlueAmber)
.addFlavor(getString(R.string.blue_amber_dark_theme), R.style.NoBarBlueAmberDark)
.addFlavor(getString(R.string.indigo_pink_theme), R.style.NoBarIndigoPink)
.addFlavor(getString(R.string.indigo_pink_dark_theme), R.style.NoBarIndigoPinkDark)
.addFlavor(getString(R.string.red_teal_theme), R.style.NoBarRedTeal)
.addFlavor(getString(R.string.red_teal_dark_theme), R.style.NoBarRedTealDark)
.setSharedPreferences(PreferenceManager.getDefaultSharedPreferences(this))
.initialize()
}
private fun tryToHandleBug() {
val oldHandler = Thread.getDefaultUncaughtExceptionHandler()
Thread.setDefaultUncaughtExceptionHandler { thread, e ->
if (e is java.lang.NoClassDefFoundError && e.stackTrace.asList().any { it.toString().contains("android.view.ViewDebug") })
Unit
else
oldHandler.uncaughtException(thread, e)
}
}
}

View File

@ -22,7 +22,10 @@ import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
import apps.amine.bou.readerforselfoss.utils.openItemUrl
import apps.amine.bou.readerforselfoss.utils.shareLink
import com.bumptech.glide.request.RequestOptions
import com.ftinc.scoop.Scoop
class ReaderActivity : DragDismissActivity() {
@ -39,6 +42,7 @@ class ReaderActivity : DragDismissActivity() {
}
override fun onCreateContent(inflater: LayoutInflater, parent: ViewGroup, savedInstanceState: Bundle?): View {
Scoop.getInstance().apply(this)
val v = inflater.inflate(R.layout.activity_reader, parent, false)
showProgressBar()
@ -71,10 +75,10 @@ class ReaderActivity : DragDismissActivity() {
}
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isEmpty())
Glide
.with(applicationContext)
.load(response.body()!!.lead_image_url)
.with(baseContext)
.asBitmap()
.fitCenter()
.load(response.body()!!.lead_image_url)
.apply(RequestOptions.fitCenterTransform())
.into(image)
shareBtn.setOnClickListener {
@ -82,10 +86,12 @@ class ReaderActivity : DragDismissActivity() {
}
browserBtn.setOnClickListener {
val intent = Intent(Intent.ACTION_VIEW)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.data = Uri.parse(response.body()!!.url)
startActivity(intent)
this@ReaderActivity.openItemUrl(
response.body()!!.url,
customTabsIntent,
false,
false,
this@ReaderActivity)
}
hideProgressBar()
@ -95,12 +101,13 @@ class ReaderActivity : DragDismissActivity() {
override fun onFailure(call: Call<ParsedContent>, t: Throwable) = openInBrowserAfterFailing()
private fun openInBrowserAfterFailing() {
CustomTabActivityHelper.openCustomTab(this@ReaderActivity, customTabsIntent, Uri.parse(url)
) { _, uri ->
val intent = Intent(Intent.ACTION_VIEW, uri)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
this@ReaderActivity.openItemUrl(
url,
customTabsIntent,
true,
false,
this@ReaderActivity
)
finish()
}
})

View File

@ -2,9 +2,11 @@ package apps.amine.bou.readerforselfoss
import android.content.Intent
import android.os.Bundle
import android.preference.PreferenceManager
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.support.v7.widget.Toolbar
import android.widget.Toast
import com.melnykov.fab.FloatingActionButton
@ -15,14 +17,19 @@ import retrofit2.Response
import apps.amine.bou.readerforselfoss.adapters.SourcesListAdapter
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.Sources
import com.ftinc.scoop.Scoop
class SourcesActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Scoop.getInstance().apply(this)
setContentView(R.layout.activity_sources)
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
supportActionBar?.setDisplayShowHomeEnabled(true)
}
override fun onResume() {
@ -30,7 +37,10 @@ class SourcesActivity : AppCompatActivity() {
val mFab: FloatingActionButton = findViewById(R.id.fab)
val mRecyclerView: RecyclerView = findViewById(R.id.activity_sources)
val mLayoutManager = LinearLayoutManager(this)
val api = SelfossApi(this, this@SourcesActivity)
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
val api = SelfossApi(this, this@SourcesActivity, prefs.getBoolean("isSelfSignedCert", false))
var items: ArrayList<Sources> = ArrayList()
mFab.attachToRecyclerView(mRecyclerView)

View File

@ -2,14 +2,12 @@ package apps.amine.bou.readerforselfoss.adapters
import android.app.Activity
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Color
import android.support.constraint.ConstraintLayout
import android.support.design.widget.Snackbar
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import android.support.v7.widget.CardView
import android.support.v7.widget.RecyclerView
import android.text.Html
import android.text.format.DateUtils
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageButton
@ -21,22 +19,24 @@ import android.widget.Toast
import com.amulyakhare.textdrawable.TextDrawable
import com.amulyakhare.textdrawable.util.ColorGenerator
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.BitmapImageViewTarget
import com.like.LikeButton
import com.like.OnLikeListener
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.Item
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.themes.AppColors
import apps.amine.bou.readerforselfoss.utils.*
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
import apps.amine.bou.readerforselfoss.utils.glide.bitmapCenterCrop
import apps.amine.bou.readerforselfoss.utils.glide.bitmapFitCenter
import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable
import com.crashlytics.android.Crashlytics
import kotlin.collections.ArrayList
class ItemCardAdapter(private val app: Activity,
private val items: ArrayList<Item>,
@ -44,8 +44,11 @@ class ItemCardAdapter(private val app: Activity,
private val helper: CustomTabActivityHelper,
private val internalBrowser: Boolean,
private val articleViewer: Boolean,
private val fullHeightCards: Boolean) : RecyclerView.Adapter<ItemCardAdapter.ViewHolder>() {
private val c: Context = app.applicationContext
private val fullHeightCards: Boolean,
private val appColors: AppColors,
val debugReadingItems: Boolean,
val userIdentifier: String) : RecyclerView.Adapter<ItemCardAdapter.ViewHolder>() {
private val c: Context = app.baseContext
private val generator: ColorGenerator = ColorGenerator.MATERIAL
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
@ -63,7 +66,7 @@ class ItemCardAdapter(private val app: Activity,
holder.sourceTitleAndDate.text = itm.sourceAndDateText()
if (itm.getThumbnail(c).isEmpty()) {
Glide.clear(holder.itemImage)
Glide.with(c).clear(holder.itemImage)
holder.itemImage.setImageDrawable(null)
} else {
if (fullHeightCards) {
@ -127,11 +130,31 @@ class ItemCardAdapter(private val app: Activity,
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
if (debugReadingItems) {
val message =
"message: ${response.message()} " +
"response isSuccess: ${response.isSuccessful} " +
"response code: ${response.code()} " +
"response message: ${response.message()} " +
"response errorBody: ${response.errorBody()?.string()} " +
"body success: ${response.body()?.success} " +
"body isSuccess: ${response.body()?.isSuccess}"
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
Crashlytics.logException(Exception("Was success, but did it work ?"))
Toast.makeText(c, message, Toast.LENGTH_LONG).show()
}
doUnmark(i, position)
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
if (debugReadingItems) {
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "READ_DEBUG_ERROR", t.message)
Crashlytics.logException(t)
Toast.makeText(c, t.message, Toast.LENGTH_LONG).show()
}
Toast.makeText(app, app.getString(R.string.cant_mark_read), Toast.LENGTH_SHORT).show()
items.add(i)
notifyItemInserted(position)
@ -150,6 +173,7 @@ class ItemCardAdapter(private val app: Activity,
lateinit var sourceTitleAndDate: TextView
init {
(mView.findViewById<CardView>(R.id.card)).setCardBackgroundColor(appColors.cardBackground)
handleClickListeners()
handleCustomTabActions()
}
@ -208,7 +232,7 @@ class ItemCardAdapter(private val app: Activity,
helper.bindCustomTabsService(app)
mView.setOnClickListener {
c.openItemUrl(items[adapterPosition],
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
customTabsIntent,
internalBrowser,
articleViewer,

View File

@ -3,16 +3,11 @@ package apps.amine.bou.readerforselfoss.adapters
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.net.Uri
import android.support.constraint.ConstraintLayout
import android.support.design.widget.Snackbar
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import android.support.v7.widget.RecyclerView
import android.text.Html
import android.text.format.DateUtils
import android.util.TypedValue
import android.view.LayoutInflater
import android.view.View
@ -21,15 +16,11 @@ import android.widget.*
import com.amulyakhare.textdrawable.TextDrawable
import com.amulyakhare.textdrawable.util.ColorGenerator
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.BitmapImageViewTarget
import com.like.LikeButton
import com.like.OnLikeListener
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
import java.text.ParseException
import java.text.SimpleDateFormat
import java.util.*
import apps.amine.bou.readerforselfoss.R
@ -38,6 +29,10 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.utils.*
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
import apps.amine.bou.readerforselfoss.utils.glide.bitmapCenterCrop
import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable
import com.crashlytics.android.Crashlytics
import kotlin.collections.ArrayList
class ItemListAdapter(private val app: Activity,
@ -46,9 +41,11 @@ class ItemListAdapter(private val app: Activity,
private val helper: CustomTabActivityHelper,
private val clickBehavior: Boolean,
private val internalBrowser: Boolean,
private val articleViewer: Boolean) : RecyclerView.Adapter<ItemListAdapter.ViewHolder>() {
private val articleViewer: Boolean,
val debugReadingItems: Boolean,
val userIdentifier: String) : RecyclerView.Adapter<ItemListAdapter.ViewHolder>() {
private val generator: ColorGenerator = ColorGenerator.MATERIAL
private val c: Context = app.applicationContext
private val c: Context = app.baseContext
private val bars: ArrayList<Boolean> = ArrayList(Collections.nCopies(items.size + 1, false))
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
@ -141,11 +138,31 @@ class ItemListAdapter(private val app: Activity,
api.markItem(i.id).enqueue(object : Callback<SuccessResponse> {
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
if (debugReadingItems) {
val message =
"message: ${response.message()} " +
"response isSuccess: ${response.isSuccessful} " +
"response code: ${response.code()} " +
"response message: ${response.message()} " +
"response errorBody: ${response.errorBody()?.string()} " +
"body success: ${response.body()?.success} " +
"body isSuccess: ${response.body()?.isSuccess}"
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
Crashlytics.logException(Exception("Was success, but did it work ?"))
Toast.makeText(c, message, Toast.LENGTH_LONG).show()
}
doUnmark(i, position)
}
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
if (debugReadingItems) {
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "READ_DEBUG_ERROR", t.message)
Crashlytics.logException(t)
Toast.makeText(c, t.message, Toast.LENGTH_LONG).show()
}
Toast.makeText(app, app.getString(R.string.cant_mark_read), Toast.LENGTH_SHORT).show()
items.add(i)
notifyItemInserted(position)
@ -222,7 +239,7 @@ class ItemListAdapter(private val app: Activity,
if (!clickBehavior) {
mView.setOnClickListener {
c.openItemUrl(items[adapterPosition],
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
customTabsIntent,
internalBrowser,
articleViewer,
@ -235,7 +252,7 @@ class ItemListAdapter(private val app: Activity,
} else {
mView.setOnClickListener { actionBarShowHide() }
mView.setOnLongClickListener {
c.openItemUrl(items[adapterPosition],
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
customTabsIntent,
internalBrowser,
articleViewer,

View File

@ -21,7 +21,7 @@ import apps.amine.bou.readerforselfoss.R
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
import apps.amine.bou.readerforselfoss.api.selfoss.Sources
import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
import apps.amine.bou.readerforselfoss.utils.circularBitmapDrawable
import apps.amine.bou.readerforselfoss.utils.glide.circularBitmapDrawable
import apps.amine.bou.readerforselfoss.utils.toTextDrawableString

View File

@ -2,11 +2,6 @@ package apps.amine.bou.readerforselfoss.api.selfoss
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.support.v7.app.AlertDialog
import android.widget.Toast
import apps.amine.bou.readerforselfoss.LoginActivity
import apps.amine.bou.readerforselfoss.R
import java.util.concurrent.ConcurrentHashMap
import com.burgstaller.okhttp.AuthenticationCacheInterceptor
@ -23,26 +18,35 @@ import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.getUnsafeHttpClient
// codebeat:disable[ARITY,TOO_MANY_FUNCTIONS]
class SelfossApi(c: Context, callingActivity: Activity) {
class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Boolean) {
private lateinit var service: SelfossService
private val config: Config = Config(c)
private val userName: String
private val password: String
fun OkHttpClient.Builder.maybeWithSelfSigned(isWithSelfSignedCert: Boolean): OkHttpClient.Builder =
if (isWithSelfSignedCert) {
getUnsafeHttpClient()
} else {
this
}
fun Credentials.createAuthenticator(): DispatchingAuthenticator =
DispatchingAuthenticator.Builder()
.with("digest", DigestAuthenticator(this))
.with("basic", BasicAuthenticator(this))
.build()
fun DispatchingAuthenticator.getHttpClien(): OkHttpClient {
fun DispatchingAuthenticator.getHttpClien(isWithSelfSignedCert: Boolean): OkHttpClient {
val authCache = ConcurrentHashMap<String, CachingAuthenticator>()
return OkHttpClient
.Builder()
.maybeWithSelfSigned(isWithSelfSignedCert)
.authenticator(CachingAuthenticatorDecorator(this, authCache))
.addInterceptor(AuthenticationCacheInterceptor(authCache))
.build()
@ -71,7 +75,7 @@ class SelfossApi(c: Context, callingActivity: Activity) {
Retrofit
.Builder()
.baseUrl(config.baseUrl)
.client(authenticator.getHttpClien())
.client(authenticator.getHttpClien(isWithSelfSignedCert))
.addConverterFactory(GsonConverterFactory.create(gson))
.build()
service = retrofit.create(SelfossService::class.java)
@ -84,16 +88,16 @@ class SelfossApi(c: Context, callingActivity: Activity) {
service.loginToSelfoss(config.userLogin, config.userPassword)
fun readItems(tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
getItems("read", tag, sourceId, search)
getItems("read", tag, sourceId, search, 200)
fun newItems(tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
getItems("unread", tag, sourceId, search)
fun newItems(tag: String?, sourceId: Long?, search: String?, itemsNumber: Int): Call<List<Item>> =
getItems("unread", tag, sourceId, search, itemsNumber)
fun starredItems(tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
getItems("starred", tag, sourceId, search)
getItems("starred", tag, sourceId, search, 200)
private fun getItems(type: String, tag: String?, sourceId: Long?, search: String?): Call<List<Item>> =
service.getItems(type, tag, sourceId, search, userName, password)
private fun getItems(type: String, tag: String?, sourceId: Long?, search: String?, items: Int): Call<List<Item>> =
service.getItems(type, tag, sourceId, search, userName, password, items)
fun markItem(itemId: String): Call<SuccessResponse> =
service.markAsRead(itemId, userName, password)

View File

@ -22,7 +22,8 @@ internal interface SelfossService {
@Query("source") source: Long?,
@Query("search") search: String?,
@Query("username") username: String,
@Query("password") password: String): Call<List<Item>>
@Query("password") password: String,
@Query("items") items: Int): Call<List<Item>>
@POST("mark/{id}")
fun markAsRead(@Path("id") id: String,

View File

@ -6,12 +6,19 @@ import android.preference.PreferenceActivity;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.AppBarLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import apps.amine.bou.readerforselfoss.R;
import com.ftinc.scoop.Scoop;
/**
* A {@link PreferenceActivity} which implements and proxies the necessary calls
@ -25,12 +32,23 @@ public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
protected void onCreate(Bundle savedInstanceState) {
getDelegate().installViewFactory();
getDelegate().onCreate(savedInstanceState);
Scoop.getInstance().apply(this);
super.onCreate(savedInstanceState);
}
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
AppBarLayout bar = (AppBarLayout) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false);
Toolbar toolbar = bar.findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
root.addView(bar, 0);
getDelegate().onPostCreate(savedInstanceState);
}

View File

@ -2,24 +2,34 @@ package apps.amine.bou.readerforselfoss.settings;
import android.annotation.TargetApi;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.SwitchPreference;
import android.support.v7.app.ActionBar;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.text.InputFilter;
import android.text.Spanned;
import android.view.MenuItem;
import android.widget.Toast;
import java.util.List;
import apps.amine.bou.readerforselfoss.R;
import apps.amine.bou.readerforselfoss.utils.Config;
import com.ftinc.scoop.ui.ScoopSettingsActivity;
/**
@ -118,6 +128,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
protected boolean isValidFragment(String fragmentName) {
return PreferenceFragment.class.getName().equals(fragmentName)
|| GeneralPreferenceFragment.class.getName().equals(fragmentName)
|| DebugPreferenceFragment.class.getName().equals(fragmentName)
|| LinksPreferenceFragment.class.getName().equals(fragmentName);
}
@ -143,6 +154,61 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
return true;
}
});
EditTextPreference itemsNumber = (EditTextPreference) findPreference("prefer_api_items_number");
itemsNumber.getEditText().setFilters(new InputFilter[]{
new InputFilter (){
@Override
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
try {
int input = Integer.parseInt(dest.toString() + source.toString());
if (input <= 200 && input >0)
return null;
} catch (NumberFormatException nfe) { }
return "";
}
}
});
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
getActivity().finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class DebugPreferenceFragment extends PreferenceFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_debug);
setHasOptionsMenu(true);
SharedPreferences pref = getActivity().getSharedPreferences(Config.Companion.getSettingsName(), Context.MODE_PRIVATE);
final String id = pref.getString("unique_id", "...");
final Preference identifier = findPreference("debug_identifier");
final ClipboardManager clipboard = (ClipboardManager)
getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
identifier.setOnPreferenceClickListener(new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
ClipData clip = ClipData.newPlainText("Selfoss unique id", id);
clipboard.setPrimaryClip(clip);
Toast.makeText(getActivity(), R.string.unique_id_to_clipboard, Toast.LENGTH_LONG).show();
return true;
}
});
identifier.setTitle(id);
}
@Override
@ -201,6 +267,17 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
}
}
@Override
public void onHeaderClick(Header header, int position) {
super.onHeaderClick(header, position);
if (header.id == R.id.theme_change) {
Intent intent = ScoopSettingsActivity.createIntent(getApplicationContext());
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
getApplicationContext().startActivity(intent);
finish();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();

View File

@ -0,0 +1,53 @@
package apps.amine.bou.readerforselfoss.themes
import android.app.Activity
import android.content.Context
import android.support.annotation.ColorInt
import android.util.TypedValue
import apps.amine.bou.readerforselfoss.R
import java.lang.reflect.AccessibleObject.setAccessible
class AppColors(a: Activity) {
@ColorInt val accent: Int
@ColorInt val dark: Int
@ColorInt val primary: Int
@ColorInt val cardBackground: Int
@ColorInt val windowBackground: Int
val isDarkTheme: Boolean
init {
val wrapper = Context::class.java
val method = wrapper!!.getMethod("getThemeResId")
method.isAccessible = true
isDarkTheme = when(method.invoke(a.baseContext)) {
R.style.NoBarTealOrangeDark,
R.style.NoBarDark,
R.style.NoBarBlueAmberDark,
R.style.NoBarGreyOrangeDark,
R.style.NoBarIndigoPinkDark,
R.style.NoBarRedTealDark,
R.style.NoBarCyanPinkDark -> true
else -> false
}
val typedAccent = TypedValue()
val typedAccentDark = TypedValue()
val typedPrimary = TypedValue()
val typedCardBackground = TypedValue()
val typedWindowBackground = TypedValue()
a.theme.resolveAttribute(R.attr.colorAccent, typedAccent, true)
a.theme.resolveAttribute(R.attr.colorAccent, typedAccent, true)
a.theme.resolveAttribute(R.attr.colorPrimary, typedPrimary, true)
a.theme.resolveAttribute(R.attr.cardBackgroundColor, typedCardBackground, true)
a.theme.resolveAttribute(android.R.attr.colorBackground, typedWindowBackground, true)
accent = typedAccent.data
dark = typedAccentDark.data
primary = typedPrimary.data
cardBackground = typedCardBackground.data
windowBackground = typedWindowBackground.data
}
}

View File

@ -36,7 +36,10 @@ fun Context.checkAndDisplayStoreApk() = {
} else Unit
}
fun String.isUrlValid(): Boolean {
fun String.isUrlValid(): Boolean =
HttpUrl.parse(this) != null && Patterns.WEB_URL.matcher(this).matches()
fun String.isBaseUrlValid(): Boolean {
val baseUrl = HttpUrl.parse(this)
var existsAndEndsWithSlash = false
if (baseUrl != null) {

View File

@ -1,24 +0,0 @@
package apps.amine.bou.readerforselfoss.utils
import android.content.Context
import android.graphics.Bitmap
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.target.BitmapImageViewTarget
fun Context.bitmapCenterCrop(url: String, iv: ImageView) =
Glide.with(this).load(url).asBitmap().centerCrop().into(iv)
fun Context.bitmapFitCenter(url: String, iv: ImageView) =
Glide.with(this).load(url).asBitmap().fitCenter().into(iv)
fun Context.circularBitmapDrawable(url: String, iv: ImageView) =
Glide.with(this).load(url).asBitmap().centerCrop().into(object : BitmapImageViewTarget(iv) {
override fun setResource(resource: Bitmap) {
val circularBitmapDrawable = RoundedBitmapDrawableFactory.create(resources, resource)
circularBitmapDrawable.isCircular = true
iv.setImageDrawable(circularBitmapDrawable)
}
})

View File

@ -0,0 +1,39 @@
package apps.amine.bou.readerforselfoss.utils
import okhttp3.OkHttpClient
import java.security.cert.CertificateException
import java.security.cert.X509Certificate
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManager
import javax.net.ssl.X509TrustManager
fun getUnsafeHttpClient() =
try {
// Create a trust manager that does not validate certificate chains
val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager {
override fun getAcceptedIssuers(): Array<X509Certificate> =
arrayOf()
@Throws(CertificateException::class)
override fun checkClientTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {
}
@Throws(CertificateException::class)
override fun checkServerTrusted(chain: Array<java.security.cert.X509Certificate>, authType: String) {
}
})
// Install the all-trusting trust manager
val sslContext = SSLContext.getInstance("SSL")
sslContext.init(null, trustAllCerts, java.security.SecureRandom())
val sslSocketFactory = sslContext.socketFactory
OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager)
.hostnameVerifier { _, _ -> true }
} catch (e: Exception) {
throw RuntimeException(e)
}

View File

@ -50,15 +50,13 @@ fun Context.buildCustomTabsIntent(): CustomTabsIntent {
return intentBuilder.build()
}
fun Context.openItemUrl(i: Item,
fun Context.openItemUrl(linkDecoded: String,
customTabsIntent: CustomTabsIntent,
internalBrowser: Boolean,
articleViewer: Boolean,
app: Activity) {
if (!internalBrowser) {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(i.getLinkDecoded())
app.startActivity(intent)
if (!internalBrowser || !linkDecoded.isUrlValid()) {
openInBrowser(linkDecoded, app)
} else {
if (articleViewer) {
val intent = Intent(this, ReaderActivity::class.java)
@ -68,15 +66,25 @@ fun Context.openItemUrl(i: Item,
.setDragElasticity(DragDismissIntentBuilder.DragElasticity.NORMAL) // Larger elasticities will make it easier to dismiss.
.build(intent)
intent.putExtra("url", i.getLinkDecoded())
intent.putExtra("url", linkDecoded)
app.startActivity(intent)
} else {
CustomTabActivityHelper.openCustomTab(app, customTabsIntent, Uri.parse(i.getLinkDecoded())
) { _, uri ->
val intent = Intent(Intent.ACTION_VIEW, uri)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
try {
CustomTabActivityHelper.openCustomTab(app, customTabsIntent, Uri.parse(linkDecoded)
) { _, uri ->
val intent = Intent(Intent.ACTION_VIEW, uri)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
} catch (e: Exception) {
openInBrowser(linkDecoded, app)
}
}
}
}
private fun openInBrowser(linkDecoded: String, app: Activity) {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(linkDecoded)
app.startActivity(intent)
}

View File

@ -0,0 +1,16 @@
package apps.amine.bou.readerforselfoss.utils.bottombar
import com.ashokvarma.bottomnavigation.TextBadgeItem
fun TextBadgeItem.removeBadge(): TextBadgeItem {
this.setText("")
this.hide()
return this
}
fun TextBadgeItem.maybeShow(): TextBadgeItem =
if (this.isHidden)
this.show()
else
this

View File

@ -0,0 +1,29 @@
package apps.amine.bou.readerforselfoss.utils.glide
import android.content.Context
import android.graphics.Bitmap
import android.support.v4.graphics.drawable.RoundedBitmapDrawableFactory
import android.widget.ImageView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.bumptech.glide.request.target.BitmapImageViewTarget
fun Context.bitmapCenterCrop(url: String, iv: ImageView) =
Glide.with(this).asBitmap().load(url).apply(RequestOptions.centerCropTransform()).into(iv)
fun Context.bitmapFitCenter(url: String, iv: ImageView) =
Glide.with(this).asBitmap().load(url).apply(RequestOptions.fitCenterTransform()).into(iv)
fun Context.circularBitmapDrawable(url: String, iv: ImageView) =
Glide.with(this)
.asBitmap()
.load(url)
.apply(RequestOptions.centerCropTransform()).
into(object : BitmapImageViewTarget(iv) {
override fun setResource(resource: Bitmap?) {
val circularBitmapDrawable = RoundedBitmapDrawableFactory.create(resources, resource)
circularBitmapDrawable.isCircular = true
iv.setImageDrawable(circularBitmapDrawable)
}
})

View File

@ -0,0 +1,32 @@
package apps.amine.bou.readerforselfoss.utils.glide
import android.content.Context
import apps.amine.bou.readerforselfoss.utils.Config
import apps.amine.bou.readerforselfoss.utils.getUnsafeHttpClient
import com.bumptech.glide.Glide
import com.bumptech.glide.GlideBuilder
import com.bumptech.glide.Registry
import com.bumptech.glide.module.GlideModule
import com.bumptech.glide.load.model.GlideUrl
import java.io.InputStream
class SelfSignedGlideModule : GlideModule {
override fun applyOptions(context: Context?, builder: GlideBuilder?) {}
override fun registerComponents(context: Context?, glide: Glide?, registry: Registry?) {
if (context != null) {
val pref = context?.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
if (pref.getBoolean("isSelfSignedCert", false)) {
val client = getUnsafeHttpClient().build()
registry?.append(GlideUrl::class.java, InputStream::class.java,
com.bumptech.glide.integration.okhttp3.OkHttpUrlLoader.Factory(client))
}
}
}
}

View File

@ -1,9 +0,0 @@
<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

@ -1,9 +0,0 @@
<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: 271 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 458 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 498 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 212 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 355 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 339 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 504 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 725 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 466 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 573 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 966 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@ -2,12 +2,12 @@
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@color/white"/>
android:drawable="@color/ic_launcher_background"/>
<item>
<bitmap
android:gravity="center"
android:src="@mipmap/ic_launcher"/>
android:src="@mipmap/ic_launcher_foreground"/>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

View File

@ -0,0 +1,4 @@
<vector android:height="24dp" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFF" 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,4 @@
<vector android:height="24dp" android:viewportHeight="24.0"
android:viewportWidth="24.0" android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
<path android:fillColor="#FFFFFF" android:pathData="M1,21h4L5,9L1,9v12zM23,10c0,-1.1 -0.9,-2 -2,-2h-6.31l0.95,-4.57 0.03,-0.32c0,-0.41 -0.17,-0.79 -0.44,-1.06L14.17,1 7.59,7.59C7.22,7.95 7,8.45 7,9v10c0,1.1 0.9,2 2,2h9c0.83,0 1.54,-0.5 1.84,-1.22l3.02,-7.05c0.09,-0.23 0.14,-0.47 0.14,-0.73v-1.91l-0.01,-0.01L23,10z"/>
</vector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -1,130 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
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
android:id="@+id/bottomBar"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
app:bb_tabletMode="true"
app:bb_tabXmlResource="@xml/bottombar"
app:bb_activeTabColor="@color/white"
app:bb_inActiveTabColor="@color/black"
app:bb_badgeBackgroundColor="@color/colorPrimary"/>
<com.github.stkent.amplify.prompt.DefaultLayoutPromptView
android:id="@+id/prompt_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:prompt_view_user_opinion_question_title="@string/rating_prompt_title"
app:prompt_view_user_opinion_question_positive_button_label="@string/rating_prompt_yes"
app:prompt_view_user_opinion_question_negative_button_label="@string/rating_prompt_no"
app:prompt_view_positive_feedback_question_title="@string/rating_prompt_rating_title"
app:prompt_view_positive_feedback_question_positive_button_label="@string/rating_prompt_rating_yes"
app:prompt_view_positive_feedback_question_negative_button_label="@string/rating_prompt_rating_no"
app:prompt_view_critical_feedback_question_title="@string/rating_prompt_feedback_title"
app:prompt_view_critical_feedback_question_positive_button_label="@string/rating_prompt_feedback_yes"
app:prompt_view_critical_feedback_question_negative_button_label="@string/rating_prompt_feedback_no"
app:prompt_view_thanks_title="@string/rating_prompt_thanks"
app:prompt_view_positive_button_background_color="@color/colorPrimary"
app:prompt_view_positive_button_text_color="@color/white"
app:prompt_view_positive_button_border_color="@color/colorPrimary"
app:prompt_view_negative_button_background_color="@color/colorAccent"
app:prompt_view_negative_button_border_color="@color/white"
app:prompt_view_thanks_display_time_ms="2000"
android:layout_toEndOf="@+id/bottomBar"
android:layout_toRightOf="@+id/bottomBar"/>
<!-- This could be your fragment container, or something -->
<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toEndOf="@+id/bottomBar"
android:layout_toRightOf="@+id/bottomBar"
android:layout_below="@id/prompt_view">
<android.support.design.widget.CoordinatorLayout
android:id="@+id/intern_coordLayout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/emptyText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="fill"
android:paddingTop="100dp"
android:text="@string/nothing_here"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:textColor="@color/about_libraries_card_dark"
android:visibility="gone" />
<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" />
</LinearLayout>
</android.support.v4.widget.SwipeRefreshLayout>
</FrameLayout>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>

View File

@ -1,118 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="apps.amine.bou.readerforselfoss.AddSourceActivity">
tools:context="apps.amine.bou.readerforselfoss.AddSourceActivity"
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" />
</android.support.design.widget.AppBarLayout>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/formContainer"
android:visibility="gone"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintVertical_bias="0.0">
<TextView
android:text="@string/add_source"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView2"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textAlignment="center"
android:layout_marginTop="16dp"
android:layout_width="match_parent">
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="16dp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:id="@+id/nameInput"
android:layout_marginTop="32dp"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:inputType="text"
android:hint="@string/add_source_hint_name"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:ems="10"
android:id="@+id/sourceUri"
android:hint="@string/add_source_hint_url"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/nameInput"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:id="@+id/tags"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/sourceUri"
android:hint="@string/add_source_hint_tags"
android:inputType="text"/>
app:layout_constraintBottom_toBottomOf="parent"
android:id="@+id/formContainer"
android:visibility="gone"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintVertical_bias="0.0">
<Spinner
android:layout_width="match_parent"
android:id="@+id/spoutsSpinner"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/tags"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_height="40dp"/>
<TextView
android:text="@string/add_source"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView2"
android:textAppearance="@style/TextAppearance.AppCompat.Large"
android:textAlignment="center"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="16dp"/>
<Button
android:text="@string/add_source_save"
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:id="@+id/nameInput"
android:layout_marginTop="32dp"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:inputType="text"
android:hint="@string/add_source_hint_name"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textUri"
android:ems="10"
android:id="@+id/sourceUri"
android:hint="@string/add_source_hint_url"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/nameInput"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:id="@+id/tags"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/sourceUri"
android:hint="@string/add_source_hint_tags"
android:inputType="text"/>
<Spinner
android:layout_width="match_parent"
android:id="@+id/spoutsSpinner"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/tags"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_height="40dp"/>
<Button
android:text="@string/add_source_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/saveBtn"
android:elevation="5dp"
android:textColor="?attr/colorAccent"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/spoutsSpinner"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="16dp"
app:layout_constraintVertical_bias="0.0"/>
</android.support.constraint.ConstraintLayout>
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/saveBtn"
android:elevation="5dp"
android:textColor="@color/colorAccent"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:id="@+id/progress"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toBottomOf="@+id/spoutsSpinner"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="16dp"
app:layout_constraintVertical_bias="0.0"/>
android:visibility="visible"/>
</android.support.constraint.ConstraintLayout>
<ProgressBar
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progress"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="visible"/>
</android.support.constraint.ConstraintLayout>
</LinearLayout>

View File

@ -27,6 +27,7 @@
app:prompt_view_positive_button_border_color="@color/colorPrimary"
app:prompt_view_negative_button_background_color="@color/colorAccent"
app:prompt_view_negative_button_border_color="@color/white"
app:prompt_view_background_color="?attr/colorAccent"
app:prompt_view_thanks_display_time_ms="2000"/>
<android.support.design.widget.CoordinatorLayout
@ -53,8 +54,7 @@
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ToolBarStyle"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
app:theme="@style/ToolBarStyle" />
</android.support.design.widget.AppBarLayout>
@ -74,7 +74,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/background_grey">
android:background="?android:attr/windowBackground">
<TextView
android:id="@+id/emptyText"
@ -85,7 +85,6 @@
android:text="@string/nothing_here"
android:textAlignment="center"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:textColor="@color/about_libraries_card_dark"
android:background="@color/transparent"
android:visibility="gone" />
<android.support.v7.widget.RecyclerView
@ -104,17 +103,10 @@
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
<com.roughike.bottombar.BottomBar
<com.ashokvarma.bottomnavigation.BottomNavigationBar
android:layout_gravity="bottom"
android:id="@+id/bottomBar"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_gravity="bottom"
app:bb_behavior="shy"
android:layout_alignParentBottom="true"
app:bb_tabXmlResource="@xml/bottombar"
app:bb_activeTabColor="@color/white"
app:bb_badgeBackgroundColor="@color/colorPrimary"
app:bb_inActiveTabColor="@color/black"
app:bb_badgesHideWhenActive="false" />
android:layout_height="60dp"/>
</android.support.design.widget.CoordinatorLayout>
</RelativeLayout>

View File

@ -2,137 +2,168 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:gravity="center_horizontal"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="apps.amine.bou.readerforselfoss.LoginActivity">
<!-- Login progress -->
<ProgressBar
android:id="@+id/login_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:visibility="gone"/>
<ScrollView
android:id="@+id/login_form"
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="wrap_content">
<LinearLayout
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ToolBarStyle" />
</android.support.design.widget.AppBarLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<!-- Login progress -->
<ProgressBar
android:id="@+id/login_progress"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
android:layout_marginBottom="8dp"
android:visibility="gone"/>
<android.support.design.widget.TextInputLayout
<ScrollView
android:id="@+id/login_form"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/urlLayout"
>
android:orientation="vertical">
<EditText
android:id="@+id/url"
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_url"
android:imeActionId="@+id/login"
android:inputType="textUri"
android:imeOptions="actionUnspecified"
android:maxLines="1"
/>
android:id="@+id/urlLayout"
>
</android.support.design.widget.TextInputLayout>
<EditText
android:id="@+id/url"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_url"
android:imeActionId="@+id/login"
android:inputType="textUri"
android:imeOptions="actionUnspecified"
android:maxLines="1"
/>
<Switch
android:text="@string/withLoginSwitch"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/withLogin"
android:layout_weight="1"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/loginLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
<Switch
android:text="@string/withLoginSwitch"
android:layout_width="match_parent"
android:layout_height="0dp"
android:id="@+id/withLogin"
android:layout_weight="1"/>
<AutoCompleteTextView
android:id="@+id/login"
<android.support.design.widget.TextInputLayout
android:id="@+id/loginLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_login"
android:inputType="text"
android:maxLines="1"
/>
android:visibility="gone">
</android.support.design.widget.TextInputLayout>
<AutoCompleteTextView
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_login"
android:inputType="text"
android:maxLines="1"
/>
<android.support.design.widget.TextInputLayout
android:id="@+id/passwordLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone">
</android.support.design.widget.TextInputLayout>
<EditText
android:id="@+id/password"
<android.support.design.widget.TextInputLayout
android:id="@+id/passwordLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:inputType="textPassword"
android:maxLines="1"
/>
android:visibility="gone">
</android.support.design.widget.TextInputLayout>
<EditText
android:id="@+id/password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_password"
android:inputType="textPassword"
android:maxLines="1"
/>
<Switch
android:id="@+id/withHttpLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="@string/withHttpLoginSwitch" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/httpLoginInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<EditText
android:id="@+id/httpLogin"
<Switch
android:id="@+id/withHttpLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_http_login" />
</android.support.design.widget.TextInputLayout>
android:layout_weight="1"
android:text="@string/withHttpLoginSwitch" />
<android.support.design.widget.TextInputLayout
android:id="@+id/httpPasswordInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<android.support.design.widget.TextInputLayout
android:id="@+id/httpLoginInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<EditText
android:id="@+id/httpPassword"
<EditText
android:id="@+id/httpLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/prompt_http_login" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/httpPasswordInput"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone">
<EditText
android:id="@+id/httpPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="@string/prompt_http_password" />
</android.support.design.widget.TextInputLayout>
<Switch
android:id="@+id/withSelfhostedCert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword"
android:hint="@string/prompt_http_password" />
</android.support.design.widget.TextInputLayout>
android:text="@string/self_hosted_cert_switch" />
<Button
android:id="@+id/email_sign_in_button"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="16dp"
android:text="@string/action_sign_in"
android:textStyle="bold" />
<TextView
android:id="@+id/warningText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/self_signed_cert_warning"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:visibility="gone" />
<Button
android:id="@+id/email_sign_in_button"
style="?android:textAppearanceSmall"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:layout_marginTop="16dp"
android:text="@string/action_sign_in"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</LinearLayout>
</LinearLayout>
</ScrollView>
</LinearLayout>

View File

@ -5,7 +5,8 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="apps.amine.bou.readerforselfoss.ReaderActivity">
tools:context="apps.amine.bou.readerforselfoss.ReaderActivity"
android:background="?android:attr/windowBackground">
<ImageView
android:id="@+id/imageView"
@ -96,7 +97,7 @@
android:padding="4dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_open_in_browser_black_24dp"
android:tint="#000000"
android:tint="?android:attr/textColorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/shareBtn"
app:layout_constraintHorizontal_bias="0.5"
@ -113,7 +114,7 @@
android:padding="4dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_share_black_24dp"
android:tint="#000000"
android:tint="?android:attr/textColorPrimary"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"

View File

@ -8,12 +8,22 @@
android:layout_height="match_parent"
tools:context="apps.amine.bou.readerforselfoss.SourcesActivity"
xmlns:fab="http://schemas.android.com/apk/res-auto">
<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" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/activity_sources"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_grey"
android:scrollbars="vertical"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</android.support.v7.widget.RecyclerView>
@ -24,8 +34,9 @@
android:layout_height="wrap_content"
android:layout_gravity="end|bottom|right"
android:src="@drawable/ic_add_black_24dp"
fab:fab_colorNormal="@color/colorAccent"
fab:fab_colorPressed="@color/colorAccentDark"
android:tint="?android:textColorPrimary"
fab:fab_colorNormal="?attr/colorAccent"
fab:fab_colorPressed="?attr/colorAccentDark"
fab:fab_colorRipple="@color/pink"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingTop="@dimen/activity_vertical_margin"

View File

@ -6,13 +6,15 @@
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:id="@+id/card"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="0dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_bias="0.62"
app:layout_constraintTop_toTopOf="parent"
app:cardElevation="2dp"
app:cardUseCompatPadding="true"
card_view:cardElevation="2dp"
card_view:cardUseCompatPadding="true"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
@ -60,24 +62,21 @@
android:layout_width="40dp" />
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/title"
tools:text="Titre"
android:fontFamily="sans-serif"
android:textSize="16sp"
android:textAllCaps="false"
android:textAlignment="viewStart"
android:textColor="@color/black"
android:layout_marginEnd="8dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="8dp"
android:layout_marginRight="8dp"
android:layout_marginStart="8dp"
android:gravity="start"
android:textAlignment="viewStart"
android:textStyle="bold"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintLeft_toRightOf="@+id/sourceImage"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/sourceImage"
android:gravity="start" />
tools:text="Titre" />
<TextView
android:layout_width="wrap_content"
@ -85,7 +84,6 @@
android:id="@+id/sourceTitleAndDate"
android:textSize="14sp"
tools:text="Google Actualité Il y a 5h"
android:textColor="#868686"
android:textAlignment="viewStart"
app:layout_constraintTop_toBottomOf="@+id/title"
android:layout_marginTop="8dp"
@ -117,38 +115,38 @@
android:layout_marginEnd="8dp"/>
<ImageButton
android:id="@+id/shareBtn"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="@drawable/ic_share_black_24dp"
android:layout_centerVertical="true"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:layout_toLeftOf="@+id/favButton"
android:layout_toStartOf="@+id/favButton"
android:id="@+id/shareBtn"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:elevation="5dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:tint="#000000"
android:adjustViewBounds="true"
android:padding="4dp"
android:scaleType="centerCrop"
android:padding="4dp"/>
android:src="@drawable/ic_share_black_24dp"
android:tint="?android:attr/textColorPrimary" />
<ImageButton
android:id="@+id/browserBtn"
android:layout_width="35dp"
android:layout_height="35dp"
android:src="@drawable/ic_open_in_browser_black_24dp"
android:layout_centerVertical="true"
android:layout_toLeftOf="@+id/shareBtn"
android:layout_toStartOf="@+id/shareBtn"
android:id="@+id/browserBtn"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:elevation="5dp"
android:background="@android:color/transparent"
android:tint="#000000"
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:padding="4dp"/>
android:src="@drawable/ic_open_in_browser_black_24dp"
android:tint="?android:attr/textColorPrimary" />
</RelativeLayout>

View File

@ -3,11 +3,10 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="horizontal"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="88dp"
android:background="#EDEDED">
android:minHeight="88dp">
<ImageView
android:id="@+id/itemImage"
@ -20,25 +19,25 @@
/>
<TextView
android:id="@+id/title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="@+id/title"
tools:text="Titre"
android:fontFamily="sans-serif"
android:textSize="16sp"
android:textAllCaps="false"
android:textAlignment="viewStart"
app:layout_constraintLeft_toRightOf="@+id/itemImage"
android:layout_marginStart="16dp"
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent"
android:textColor="@color/black"
android:layout_marginEnd="16dp"
app:layout_constraintRight_toRightOf="parent"
android:layout_marginLeft="16dp"
android:layout_marginRight="16dp"
android:layout_marginStart="16dp"
android:layout_marginTop="16dp"
android:fontFamily="sans-serif"
android:gravity="start"
android:textAlignment="viewStart"
android:textAllCaps="false"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintHorizontal_bias="0.0"
android:gravity="start" />
app:layout_constraintLeft_toRightOf="@+id/itemImage"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="Titre" />
<TextView
android:layout_width="wrap_content"
@ -46,7 +45,6 @@
android:id="@+id/sourceTitleAndDate"
android:textSize="14sp"
tools:text="Google Actualité Il y a 5h"
android:textColor="#868686"
android:textAlignment="viewStart"
app:layout_constraintTop_toBottomOf="@+id/title"
android:layout_marginTop="8dp"
@ -90,11 +88,11 @@
android:layout_toStartOf="@+id/favButton"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:backgroundTint="?android:attr/textColorPrimary"
android:elevation="5dp"
android:padding="4dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_share_black_24dp"
android:tint="#000000" />
android:src="@drawable/ic_share_black_24dp" />
<ImageButton
android:id="@+id/browserBtn"
@ -107,11 +105,11 @@
android:layout_toStartOf="@+id/shareBtn"
android:adjustViewBounds="true"
android:background="@android:color/transparent"
android:backgroundTint="?android:attr/textColorPrimary"
android:elevation="5dp"
android:padding="4dp"
android:scaleType="centerCrop"
android:src="@drawable/ic_open_in_browser_black_24dp"
android:tint="#000000" />
android:src="@drawable/ic_open_in_browser_black_24dp" />
</RelativeLayout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.AppBarLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:theme="@style/ToolBarStyle" />
</android.support.design.widget.AppBarLayout>

View File

@ -5,7 +5,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:background="#EDEDED"
android:layout_height="48dp">
@ -37,6 +36,7 @@
android:id="@+id/deleteBtn"
android:background="@drawable/ic_remove_circle_outline_black_24dp"
style="@style/Widget.AppCompat.Button.Borderless"
android:backgroundTint="?android:textColorSecondary"
android:elevation="4dp"
android:layout_marginTop="16dp"
app:layout_constraintTop_toTopOf="parent"

View File

@ -0,0 +1,11 @@
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
</RelativeLayout>

View File

@ -2,6 +2,14 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/loging_debug"
android:checkable="true"
android:checked="false"
android:icon="@drawable/ic_bug_report"
android:title="@string/login_menu_debug"
app:showAsAction="never" />
<item android:id="@+id/about"
android:title="@string/action_about"
android:orderInCategory="102"

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 182 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 803 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -116,4 +116,33 @@
<string name="menu_home_search">Rechercher</string>
<string name="can_delete_source">Petit soucis lors de la suppression de la source.</string>
<string name="base_url_error">Il y a eu un souci lors de la communication avec votre instance Selfoss. Si le problèmes persiste, contactez-moi pour trouver une solution.</string>
<string name="pref_header_theme">Thèmes</string>
<string name="default_theme">Par défaut</string>
<string name="teal_orange_theme">Sarcelle/Orange/Clair</string>
<string name="cyan_pink_theme">Cyan/Rose/Clair</string>
<string name="grey_orange_theme">Gris/Orange/Clair</string>
<string name="blue_amber_theme">Bleu/Ambre/Clair</string>
<string name="indigo_pink_theme">Indigo/Rose/Clair</string>
<string name="red_teal_theme">Rouge/Sarcelle/Clair</string>
<string name="teal_orange_dark_theme">Sarcelle/Orange/Foncé</string>
<string name="cyan_pink_dark_theme">Cyan/Rose/Foncé</string>
<string name="default_dark_theme">Par défaut/Foncé</string>
<string name="grey_orange_dark_theme">Gris/Orange/Foncé</string>
<string name="blue_amber_dark_theme">Bleu/Ambre/Foncé</string>
<string name="indigo_pink_dark_theme">Indigo/Rose/Foncé</string>
<string name="red_teal_dark_theme">Rouge/Sarcelle/Foncé</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activez pour loguer toutes les erreurs de conexion</string>
<string name="login_debug_on">Toutes les erreurs de connexion vont être loguées</string>
<string name="login_debug_off">Aucune erreur de connexion ne sera loguée</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Certificat auto-signé ?</string>
<string name="self_signed_cert_warning">Pour des raisons de sécurités, les certificats auto-signés sont désactivés par défaut. En les activant, je ne serais pas responsable de quelconques problèmes de sécurité rencontrés.</string>
<string name="pref_selfoss_category">Api Selfoss</string>
<string name="pref_api_items_number_title">Nombre d\'articles chargés</string>
<string name="read_debug_title">Des articles lus marqués comme non lus ?</string>
<string name="read_debug_on">Les appels API vont être logués lorsequ\'un article est marqué comme lu</string>
<string name="read_debug_off">Aucun log quand un article est marqué comme lu</string>
<string name="summary_debug_identifier">Identifiant de debug</string>
<string name="unique_id_to_clipboard">Texte copié</string>
</resources>

View File

@ -116,4 +116,33 @@
<string name="menu_home_search">Zoeken</string>
<string name="can_delete_source">Can\'t delete the source...</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
</resources>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Theme">
<attr name="colorAccentDark" format="reference|color" />
</declare-styleable>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>

View File

@ -118,4 +118,33 @@
<string name="menu_home_search">Search</string>
<string name="can_delete_source">Can\'t delete the source...</string>
<string name="base_url_error">There was an issue when trying to communicate with your Selfoss Instance. If the issue persists, please get in touch with me.</string>
<string name="pref_header_theme">Themes</string>
<string name="default_theme">Default</string>
<string name="teal_orange_theme">Teal/Orange/Light</string>
<string name="cyan_pink_theme">Cyan/Pink/Light</string>
<string name="grey_orange_theme">Grey/Orange/Light</string>
<string name="blue_amber_theme">Blue/Amber/Light</string>
<string name="indigo_pink_theme">Indigo/Pink/Light</string>
<string name="red_teal_theme">Red/Teal/Light</string>
<string name="teal_orange_dark_theme">Teal/Orange/Dark</string>
<string name="cyan_pink_dark_theme">Cyan/Pink/Dark</string>
<string name="default_dark_theme">Default/Dark</string>
<string name="grey_orange_dark_theme">Grey/Orange/Dark</string>
<string name="blue_amber_dark_theme">Blue/Amber/Dark</string>
<string name="indigo_pink_dark_theme">Indigo/Pink/Dark</string>
<string name="red_teal_dark_theme">Red/Teal/Dark</string>
<string name="pref_header_debug">Debug</string>
<string name="login_debug_title">Activate to log login errors</string>
<string name="login_debug_on">Any error on the login page will be logged</string>
<string name="login_debug_off">No log on the login page</string>
<string name="login_menu_debug">Debug</string>
<string name="self_hosted_cert_switch">Using a self hosted certificate ?</string>
<string name="self_signed_cert_warning">Due to security reasons, self signed certificates are not supported by default. By activating this, I\'ll not be responsible of any security problem you encounter.</string>
<string name="pref_selfoss_category">Selfoss Api</string>
<string name="pref_api_items_number_title">Loaded items number</string>
<string name="read_debug_title">Read articles appearing as unread ?</string>
<string name="read_debug_off">No log when marking an item as read</string>
<string name="read_debug_on">Api calls will be logged when marking an article as read</string>
<string name="summary_debug_identifier">Debug identifier</string>
<string name="unique_id_to_clipboard">Identifier copied to your clipboard</string>
</resources>

View File

@ -1,32 +1,194 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<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>
<style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowBackground">@drawable/background_splash</item>
</style>
<style name="NoBar" parent="Theme.AppCompat.Light.NoActionBar">
<style name="NoBar" parent="MaterialDrawerTheme.Light">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColor">#000000</item>
<item name="colorAccentDark">@color/colorAccentDark</item>
<item name="cardBackgroundColor">@color/white</item>
<item name="android:colorBackground">@color/md_grey_50</item>
<item name="android:textColorPrimary">@color/md_grey_900</item>
<item name="android:textColorSecondary">@color/md_grey_400</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarDark" parent="MaterialDrawerTheme">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="colorAccentDark">@color/colorAccentDark</item>
<item name="cardBackgroundColor">@color/md_grey_800</item>
<item name="android:colorBackground">#303030</item>
<item name="bnbBackgroundColor">@color/md_grey_900</item>
<item name="android:textColorPrimary">@color/md_white_1000</item>
<item name="android:textColorSecondary">@color/md_grey_600</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</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="material_drawer_header_selection_text">@color/md_grey_900</item>
<item name="actionMenuTextColor">@color/white</item>
<!--<item name="actionOverflowButtonStyle">@style/ActionButtonOverflowStyle</item>
<item name="drawerArrowStyle">@style/DrawerArrowStyle</item>-->
</style>
<style name="NoBarBlueAmber" parent="MaterialDrawerTheme.Light">
<item name="colorPrimary">@color/md_blue_500</item>
<item name="colorPrimaryDark">@color/md_blue_700</item>
<item name="colorAccent">@color/md_amber_500</item>
<item name="colorAccentDark">@color/md_amber_700</item>
<item name="cardBackgroundColor">@color/white</item>
<item name="android:colorBackground">@color/md_grey_50</item>
<item name="android:textColorPrimary">@color/md_grey_900</item>
<item name="android:textColorSecondary">@color/md_grey_400</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarBlueAmberDark" parent="MaterialDrawerTheme">
<item name="colorPrimary">@color/md_blue_500</item>
<item name="colorPrimaryDark">@color/md_blue_700</item>
<item name="colorAccent">@color/md_amber_500</item>
<item name="colorAccentDark">@color/md_amber_700</item>
<item name="cardBackgroundColor">@color/md_grey_800</item>
<item name="android:colorBackground">#303030</item>
<item name="bnbBackgroundColor">@color/md_grey_900</item>
<item name="android:textColorPrimary">@color/md_white_1000</item>
<item name="android:textColorSecondary">@color/md_grey_600</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarGreyOrange" parent="MaterialDrawerTheme.Light">
<item name="colorPrimary">@color/md_blue_grey_500</item>
<item name="colorPrimaryDark">@color/md_blue_grey_700</item>
<item name="colorAccent">@color/md_deep_orange_500</item>
<item name="colorAccentDark">@color/md_deep_orange_700</item>
<item name="cardBackgroundColor">@color/white</item>
<item name="android:colorBackground">@color/md_grey_50</item>
<item name="android:textColorPrimary">@color/md_grey_900</item>
<item name="android:textColorSecondary">@color/md_grey_400</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarGreyOrangeDark" parent="MaterialDrawerTheme">
<item name="colorPrimary">@color/md_blue_grey_500</item>
<item name="colorPrimaryDark">@color/md_blue_grey_700</item>
<item name="colorAccent">@color/md_deep_orange_500</item>
<item name="colorAccentDark">@color/md_deep_orange_700</item>
<item name="cardBackgroundColor">@color/md_grey_800</item>
<item name="android:colorBackground">#303030</item>
<item name="bnbBackgroundColor">@color/md_grey_900</item>
<item name="android:textColorPrimary">@color/md_white_1000</item>
<item name="android:textColorSecondary">@color/md_grey_600</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarIndigoPink" parent="MaterialDrawerTheme.Light">
<item name="colorPrimary">@color/md_indigo_500</item>
<item name="colorPrimaryDark">@color/md_indigo_700</item>
<item name="colorAccent">@color/md_pink_500</item>
<item name="colorAccentDark">@color/md_pink_700</item>
<item name="cardBackgroundColor">@color/white</item>
<item name="android:colorBackground">@color/md_grey_50</item>
<item name="android:textColorPrimary">@color/md_grey_900</item>
<item name="android:textColorSecondary">@color/md_grey_400</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarIndigoPinkDark" parent="MaterialDrawerTheme">
<item name="colorPrimary">@color/md_indigo_500</item>
<item name="colorPrimaryDark">@color/md_indigo_700</item>
<item name="colorAccent">@color/md_pink_500</item>
<item name="colorAccentDark">@color/md_pink_700</item>
<item name="cardBackgroundColor">@color/md_grey_800</item>
<item name="android:colorBackground">#303030</item>
<item name="bnbBackgroundColor">@color/md_grey_900</item>
<item name="android:textColorPrimary">@color/md_white_1000</item>
<item name="android:textColorSecondary">@color/md_grey_600</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarRedTeal" parent="MaterialDrawerTheme.Light">
<item name="colorPrimary">@color/md_red_500</item>
<item name="colorPrimaryDark">@color/md_red_700</item>
<item name="colorAccent">@color/md_teal_500</item>
<item name="colorAccentDark">@color/md_teal_700</item>
<item name="cardBackgroundColor">@color/white</item>
<item name="android:colorBackground">@color/md_grey_50</item>
<item name="android:textColorPrimary">@color/md_grey_900</item>
<item name="android:textColorSecondary">@color/md_grey_400</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarRedTealDark" parent="MaterialDrawerTheme">
<item name="colorPrimary">@color/md_red_500</item>
<item name="colorPrimaryDark">@color/md_red_700</item>
<item name="colorAccent">@color/md_teal_500</item>
<item name="colorAccentDark">@color/md_teal_700</item>
<item name="cardBackgroundColor">@color/md_grey_800</item>
<item name="android:colorBackground">#303030</item>
<item name="bnbBackgroundColor">@color/md_grey_900</item>
<item name="android:textColorPrimary">@color/md_white_1000</item>
<item name="android:textColorSecondary">@color/md_grey_600</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarCyanPink" parent="MaterialDrawerTheme.Light">
<item name="colorPrimary">@color/md_cyan_500</item>
<item name="colorPrimaryDark">@color/md_cyan_700</item>
<item name="colorAccent">@color/md_pink_500</item>
<item name="colorAccentDark">@color/md_pink_700</item>
<item name="cardBackgroundColor">@color/white</item>
<item name="android:colorBackground">@color/md_grey_50</item>
<item name="android:textColorPrimary">@color/md_grey_900</item>
<item name="android:textColorSecondary">@color/md_grey_400</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarCyanPinkDark" parent="MaterialDrawerTheme">
<item name="colorPrimary">@color/md_cyan_500</item>
<item name="colorPrimaryDark">@color/md_cyan_700</item>
<item name="colorAccent">@color/md_pink_500</item>
<item name="colorAccentDark">@color/md_pink_700</item>
<item name="cardBackgroundColor">@color/md_grey_800</item>
<item name="android:colorBackground">#303030</item>
<item name="bnbBackgroundColor">@color/md_grey_900</item>
<item name="android:textColorPrimary">@color/md_white_1000</item>
<item name="android:textColorSecondary">@color/md_grey_600</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarTealOrange" parent="MaterialDrawerTheme.Light">
<item name="colorPrimary">@color/md_teal_500</item>
<item name="colorPrimaryDark">@color/md_teal_700</item>
<item name="colorAccent">@color/md_orange_500</item>
<item name="colorAccentDark">@color/md_orange_700</item>
<item name="cardBackgroundColor">@color/white</item>
<item name="android:colorBackground">@color/md_grey_50</item>
<item name="android:textColorPrimary">@color/md_grey_900</item>
<item name="android:textColorSecondary">@color/md_grey_400</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
<style name="NoBarTealOrangeDark" parent="MaterialDrawerTheme">
<item name="colorPrimary">@color/md_teal_500</item>
<item name="colorPrimaryDark">@color/md_teal_700</item>
<item name="colorAccent">@color/md_orange_500</item>
<item name="colorAccentDark">@color/md_orange_700</item>
<item name="cardBackgroundColor">@color/md_grey_800</item>
<item name="android:colorBackground">#303030</item>
<item name="bnbBackgroundColor">@color/md_grey_900</item>
<item name="android:textColorPrimary">@color/md_white_1000</item>
<item name="android:textColorSecondary">@color/md_grey_600</item>
<item name="material_drawer_header_selection_text">@color/md_grey_900</item>
</style>
</resources>

View File

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<SwitchPreference
android:defaultValue="false"
android:key="loging_debug"
android:summaryOff="@string/login_debug_off"
android:summaryOn="@string/login_debug_on"
android:title="@string/login_debug_title" />
<SwitchPreference
android:defaultValue="false"
android:key="read_debug"
android:summaryOff="@string/read_debug_off"
android:summaryOn="@string/read_debug_on"
android:title="@string/read_debug_title" />
<Preference
android:enabled="true"
android:key="debug_identifier"
android:summary="@string/summary_debug_identifier" />
</PreferenceScreen>

Some files were not shown because too many files have changed in this diff Show More