Compare commits
31 Commits
Author | SHA1 | Date | |
---|---|---|---|
ebf4d294a8 | |||
4a4dbacc95 | |||
687839b5f8 | |||
8fb339034f | |||
8e9fd9c985 | |||
72400f71c0 | |||
1151587951 | |||
abcd500045 | |||
beda24e736 | |||
37b2c5c2df | |||
7b5246ebf1 | |||
d6d5e72f48 | |||
fa8e88d489 | |||
1ef2da9f76 | |||
1ebd894be7 | |||
a9c493d105 | |||
f833d73fab | |||
9e6602f114 | |||
3bdfef9f8b | |||
6f7f475a6b | |||
8fc5fab67b | |||
6927e92396 | |||
c7470396d7 | |||
f21570e2e4 | |||
51f406e20c | |||
9e3fde744e | |||
ccf406ae68 | |||
bc78d1e079 | |||
d151eb261e | |||
0856598cd9 | |||
f0563efc62 |
4
.github/CONTRIBUTING.md
vendored
@ -10,7 +10,7 @@ Please read the guidelines before contributing, and follow them (or try to) when
|
|||||||
|
|
||||||
There are many ways to contribute to this project, you could report bugs, request missing features, suggest enhancements and changes to existing ones. You also can improve the README with useful tips that could help the other users.
|
There are many ways to contribute to this project, you could report bugs, request missing features, suggest enhancements and changes to existing ones. You also can improve the README with useful tips that could help the other users.
|
||||||
|
|
||||||
You can fork the repository, and [help me solve some issues](https://github.com/aminecmi/ReaderforSelfoss/labels/help%20wanted) or [develop new things](https://github.com/aminecmi/ReaderforSelfoss/issues)
|
You can fork the repository, and [help me solve some issues](https://github.com/aminecmi/ReaderforSelfoss/issues?q=is%3Aissue+is%3Aopen+label%3A%22Up+For+Grabs%22) or [develop new things](https://github.com/aminecmi/ReaderforSelfoss/issues)
|
||||||
|
|
||||||
### What I can't help you with.
|
### What I can't help you with.
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ Always check if the web version of your instance is working.
|
|||||||
* Please ask before starting to work on an issue. I may be working on it, or someone else could be doing so.
|
* Please ask before starting to work on an issue. I may be working on it, or someone else could be doing so.
|
||||||
* Each pull request should implement **ONE** feature or bugfix. Keep in mind that you can submit as many PR as you want.
|
* Each pull request should implement **ONE** feature or bugfix. Keep in mind that you can submit as many PR as you want.
|
||||||
* Your code must be simple and clear enough to avoid using comments to explain what it does.
|
* Your code must be simple and clear enough to avoid using comments to explain what it does.
|
||||||
* Follow the used coding style [the official one](https://kotlinlang.org/docs/reference/coding-conventions.html) ([some idoms for reference](http://kotlinlang.org/docs/reference/idioms.html)) with more to come.
|
* Follow the used coding style [the android koding style](https://android.github.io/kotlin-guides/style.html) ([some idoms for reference](http://kotlinlang.org/docs/reference/idioms.html)) with more to come.
|
||||||
* Try as much as possible to write a test for your feature, and if you do so, run it, and make it work.
|
* Try as much as possible to write a test for your feature, and if you do so, run it, and make it work.
|
||||||
* Always check your changes and discard the ones that are irrelevant to your feature or bugfix.
|
* Always check your changes and discard the ones that are irrelevant to your feature or bugfix.
|
||||||
* Have meaningful commit messages.
|
* Have meaningful commit messages.
|
||||||
|
44
CHANGELOG.md
@ -1,3 +1,47 @@
|
|||||||
|
**1.5.4.14**
|
||||||
|
|
||||||
|
- Fixing infinite scroll trying to load more items when there are no more.
|
||||||
|
|
||||||
|
**1.5.4.13**
|
||||||
|
|
||||||
|
- Displaying the right number of items.
|
||||||
|
|
||||||
|
- Fixing infinite scroll remaining issues. Should be stable enough.
|
||||||
|
|
||||||
|
**1.5.4.12**
|
||||||
|
|
||||||
|
- Fixed fab and toolbar issue (#113)
|
||||||
|
|
||||||
|
- Fixed links clickable (#114)
|
||||||
|
|
||||||
|
- Changed the link colors in the article viewer
|
||||||
|
|
||||||
|
**1.5.4.11**
|
||||||
|
|
||||||
|
- Hiding FABs on scroll.
|
||||||
|
|
||||||
|
- Closing #109 (code cleaning)
|
||||||
|
|
||||||
|
- Hiding fabs on scroll (#101)
|
||||||
|
|
||||||
|
**1.5.4.10**
|
||||||
|
|
||||||
|
- Displaying a loader when "reading more" in the article viewer.
|
||||||
|
|
||||||
|
- Displaying the thumbnail instead of icon on the article viewer.
|
||||||
|
|
||||||
|
- Scrolling to top when loading content with the "read more" button.
|
||||||
|
|
||||||
|
**1.5.4.09**
|
||||||
|
|
||||||
|
- Using the kotlin wrapper for the material drawer (see #98 for more details).
|
||||||
|
|
||||||
|
- Updated support libraries
|
||||||
|
|
||||||
|
- Changed the Floating Action Button to the support library version.
|
||||||
|
|
||||||
|
- New reader activity action bar #103.
|
||||||
|
|
||||||
**1.5.4.08**
|
**1.5.4.08**
|
||||||
|
|
||||||
- Thanks @jrafaelsantana for translating the whole app in Brazilian Portuguese.
|
- Thanks @jrafaelsantana for translating the whole app in Brazilian Portuguese.
|
||||||
|
@ -31,6 +31,8 @@ apply plugin: 'io.fabric'
|
|||||||
|
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
maven {
|
maven {
|
||||||
url 'https://maven.fabric.io/public'
|
url 'https://maven.fabric.io/public'
|
||||||
@ -38,12 +40,12 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 26
|
compileSdkVersion 27
|
||||||
buildToolsVersion '26.0.2'
|
buildToolsVersion '27.0.0'
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "apps.amine.bou.readerforselfoss"
|
applicationId "apps.amine.bou.readerforselfoss"
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 26
|
targetSdkVersion 27
|
||||||
versionCode versionCodeFromGit()
|
versionCode versionCodeFromGit()
|
||||||
versionName versionNameFromGit()
|
versionName versionNameFromGit()
|
||||||
|
|
||||||
@ -107,13 +109,13 @@ dependencies {
|
|||||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
|
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
|
||||||
|
|
||||||
// Android Support
|
// Android Support
|
||||||
compile 'com.android.support:appcompat-v7:26.1.0'
|
compile 'com.android.support:appcompat-v7:27.0.0'
|
||||||
compile 'com.android.support:design:26.1.0'
|
compile 'com.android.support:design:27.0.0'
|
||||||
compile 'com.android.support:recyclerview-v7:26.1.0'
|
compile 'com.android.support:recyclerview-v7:27.0.0'
|
||||||
compile 'com.android.support:support-v4:26.1.0'
|
compile 'com.android.support:support-v4:27.0.0'
|
||||||
compile 'com.android.support:support-vector-drawable:26.1.0'
|
compile 'com.android.support:support-vector-drawable:27.0.0'
|
||||||
compile 'com.android.support:customtabs:26.1.0'
|
compile 'com.android.support:customtabs:27.0.0'
|
||||||
compile 'com.android.support:cardview-v7:26.1.0'
|
compile 'com.android.support:cardview-v7:27.0.0'
|
||||||
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||||
|
|
||||||
// Firebase + crashlytics
|
// Firebase + crashlytics
|
||||||
@ -131,7 +133,7 @@ dependencies {
|
|||||||
compile 'agency.tango.android:material-intro-screen:0.0.5'
|
compile 'agency.tango.android:material-intro-screen:0.0.5'
|
||||||
|
|
||||||
// About
|
// About
|
||||||
compile('com.mikepenz:aboutlibraries:5.9.7@aar') {
|
compile('com.mikepenz:aboutlibraries:6.0.0@aar') {
|
||||||
transitive = true
|
transitive = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,7 +145,6 @@ dependencies {
|
|||||||
|
|
||||||
// Material-ish things
|
// Material-ish things
|
||||||
compile 'com.ashokvarma.android:bottom-navigation-bar:2.0.3'
|
compile 'com.ashokvarma.android:bottom-navigation-bar:2.0.3'
|
||||||
compile 'com.melnykov:floatingactionbutton:1.3.0'
|
|
||||||
compile 'com.github.jd-alexander:LikeButton:0.2.1'
|
compile 'com.github.jd-alexander:LikeButton:0.2.1'
|
||||||
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
compile 'com.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||||
compile 'org.sufficientlysecure:html-textview:3.5'
|
compile 'org.sufficientlysecure:html-textview:3.5'
|
||||||
@ -159,9 +160,7 @@ dependencies {
|
|||||||
compile 'com.klinkerapps:drag-dismiss-activity:1.5.0'
|
compile 'com.klinkerapps:drag-dismiss-activity:1.5.0'
|
||||||
|
|
||||||
// Drawer
|
// Drawer
|
||||||
compile('com.mikepenz:materialdrawer:5.9.5@aar') {
|
implementation 'co.zsmb:materialdrawer-kt:1.2.1'
|
||||||
transitive = true
|
|
||||||
}
|
|
||||||
compile 'com.anupcowkur:reservoir:3.1.0'
|
compile 'com.anupcowkur:reservoir:3.1.0'
|
||||||
|
|
||||||
// Themes
|
// Themes
|
||||||
@ -169,6 +168,8 @@ dependencies {
|
|||||||
|
|
||||||
// Github issues reporter
|
// Github issues reporter
|
||||||
compile 'com.heinrichreimersoftware:android-issue-reporter:1.3.1'
|
compile 'com.heinrichreimersoftware:android-issue-reporter:1.3.1'
|
||||||
|
|
||||||
|
compile 'com.github.rubensousa:floatingtoolbar:1.5.1'
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
|
@ -32,18 +32,18 @@ class LoginActivityEspressoTest {
|
|||||||
@Rule @JvmField
|
@Rule @JvmField
|
||||||
val rule = ActivityTestRule(LoginActivity::class.java, true, false)
|
val rule = ActivityTestRule(LoginActivity::class.java, true, false)
|
||||||
|
|
||||||
lateinit var context: Context
|
private lateinit var context: Context
|
||||||
lateinit var url: String
|
private lateinit var url: String
|
||||||
lateinit var username: String
|
private lateinit var username: String
|
||||||
lateinit var password: String
|
private lateinit var password: String
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
context = InstrumentationRegistry.getInstrumentation().targetContext
|
context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
val editor =
|
val editor =
|
||||||
context
|
context
|
||||||
.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
|
.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
|
||||||
.edit()
|
.edit()
|
||||||
editor.clear()
|
editor.clear()
|
||||||
editor.commit()
|
editor.commit()
|
||||||
|
|
||||||
@ -77,12 +77,12 @@ class LoginActivityEspressoTest {
|
|||||||
fun wrongLoginUrl() {
|
fun wrongLoginUrl() {
|
||||||
rule.launchActivity(Intent())
|
rule.launchActivity(Intent())
|
||||||
|
|
||||||
onView(withId(R.id.login_progress))
|
onView(withId(R.id.loginProgress))
|
||||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)))
|
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)))
|
||||||
|
|
||||||
onView(withId(R.id.url)).perform(click()).perform(typeText("WRONGURL"))
|
onView(withId(R.id.urlView)).perform(click()).perform(typeText("WRONGURL"))
|
||||||
|
|
||||||
onView(withId(R.id.email_sign_in_button)).perform(click())
|
onView(withId(R.id.signInButton)).perform(click())
|
||||||
|
|
||||||
onView(withId(R.id.urlLayout)).check(matches(isHintOrErrorEnabled()))
|
onView(withId(R.id.urlLayout)).check(matches(isHintOrErrorEnabled()))
|
||||||
}
|
}
|
||||||
@ -94,24 +94,24 @@ class LoginActivityEspressoTest {
|
|||||||
|
|
||||||
rule.launchActivity(Intent())
|
rule.launchActivity(Intent())
|
||||||
|
|
||||||
onView(withId(R.id.url)).perform(click()).perform(typeText(url), closeSoftKeyboard())
|
onView(withId(R.id.urlView)).perform(click()).perform(typeText(url), closeSoftKeyboard())
|
||||||
|
|
||||||
onView(withId(R.id.withLogin)).perform(click())
|
onView(withId(R.id.withLogin)).perform(click())
|
||||||
|
|
||||||
onView(withId(R.id.email_sign_in_button)).perform(click())
|
onView(withId(R.id.signInButton)).perform(click())
|
||||||
|
|
||||||
onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled()))
|
onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled()))
|
||||||
onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled()))
|
onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled()))
|
||||||
|
|
||||||
onView(withId(R.id.login)).perform(click()).perform(typeText(username), closeSoftKeyboard())
|
onView(withId(R.id.loginView)).perform(click()).perform(typeText(username), closeSoftKeyboard())
|
||||||
|
|
||||||
onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled()))
|
onView(withId(R.id.passwordLayout)).check(matches(isHintOrErrorEnabled()))
|
||||||
|
|
||||||
onView(withId(R.id.email_sign_in_button)).perform(click())
|
onView(withId(R.id.signInButton)).perform(click())
|
||||||
|
|
||||||
onView(withId(R.id.passwordLayout)).check(
|
onView(withId(R.id.passwordLayout)).check(
|
||||||
matches(
|
matches(
|
||||||
isHintOrErrorEnabled())
|
isHintOrErrorEnabled())
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -121,15 +121,15 @@ class LoginActivityEspressoTest {
|
|||||||
|
|
||||||
rule.launchActivity(Intent())
|
rule.launchActivity(Intent())
|
||||||
|
|
||||||
onView(withId(R.id.url)).perform(click()).perform(typeText(url), closeSoftKeyboard())
|
onView(withId(R.id.urlView)).perform(click()).perform(typeText(url), closeSoftKeyboard())
|
||||||
|
|
||||||
onView(withId(R.id.withLogin)).perform(click())
|
onView(withId(R.id.withLogin)).perform(click())
|
||||||
|
|
||||||
onView(withId(R.id.login)).perform(click()).perform(typeText(username), closeSoftKeyboard())
|
onView(withId(R.id.loginView)).perform(click()).perform(typeText(username), closeSoftKeyboard())
|
||||||
|
|
||||||
onView(withId(R.id.password)).perform(click()).perform(typeText("WRONGPASS"), closeSoftKeyboard())
|
onView(withId(R.id.passwordView)).perform(click()).perform(typeText("WRONGPASS"), closeSoftKeyboard())
|
||||||
|
|
||||||
onView(withId(R.id.email_sign_in_button)).perform(click())
|
onView(withId(R.id.signInButton)).perform(click())
|
||||||
|
|
||||||
onView(withId(R.id.urlLayout)).check(matches(isHintOrErrorEnabled()))
|
onView(withId(R.id.urlLayout)).check(matches(isHintOrErrorEnabled()))
|
||||||
onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled()))
|
onView(withId(R.id.loginLayout)).check(matches(isHintOrErrorEnabled()))
|
||||||
@ -142,15 +142,15 @@ class LoginActivityEspressoTest {
|
|||||||
|
|
||||||
rule.launchActivity(Intent())
|
rule.launchActivity(Intent())
|
||||||
|
|
||||||
onView(withId(R.id.url)).perform(click()).perform(typeText(url), closeSoftKeyboard())
|
onView(withId(R.id.urlView)).perform(click()).perform(typeText(url), closeSoftKeyboard())
|
||||||
|
|
||||||
onView(withId(R.id.withLogin)).perform(click())
|
onView(withId(R.id.withLogin)).perform(click())
|
||||||
|
|
||||||
onView(withId(R.id.login)).perform(click()).perform(typeText(username), closeSoftKeyboard())
|
onView(withId(R.id.loginView)).perform(click()).perform(typeText(username), closeSoftKeyboard())
|
||||||
|
|
||||||
onView(withId(R.id.password)).perform(click()).perform(typeText(password), closeSoftKeyboard())
|
onView(withId(R.id.passwordView)).perform(click()).perform(typeText(password), closeSoftKeyboard())
|
||||||
|
|
||||||
onView(withId(R.id.email_sign_in_button)).perform(click())
|
onView(withId(R.id.signInButton)).perform(click())
|
||||||
|
|
||||||
intended(hasComponent(HomeActivity::class.java.name))
|
intended(hasComponent(HomeActivity::class.java.name))
|
||||||
|
|
||||||
|
@ -65,8 +65,7 @@
|
|||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".ReaderActivity"
|
android:name=".ReaderActivity">
|
||||||
android:theme="@style/DragDismissTheme">
|
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<meta-data
|
<meta-data
|
||||||
|
@ -5,11 +5,9 @@ import android.os.Bundle
|
|||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
import android.support.constraint.ConstraintLayout
|
import android.support.constraint.ConstraintLayout
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.widget.Toolbar
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.AdapterView
|
import android.widget.AdapterView
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import android.widget.Button
|
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
import android.widget.Spinner
|
import android.widget.Spinner
|
||||||
@ -21,6 +19,7 @@ import apps.amine.bou.readerforselfoss.api.selfoss.SuccessResponse
|
|||||||
import apps.amine.bou.readerforselfoss.utils.Config
|
import apps.amine.bou.readerforselfoss.utils.Config
|
||||||
import apps.amine.bou.readerforselfoss.utils.isBaseUrlValid
|
import apps.amine.bou.readerforselfoss.utils.isBaseUrlValid
|
||||||
import com.ftinc.scoop.Scoop
|
import com.ftinc.scoop.Scoop
|
||||||
|
import kotlinx.android.synthetic.main.activity_add_source.*
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
@ -34,31 +33,29 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
Scoop.getInstance().apply(this)
|
Scoop.getInstance().apply(this)
|
||||||
setContentView(R.layout.activity_add_source)
|
setContentView(R.layout.activity_add_source)
|
||||||
val toolbar: Toolbar = findViewById(R.id.toolbar)
|
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
supportActionBar?.setDisplayShowHomeEnabled(true)
|
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||||
|
|
||||||
val mProgress: ProgressBar = findViewById(R.id.progress)
|
|
||||||
val mForm: ConstraintLayout = findViewById(R.id.formContainer)
|
|
||||||
val mNameInput: EditText = findViewById(R.id.nameInput)
|
|
||||||
val mSourceUri: EditText = findViewById(R.id.sourceUri)
|
|
||||||
val mTags: EditText = findViewById(R.id.tags)
|
|
||||||
val mSpoutsSpinner: Spinner = findViewById(R.id.spoutsSpinner)
|
|
||||||
val mSaveBtn: Button = findViewById(R.id.saveBtn)
|
|
||||||
var api: SelfossApi? = null
|
var api: SelfossApi? = null
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
api = SelfossApi(this, this@AddSourceActivity, prefs.getBoolean("isSelfSignedCert", false), prefs.getBoolean("should_log_everything", false))
|
api = SelfossApi(
|
||||||
|
this,
|
||||||
|
this@AddSourceActivity,
|
||||||
|
prefs.getBoolean("isSelfSignedCert", false),
|
||||||
|
prefs.getBoolean("should_log_everything", false)
|
||||||
|
)
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
mustLoginToAddSource()
|
mustLoginToAddSource()
|
||||||
}
|
}
|
||||||
|
|
||||||
maybeGetDetailsFromIntentSharing(intent, mSourceUri, mNameInput)
|
maybeGetDetailsFromIntentSharing(intent, sourceUri, nameInput)
|
||||||
|
|
||||||
mSaveBtn.setOnClickListener {
|
saveBtn.setOnClickListener {
|
||||||
handleSaveSource(mTags, mNameInput.text.toString(), mSourceUri.text.toString(), api!!)
|
handleSaveSource(tags, nameInput.text.toString(), sourceUri.text.toString(), api!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
val config = Config(this)
|
val config = Config(this)
|
||||||
@ -66,13 +63,13 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid()) {
|
if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid()) {
|
||||||
mustLoginToAddSource()
|
mustLoginToAddSource()
|
||||||
} else {
|
} else {
|
||||||
handleSpoutsSpinner(mSpoutsSpinner, api, mProgress, mForm)
|
handleSpoutsSpinner(spoutsSpinner, api, progress, formContainer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSpoutsSpinner(mSpoutsSpinner: Spinner, api: SelfossApi?, mProgress: ProgressBar, mForm: ConstraintLayout) {
|
private fun handleSpoutsSpinner(spoutsSpinner: Spinner, api: SelfossApi?, mProgress: ProgressBar, formContainer: ConstraintLayout) {
|
||||||
val spoutsKV = HashMap<String, String>()
|
val spoutsKV = HashMap<String, String>()
|
||||||
mSpoutsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
spoutsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||||
override fun onItemSelected(adapterView: AdapterView<*>, view: View, i: Int, l: Long) {
|
override fun onItemSelected(adapterView: AdapterView<*>, view: View, i: Int, l: Long) {
|
||||||
val spoutName = (view as TextView).text.toString()
|
val spoutName = (view as TextView).text.toString()
|
||||||
mSpoutsValue = spoutsKV[spoutName]
|
mSpoutsValue = spoutsKV[spoutName]
|
||||||
@ -95,15 +92,15 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mProgress.visibility = View.GONE
|
mProgress.visibility = View.GONE
|
||||||
mForm.visibility = View.VISIBLE
|
formContainer.visibility = View.VISIBLE
|
||||||
|
|
||||||
val spinnerArrayAdapter =
|
val spinnerArrayAdapter =
|
||||||
ArrayAdapter(
|
ArrayAdapter(
|
||||||
this@AddSourceActivity,
|
this@AddSourceActivity,
|
||||||
android.R.layout.simple_spinner_item,
|
android.R.layout.simple_spinner_item,
|
||||||
itemsStrings)
|
itemsStrings)
|
||||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||||
mSpoutsSpinner.adapter = spinnerArrayAdapter
|
spoutsSpinner.adapter = spinnerArrayAdapter
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
handleProblemWithSpouts()
|
handleProblemWithSpouts()
|
||||||
@ -121,10 +118,10 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun maybeGetDetailsFromIntentSharing(intent: Intent, mSourceUri: EditText, mNameInput: EditText) {
|
private fun maybeGetDetailsFromIntentSharing(intent: Intent, sourceUri: EditText, nameInput: EditText) {
|
||||||
if (Intent.ACTION_SEND == intent.action && "text/plain" == intent.type) {
|
if (Intent.ACTION_SEND == intent.action && "text/plain" == intent.type) {
|
||||||
mSourceUri.setText(intent.getStringExtra(Intent.EXTRA_TEXT))
|
sourceUri.setText(intent.getStringExtra(Intent.EXTRA_TEXT))
|
||||||
mNameInput.setText(intent.getStringExtra(Intent.EXTRA_TITLE))
|
nameInput.setText(intent.getStringExtra(Intent.EXTRA_TITLE))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,7 +132,7 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSaveSource(mTags: EditText, title: String, url: String, api: SelfossApi) {
|
private fun handleSaveSource(tags: EditText, title: String, url: String, api: SelfossApi) {
|
||||||
|
|
||||||
val sourceDetailsAvailable = title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()
|
val sourceDetailsAvailable = title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()
|
||||||
|
|
||||||
@ -143,11 +140,11 @@ class AddSourceActivity : AppCompatActivity() {
|
|||||||
Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
api.createSource(
|
api.createSource(
|
||||||
title,
|
title,
|
||||||
url,
|
url,
|
||||||
mSpoutsValue!!,
|
mSpoutsValue!!,
|
||||||
mTags.text.toString(),
|
tags.text.toString(),
|
||||||
""
|
""
|
||||||
).enqueue(object : Callback<SuccessResponse> {
|
).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
||||||
if (response.body() != null && response.body()!!.isSuccess) {
|
if (response.body() != null && response.body()!!.isSuccess) {
|
||||||
|
@ -9,20 +9,16 @@ import android.graphics.drawable.GradientDrawable
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
import android.support.design.widget.CoordinatorLayout
|
|
||||||
import android.support.v4.view.MenuItemCompat
|
import android.support.v4.view.MenuItemCompat
|
||||||
import android.support.v4.widget.SwipeRefreshLayout
|
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.widget.GridLayoutManager
|
import android.support.v7.widget.GridLayoutManager
|
||||||
import android.support.v7.widget.RecyclerView
|
import android.support.v7.widget.RecyclerView
|
||||||
import android.support.v7.widget.SearchView
|
import android.support.v7.widget.SearchView
|
||||||
import android.support.v7.widget.StaggeredGridLayoutManager
|
import android.support.v7.widget.StaggeredGridLayoutManager
|
||||||
import android.support.v7.widget.Toolbar
|
|
||||||
import android.support.v7.widget.helper.ItemTouchHelper
|
import android.support.v7.widget.helper.ItemTouchHelper
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.TextView
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
|
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
|
||||||
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
|
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
|
||||||
@ -41,6 +37,11 @@ import apps.amine.bou.readerforselfoss.utils.checkApkVersion
|
|||||||
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
|
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
|
||||||
import apps.amine.bou.readerforselfoss.utils.drawer.CustomUrlPrimaryDrawerItem
|
import apps.amine.bou.readerforselfoss.utils.drawer.CustomUrlPrimaryDrawerItem
|
||||||
import apps.amine.bou.readerforselfoss.utils.longHash
|
import apps.amine.bou.readerforselfoss.utils.longHash
|
||||||
|
import co.zsmb.materialdrawerkt.builders.accountHeader
|
||||||
|
import co.zsmb.materialdrawerkt.builders.drawer
|
||||||
|
import co.zsmb.materialdrawerkt.builders.footer
|
||||||
|
import co.zsmb.materialdrawerkt.draweritems.badgeable.primaryItem
|
||||||
|
import co.zsmb.materialdrawerkt.draweritems.profile.profile
|
||||||
import com.anupcowkur.reservoir.Reservoir
|
import com.anupcowkur.reservoir.Reservoir
|
||||||
import com.anupcowkur.reservoir.ReservoirGetCallback
|
import com.anupcowkur.reservoir.ReservoirGetCallback
|
||||||
import com.anupcowkur.reservoir.ReservoirPutCallback
|
import com.anupcowkur.reservoir.ReservoirPutCallback
|
||||||
@ -51,7 +52,6 @@ import com.crashlytics.android.Crashlytics
|
|||||||
import com.crashlytics.android.answers.Answers
|
import com.crashlytics.android.answers.Answers
|
||||||
import com.crashlytics.android.answers.InviteEvent
|
import com.crashlytics.android.answers.InviteEvent
|
||||||
import com.ftinc.scoop.Scoop
|
import com.ftinc.scoop.Scoop
|
||||||
import com.github.stkent.amplify.prompt.DefaultLayoutPromptView
|
|
||||||
import com.github.stkent.amplify.tracking.Amplify
|
import com.github.stkent.amplify.tracking.Amplify
|
||||||
import com.google.android.gms.appinvite.AppInviteInvitation
|
import com.google.android.gms.appinvite.AppInviteInvitation
|
||||||
import com.google.android.gms.common.ConnectionResult
|
import com.google.android.gms.common.ConnectionResult
|
||||||
@ -61,20 +61,15 @@ import com.google.gson.reflect.TypeToken
|
|||||||
import com.heinrichreimersoftware.androidissuereporter.IssueReporterLauncher
|
import com.heinrichreimersoftware.androidissuereporter.IssueReporterLauncher
|
||||||
import com.mikepenz.aboutlibraries.Libs
|
import com.mikepenz.aboutlibraries.Libs
|
||||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
import com.mikepenz.aboutlibraries.LibsBuilder
|
||||||
import com.mikepenz.materialdrawer.AccountHeader
|
|
||||||
import com.mikepenz.materialdrawer.AccountHeaderBuilder
|
|
||||||
import com.mikepenz.materialdrawer.Drawer
|
import com.mikepenz.materialdrawer.Drawer
|
||||||
import com.mikepenz.materialdrawer.DrawerBuilder
|
|
||||||
import com.mikepenz.materialdrawer.holder.BadgeStyle
|
import com.mikepenz.materialdrawer.holder.BadgeStyle
|
||||||
import com.mikepenz.materialdrawer.model.DividerDrawerItem
|
import com.mikepenz.materialdrawer.model.DividerDrawerItem
|
||||||
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
|
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
|
||||||
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
|
||||||
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
|
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import java.lang.Exception
|
import kotlinx.android.synthetic.main.activity_home.*
|
||||||
|
|
||||||
|
|
||||||
class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||||
|
|
||||||
@ -106,15 +101,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
private var displayAccountHeader: Boolean = false
|
private var displayAccountHeader: Boolean = false
|
||||||
private var infiniteScroll: Boolean = false
|
private var infiniteScroll: Boolean = false
|
||||||
|
|
||||||
private lateinit var emptyText: TextView
|
|
||||||
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 tabNewBadge: TextBadgeItem
|
||||||
private lateinit var tabArchiveBadge: TextBadgeItem
|
private lateinit var tabArchiveBadge: TextBadgeItem
|
||||||
private lateinit var tabStarredBadge: TextBadgeItem
|
private lateinit var tabStarredBadge: TextBadgeItem
|
||||||
private lateinit var toolbar: Toolbar
|
|
||||||
private lateinit var drawer: Drawer
|
private lateinit var drawer: Drawer
|
||||||
private lateinit var api: SelfossApi
|
private lateinit var api: SelfossApi
|
||||||
private lateinit var customTabActivityHelper: CustomTabActivityHelper
|
private lateinit var customTabActivityHelper: CustomTabActivityHelper
|
||||||
@ -127,6 +116,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
private var recyclerViewScrollListener: RecyclerView.OnScrollListener? = null
|
private var recyclerViewScrollListener: RecyclerView.OnScrollListener? = null
|
||||||
private lateinit var settings: SharedPreferences
|
private lateinit var settings: SharedPreferences
|
||||||
|
|
||||||
|
private var badgeNew: Int = -1
|
||||||
|
private var badgeAll: Int = -1
|
||||||
|
private var badgeFavs: Int = -1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -141,16 +134,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
|
||||||
Scoop.getInstance().apply(this)
|
Scoop.getInstance().apply(this)
|
||||||
|
|
||||||
setContentView(R.layout.activity_home)
|
setContentView(R.layout.activity_home)
|
||||||
|
|
||||||
toolbar = findViewById(R.id.toolbar)
|
setSupportActionBar(toolBar)
|
||||||
setSupportActionBar(toolbar)
|
|
||||||
|
|
||||||
if (savedInstanceState == null) {
|
if (savedInstanceState == null) {
|
||||||
val promptView: DefaultLayoutPromptView = findViewById(R.id.prompt_view)
|
|
||||||
Amplify.getSharedInstance().promptIfReady(promptView)
|
Amplify.getSharedInstance().promptIfReady(promptView)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,122 +156,114 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
appColors = AppColors(this@HomeActivity)
|
appColors = AppColors(this@HomeActivity)
|
||||||
|
|
||||||
handleBottomBar()
|
handleBottomBar()
|
||||||
|
|
||||||
handleDrawer()
|
handleDrawer()
|
||||||
|
|
||||||
coordinatorLayout = findViewById(R.id.coordLayout)
|
|
||||||
swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout)
|
|
||||||
recyclerView = findViewById(R.id.my_recycler_view)
|
|
||||||
|
|
||||||
emptyText = findViewById(R.id.emptyText)
|
|
||||||
|
|
||||||
reloadLayoutManager()
|
reloadLayoutManager()
|
||||||
|
|
||||||
handleSwipeRefreshLayout()
|
handleSwipeRefreshLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleSwipeRefreshLayout() {
|
private fun handleSwipeRefreshLayout() {
|
||||||
swipeRefreshLayout.setColorSchemeResources(
|
swipeRefreshLayout.setColorSchemeResources(
|
||||||
R.color.refresh_progress_1,
|
R.color.refresh_progress_1,
|
||||||
R.color.refresh_progress_2,
|
R.color.refresh_progress_2,
|
||||||
R.color.refresh_progress_3)
|
R.color.refresh_progress_3)
|
||||||
swipeRefreshLayout.setOnRefreshListener {
|
swipeRefreshLayout.setOnRefreshListener {
|
||||||
handleDrawerItems()
|
handleDrawerItems()
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
}
|
}
|
||||||
|
|
||||||
val simpleItemTouchCallback =
|
val simpleItemTouchCallback =
|
||||||
object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
|
object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT) {
|
||||||
|
|
||||||
override fun getSwipeDirs(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?): Int =
|
override fun getSwipeDirs(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?): Int =
|
||||||
if (elementsShown != UNREAD_SHOWN) 0 else super.getSwipeDirs(recyclerView, viewHolder)
|
if (elementsShown != UNREAD_SHOWN) 0 else super.getSwipeDirs(recyclerView, viewHolder)
|
||||||
|
|
||||||
override fun onMove(recyclerView: RecyclerView,
|
override fun onMove(recyclerView: RecyclerView,
|
||||||
viewHolder: RecyclerView.ViewHolder,
|
viewHolder: RecyclerView.ViewHolder,
|
||||||
target: RecyclerView.ViewHolder): Boolean = false
|
target: RecyclerView.ViewHolder): Boolean = false
|
||||||
|
|
||||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
|
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
|
||||||
try {
|
try {
|
||||||
val i = items[viewHolder.adapterPosition]
|
val i = items[viewHolder.adapterPosition]
|
||||||
val position = items.indexOf(i)
|
val position = items.indexOf(i)
|
||||||
|
|
||||||
val adapter = recyclerView.adapter
|
val adapter = recyclerView.adapter
|
||||||
when (adapter) {
|
when (adapter) {
|
||||||
is ItemCardAdapter -> adapter.removeItemAtIndex(position)
|
is ItemCardAdapter -> adapter.removeItemAtIndex(position)
|
||||||
is ItemListAdapter -> adapter.removeItemAtIndex(position)
|
is ItemListAdapter -> adapter.removeItemAtIndex(position)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (items.size > 0) {
|
||||||
|
badgeNew--
|
||||||
|
reloadBadgeContent()
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tabNewBadge.hide()
|
||||||
|
|
||||||
|
|
||||||
|
val manager = recyclerView.layoutManager
|
||||||
|
val lastVisibleItem: Int = when (manager) {
|
||||||
|
is StaggeredGridLayoutManager -> manager.findLastCompletelyVisibleItemPositions(null).last()
|
||||||
|
is GridLayoutManager -> manager.findLastCompletelyVisibleItemPosition()
|
||||||
|
else -> 0
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastVisibleItem === items.size && items.size <= maxItemNumber() && maxItemNumber() >= itemsNumber) {
|
||||||
|
getElementsAccordingToTab(appendResults = true, offsetOverride = lastVisibleItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (e: IndexOutOfBoundsException) {
|
||||||
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
|
Crashlytics.log(100, "SWIPE_INDEX_OUT_OF_BOUND", "IndexOutOfBoundsException when swiping")
|
||||||
|
Crashlytics.logException(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (items.size > 0)
|
|
||||||
tabNewBadge.setText("${items.size}").maybeShow()
|
|
||||||
else
|
|
||||||
tabNewBadge.hide()
|
|
||||||
|
|
||||||
|
|
||||||
val manager = recyclerView.layoutManager
|
|
||||||
val lastVisibleItem: Int = when (manager) {
|
|
||||||
is StaggeredGridLayoutManager -> manager.findLastCompletelyVisibleItemPositions(null).last()
|
|
||||||
is GridLayoutManager -> manager.findLastCompletelyVisibleItemPosition()
|
|
||||||
else -> 0
|
|
||||||
}
|
|
||||||
|
|
||||||
if (lastVisibleItem == (items.size - 1)) {
|
|
||||||
getElementsAccordingToTab(appendResults = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (e: IndexOutOfBoundsException) {
|
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
|
||||||
Crashlytics.log(100, "SWIPE_INDEX_OUT_OF_BOUND", "IndexOutOfBoundsException when swiping")
|
|
||||||
Crashlytics.logException(e)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
ItemTouchHelper(simpleItemTouchCallback).attachToRecyclerView(recyclerView)
|
ItemTouchHelper(simpleItemTouchCallback).attachToRecyclerView(recyclerView)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleBottomBar() {
|
private fun handleBottomBar() {
|
||||||
|
|
||||||
bottomBar = findViewById(R.id.bottomBar)
|
|
||||||
|
|
||||||
tabNewBadge = TextBadgeItem()
|
tabNewBadge = TextBadgeItem()
|
||||||
.setText("")
|
.setText("")
|
||||||
.setHideOnSelect(false).hide(false)
|
.setHideOnSelect(false).hide(false)
|
||||||
.setBackgroundColor(appColors.primary)
|
.setBackgroundColor(appColors.primary)
|
||||||
tabArchiveBadge = TextBadgeItem()
|
tabArchiveBadge = TextBadgeItem()
|
||||||
.setText("")
|
.setText("")
|
||||||
.setHideOnSelect(false).hide(false)
|
.setHideOnSelect(false).hide(false)
|
||||||
.setBackgroundColor(appColors.primary)
|
.setBackgroundColor(appColors.primary)
|
||||||
tabStarredBadge = TextBadgeItem()
|
tabStarredBadge = TextBadgeItem()
|
||||||
.setText("")
|
.setText("")
|
||||||
.setHideOnSelect(false).hide(false)
|
.setHideOnSelect(false).hide(false)
|
||||||
.setBackgroundColor(appColors.primary)
|
.setBackgroundColor(appColors.primary)
|
||||||
|
|
||||||
val tabNew =
|
val tabNew =
|
||||||
BottomNavigationItem(
|
BottomNavigationItem(
|
||||||
R.drawable.ic_fiber_new_black_24dp,
|
R.drawable.ic_fiber_new_black_24dp,
|
||||||
getString(R.string.tab_new)
|
getString(R.string.tab_new)
|
||||||
).setActiveColor(appColors.accent)
|
).setActiveColor(appColors.accent)
|
||||||
.setBadgeItem(tabNewBadge)
|
.setBadgeItem(tabNewBadge)
|
||||||
val tabArchive =
|
val tabArchive =
|
||||||
BottomNavigationItem(
|
BottomNavigationItem(
|
||||||
R.drawable.ic_archive_black_24dp,
|
R.drawable.ic_archive_black_24dp,
|
||||||
getString(R.string.tab_read)
|
getString(R.string.tab_read)
|
||||||
).setActiveColor(appColors.dark)
|
).setActiveColor(appColors.dark)
|
||||||
.setBadgeItem(tabArchiveBadge)
|
.setBadgeItem(tabArchiveBadge)
|
||||||
val tabStarred =
|
val tabStarred =
|
||||||
BottomNavigationItem(
|
BottomNavigationItem(
|
||||||
R.drawable.ic_favorite_black_24dp,
|
R.drawable.ic_favorite_black_24dp,
|
||||||
getString(R.string.tab_favs)
|
getString(R.string.tab_favs)
|
||||||
).setActiveColorResource(R.color.pink)
|
).setActiveColorResource(R.color.pink)
|
||||||
.setBadgeItem(tabStarredBadge)
|
.setBadgeItem(tabStarredBadge)
|
||||||
|
|
||||||
bottomBar
|
bottomBar
|
||||||
.addItem(tabNew)
|
.addItem(tabNew)
|
||||||
.addItem(tabArchive)
|
.addItem(tabArchive)
|
||||||
.addItem(tabStarred)
|
.addItem(tabStarred)
|
||||||
.setFirstSelectedPosition(0)
|
.setFirstSelectedPosition(0)
|
||||||
.initialise()
|
.initialise()
|
||||||
|
|
||||||
bottomBar.setMode(BottomNavigationBar.MODE_SHIFTING)
|
bottomBar.setMode(BottomNavigationBar.MODE_SHIFTING)
|
||||||
bottomBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC)
|
bottomBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC)
|
||||||
@ -331,86 +311,68 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
|
|
||||||
private fun handleDrawer() {
|
private fun handleDrawer() {
|
||||||
displayAccountHeader =
|
displayAccountHeader =
|
||||||
PreferenceManager.getDefaultSharedPreferences(this)
|
PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
.getBoolean("account_header_displaying", false)
|
.getBoolean("account_header_displaying", false)
|
||||||
val headerResult: AccountHeader? = if (displayAccountHeader) {
|
|
||||||
AccountHeaderBuilder()
|
drawer = drawer {
|
||||||
.withActivity(this)
|
rootViewRes = R.id.drawer_layout
|
||||||
.withHeaderBackground(R.drawable.bg)
|
toolbar = toolBar
|
||||||
.addProfiles(
|
actionBarDrawerToggleEnabled = true
|
||||||
ProfileDrawerItem()
|
actionBarDrawerToggleAnimated = true
|
||||||
.withName(
|
showOnFirstLaunch = true
|
||||||
settings.getString("url", "")
|
onSlide { _, p1 ->
|
||||||
|
bottomBar.alpha = (1 - p1)
|
||||||
|
}
|
||||||
|
onClosed {
|
||||||
|
bottomBar.show()
|
||||||
|
}
|
||||||
|
onOpened {
|
||||||
|
bottomBar.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (displayAccountHeader)
|
||||||
|
accountHeader {
|
||||||
|
background = R.drawable.bg
|
||||||
|
profile(settings.getString("url", "")) {
|
||||||
|
iconDrawable = resources.getDrawable(R.mipmap.ic_launcher)
|
||||||
|
}
|
||||||
|
selectionListEnabledForSingleProfile = false
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
primaryItem(R.string.drawer_report_bug) {
|
||||||
|
icon = R.drawable.ic_bug_report
|
||||||
|
iconTintingEnabled = true
|
||||||
|
onClick { _ ->
|
||||||
|
IssueReporterLauncher.forTarget(getString(R.string.report_github_user), getString(R.string.report_github_repo))
|
||||||
|
.theme(R.style.Theme_App_Light)
|
||||||
|
.guestToken(BuildConfig.GITHUB_TOKEN)
|
||||||
|
.guestEmailRequired(true)
|
||||||
|
.minDescriptionLength(20)
|
||||||
|
.putExtraInfo("Unique ID", settings.getString("unique_id", ""))
|
||||||
|
.putExtraInfo("From github", BuildConfig.GITHUB_VERSION)
|
||||||
|
.homeAsUpEnabled(true)
|
||||||
|
.launch(this@HomeActivity)
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
primaryItem(R.string.title_activity_settings) {
|
||||||
|
icon = R.drawable.ic_settings
|
||||||
|
iconTintingEnabled = true
|
||||||
|
onClick { _ ->
|
||||||
|
startActivityForResult(
|
||||||
|
Intent(
|
||||||
|
this@HomeActivity,
|
||||||
|
SettingsActivity::class.java
|
||||||
|
),
|
||||||
|
MENU_PREFERENCES
|
||||||
)
|
)
|
||||||
.withIcon(resources.getDrawable(R.mipmap.ic_launcher))
|
false
|
||||||
)
|
|
||||||
.withSelectionListEnabledForSingleProfile(false)
|
|
||||||
.build()
|
|
||||||
} else null
|
|
||||||
|
|
||||||
val drawerBuilder =
|
|
||||||
DrawerBuilder()
|
|
||||||
.withActivity(this)
|
|
||||||
.withRootView(R.id.drawer_layout)
|
|
||||||
.withToolbar(toolbar)
|
|
||||||
.withActionBarDrawerToggle(true)
|
|
||||||
.withActionBarDrawerToggleAnimated(true)
|
|
||||||
.withShowDrawerOnFirstLaunch(true)
|
|
||||||
.withOnDrawerListener(object: Drawer.OnDrawerListener {
|
|
||||||
override fun onDrawerSlide(v: View?, p1: Float) {
|
|
||||||
bottomBar.alpha = (1 - p1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDrawerClosed(v: View?) {
|
|
||||||
bottomBar.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDrawerOpened(v: View?) {
|
|
||||||
bottomBar.hide()
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
if (displayAccountHeader && headerResult != null)
|
|
||||||
drawerBuilder.withAccountHeader(headerResult)
|
|
||||||
|
|
||||||
drawer = drawerBuilder.build()
|
|
||||||
|
|
||||||
drawer.addStickyFooterItem(
|
|
||||||
PrimaryDrawerItem()
|
|
||||||
.withName(R.string.drawer_report_bug)
|
|
||||||
.withIcon(R.drawable.ic_bug_report)
|
|
||||||
.withIconTintingEnabled(true)
|
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
|
||||||
IssueReporterLauncher.forTarget(getString(R.string.report_github_user), getString(R.string.report_github_repo))
|
|
||||||
.theme(R.style.Theme_App_Light)
|
|
||||||
.guestToken(BuildConfig.GITHUB_TOKEN)
|
|
||||||
.guestEmailRequired(true)
|
|
||||||
.minDescriptionLength(20)
|
|
||||||
.putExtraInfo("Unique ID", settings.getString("unique_id", ""))
|
|
||||||
.putExtraInfo("From github", BuildConfig.GITHUB_VERSION)
|
|
||||||
.homeAsUpEnabled(true)
|
|
||||||
.launch(this)
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
)
|
}
|
||||||
|
}
|
||||||
drawer.addStickyFooterItem(
|
|
||||||
PrimaryDrawerItem()
|
|
||||||
.withName(R.string.title_activity_settings)
|
|
||||||
.withIcon(R.drawable.ic_settings)
|
|
||||||
.withIconTintingEnabled(true)
|
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
|
||||||
startActivityForResult(
|
|
||||||
Intent(
|
|
||||||
this@HomeActivity,
|
|
||||||
SettingsActivity::class.java
|
|
||||||
),
|
|
||||||
MENU_PREFERENCES
|
|
||||||
)
|
|
||||||
false
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -419,10 +381,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
fun handleTags(maybeTags: List<Tag>?) {
|
fun handleTags(maybeTags: List<Tag>?) {
|
||||||
if (maybeTags == null) {
|
if (maybeTags == null) {
|
||||||
if (loadedFromCache)
|
if (loadedFromCache)
|
||||||
|
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_error_loading_tags))
|
.withName(getString(R.string.drawer_error_loading_tags))
|
||||||
.withSelectable(false))
|
.withSelectable(false))
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (tag in maybeTags) {
|
for (tag in maybeTags) {
|
||||||
@ -432,20 +395,20 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
gd.setSize(30, 30)
|
gd.setSize(30, 30)
|
||||||
gd.cornerRadius = 30F
|
gd.cornerRadius = 30F
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
PrimaryDrawerItem()
|
PrimaryDrawerItem()
|
||||||
.withName(tag.tag)
|
.withName(tag.tag)
|
||||||
.withIdentifier(tag.tag.longHash())
|
.withIdentifier(tag.tag.longHash())
|
||||||
.withIcon(gd)
|
.withIcon(gd)
|
||||||
.withBadge("${tag.unread}")
|
.withBadge("${tag.unread}")
|
||||||
.withBadgeStyle(
|
.withBadgeStyle(
|
||||||
BadgeStyle().withTextColor(Color.WHITE)
|
BadgeStyle().withTextColor(Color.WHITE)
|
||||||
.withColor(appColors.accent)
|
.withColor(appColors.accent)
|
||||||
)
|
)
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
maybeTagFilter = tag
|
maybeTagFilter = tag
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,22 +419,22 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
if (maybeSources == null) {
|
if (maybeSources == null) {
|
||||||
if (loadedFromCache)
|
if (loadedFromCache)
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_error_loading_sources))
|
.withName(getString(R.string.drawer_error_loading_sources))
|
||||||
.withSelectable(false))
|
.withSelectable(false))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
for (tag in maybeSources)
|
for (tag in maybeSources)
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
CustomUrlPrimaryDrawerItem()
|
CustomUrlPrimaryDrawerItem()
|
||||||
.withName(tag.title)
|
.withName(tag.title)
|
||||||
.withIdentifier(tag.id.toLong())
|
.withIdentifier(tag.id.toLong())
|
||||||
.withIcon(tag.getIcon(this@HomeActivity))
|
.withIcon(tag.getIcon(this@HomeActivity))
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
maybeSourceFilter = tag
|
maybeSourceFilter = tag
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -479,58 +442,58 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
drawer.removeAllItems()
|
drawer.removeAllItems()
|
||||||
if (maybeDrawerData != null) {
|
if (maybeDrawerData != null) {
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_item_filters))
|
.withName(getString(R.string.drawer_item_filters))
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
.withIdentifier(DRAWER_ID_FILTERS)
|
.withIdentifier(DRAWER_ID_FILTERS)
|
||||||
.withBadge(getString(R.string.drawer_action_clear))
|
.withBadge(getString(R.string.drawer_action_clear))
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
maybeSourceFilter = null
|
maybeSourceFilter = null
|
||||||
maybeTagFilter = null
|
maybeTagFilter = null
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
drawer.addItem(DividerDrawerItem())
|
drawer.addItem(DividerDrawerItem())
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_item_tags))
|
.withName(getString(R.string.drawer_item_tags))
|
||||||
.withIdentifier(DRAWER_ID_TAGS)
|
.withIdentifier(DRAWER_ID_TAGS)
|
||||||
.withSelectable(false))
|
.withSelectable(false))
|
||||||
handleTags(maybeDrawerData.tags)
|
handleTags(maybeDrawerData.tags)
|
||||||
drawer.addItem(DividerDrawerItem())
|
drawer.addItem(DividerDrawerItem())
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
SecondaryDrawerItem()
|
SecondaryDrawerItem()
|
||||||
.withName(getString(R.string.drawer_item_sources))
|
.withName(getString(R.string.drawer_item_sources))
|
||||||
.withIdentifier(DRAWER_ID_TAGS)
|
.withIdentifier(DRAWER_ID_TAGS)
|
||||||
.withBadge(getString(R.string.drawer_action_edit))
|
.withBadge(getString(R.string.drawer_action_edit))
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
startActivity(Intent(this, SourcesActivity::class.java))
|
startActivity(Intent(this, SourcesActivity::class.java))
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
handleSources(maybeDrawerData.sources)
|
handleSources(maybeDrawerData.sources)
|
||||||
drawer.addItem(DividerDrawerItem())
|
drawer.addItem(DividerDrawerItem())
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
PrimaryDrawerItem()
|
PrimaryDrawerItem()
|
||||||
.withName(R.string.action_about)
|
.withName(R.string.action_about)
|
||||||
.withSelectable(false)
|
.withSelectable(false)
|
||||||
.withIcon(R.drawable.ic_info_outline)
|
.withIcon(R.drawable.ic_info_outline)
|
||||||
.withIconTintingEnabled(true)
|
.withIconTintingEnabled(true)
|
||||||
.withOnDrawerItemClickListener { _, _, _ ->
|
.withOnDrawerItemClickListener { _, _, _ ->
|
||||||
LibsBuilder()
|
LibsBuilder()
|
||||||
.withActivityStyle(
|
.withActivityStyle(
|
||||||
if (appColors.isDarkTheme)
|
if (appColors.isDarkTheme)
|
||||||
Libs.ActivityStyle.LIGHT_DARK_TOOLBAR
|
Libs.ActivityStyle.LIGHT_DARK_TOOLBAR
|
||||||
else
|
else
|
||||||
Libs.ActivityStyle.DARK
|
Libs.ActivityStyle.DARK
|
||||||
)
|
)
|
||||||
.withAboutIconShown(true)
|
.withAboutIconShown(true)
|
||||||
.withAboutVersionShown(true)
|
.withAboutVersionShown(true)
|
||||||
.start(this@HomeActivity)
|
.start(this@HomeActivity)
|
||||||
false
|
false
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
if (!loadedFromCache)
|
if (!loadedFromCache)
|
||||||
@ -544,15 +507,15 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
} else {
|
} else {
|
||||||
if (!loadedFromCache) {
|
if (!loadedFromCache) {
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
PrimaryDrawerItem()
|
PrimaryDrawerItem()
|
||||||
.withName(getString(R.string.no_tags_loaded))
|
.withName(getString(R.string.no_tags_loaded))
|
||||||
.withIdentifier(DRAWER_ID_TAGS)
|
.withIdentifier(DRAWER_ID_TAGS)
|
||||||
.withSelectable(false))
|
.withSelectable(false))
|
||||||
drawer.addItem(
|
drawer.addItem(
|
||||||
PrimaryDrawerItem()
|
PrimaryDrawerItem()
|
||||||
.withName(getString(R.string.no_sources_loaded))
|
.withName(getString(R.string.no_sources_loaded))
|
||||||
.withIdentifier(DRAWER_ID_SOURCES)
|
.withIdentifier(DRAWER_ID_SOURCES)
|
||||||
.withSelectable(false))
|
.withSelectable(false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,29 +594,29 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
override fun onTabUnselected(position: Int) = Unit
|
override fun onTabUnselected(position: Int) = Unit
|
||||||
|
|
||||||
override fun onTabReselected(position: Int) =
|
override fun onTabReselected(position: Int) =
|
||||||
when (mLayoutManager) {
|
when (mLayoutManager) {
|
||||||
is StaggeredGridLayoutManager ->
|
is StaggeredGridLayoutManager ->
|
||||||
if (mLayoutManager.findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
|
if (mLayoutManager.findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
} else {
|
} else {
|
||||||
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
||||||
}
|
}
|
||||||
is GridLayoutManager ->
|
is GridLayoutManager ->
|
||||||
if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
|
if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
|
||||||
getElementsAccordingToTab()
|
getElementsAccordingToTab()
|
||||||
} else {
|
} else {
|
||||||
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
||||||
}
|
}
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTabSelected(position: Int) =
|
override fun onTabSelected(position: Int) =
|
||||||
when (position) {
|
when (position) {
|
||||||
0 -> getUnRead()
|
0 -> getUnRead()
|
||||||
1 -> getRead()
|
1 -> getRead()
|
||||||
2 -> getStarred()
|
2 -> getStarred()
|
||||||
else -> Unit
|
else -> Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -670,7 +633,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
else -> 0
|
else -> 0
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lastVisibleItem == (items.size - 1)) {
|
if (lastVisibleItem == (items.size - 1) && items.size < maxItemNumber()) {
|
||||||
getElementsAccordingToTab(appendResults = true)
|
getElementsAccordingToTab(appendResults = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -681,22 +644,30 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
recyclerView.addOnScrollListener(recyclerViewScrollListener)
|
recyclerView.addOnScrollListener(recyclerViewScrollListener)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mayBeEmpty() =
|
private fun mayBeEmpty() =
|
||||||
if (items.isEmpty()) {
|
if (items.isEmpty()) {
|
||||||
emptyText.visibility = View.VISIBLE
|
emptyText.visibility = View.VISIBLE
|
||||||
recyclerView.visibility = View.GONE
|
recyclerView.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
emptyText.visibility = View.GONE
|
emptyText.visibility = View.GONE
|
||||||
recyclerView.visibility = View.VISIBLE
|
recyclerView.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getElementsAccordingToTab(appendResults: Boolean = false, offsetOverride: Int? = null) {
|
||||||
|
offset = if (appendResults && offsetOverride === null) {
|
||||||
|
(offset + itemsNumber)
|
||||||
|
} else {
|
||||||
|
offsetOverride ?: 0
|
||||||
|
}
|
||||||
|
firstVisible = if (appendResults) firstVisible else 0
|
||||||
|
|
||||||
private fun getElementsAccordingToTab(appendResults: Boolean = false) =
|
|
||||||
when (elementsShown) {
|
when (elementsShown) {
|
||||||
UNREAD_SHOWN -> getUnRead(appendResults)
|
UNREAD_SHOWN -> getUnRead(appendResults)
|
||||||
READ_SHOWN -> getRead(appendResults)
|
READ_SHOWN -> getRead(appendResults)
|
||||||
FAV_SHOWN -> getStarred(appendResults)
|
FAV_SHOWN -> getStarred(appendResults)
|
||||||
else -> getUnRead(appendResults)
|
else -> getUnRead(appendResults)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun doCallTo(appendResults: Boolean, toastMessage: Int, call: (String?, Long?, String?) -> Call<List<Item>>) {
|
private fun doCallTo(appendResults: Boolean, toastMessage: Int, call: (String?, Long?, String?) -> Call<List<Item>>) {
|
||||||
fun handleItemsResponse(response: Response<List<Item>>) {
|
fun handleItemsResponse(response: Response<List<Item>>) {
|
||||||
@ -723,38 +694,29 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
swipeRefreshLayout.post { swipeRefreshLayout.isRefreshing = true }
|
swipeRefreshLayout.post { swipeRefreshLayout.isRefreshing = true }
|
||||||
|
|
||||||
call(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter)
|
call(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter)
|
||||||
.enqueue(object : Callback<List<Item>> {
|
.enqueue(object : Callback<List<Item>> {
|
||||||
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
||||||
handleItemsResponse(response)
|
handleItemsResponse(response)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
||||||
swipeRefreshLayout.isRefreshing = false
|
swipeRefreshLayout.isRefreshing = false
|
||||||
Toast.makeText(this@HomeActivity, toastMessage, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@HomeActivity, toastMessage, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getUnRead(appendResults: Boolean = false) {
|
private fun getUnRead(appendResults: Boolean = false) {
|
||||||
offset = if (appendResults) (offset + itemsNumber)
|
|
||||||
else 0
|
|
||||||
firstVisible = if (appendResults) firstVisible else 0
|
|
||||||
elementsShown = UNREAD_SHOWN
|
elementsShown = UNREAD_SHOWN
|
||||||
doCallTo(appendResults, R.string.cant_get_new_elements){t, id, f -> api.newItems(t, id, f, itemsNumber, offset)}
|
doCallTo(appendResults, R.string.cant_get_new_elements){t, id, f -> api.newItems(t, id, f, itemsNumber, offset)}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getRead(appendResults: Boolean = false) {
|
private fun getRead(appendResults: Boolean = false) {
|
||||||
offset = if (appendResults) (offset + itemsNumber)
|
|
||||||
else 0
|
|
||||||
firstVisible = if (appendResults) firstVisible else 0
|
|
||||||
elementsShown = READ_SHOWN
|
elementsShown = READ_SHOWN
|
||||||
doCallTo(appendResults, R.string.cant_get_read){t, id, f -> api.readItems(t, id, f, itemsNumber, offset)}
|
doCallTo(appendResults, R.string.cant_get_read){t, id, f -> api.readItems(t, id, f, itemsNumber, offset)}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getStarred(appendResults: Boolean = false) {
|
private fun getStarred(appendResults: Boolean = false) {
|
||||||
offset = if (appendResults) (offset + itemsNumber)
|
|
||||||
else 0
|
|
||||||
firstVisible = if (appendResults) firstVisible else 0
|
|
||||||
elementsShown = FAV_SHOWN
|
elementsShown = FAV_SHOWN
|
||||||
doCallTo(appendResults, R.string.cant_get_favs){t, id, f -> api.starredItems(t, id, f, itemsNumber, offset)}
|
doCallTo(appendResults, R.string.cant_get_favs){t, id, f -> api.starredItems(t, id, f, itemsNumber, offset)}
|
||||||
}
|
}
|
||||||
@ -774,29 +736,29 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
val mAdapter: RecyclerView.Adapter<*>
|
val mAdapter: RecyclerView.Adapter<*>
|
||||||
if (shouldBeCardView) {
|
if (shouldBeCardView) {
|
||||||
mAdapter =
|
mAdapter =
|
||||||
ItemCardAdapter(
|
ItemCardAdapter(
|
||||||
this,
|
this,
|
||||||
items,
|
items,
|
||||||
api,
|
api,
|
||||||
customTabActivityHelper,
|
customTabActivityHelper,
|
||||||
internalBrowser,
|
internalBrowser,
|
||||||
articleViewer,
|
articleViewer,
|
||||||
fullHeightCards,
|
fullHeightCards,
|
||||||
appColors,
|
appColors,
|
||||||
debugReadingItems,
|
debugReadingItems,
|
||||||
userIdentifier)
|
userIdentifier)
|
||||||
} else {
|
} else {
|
||||||
mAdapter =
|
mAdapter =
|
||||||
ItemListAdapter(
|
ItemListAdapter(
|
||||||
this,
|
this,
|
||||||
items,
|
items,
|
||||||
api,
|
api,
|
||||||
customTabActivityHelper,
|
customTabActivityHelper,
|
||||||
clickBehavior,
|
clickBehavior,
|
||||||
internalBrowser,
|
internalBrowser,
|
||||||
articleViewer,
|
articleViewer,
|
||||||
debugReadingItems,
|
debugReadingItems,
|
||||||
userIdentifier)
|
userIdentifier)
|
||||||
}
|
}
|
||||||
recyclerView.adapter = mAdapter
|
recyclerView.adapter = mAdapter
|
||||||
mAdapter.notifyDataSetChanged()
|
mAdapter.notifyDataSetChanged()
|
||||||
@ -813,26 +775,38 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
api.stats.enqueue(object : Callback<Stats> {
|
api.stats.enqueue(object : Callback<Stats> {
|
||||||
override fun onResponse(call: Call<Stats>, response: Response<Stats>) {
|
override fun onResponse(call: Call<Stats>, response: Response<Stats>) {
|
||||||
if (response.body() != null) {
|
if (response.body() != null) {
|
||||||
if (displayUnreadCount)
|
|
||||||
tabNewBadge
|
badgeNew = response.body()!!.unread
|
||||||
.setText(response.body()!!.unread.toString())
|
badgeAll = response.body()!!.total
|
||||||
.maybeShow()
|
badgeFavs = response.body()!!.starred
|
||||||
if (displayAllCount) {
|
reloadBadgeContent()
|
||||||
tabArchiveBadge
|
|
||||||
.setText(response.body()!!.total.toString())
|
|
||||||
.maybeShow()
|
|
||||||
tabStarredBadge
|
|
||||||
.setText(response.body()!!.starred.toString())
|
|
||||||
.maybeShow()
|
|
||||||
} else {
|
|
||||||
tabArchiveBadge.removeBadge()
|
|
||||||
tabStarredBadge.removeBadge()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<Stats>, t: Throwable) {}
|
override fun onFailure(call: Call<Stats>, t: Throwable) {}
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
reloadBadgeContent(succeeded = false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun reloadBadgeContent(succeeded: Boolean = true) {
|
||||||
|
if (succeeded) {
|
||||||
|
if (displayUnreadCount)
|
||||||
|
tabNewBadge
|
||||||
|
.setText(badgeNew.toString())
|
||||||
|
.maybeShow()
|
||||||
|
if (displayAllCount) {
|
||||||
|
tabArchiveBadge
|
||||||
|
.setText(badgeAll.toString())
|
||||||
|
.maybeShow()
|
||||||
|
tabStarredBadge
|
||||||
|
.setText(badgeFavs.toString())
|
||||||
|
.maybeShow()
|
||||||
|
} else {
|
||||||
|
tabArchiveBadge.removeBadge()
|
||||||
|
tabStarredBadge.removeBadge()
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
tabNewBadge.removeBadge()
|
tabNewBadge.removeBadge()
|
||||||
tabArchiveBadge.removeBadge()
|
tabArchiveBadge.removeBadge()
|
||||||
@ -895,8 +869,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
api.update().enqueue(object : Callback<String> {
|
api.update().enqueue(object : Callback<String> {
|
||||||
override fun onResponse(call: Call<String>, response: Response<String>) {
|
override fun onResponse(call: Call<String>, response: Response<String>) {
|
||||||
Toast.makeText(this@HomeActivity,
|
Toast.makeText(this@HomeActivity,
|
||||||
R.string.refresh_success_response, Toast.LENGTH_LONG)
|
R.string.refresh_success_response, Toast.LENGTH_LONG)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<String>, t: Throwable) {
|
override fun onFailure(call: Call<String>, t: Throwable) {
|
||||||
@ -941,17 +915,17 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
R.id.action_share_the_app -> {
|
R.id.action_share_the_app -> {
|
||||||
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
|
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
|
||||||
val share = AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
|
val share = AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
|
||||||
.setMessage(getString(R.string.invitation_message))
|
.setMessage(getString(R.string.invitation_message))
|
||||||
.setDeepLink(Uri.parse("https://ymbh5.app.goo.gl/qbvQ"))
|
.setDeepLink(Uri.parse("https://ymbh5.app.goo.gl/qbvQ"))
|
||||||
.setCallToActionText(getString(R.string.invitation_cta))
|
.setCallToActionText(getString(R.string.invitation_cta))
|
||||||
.build()
|
.build()
|
||||||
startActivityForResult(share, REQUEST_INVITE)
|
startActivityForResult(share, REQUEST_INVITE)
|
||||||
} else {
|
} else {
|
||||||
val sendIntent = Intent()
|
val sendIntent = Intent()
|
||||||
sendIntent.action = Intent.ACTION_SEND
|
sendIntent.action = Intent.ACTION_SEND
|
||||||
sendIntent.putExtra(
|
sendIntent.putExtra(
|
||||||
Intent.EXTRA_TEXT,
|
Intent.EXTRA_TEXT,
|
||||||
getString(R.string.invitation_message) + " https://ymbh5.app.goo.gl/qbvQ"
|
getString(R.string.invitation_message) + " https://ymbh5.app.goo.gl/qbvQ"
|
||||||
)
|
)
|
||||||
sendIntent.type = "text/plain"
|
sendIntent.type = "text/plain"
|
||||||
startActivityForResult(sendIntent, REQUEST_INVITE_BYMAIL)
|
startActivityForResult(sendIntent, REQUEST_INVITE_BYMAIL)
|
||||||
@ -961,4 +935,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
|||||||
else -> return super.onOptionsItemSelected(item)
|
else -> return super.onOptionsItemSelected(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun maxItemNumber(): Int =
|
||||||
|
when (elementsShown) {
|
||||||
|
UNREAD_SHOWN -> badgeNew
|
||||||
|
READ_SHOWN -> badgeAll
|
||||||
|
FAV_SHOWN -> badgeFavs
|
||||||
|
else -> badgeNew // if !elementsShown then unread are fetched.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.support.design.widget.TextInputLayout
|
|
||||||
import android.support.v7.app.AlertDialog
|
import android.support.v7.app.AlertDialog
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.widget.Toolbar
|
import android.support.v7.widget.Toolbar
|
||||||
@ -15,9 +14,6 @@ import android.view.Menu
|
|||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.inputmethod.EditorInfo
|
import android.view.inputmethod.EditorInfo
|
||||||
import android.widget.Button
|
|
||||||
import android.widget.EditText
|
|
||||||
import android.widget.Switch
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
||||||
@ -32,6 +28,8 @@ import com.mikepenz.aboutlibraries.LibsBuilder
|
|||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
import kotlinx.android.synthetic.main.activity_login.*
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class LoginActivity : AppCompatActivity() {
|
class LoginActivity : AppCompatActivity() {
|
||||||
@ -43,14 +41,7 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private lateinit var settings: SharedPreferences
|
private lateinit var settings: SharedPreferences
|
||||||
private lateinit var editor: SharedPreferences.Editor
|
private lateinit var editor: SharedPreferences.Editor
|
||||||
private lateinit var mFirebaseAnalytics: FirebaseAnalytics
|
private lateinit var firebaseAnalytics: FirebaseAnalytics
|
||||||
private lateinit var mUrlView: EditText
|
|
||||||
private lateinit var mLoginView: TextView
|
|
||||||
private lateinit var mHTTPLoginView: TextView
|
|
||||||
private lateinit var mProgressView: View
|
|
||||||
private lateinit var mPasswordView: EditText
|
|
||||||
private lateinit var mHTTPPasswordView: EditText
|
|
||||||
private lateinit var mLoginFormView: View
|
|
||||||
private lateinit var userIdentifier: String
|
private lateinit var userIdentifier: String
|
||||||
private var logErrors: Boolean = false
|
private var logErrors: Boolean = false
|
||||||
|
|
||||||
@ -61,7 +52,6 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
Scoop.getInstance().apply(this)
|
Scoop.getInstance().apply(this)
|
||||||
setContentView(R.layout.activity_login)
|
setContentView(R.layout.activity_login)
|
||||||
|
|
||||||
val toolbar: Toolbar = findViewById(R.id.toolbar)
|
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
|
|
||||||
handleBaseUrlFail()
|
handleBaseUrlFail()
|
||||||
@ -69,7 +59,7 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
|
settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
|
||||||
userIdentifier = settings.getString("unique_id", "")
|
userIdentifier = settings.getString("unique_id", "")
|
||||||
logErrors = settings.getBoolean("loging_debug", false)
|
logErrors = settings.getBoolean("login_debug", false)
|
||||||
|
|
||||||
editor = settings.edit()
|
editor = settings.edit()
|
||||||
|
|
||||||
@ -77,60 +67,44 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
goToMain()
|
goToMain()
|
||||||
}
|
}
|
||||||
|
|
||||||
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this)
|
firebaseAnalytics = FirebaseAnalytics.getInstance(this)
|
||||||
mUrlView = findViewById(R.id.url)
|
|
||||||
mLoginView = findViewById(R.id.login)
|
|
||||||
mHTTPLoginView = findViewById(R.id.httpLogin)
|
|
||||||
mPasswordView = findViewById(R.id.password)
|
|
||||||
mHTTPPasswordView = findViewById(R.id.httpPassword)
|
|
||||||
mLoginFormView = findViewById(R.id.login_form)
|
|
||||||
mProgressView = findViewById(R.id.login_progress)
|
|
||||||
|
|
||||||
handleActions()
|
handleActions()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleActions() {
|
private fun handleActions() {
|
||||||
val mSwitch: Switch = findViewById(R.id.withLogin)
|
|
||||||
val mHTTPSwitch: Switch = findViewById(R.id.withHttpLogin)
|
|
||||||
val mLoginLayout: TextInputLayout = findViewById(R.id.loginLayout)
|
|
||||||
val mHTTPLoginLayout: TextInputLayout = findViewById(R.id.httpLoginInput)
|
|
||||||
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 ->
|
withSelfhostedCert.setOnCheckedChangeListener { _, b ->
|
||||||
isWithSelfSignedCert = !isWithSelfSignedCert
|
isWithSelfSignedCert = !isWithSelfSignedCert
|
||||||
val visi: Int = if (b) View.VISIBLE else View.GONE
|
val visi: Int = if (b) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
warningTextview.visibility = visi
|
warningText.visibility = visi
|
||||||
}
|
}
|
||||||
|
|
||||||
mPasswordView.setOnEditorActionListener(TextView.OnEditorActionListener { _, id, _ ->
|
passwordView.setOnEditorActionListener(TextView.OnEditorActionListener { _, id, _ ->
|
||||||
if (id == R.id.login || id == EditorInfo.IME_NULL) {
|
if (id == R.id.loginView || id == EditorInfo.IME_NULL) {
|
||||||
attemptLogin()
|
attemptLogin()
|
||||||
return@OnEditorActionListener true
|
return@OnEditorActionListener true
|
||||||
}
|
}
|
||||||
false
|
false
|
||||||
})
|
})
|
||||||
|
|
||||||
mEmailSignInButton.setOnClickListener { attemptLogin() }
|
signInButton.setOnClickListener { attemptLogin() }
|
||||||
|
|
||||||
mSwitch.setOnCheckedChangeListener { _, b ->
|
withLogin.setOnCheckedChangeListener { _, b ->
|
||||||
isWithLogin = !isWithLogin
|
isWithLogin = !isWithLogin
|
||||||
val visi: Int = if (b) View.VISIBLE else View.GONE
|
val visi: Int = if (b) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
mLoginLayout.visibility = visi
|
loginLayout.visibility = visi
|
||||||
mPasswordLayout.visibility = visi
|
passwordLayout.visibility = visi
|
||||||
}
|
}
|
||||||
|
|
||||||
mHTTPSwitch.setOnCheckedChangeListener { _, b ->
|
withHttpLogin.setOnCheckedChangeListener { _, b ->
|
||||||
isWithHTTPLogin = !isWithHTTPLogin
|
isWithHTTPLogin = !isWithHTTPLogin
|
||||||
val visi: Int = if (b) View.VISIBLE else View.GONE
|
val visi: Int = if (b) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
mHTTPLoginLayout.visibility = visi
|
httpLoginInput.visibility = visi
|
||||||
mHTTPPasswordLayout.visibility = visi
|
httpPasswordInput.visibility = visi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,9 +114,9 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
||||||
alertDialog.setMessage(getString(R.string.base_url_error))
|
alertDialog.setMessage(getString(R.string.base_url_error))
|
||||||
alertDialog.setButton(
|
alertDialog.setButton(
|
||||||
AlertDialog.BUTTON_NEUTRAL,
|
AlertDialog.BUTTON_NEUTRAL,
|
||||||
"OK",
|
"OK",
|
||||||
{ dialog, _ -> dialog.dismiss() })
|
{ dialog, _ -> dialog.dismiss() })
|
||||||
alertDialog.show()
|
alertDialog.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -156,25 +130,25 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
private fun attemptLogin() {
|
private fun attemptLogin() {
|
||||||
|
|
||||||
// Reset errors.
|
// Reset errors.
|
||||||
mUrlView.error = null
|
urlView.error = null
|
||||||
mLoginView.error = null
|
loginView.error = null
|
||||||
mHTTPLoginView.error = null
|
httpLoginView.error = null
|
||||||
mPasswordView.error = null
|
passwordView.error = null
|
||||||
mHTTPPasswordView.error = null
|
httpPasswordView.error = null
|
||||||
|
|
||||||
// Store values at the time of the login attempt.
|
// Store values at the time of the login attempt.
|
||||||
val url = mUrlView.text.toString()
|
val url = urlView.text.toString()
|
||||||
val login = mLoginView.text.toString()
|
val login = loginView.text.toString()
|
||||||
val httpLogin = mHTTPLoginView.text.toString()
|
val httpLogin = httpLoginView.text.toString()
|
||||||
val password = mPasswordView.text.toString()
|
val password = passwordView.text.toString()
|
||||||
val httpPassword = mHTTPPasswordView.text.toString()
|
val httpPassword = httpPasswordView.text.toString()
|
||||||
|
|
||||||
var cancel = false
|
var cancel = false
|
||||||
var focusView: View? = null
|
var focusView: View? = null
|
||||||
|
|
||||||
if (!url.isBaseUrlValid()) {
|
if (!url.isBaseUrlValid()) {
|
||||||
mUrlView.error = getString(R.string.login_url_problem)
|
urlView.error = getString(R.string.login_url_problem)
|
||||||
focusView = mUrlView
|
focusView = urlView
|
||||||
cancel = true
|
cancel = true
|
||||||
inValidCount++
|
inValidCount++
|
||||||
if (inValidCount == 3) {
|
if (inValidCount == 3) {
|
||||||
@ -182,9 +156,9 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
||||||
alertDialog.setMessage(getString(R.string.text_wrong_url))
|
alertDialog.setMessage(getString(R.string.text_wrong_url))
|
||||||
alertDialog.setButton(
|
alertDialog.setButton(
|
||||||
AlertDialog.BUTTON_NEUTRAL,
|
AlertDialog.BUTTON_NEUTRAL,
|
||||||
"OK",
|
"OK",
|
||||||
{ dialog, _ -> dialog.dismiss() })
|
{ dialog, _ -> dialog.dismiss() })
|
||||||
alertDialog.show()
|
alertDialog.show()
|
||||||
inValidCount = 0
|
inValidCount = 0
|
||||||
}
|
}
|
||||||
@ -192,14 +166,14 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
if (isWithLogin || isWithHTTPLogin) {
|
if (isWithLogin || isWithHTTPLogin) {
|
||||||
if (TextUtils.isEmpty(password)) {
|
if (TextUtils.isEmpty(password)) {
|
||||||
mPasswordView.error = getString(R.string.error_invalid_password)
|
passwordView.error = getString(R.string.error_invalid_password)
|
||||||
focusView = mPasswordView
|
focusView = passwordView
|
||||||
cancel = true
|
cancel = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextUtils.isEmpty(login)) {
|
if (TextUtils.isEmpty(login)) {
|
||||||
mLoginView.error = getString(R.string.error_field_required)
|
loginView.error = getString(R.string.error_field_required)
|
||||||
focusView = mLoginView
|
focusView = loginView
|
||||||
cancel = true
|
cancel = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,11 +200,11 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
editor.remove("password")
|
editor.remove("password")
|
||||||
editor.remove("httpPassword")
|
editor.remove("httpPassword")
|
||||||
editor.apply()
|
editor.apply()
|
||||||
mUrlView.error = getString(R.string.wrong_infos)
|
urlView.error = getString(R.string.wrong_infos)
|
||||||
mLoginView.error = getString(R.string.wrong_infos)
|
loginView.error = getString(R.string.wrong_infos)
|
||||||
mPasswordView.error = getString(R.string.wrong_infos)
|
passwordView.error = getString(R.string.wrong_infos)
|
||||||
mHTTPLoginView.error = getString(R.string.wrong_infos)
|
httpLoginView.error = getString(R.string.wrong_infos)
|
||||||
mHTTPPasswordView.error = getString(R.string.wrong_infos)
|
httpPasswordView.error = getString(R.string.wrong_infos)
|
||||||
if (logErrors) {
|
if (logErrors) {
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
Crashlytics.log(100, "LOGIN_DEBUG_ERRROR", t.message)
|
Crashlytics.log(100, "LOGIN_DEBUG_ERRROR", t.message)
|
||||||
@ -242,7 +216,7 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
||||||
if (response.body() != null && response.body()!!.isSuccess) {
|
if (response.body() != null && response.body()!!.isSuccess) {
|
||||||
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, Bundle())
|
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, Bundle())
|
||||||
goToMain()
|
goToMain()
|
||||||
} else {
|
} else {
|
||||||
preferenceError(Exception("No response body..."))
|
preferenceError(Exception("No response body..."))
|
||||||
@ -260,34 +234,34 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
private fun showProgress(show: Boolean) {
|
private fun showProgress(show: Boolean) {
|
||||||
val shortAnimTime = resources.getInteger(android.R.integer.config_shortAnimTime)
|
val shortAnimTime = resources.getInteger(android.R.integer.config_shortAnimTime)
|
||||||
|
|
||||||
mLoginFormView.visibility = if (show) View.GONE else View.VISIBLE
|
loginForm.visibility = if (show) View.GONE else View.VISIBLE
|
||||||
mLoginFormView
|
loginForm
|
||||||
.animate()
|
.animate()
|
||||||
.setDuration(shortAnimTime.toLong())
|
.setDuration(shortAnimTime.toLong())
|
||||||
.alpha(
|
.alpha(
|
||||||
if (show) 0F else 1F
|
if (show) 0F else 1F
|
||||||
).setListener(object : AnimatorListenerAdapter() {
|
).setListener(object : AnimatorListenerAdapter() {
|
||||||
override fun onAnimationEnd(animation: Animator) {
|
override fun onAnimationEnd(animation: Animator) {
|
||||||
mLoginFormView.visibility = if (show) View.GONE else View.VISIBLE
|
loginForm.visibility = if (show) View.GONE else View.VISIBLE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
mProgressView.visibility = if (show) View.VISIBLE else View.GONE
|
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
|
||||||
mProgressView
|
loginProgress
|
||||||
.animate()
|
.animate()
|
||||||
.setDuration(shortAnimTime.toLong())
|
.setDuration(shortAnimTime.toLong())
|
||||||
.alpha(
|
.alpha(
|
||||||
if (show) 1F else 0F
|
if (show) 1F else 0F
|
||||||
).setListener(object : AnimatorListenerAdapter() {
|
).setListener(object : AnimatorListenerAdapter() {
|
||||||
override fun onAnimationEnd(animation: Animator) {
|
override fun onAnimationEnd(animation: Animator) {
|
||||||
mProgressView.visibility = if (show) View.VISIBLE else View.GONE
|
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
menuInflater.inflate(R.menu.login_menu, menu)
|
menuInflater.inflate(R.menu.login_menu, menu)
|
||||||
menu.findItem(R.id.loging_debug).isChecked = logErrors
|
menu.findItem(R.id.login_debug).isChecked = logErrors
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,17 +269,17 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.about -> {
|
R.id.about -> {
|
||||||
LibsBuilder()
|
LibsBuilder()
|
||||||
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
|
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
|
||||||
.withAboutIconShown(true)
|
.withAboutIconShown(true)
|
||||||
.withAboutVersionShown(true)
|
.withAboutVersionShown(true)
|
||||||
.start(this)
|
.start(this)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
R.id.loging_debug -> {
|
R.id.login_debug -> {
|
||||||
val newState = !item.isChecked
|
val newState = !item.isChecked
|
||||||
item.isChecked = newState
|
item.isChecked = newState
|
||||||
logErrors = newState
|
logErrors = newState
|
||||||
editor.putBoolean("loging_debug", newState)
|
editor.putBoolean("login_debug", newState)
|
||||||
editor.apply()
|
editor.apply()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -1,114 +1,190 @@
|
|||||||
package apps.amine.bou.readerforselfoss
|
package apps.amine.bou.readerforselfoss
|
||||||
|
|
||||||
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
import android.view.LayoutInflater
|
import android.support.customtabs.CustomTabsIntent
|
||||||
|
import android.support.design.widget.FloatingActionButton
|
||||||
|
import android.support.v4.widget.NestedScrollView
|
||||||
|
import android.support.v7.app.AppCompatActivity
|
||||||
|
import android.text.Html
|
||||||
|
import android.text.method.LinkMovementMethod
|
||||||
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
|
||||||
import android.widget.ImageButton
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.TextView
|
|
||||||
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
|
import apps.amine.bou.readerforselfoss.api.mercury.MercuryApi
|
||||||
import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent
|
import apps.amine.bou.readerforselfoss.api.mercury.ParsedContent
|
||||||
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
|
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
|
||||||
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
|
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
|
||||||
|
import apps.amine.bou.readerforselfoss.utils.isEmptyOrNullOrNullString
|
||||||
import apps.amine.bou.readerforselfoss.utils.openItemUrl
|
import apps.amine.bou.readerforselfoss.utils.openItemUrl
|
||||||
import apps.amine.bou.readerforselfoss.utils.shareLink
|
import apps.amine.bou.readerforselfoss.utils.shareLink
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import com.crashlytics.android.Crashlytics
|
||||||
import com.ftinc.scoop.Scoop
|
import com.ftinc.scoop.Scoop
|
||||||
|
import com.github.rubensousa.floatingtoolbar.FloatingToolbar
|
||||||
import org.sufficientlysecure.htmltextview.HtmlHttpImageGetter
|
import org.sufficientlysecure.htmltextview.HtmlHttpImageGetter
|
||||||
import org.sufficientlysecure.htmltextview.HtmlTextView
|
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import xyz.klinker.android.drag_dismiss.activity.DragDismissActivity
|
import kotlinx.android.synthetic.main.activity_reader.*
|
||||||
|
|
||||||
|
|
||||||
class ReaderActivity : DragDismissActivity() {
|
class ReaderActivity : AppCompatActivity() {
|
||||||
private lateinit var mCustomTabActivityHelper: CustomTabActivityHelper
|
private lateinit var mCustomTabActivityHelper: CustomTabActivityHelper
|
||||||
|
//private lateinit var content: HtmlTextView
|
||||||
|
private lateinit var url: String
|
||||||
|
private lateinit var contentText: String
|
||||||
|
private lateinit var contentSource: String
|
||||||
|
private lateinit var contentImage: String
|
||||||
|
private lateinit var contentTitle: String
|
||||||
|
private lateinit var fab: FloatingActionButton
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
mCustomTabActivityHelper.bindCustomTabsService(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
super.onStop()
|
super.onStop()
|
||||||
mCustomTabActivityHelper.unbindCustomTabsService(this)
|
mCustomTabActivityHelper.unbindCustomTabsService(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreateContent(inflater: LayoutInflater, parent: ViewGroup, savedInstanceState: Bundle?): View {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
Scoop.getInstance().apply(this)
|
Scoop.getInstance().apply(this)
|
||||||
val v = inflater.inflate(R.layout.activity_reader, parent, false)
|
setContentView(R.layout.activity_reader)
|
||||||
showProgressBar()
|
|
||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
|
||||||
|
|
||||||
val image: ImageView = v.findViewById(R.id.imageView)
|
url = intent.getStringExtra("url")
|
||||||
val source: TextView = v.findViewById(R.id.source)
|
contentText = intent.getStringExtra("content")
|
||||||
val title: TextView = v.findViewById(R.id.title)
|
contentTitle = intent.getStringExtra("title")
|
||||||
val content: HtmlTextView = v.findViewById(R.id.content)
|
contentImage = intent.getStringExtra("image")
|
||||||
val url = intent.getStringExtra("url")
|
contentSource = intent.getStringExtra("source")
|
||||||
val parser = MercuryApi(BuildConfig.MERCURY_KEY, prefs.getBoolean("should_log_everything", false))
|
|
||||||
val browserBtn: ImageButton = v.findViewById(R.id.browserBtn)
|
|
||||||
val shareBtn: ImageButton = v.findViewById(R.id.shareBtn)
|
|
||||||
|
|
||||||
|
fab = findViewById(R.id.fab)
|
||||||
|
val mFloatingToolbar: FloatingToolbar = findViewById(R.id.floatingToolbar)
|
||||||
|
mFloatingToolbar.attachFab(fab)
|
||||||
|
|
||||||
val customTabsIntent = this@ReaderActivity.buildCustomTabsIntent()
|
val customTabsIntent = this@ReaderActivity.buildCustomTabsIntent()
|
||||||
mCustomTabActivityHelper = CustomTabActivityHelper()
|
mCustomTabActivityHelper = CustomTabActivityHelper()
|
||||||
mCustomTabActivityHelper.bindCustomTabsService(this)
|
mCustomTabActivityHelper.bindCustomTabsService(this)
|
||||||
|
|
||||||
|
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
|
|
||||||
|
mFloatingToolbar.setClickListener(object : FloatingToolbar.ItemClickListener {
|
||||||
|
override fun onItemClick(item: MenuItem) {
|
||||||
|
when (item.itemId) {
|
||||||
|
R.id.more_action -> getContentFromMercury(customTabsIntent, prefs)
|
||||||
|
R.id.share_action -> this@ReaderActivity.shareLink(url)
|
||||||
|
R.id.open_action -> this@ReaderActivity.openItemUrl(
|
||||||
|
url,
|
||||||
|
contentText,
|
||||||
|
contentImage,
|
||||||
|
contentTitle,
|
||||||
|
contentSource,
|
||||||
|
customTabsIntent,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
this@ReaderActivity)
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onItemLongClick(item: MenuItem?) {
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
if (contentText.isEmptyOrNullOrNullString()) {
|
||||||
|
getContentFromMercury(customTabsIntent, prefs)
|
||||||
|
} else {
|
||||||
|
source.text = contentSource
|
||||||
|
titleView.text = contentTitle
|
||||||
|
tryToHandleHtml(contentText, customTabsIntent, prefs)
|
||||||
|
|
||||||
|
if (!contentImage.isEmptyOrNullOrNullString()) {
|
||||||
|
imageView.visibility = View.VISIBLE
|
||||||
|
Glide
|
||||||
|
.with(baseContext)
|
||||||
|
.asBitmap()
|
||||||
|
.load(contentImage)
|
||||||
|
.apply(RequestOptions.fitCenterTransform())
|
||||||
|
.into(imageView)
|
||||||
|
} else {
|
||||||
|
imageView.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nestedScrollView.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { _, _, scrollY, _, oldScrollY ->
|
||||||
|
if (scrollY > oldScrollY) {
|
||||||
|
fab.hide()
|
||||||
|
} else {
|
||||||
|
if (mFloatingToolbar.isShowing) mFloatingToolbar.hide() else fab.show()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
content.movementMethod = LinkMovementMethod.getInstance()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getContentFromMercury(customTabsIntent: CustomTabsIntent, prefs: SharedPreferences) {
|
||||||
|
progressBar.visibility = View.VISIBLE
|
||||||
|
val parser = MercuryApi(BuildConfig.MERCURY_KEY, prefs.getBoolean("should_log_everything", false))
|
||||||
|
|
||||||
parser.parseUrl(url).enqueue(object : Callback<ParsedContent> {
|
parser.parseUrl(url).enqueue(object : Callback<ParsedContent> {
|
||||||
override fun onResponse(call: Call<ParsedContent>, response: Response<ParsedContent>) {
|
override fun onResponse(call: Call<ParsedContent>, response: Response<ParsedContent>) {
|
||||||
if (response.body() != null && response.body()!!.content != null && response.body()!!.content.isNotEmpty()) {
|
if (response.body() != null && response.body()!!.content != null && response.body()!!.content.isNotEmpty()) {
|
||||||
source.text = response.body()!!.domain
|
source.text = response.body()!!.domain
|
||||||
title.text = response.body()!!.title
|
titleView.text = response.body()!!.title
|
||||||
|
this@ReaderActivity.url = response.body()!!.url
|
||||||
|
|
||||||
if (response.body()!!.content != null && !response.body()!!.content.isEmpty()) {
|
if (response.body()!!.content != null && !response.body()!!.content.isEmpty()) {
|
||||||
try {
|
tryToHandleHtml(response.body()!!.content, customTabsIntent, prefs)
|
||||||
content.setHtml(response.body()!!.content, HtmlHttpImageGetter(content, null, true))
|
|
||||||
} catch (e: IndexOutOfBoundsException) {
|
|
||||||
openInBrowserAfterFailing()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isEmpty())
|
|
||||||
|
if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isEmpty()) {
|
||||||
|
imageView.visibility = View.VISIBLE
|
||||||
Glide
|
Glide
|
||||||
.with(baseContext)
|
.with(baseContext)
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.load(response.body()!!.lead_image_url)
|
.load(response.body()!!.lead_image_url)
|
||||||
.apply(RequestOptions.fitCenterTransform())
|
.apply(RequestOptions.fitCenterTransform())
|
||||||
.into(image)
|
.into(imageView)
|
||||||
|
} else {
|
||||||
shareBtn.setOnClickListener {
|
imageView.visibility = View.GONE
|
||||||
this@ReaderActivity.shareLink(response.body()!!.url)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
browserBtn.setOnClickListener {
|
nestedScrollView.scrollTo(0, 0)
|
||||||
this@ReaderActivity.openItemUrl(
|
|
||||||
response.body()!!.url,
|
|
||||||
customTabsIntent,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
this@ReaderActivity)
|
|
||||||
}
|
|
||||||
|
|
||||||
hideProgressBar()
|
progressBar.visibility = View.GONE
|
||||||
} else openInBrowserAfterFailing()
|
} else openInBrowserAfterFailing(customTabsIntent)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFailure(call: Call<ParsedContent>, t: Throwable) = openInBrowserAfterFailing()
|
override fun onFailure(call: Call<ParsedContent>, t: Throwable) = openInBrowserAfterFailing(customTabsIntent)
|
||||||
|
|
||||||
private fun openInBrowserAfterFailing() {
|
|
||||||
this@ReaderActivity.openItemUrl(
|
|
||||||
url,
|
|
||||||
customTabsIntent,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
this@ReaderActivity
|
|
||||||
)
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return v
|
}
|
||||||
|
|
||||||
|
private fun tryToHandleHtml(c: String, customTabsIntent: CustomTabsIntent, prefs: SharedPreferences) {
|
||||||
|
try {
|
||||||
|
content.text = Html.fromHtml(c, HtmlHttpImageGetter(content, null, true), null)
|
||||||
|
|
||||||
|
//content.setHtml(response.body()!!.content, HtmlHttpImageGetter(content, null, true))
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Crashlytics.setUserIdentifier(prefs.getString("unique_id", ""))
|
||||||
|
Crashlytics.log(100, "CANT_TRANSFORM_TO_HTML", e.message)
|
||||||
|
Crashlytics.logException(e)
|
||||||
|
openInBrowserAfterFailing(customTabsIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun openInBrowserAfterFailing(customTabsIntent: CustomTabsIntent) {
|
||||||
|
progressBar.visibility = View.GONE
|
||||||
|
this@ReaderActivity.openItemUrl(
|
||||||
|
url,
|
||||||
|
contentText,
|
||||||
|
contentImage,
|
||||||
|
contentTitle,
|
||||||
|
contentSource,
|
||||||
|
customTabsIntent,
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
this@ReaderActivity
|
||||||
|
)
|
||||||
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,35 +5,36 @@ import android.os.Bundle
|
|||||||
import android.preference.PreferenceManager
|
import android.preference.PreferenceManager
|
||||||
import android.support.v7.app.AppCompatActivity
|
import android.support.v7.app.AppCompatActivity
|
||||||
import android.support.v7.widget.LinearLayoutManager
|
import android.support.v7.widget.LinearLayoutManager
|
||||||
import android.support.v7.widget.RecyclerView
|
|
||||||
import android.support.v7.widget.Toolbar
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import apps.amine.bou.readerforselfoss.adapters.SourcesListAdapter
|
import apps.amine.bou.readerforselfoss.adapters.SourcesListAdapter
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
||||||
import apps.amine.bou.readerforselfoss.api.selfoss.Sources
|
import apps.amine.bou.readerforselfoss.api.selfoss.Sources
|
||||||
import com.ftinc.scoop.Scoop
|
import com.ftinc.scoop.Scoop
|
||||||
import com.melnykov.fab.FloatingActionButton
|
|
||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
import kotlinx.android.synthetic.main.activity_sources.*
|
||||||
|
|
||||||
class SourcesActivity : AppCompatActivity() {
|
class SourcesActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
Scoop.getInstance().apply(this)
|
Scoop.getInstance().apply(this)
|
||||||
setContentView(R.layout.activity_sources)
|
setContentView(R.layout.activity_sources)
|
||||||
val toolbar: Toolbar = findViewById(R.id.toolbar)
|
|
||||||
setSupportActionBar(toolbar)
|
setSupportActionBar(toolbar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||||
supportActionBar?.setDisplayShowHomeEnabled(true)
|
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStop() {
|
||||||
|
super.onStop()
|
||||||
|
recyclerView.clearOnScrollListeners()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
val mFab: FloatingActionButton = findViewById(R.id.fab)
|
|
||||||
val mRecyclerView: RecyclerView = findViewById(R.id.activity_sources)
|
|
||||||
val mLayoutManager = LinearLayoutManager(this)
|
val mLayoutManager = LinearLayoutManager(this)
|
||||||
|
|
||||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||||
@ -41,9 +42,8 @@ class SourcesActivity : AppCompatActivity() {
|
|||||||
val api = SelfossApi(this, this@SourcesActivity, prefs.getBoolean("isSelfSignedCert", false), prefs.getBoolean("should_log_everything", false))
|
val api = SelfossApi(this, this@SourcesActivity, prefs.getBoolean("isSelfSignedCert", false), prefs.getBoolean("should_log_everything", false))
|
||||||
var items: ArrayList<Sources> = ArrayList()
|
var items: ArrayList<Sources> = ArrayList()
|
||||||
|
|
||||||
mFab.attachToRecyclerView(mRecyclerView)
|
recyclerView.setHasFixedSize(true)
|
||||||
mRecyclerView.setHasFixedSize(true)
|
recyclerView.layoutManager = mLayoutManager
|
||||||
mRecyclerView.layoutManager = mLayoutManager
|
|
||||||
|
|
||||||
api.sources.enqueue(object : Callback<List<Sources>> {
|
api.sources.enqueue(object : Callback<List<Sources>> {
|
||||||
override fun onResponse(call: Call<List<Sources>>, response: Response<List<Sources>>) {
|
override fun onResponse(call: Call<List<Sources>>, response: Response<List<Sources>>) {
|
||||||
@ -51,7 +51,7 @@ class SourcesActivity : AppCompatActivity() {
|
|||||||
items = response.body() as ArrayList<Sources>
|
items = response.body() as ArrayList<Sources>
|
||||||
}
|
}
|
||||||
val mAdapter = SourcesListAdapter(this@SourcesActivity, items, api)
|
val mAdapter = SourcesListAdapter(this@SourcesActivity, items, api)
|
||||||
mRecyclerView.adapter = mAdapter
|
recyclerView.adapter = mAdapter
|
||||||
mAdapter.notifyDataSetChanged()
|
mAdapter.notifyDataSetChanged()
|
||||||
if (items.isEmpty()) Toast.makeText(this@SourcesActivity, R.string.nothing_here, Toast.LENGTH_SHORT).show()
|
if (items.isEmpty()) Toast.makeText(this@SourcesActivity, R.string.nothing_here, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ class SourcesActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
mFab.setOnClickListener {
|
fab.setOnClickListener {
|
||||||
startActivity(Intent(this@SourcesActivity, AddSourceActivity::class.java))
|
startActivity(Intent(this@SourcesActivity, AddSourceActivity::class.java))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@ import android.support.v7.widget.RecyclerView
|
|||||||
import android.text.Html
|
import android.text.Html
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageButton
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.ImageView.ScaleType
|
import android.widget.ImageView.ScaleType
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
@ -38,6 +36,7 @@ import com.like.OnLikeListener
|
|||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
import kotlinx.android.synthetic.main.card_item.view.*
|
||||||
|
|
||||||
class ItemCardAdapter(private val app: Activity,
|
class ItemCardAdapter(private val app: Activity,
|
||||||
private val items: ArrayList<Item>,
|
private val items: ArrayList<Item>,
|
||||||
@ -61,32 +60,32 @@ class ItemCardAdapter(private val app: Activity,
|
|||||||
val itm = items[position]
|
val itm = items[position]
|
||||||
|
|
||||||
|
|
||||||
holder.saveBtn.isLiked = itm.starred
|
holder.mView.favButton.isLiked = itm.starred
|
||||||
holder.title.text = Html.fromHtml(itm.title)
|
holder.mView.title.text = Html.fromHtml(itm.title)
|
||||||
|
|
||||||
holder.sourceTitleAndDate.text = itm.sourceAndDateText()
|
holder.mView.sourceTitleAndDate.text = itm.sourceAndDateText()
|
||||||
|
|
||||||
if (itm.getThumbnail(c).isEmpty()) {
|
if (itm.getThumbnail(c).isEmpty()) {
|
||||||
Glide.with(c).clear(holder.itemImage)
|
Glide.with(c).clear(holder.mView.itemImage)
|
||||||
holder.itemImage.setImageDrawable(null)
|
holder.mView.itemImage.setImageDrawable(null)
|
||||||
} else {
|
} else {
|
||||||
c.bitmapCenterCrop(itm.getThumbnail(c), holder.itemImage)
|
c.bitmapCenterCrop(itm.getThumbnail(c), holder.mView.itemImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itm.getIcon(c).isEmpty()) {
|
if (itm.getIcon(c).isEmpty()) {
|
||||||
val color = generator.getColor(itm.sourcetitle)
|
val color = generator.getColor(itm.sourcetitle)
|
||||||
|
|
||||||
val drawable =
|
val drawable =
|
||||||
TextDrawable
|
TextDrawable
|
||||||
.builder()
|
.builder()
|
||||||
.round()
|
.round()
|
||||||
.build(itm.sourcetitle.toTextDrawableString(), color)
|
.build(itm.sourcetitle.toTextDrawableString(), color)
|
||||||
holder.sourceImage.setImageDrawable(drawable)
|
holder.mView.sourceImage.setImageDrawable(drawable)
|
||||||
} else {
|
} else {
|
||||||
c.circularBitmapDrawable(itm.getIcon(c), holder.sourceImage)
|
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.sourceImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.saveBtn.isLiked = itm.starred
|
holder.mView.favButton.isLiked = itm.starred
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int {
|
override fun getItemCount(): Int {
|
||||||
@ -128,13 +127,13 @@ class ItemCardAdapter(private val app: Activity,
|
|||||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
||||||
if (!response.succeeded() && debugReadingItems) {
|
if (!response.succeeded() && debugReadingItems) {
|
||||||
val message =
|
val message =
|
||||||
"message: ${response.message()} " +
|
"message: ${response.message()} " +
|
||||||
"response isSuccess: ${response.isSuccessful} " +
|
"response isSuccess: ${response.isSuccessful} " +
|
||||||
"response code: ${response.code()} " +
|
"response code: ${response.code()} " +
|
||||||
"response message: ${response.message()} " +
|
"response message: ${response.message()} " +
|
||||||
"response errorBody: ${response.errorBody()?.string()} " +
|
"response errorBody: ${response.errorBody()?.string()} " +
|
||||||
"body success: ${response.body()?.success} " +
|
"body success: ${response.body()?.success} " +
|
||||||
"body isSuccess: ${response.body()?.isSuccess}"
|
"body isSuccess: ${response.body()?.isSuccess}"
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
||||||
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
||||||
@ -160,14 +159,6 @@ class ItemCardAdapter(private val app: Activity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(val mView: CardView) : RecyclerView.ViewHolder(mView) {
|
inner class ViewHolder(val mView: CardView) : RecyclerView.ViewHolder(mView) {
|
||||||
lateinit var saveBtn: LikeButton
|
|
||||||
lateinit var browserBtn: ImageButton
|
|
||||||
lateinit var shareBtn: ImageButton
|
|
||||||
lateinit var itemImage: ImageView
|
|
||||||
lateinit var sourceImage: ImageView
|
|
||||||
lateinit var title: TextView
|
|
||||||
lateinit var sourceTitleAndDate: TextView
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
mView.setCardBackgroundColor(appColors.cardBackground)
|
mView.setCardBackgroundColor(appColors.cardBackground)
|
||||||
handleClickListeners()
|
handleClickListeners()
|
||||||
@ -175,27 +166,20 @@ class ItemCardAdapter(private val app: Activity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleClickListeners() {
|
private fun handleClickListeners() {
|
||||||
sourceImage = mView.findViewById(R.id.sourceImage)
|
|
||||||
itemImage = mView.findViewById(R.id.itemImage)
|
|
||||||
title = mView.findViewById(R.id.title)
|
|
||||||
sourceTitleAndDate = mView.findViewById(R.id.sourceTitleAndDate)
|
|
||||||
saveBtn = mView.findViewById(R.id.favButton)
|
|
||||||
shareBtn = mView.findViewById(R.id.shareBtn)
|
|
||||||
browserBtn = mView.findViewById(R.id.browserBtn)
|
|
||||||
|
|
||||||
if (!fullHeightCards) {
|
if (!fullHeightCards) {
|
||||||
itemImage.maxHeight = c.resources.getDimension(R.dimen.card_image_max_height).toInt()
|
mView.itemImage.maxHeight = c.resources.getDimension(R.dimen.card_image_max_height).toInt()
|
||||||
itemImage.scaleType = ScaleType.CENTER_CROP
|
mView.itemImage.scaleType = ScaleType.CENTER_CROP
|
||||||
}
|
}
|
||||||
|
|
||||||
saveBtn.setOnLikeListener(object : OnLikeListener {
|
mView.favButton.setOnLikeListener(object : OnLikeListener {
|
||||||
override fun liked(likeButton: LikeButton) {
|
override fun liked(likeButton: LikeButton) {
|
||||||
val (id) = items[adapterPosition]
|
val (id) = items[adapterPosition]
|
||||||
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
saveBtn.isLiked = false
|
mView.favButton.isLiked = false
|
||||||
Toast.makeText(c, R.string.cant_mark_favortie, Toast.LENGTH_SHORT).show()
|
Toast.makeText(c, R.string.cant_mark_favortie, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -207,18 +191,18 @@ class ItemCardAdapter(private val app: Activity,
|
|||||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
saveBtn.isLiked = true
|
mView.favButton.isLiked = true
|
||||||
Toast.makeText(c, R.string.cant_unmark_favortie, Toast.LENGTH_SHORT).show()
|
Toast.makeText(c, R.string.cant_unmark_favortie, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
shareBtn.setOnClickListener {
|
mView.shareBtn.setOnClickListener {
|
||||||
c.shareLink(items[adapterPosition].getLinkDecoded())
|
c.shareLink(items[adapterPosition].getLinkDecoded())
|
||||||
}
|
}
|
||||||
|
|
||||||
browserBtn.setOnClickListener {
|
mView.browserBtn.setOnClickListener {
|
||||||
c.openInBrowserAsNewTask(items[adapterPosition])
|
c.openInBrowserAsNewTask(items[adapterPosition])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -229,10 +213,14 @@ class ItemCardAdapter(private val app: Activity,
|
|||||||
|
|
||||||
mView.setOnClickListener {
|
mView.setOnClickListener {
|
||||||
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
|
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
|
||||||
customTabsIntent,
|
items[adapterPosition].content,
|
||||||
internalBrowser,
|
items[adapterPosition].getThumbnail(c),
|
||||||
articleViewer,
|
items[adapterPosition].title,
|
||||||
app)
|
items[adapterPosition].sourceAndDateText(),
|
||||||
|
customTabsIntent,
|
||||||
|
internalBrowser,
|
||||||
|
articleViewer,
|
||||||
|
app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,6 @@ import android.util.TypedValue
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ImageButton
|
|
||||||
import android.widget.ImageView
|
|
||||||
import android.widget.RelativeLayout
|
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import apps.amine.bou.readerforselfoss.R
|
import apps.amine.bou.readerforselfoss.R
|
||||||
@ -40,7 +37,7 @@ import retrofit2.Callback
|
|||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
|
import kotlinx.android.synthetic.main.list_item.view.*
|
||||||
|
|
||||||
class ItemListAdapter(private val app: Activity,
|
class ItemListAdapter(private val app: Activity,
|
||||||
private val items: ArrayList<Item>,
|
private val items: ArrayList<Item>,
|
||||||
@ -64,27 +61,27 @@ class ItemListAdapter(private val app: Activity,
|
|||||||
val itm = items[position]
|
val itm = items[position]
|
||||||
|
|
||||||
|
|
||||||
holder.saveBtn.isLiked = itm.starred
|
holder.mView.favButton.isLiked = itm.starred
|
||||||
holder.title.text = Html.fromHtml(itm.title)
|
holder.mView.title.text = Html.fromHtml(itm.title)
|
||||||
|
|
||||||
holder.sourceTitleAndDate.text = itm.sourceAndDateText()
|
holder.mView.sourceTitleAndDate.text = itm.sourceAndDateText()
|
||||||
|
|
||||||
if (itm.getThumbnail(c).isEmpty()) {
|
if (itm.getThumbnail(c).isEmpty()) {
|
||||||
val sizeInInt = 46
|
val sizeInInt = 46
|
||||||
val sizeInDp = TypedValue.applyDimension(
|
val sizeInDp = TypedValue.applyDimension(
|
||||||
TypedValue.COMPLEX_UNIT_DIP, sizeInInt.toFloat(), c.resources
|
TypedValue.COMPLEX_UNIT_DIP, sizeInInt.toFloat(), c.resources
|
||||||
.displayMetrics).toInt()
|
.displayMetrics).toInt()
|
||||||
|
|
||||||
val marginInInt = 16
|
val marginInInt = 16
|
||||||
val marginInDp = TypedValue.applyDimension(
|
val marginInDp = TypedValue.applyDimension(
|
||||||
TypedValue.COMPLEX_UNIT_DIP, marginInInt.toFloat(), c.resources
|
TypedValue.COMPLEX_UNIT_DIP, marginInInt.toFloat(), c.resources
|
||||||
.displayMetrics).toInt()
|
.displayMetrics).toInt()
|
||||||
|
|
||||||
val params = holder.sourceImage.layoutParams as ViewGroup.MarginLayoutParams
|
val params = holder.mView.itemImage.layoutParams as ViewGroup.MarginLayoutParams
|
||||||
params.height = sizeInDp
|
params.height = sizeInDp
|
||||||
params.width = sizeInDp
|
params.width = sizeInDp
|
||||||
params.setMargins(marginInDp, 0, 0, 0)
|
params.setMargins(marginInDp, 0, 0, 0)
|
||||||
holder.sourceImage.layoutParams = params
|
holder.mView.itemImage.layoutParams = params
|
||||||
|
|
||||||
if (itm.getIcon(c).isEmpty()) {
|
if (itm.getIcon(c).isEmpty()) {
|
||||||
val color = generator.getColor(itm.sourcetitle)
|
val color = generator.getColor(itm.sourcetitle)
|
||||||
@ -96,17 +93,17 @@ class ItemListAdapter(private val app: Activity,
|
|||||||
val builder = TextDrawable.builder().round()
|
val builder = TextDrawable.builder().round()
|
||||||
|
|
||||||
val drawable = builder.build(textDrawable.toString(), color)
|
val drawable = builder.build(textDrawable.toString(), color)
|
||||||
holder.sourceImage.setImageDrawable(drawable)
|
holder.mView.itemImage.setImageDrawable(drawable)
|
||||||
} else {
|
} else {
|
||||||
c.circularBitmapDrawable(itm.getIcon(c), holder.sourceImage)
|
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.itemImage)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
c.bitmapCenterCrop(itm.getThumbnail(c), holder.sourceImage)
|
c.bitmapCenterCrop(itm.getThumbnail(c), holder.mView.itemImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bars[position]) holder.actionBar.visibility = View.VISIBLE else holder.actionBar.visibility = View.GONE
|
if (bars[position]) holder.mView.actionBar.visibility = View.VISIBLE else holder.mView.actionBar.visibility = View.GONE
|
||||||
|
|
||||||
holder.saveBtn.isLiked = itm.starred
|
holder.mView.favButton.isLiked = itm.starred
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
@ -147,13 +144,13 @@ class ItemListAdapter(private val app: Activity,
|
|||||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
||||||
if (!response.succeeded() && debugReadingItems) {
|
if (!response.succeeded() && debugReadingItems) {
|
||||||
val message =
|
val message =
|
||||||
"message: ${response.message()} " +
|
"message: ${response.message()} " +
|
||||||
"response isSuccess: ${response.isSuccessful} " +
|
"response isSuccess: ${response.isSuccessful} " +
|
||||||
"response code: ${response.code()} " +
|
"response code: ${response.code()} " +
|
||||||
"response message: ${response.message()} " +
|
"response message: ${response.message()} " +
|
||||||
"response errorBody: ${response.errorBody()?.string()} " +
|
"response errorBody: ${response.errorBody()?.string()} " +
|
||||||
"body success: ${response.body()?.success} " +
|
"body success: ${response.body()?.success} " +
|
||||||
"body isSuccess: ${response.body()?.isSuccess}"
|
"body isSuccess: ${response.body()?.isSuccess}"
|
||||||
Crashlytics.setUserIdentifier(userIdentifier)
|
Crashlytics.setUserIdentifier(userIdentifier)
|
||||||
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
||||||
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
||||||
@ -179,13 +176,6 @@ class ItemListAdapter(private val app: Activity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
|
inner class ViewHolder(val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
|
||||||
lateinit var saveBtn: LikeButton
|
|
||||||
lateinit var browserBtn: ImageButton
|
|
||||||
lateinit var shareBtn: ImageButton
|
|
||||||
lateinit var actionBar: RelativeLayout
|
|
||||||
lateinit var sourceImage: ImageView
|
|
||||||
lateinit var title: TextView
|
|
||||||
lateinit var sourceTitleAndDate: TextView
|
|
||||||
|
|
||||||
init {
|
init {
|
||||||
handleClickListeners()
|
handleClickListeners()
|
||||||
@ -193,23 +183,15 @@ class ItemListAdapter(private val app: Activity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleClickListeners() {
|
private fun handleClickListeners() {
|
||||||
actionBar = mView.findViewById(R.id.actionBar)
|
|
||||||
sourceImage = mView.findViewById(R.id.itemImage)
|
|
||||||
title = mView.findViewById(R.id.title)
|
|
||||||
sourceTitleAndDate = mView.findViewById(R.id.sourceTitleAndDate)
|
|
||||||
saveBtn = mView.findViewById(R.id.favButton)
|
|
||||||
shareBtn = mView.findViewById(R.id.shareBtn)
|
|
||||||
browserBtn = mView.findViewById(R.id.browserBtn)
|
|
||||||
|
|
||||||
|
mView.favButton.setOnLikeListener(object : OnLikeListener {
|
||||||
saveBtn.setOnLikeListener(object : OnLikeListener {
|
|
||||||
override fun liked(likeButton: LikeButton) {
|
override fun liked(likeButton: LikeButton) {
|
||||||
val (id) = items[adapterPosition]
|
val (id) = items[adapterPosition]
|
||||||
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
||||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
saveBtn.isLiked = false
|
mView.favButton.isLiked = false
|
||||||
Toast.makeText(c, R.string.cant_mark_favortie, Toast.LENGTH_SHORT).show()
|
Toast.makeText(c, R.string.cant_mark_favortie, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -221,18 +203,18 @@ class ItemListAdapter(private val app: Activity,
|
|||||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
||||||
|
|
||||||
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
override fun onFailure(call: Call<SuccessResponse>, t: Throwable) {
|
||||||
saveBtn.isLiked = true
|
mView.favButton.isLiked = true
|
||||||
Toast.makeText(c, R.string.cant_unmark_favortie, Toast.LENGTH_SHORT).show()
|
Toast.makeText(c, R.string.cant_unmark_favortie, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
shareBtn.setOnClickListener {
|
mView.shareBtn.setOnClickListener {
|
||||||
c.shareLink(items[adapterPosition].getLinkDecoded())
|
c.shareLink(items[adapterPosition].getLinkDecoded())
|
||||||
}
|
}
|
||||||
|
|
||||||
browserBtn.setOnClickListener {
|
mView.browserBtn.setOnClickListener {
|
||||||
c.openInBrowserAsNewTask(items[adapterPosition])
|
c.openInBrowserAsNewTask(items[adapterPosition])
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -247,10 +229,14 @@ class ItemListAdapter(private val app: Activity,
|
|||||||
if (!clickBehavior) {
|
if (!clickBehavior) {
|
||||||
mView.setOnClickListener {
|
mView.setOnClickListener {
|
||||||
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
|
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
|
||||||
customTabsIntent,
|
items[adapterPosition].content,
|
||||||
internalBrowser,
|
items[adapterPosition].getThumbnail(c),
|
||||||
articleViewer,
|
items[adapterPosition].title,
|
||||||
app)
|
items[adapterPosition].sourceAndDateText(),
|
||||||
|
customTabsIntent,
|
||||||
|
internalBrowser,
|
||||||
|
articleViewer,
|
||||||
|
app)
|
||||||
}
|
}
|
||||||
mView.setOnLongClickListener {
|
mView.setOnLongClickListener {
|
||||||
actionBarShowHide()
|
actionBarShowHide()
|
||||||
@ -260,10 +246,14 @@ class ItemListAdapter(private val app: Activity,
|
|||||||
mView.setOnClickListener { actionBarShowHide() }
|
mView.setOnClickListener { actionBarShowHide() }
|
||||||
mView.setOnLongClickListener {
|
mView.setOnLongClickListener {
|
||||||
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
|
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
|
||||||
customTabsIntent,
|
items[adapterPosition].content,
|
||||||
internalBrowser,
|
items[adapterPosition].getThumbnail(c),
|
||||||
articleViewer,
|
items[adapterPosition].title,
|
||||||
app)
|
items[adapterPosition].sourceAndDateText(),
|
||||||
|
customTabsIntent,
|
||||||
|
internalBrowser,
|
||||||
|
articleViewer,
|
||||||
|
app)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -271,7 +261,11 @@ class ItemListAdapter(private val app: Activity,
|
|||||||
|
|
||||||
private fun actionBarShowHide() {
|
private fun actionBarShowHide() {
|
||||||
bars[adapterPosition] = true
|
bars[adapterPosition] = true
|
||||||
if (actionBar.visibility == View.GONE) actionBar.visibility = View.VISIBLE else actionBar.visibility = View.GONE
|
if (mView.actionBar.visibility == View.GONE) {
|
||||||
|
mView.actionBar.visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
mView.actionBar.visibility = View.GONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@ import com.amulyakhare.textdrawable.util.ColorGenerator
|
|||||||
import retrofit2.Call
|
import retrofit2.Call
|
||||||
import retrofit2.Callback
|
import retrofit2.Callback
|
||||||
import retrofit2.Response
|
import retrofit2.Response
|
||||||
|
import kotlinx.android.synthetic.main.source_list_item.view.*
|
||||||
|
|
||||||
|
|
||||||
class SourcesListAdapter(private val app: Activity,
|
class SourcesListAdapter(private val app: Activity,
|
||||||
@ -41,13 +42,13 @@ class SourcesListAdapter(private val app: Activity,
|
|||||||
val color = generator.getColor(itm.title)
|
val color = generator.getColor(itm.title)
|
||||||
|
|
||||||
val drawable =
|
val drawable =
|
||||||
TextDrawable
|
TextDrawable
|
||||||
.builder()
|
.builder()
|
||||||
.round()
|
.round()
|
||||||
.build(itm.title.toTextDrawableString(), color)
|
.build(itm.title.toTextDrawableString(), color)
|
||||||
holder.sourceImage.setImageDrawable(drawable)
|
holder.itemImage.setImageDrawable(drawable)
|
||||||
} else {
|
} else {
|
||||||
c.circularBitmapDrawable(itm.getIcon(c), holder.sourceImage)
|
c.circularBitmapDrawable(itm.getIcon(c), holder.itemImage)
|
||||||
}
|
}
|
||||||
|
|
||||||
holder.sourceTitle.text = itm.title
|
holder.sourceTitle.text = itm.title
|
||||||
@ -58,17 +59,14 @@ class SourcesListAdapter(private val app: Activity,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inner class ViewHolder(internal val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
|
inner class ViewHolder(internal val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
|
||||||
lateinit var sourceImage: ImageView
|
lateinit var itemImage: ImageView
|
||||||
lateinit var sourceTitle: TextView
|
lateinit var sourceTitle: TextView
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|
||||||
handleClickListeners()
|
handleClickListeners()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleClickListeners() {
|
private fun handleClickListeners() {
|
||||||
sourceImage = mView.findViewById(R.id.itemImage)
|
|
||||||
sourceTitle = mView.findViewById(R.id.sourceTitle)
|
|
||||||
|
|
||||||
val deleteBtn: Button = mView.findViewById(R.id.deleteBtn)
|
val deleteBtn: Button = mView.findViewById(R.id.deleteBtn)
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ data class Sources(@SerializedName("id") val id: String,
|
|||||||
data class Item(@SerializedName("id") val id: String,
|
data class Item(@SerializedName("id") val id: String,
|
||||||
@SerializedName("datetime") val datetime: String,
|
@SerializedName("datetime") val datetime: String,
|
||||||
@SerializedName("title") val title: String,
|
@SerializedName("title") val title: String,
|
||||||
|
@SerializedName("content") val content: String,
|
||||||
@SerializedName("unread") val unread: Boolean,
|
@SerializedName("unread") val unread: Boolean,
|
||||||
@SerializedName("starred") val starred: Boolean,
|
@SerializedName("starred") val starred: Boolean,
|
||||||
@SerializedName("thumbnail") val thumbnail: String,
|
@SerializedName("thumbnail") val thumbnail: String,
|
||||||
@ -72,15 +73,16 @@ data class Item(@SerializedName("id") val id: String,
|
|||||||
}
|
}
|
||||||
|
|
||||||
constructor(source: Parcel) : this(
|
constructor(source: Parcel) : this(
|
||||||
id = source.readString(),
|
id = source.readString(),
|
||||||
datetime = source.readString(),
|
datetime = source.readString(),
|
||||||
title = source.readString(),
|
title = source.readString(),
|
||||||
unread = 0.toByte() != source.readByte(),
|
content = source.readString(),
|
||||||
starred = 0.toByte() != source.readByte(),
|
unread = 0.toByte() != source.readByte(),
|
||||||
thumbnail = source.readString(),
|
starred = 0.toByte() != source.readByte(),
|
||||||
icon = source.readString(),
|
thumbnail = source.readString(),
|
||||||
link = source.readString(),
|
icon = source.readString(),
|
||||||
sourcetitle = source.readString()
|
link = source.readString(),
|
||||||
|
sourcetitle = source.readString()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun describeContents() = 0
|
override fun describeContents() = 0
|
||||||
@ -89,6 +91,7 @@ data class Item(@SerializedName("id") val id: String,
|
|||||||
dest.writeString(id)
|
dest.writeString(id)
|
||||||
dest.writeString(datetime)
|
dest.writeString(datetime)
|
||||||
dest.writeString(title)
|
dest.writeString(title)
|
||||||
|
dest.writeString(content)
|
||||||
dest.writeByte((if (unread) 1 else 0))
|
dest.writeByte((if (unread) 1 else 0))
|
||||||
dest.writeByte((if (starred) 1 else 0))
|
dest.writeByte((if (starred) 1 else 0))
|
||||||
dest.writeString(thumbnail)
|
dest.writeString(thumbnail)
|
||||||
|
@ -51,19 +51,28 @@ fun Context.buildCustomTabsIntent(): CustomTabsIntent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Context.openItemUrlInternally(linkDecoded: String,
|
fun Context.openItemUrlInternally(linkDecoded: String,
|
||||||
|
content: String,
|
||||||
|
image: String,
|
||||||
|
title: String,
|
||||||
|
source: String,
|
||||||
customTabsIntent: CustomTabsIntent,
|
customTabsIntent: CustomTabsIntent,
|
||||||
articleViewer: Boolean,
|
articleViewer: Boolean,
|
||||||
app: Activity) {
|
app: Activity) {
|
||||||
if (articleViewer) {
|
if (articleViewer) {
|
||||||
val intent = Intent(this, ReaderActivity::class.java)
|
val intent = Intent(this, ReaderActivity::class.java)
|
||||||
|
|
||||||
DragDismissIntentBuilder(this)
|
/*DragDismissIntentBuilder(this)
|
||||||
.setFullscreenOnTablets(true) // defaults to false, tablets will have padding on each side
|
.setFullscreenOnTablets(true) // defaults to false, tablets will have padding on each side
|
||||||
.setDragElasticity(DragDismissIntentBuilder.DragElasticity.NORMAL) // Larger elasticities will make it easier to dismiss.
|
.setDragElasticity(DragDismissIntentBuilder.DragElasticity.NORMAL) // Larger elasticities will make it easier to dismiss.
|
||||||
.setDrawUnderStatusBar(true)
|
.setDrawUnderStatusBar(true)
|
||||||
.build(intent)
|
.build(intent)*/
|
||||||
|
|
||||||
|
|
||||||
intent.putExtra("url", linkDecoded)
|
intent.putExtra("url", linkDecoded)
|
||||||
|
intent.putExtra("content", content)
|
||||||
|
intent.putExtra("title", title)
|
||||||
|
intent.putExtra("image", image)
|
||||||
|
intent.putExtra("source", source)
|
||||||
app.startActivity(intent)
|
app.startActivity(intent)
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
@ -80,6 +89,10 @@ fun Context.openItemUrlInternally(linkDecoded: String,
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun Context.openItemUrl(linkDecoded: String,
|
fun Context.openItemUrl(linkDecoded: String,
|
||||||
|
content: String,
|
||||||
|
image: String,
|
||||||
|
title: String,
|
||||||
|
source: String,
|
||||||
customTabsIntent: CustomTabsIntent,
|
customTabsIntent: CustomTabsIntent,
|
||||||
internalBrowser: Boolean,
|
internalBrowser: Boolean,
|
||||||
articleViewer: Boolean,
|
articleViewer: Boolean,
|
||||||
@ -91,7 +104,7 @@ fun Context.openItemUrl(linkDecoded: String,
|
|||||||
if (!internalBrowser) {
|
if (!internalBrowser) {
|
||||||
openInBrowser(linkDecoded, app)
|
openInBrowser(linkDecoded, app)
|
||||||
} else {
|
} else {
|
||||||
this.openItemUrlInternally(linkDecoded, customTabsIntent, articleViewer, app)
|
this.openItemUrlInternally(linkDecoded, content, image, title, source, customTabsIntent, articleViewer, app)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -103,7 +116,7 @@ private fun openInBrowser(linkDecoded: String, app: Activity) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun String.isUrlValid(): Boolean =
|
fun String.isUrlValid(): Boolean =
|
||||||
HttpUrl.parse(this) != null && Patterns.WEB_URL.matcher(this).matches()
|
HttpUrl.parse(this) != null && Patterns.WEB_URL.matcher(this).matches()
|
||||||
|
|
||||||
fun String.isBaseUrlValid(): Boolean {
|
fun String.isBaseUrlValid(): Boolean {
|
||||||
val baseUrl = HttpUrl.parse(this)
|
val baseUrl = HttpUrl.parse(this)
|
||||||
|
@ -0,0 +1,33 @@
|
|||||||
|
package apps.amine.bou.readerforselfoss.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.support.design.widget.CoordinatorLayout
|
||||||
|
import android.support.design.widget.FloatingActionButton
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.View
|
||||||
|
|
||||||
|
class ScrollAwareFABBehavior(context: Context, attrs: AttributeSet) : CoordinatorLayout.Behavior<FloatingActionButton>() {
|
||||||
|
|
||||||
|
override fun onStartNestedScroll(coordinatorLayout: CoordinatorLayout, child: FloatingActionButton,
|
||||||
|
directTargetChild: View, target: View, nestedScrollAxes: Int): Boolean {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNestedScroll(coordinatorLayout: CoordinatorLayout,
|
||||||
|
child: FloatingActionButton,
|
||||||
|
target: View, dxConsumed: Int, dyConsumed: Int,
|
||||||
|
dxUnconsumed: Int, dyUnconsumed: Int) {
|
||||||
|
super.onNestedScroll(coordinatorLayout, child, target, dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed)
|
||||||
|
if (dyConsumed > 0 && child.visibility == View.VISIBLE) {
|
||||||
|
child.hide(object : FloatingActionButton.OnVisibilityChangedListener() {
|
||||||
|
override fun onHidden(fab: FloatingActionButton?) {
|
||||||
|
super.onHidden(fab)
|
||||||
|
fab!!.visibility = View.INVISIBLE
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
} else if (dyConsumed < 0 && child.visibility != View.VISIBLE) {
|
||||||
|
child.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
BIN
app/src/main/res/drawable-hdpi/ic_add.png
Normal file
After Width: | Height: | Size: 134 B |
Before Width: | Height: | Size: 124 B |
BIN
app/src/main/res/drawable-hdpi/ic_chrome_reader_mode.png
Normal file
After Width: | Height: | Size: 216 B |
BIN
app/src/main/res/drawable-hdpi/ic_open_in_browser.png
Normal file
After Width: | Height: | Size: 204 B |
BIN
app/src/main/res/drawable-mdpi/ic_add.png
Normal file
After Width: | Height: | Size: 116 B |
Before Width: | Height: | Size: 86 B |
BIN
app/src/main/res/drawable-mdpi/ic_chrome_reader_mode.png
Normal file
After Width: | Height: | Size: 136 B |
BIN
app/src/main/res/drawable-mdpi/ic_open_in_browser.png
Normal file
After Width: | Height: | Size: 157 B |
BIN
app/src/main/res/drawable-xhdpi/ic_add.png
Normal file
After Width: | Height: | Size: 168 B |
Before Width: | Height: | Size: 108 B |
BIN
app/src/main/res/drawable-xhdpi/ic_chrome_reader_mode.png
Normal file
After Width: | Height: | Size: 171 B |
BIN
app/src/main/res/drawable-xhdpi/ic_open_in_browser.png
Normal file
After Width: | Height: | Size: 230 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_add.png
Normal file
After Width: | Height: | Size: 242 B |
Before Width: | Height: | Size: 114 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_chrome_reader_mode.png
Normal file
After Width: | Height: | Size: 263 B |
BIN
app/src/main/res/drawable-xxhdpi/ic_open_in_browser.png
Normal file
After Width: | Height: | Size: 318 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_add.png
Normal file
After Width: | Height: | Size: 500 B |
Before Width: | Height: | Size: 119 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_chrome_reader_mode.png
Normal file
After Width: | Height: | Size: 296 B |
BIN
app/src/main/res/drawable-xxxhdpi/ic_open_in_browser.png
Normal file
After Width: | Height: | Size: 408 B |
@ -9,7 +9,7 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<com.github.stkent.amplify.prompt.DefaultLayoutPromptView
|
<com.github.stkent.amplify.prompt.DefaultLayoutPromptView
|
||||||
android:id="@+id/prompt_view"
|
android:id="@+id/promptView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
app:prompt_view_user_opinion_question_title="@string/rating_prompt_title"
|
app:prompt_view_user_opinion_question_title="@string/rating_prompt_title"
|
||||||
@ -34,7 +34,7 @@
|
|||||||
android:id="@+id/coordLayout"
|
android:id="@+id/coordLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_below="@id/prompt_view">
|
android:layout_below="@id/promptView">
|
||||||
|
|
||||||
<android.support.design.widget.CoordinatorLayout
|
<android.support.design.widget.CoordinatorLayout
|
||||||
android:id="@+id/intern_coordLayout"
|
android:id="@+id/intern_coordLayout"
|
||||||
@ -51,7 +51,7 @@
|
|||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<android.support.v7.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolBar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
app:theme="@style/ToolBarStyle"
|
app:theme="@style/ToolBarStyle"
|
||||||
@ -89,7 +89,7 @@
|
|||||||
android:background="@color/transparent"
|
android:background="@color/transparent"
|
||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
<android.support.v7.widget.RecyclerView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/my_recycler_view"
|
android:id="@+id/recyclerView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/transparent"
|
android:background="@color/transparent"
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
android:paddingTop="@dimen/activity_vertical_margin">
|
android:paddingTop="@dimen/activity_vertical_margin">
|
||||||
<!-- Login progress -->
|
<!-- Login progress -->
|
||||||
<ProgressBar
|
<ProgressBar
|
||||||
android:id="@+id/login_progress"
|
android:id="@+id/loginProgress"
|
||||||
style="?android:attr/progressBarStyleLarge"
|
style="?android:attr/progressBarStyleLarge"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@ -36,7 +36,7 @@
|
|||||||
android:visibility="gone"/>
|
android:visibility="gone"/>
|
||||||
|
|
||||||
<ScrollView
|
<ScrollView
|
||||||
android:id="@+id/login_form"
|
android:id="@+id/loginForm"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
@ -52,14 +52,13 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/url"
|
android:id="@+id/urlView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/prompt_url"
|
android:hint="@string/prompt_url"
|
||||||
android:imeOptions="actionUnspecified"
|
android:imeOptions="actionUnspecified"
|
||||||
android:inputType="textUri"
|
android:inputType="textUri"
|
||||||
android:maxLines="1"
|
android:maxLines="1" />
|
||||||
/>
|
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
@ -77,13 +76,12 @@
|
|||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<AutoCompleteTextView
|
<AutoCompleteTextView
|
||||||
android:id="@+id/login"
|
android:id="@+id/loginView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/prompt_login"
|
android:hint="@string/prompt_login"
|
||||||
android:inputType="text"
|
android:inputType="text"
|
||||||
android:maxLines="1"
|
android:maxLines="1" />
|
||||||
/>
|
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
@ -94,13 +92,12 @@
|
|||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/password"
|
android:id="@+id/passwordView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/prompt_password"
|
android:hint="@string/prompt_password"
|
||||||
android:inputType="textPassword"
|
android:inputType="textPassword"
|
||||||
android:maxLines="1"
|
android:maxLines="1" />
|
||||||
/>
|
|
||||||
|
|
||||||
</android.support.design.widget.TextInputLayout>
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
@ -118,7 +115,7 @@
|
|||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/httpLogin"
|
android:id="@+id/httpLoginView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:hint="@string/prompt_http_login" />
|
android:hint="@string/prompt_http_login" />
|
||||||
@ -131,11 +128,11 @@
|
|||||||
android:visibility="gone">
|
android:visibility="gone">
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/httpPassword"
|
android:id="@+id/httpPasswordView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:inputType="textPassword"
|
android:hint="@string/prompt_http_password"
|
||||||
android:hint="@string/prompt_http_password" />
|
android:inputType="textPassword" />
|
||||||
</android.support.design.widget.TextInputLayout>
|
</android.support.design.widget.TextInputLayout>
|
||||||
|
|
||||||
<Switch
|
<Switch
|
||||||
@ -153,7 +150,7 @@
|
|||||||
android:visibility="gone" />
|
android:visibility="gone" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/email_sign_in_button"
|
android:id="@+id/signInButton"
|
||||||
style="?android:textAppearanceSmall"
|
style="?android:textAppearanceSmall"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
@ -1,126 +1,148 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.design.widget.CoordinatorLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
tools:context="apps.amine.bou.readerforselfoss.ReaderActivity"
|
|
||||||
android:background="?android:attr/windowBackground">
|
|
||||||
|
|
||||||
<ImageView
|
<android.support.v4.widget.NestedScrollView
|
||||||
android:id="@+id/imageView"
|
android:id="@+id/nestedScrollView"
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="200dp"
|
|
||||||
android:scaleType="centerCrop"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/source"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/imageView" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/title"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="6dp"
|
|
||||||
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
|
|
||||||
android:textStyle="bold"
|
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/source" />
|
|
||||||
|
|
||||||
<org.sufficientlysecure.htmltextview.HtmlTextView
|
|
||||||
android:id="@+id/content"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginEnd="16dp"
|
|
||||||
android:layout_marginLeft="16dp"
|
|
||||||
android:layout_marginRight="16dp"
|
|
||||||
android:layout_marginStart="16dp"
|
|
||||||
android:layout_marginTop="24dp"
|
|
||||||
android:paddingBottom="48dp"
|
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
|
||||||
app:layout_constraintLeft_toLeftOf="parent"
|
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/title"
|
|
||||||
tools:text="Some text @android:string/fingerprint_icon_content_description" />
|
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="match_parent">
|
||||||
android:layout_marginBottom="0dp"
|
|
||||||
android:layout_marginEnd="0dp"
|
<android.support.constraint.ConstraintLayout
|
||||||
android:layout_marginRight="16dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_height="match_parent">
|
||||||
android:background="#BBBBBB"
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/imageView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/source"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||||
|
android:textSize="12sp"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/imageView" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/titleView"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="6dp"
|
||||||
|
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
|
||||||
|
android:textStyle="bold"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/source" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:paddingBottom="48dp"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/titleView"
|
||||||
|
android:textColorLink="?attr/colorAccent"/>
|
||||||
|
|
||||||
|
<!--<org.sufficientlysecure.htmltextview.HtmlTextView
|
||||||
|
android:id="@+id/content"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginEnd="16dp"
|
||||||
|
android:layout_marginLeft="16dp"
|
||||||
|
android:layout_marginRight="16dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:paddingBottom="48dp"
|
||||||
|
app:layout_constraintHorizontal_bias="0.0"
|
||||||
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
|
app:layout_constraintRight_toRightOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/titleView" />-->
|
||||||
|
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
|
</android.support.v4.widget.NestedScrollView>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintHorizontal_bias="0.0"
|
app:layout_constraintLeft_toLeftOf="parent"
|
||||||
app:layout_constraintRight_toRightOf="parent"
|
android:layout_gravity="end|bottom|right">
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/content"
|
|
||||||
app:layout_constraintVertical_bias="1.0">
|
|
||||||
|
|
||||||
<ImageButton
|
<com.github.rubensousa.floatingtoolbar.FloatingToolbar
|
||||||
android:id="@+id/browserBtn"
|
android:id="@+id/floatingToolbar"
|
||||||
android:layout_width="35dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:layout_centerVertical="true"
|
android:layout_gravity="bottom"
|
||||||
|
app:floatingItemBackground="?attr/colorAccent"
|
||||||
|
app:floatingMenu="@menu/reader_toolbar" />
|
||||||
|
|
||||||
|
<android.support.design.widget.FloatingActionButton
|
||||||
|
android:id="@+id/fab"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_alignParentEnd="true"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_gravity="end|bottom|right"
|
||||||
|
android:layout_marginBottom="16dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginRight="16dp"
|
android:layout_marginRight="16dp"
|
||||||
android:layout_toLeftOf="@+id/shareBtn"
|
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
android:layout_toStartOf="@+id/shareBtn"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:adjustViewBounds="true"
|
android:src="@drawable/ic_add"
|
||||||
android:background="@android:color/transparent"
|
app:backgroundTint="?attr/colorAccent"
|
||||||
android:elevation="5dp"
|
app:fabSize="mini"
|
||||||
android:padding="4dp"
|
app:rippleColor="?attr/colorAccentDark" />
|
||||||
android:scaleType="centerCrop"
|
</FrameLayout>
|
||||||
android:src="@drawable/ic_open_in_browser_black_24dp"
|
|
||||||
android:tint="@android:color/black"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toStartOf="@+id/shareBtn"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
<ImageButton
|
<FrameLayout
|
||||||
android:id="@+id/shareBtn"
|
android:id="@+id/progressBar"
|
||||||
android:layout_width="35dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="35dp"
|
android:layout_height="match_parent"
|
||||||
android:adjustViewBounds="true"
|
android:visibility="gone"
|
||||||
android:background="@android:color/transparent"
|
android:animateLayoutChanges="true"
|
||||||
android:elevation="5dp"
|
android:alpha="0.8"
|
||||||
android:padding="4dp"
|
android:background="@color/black"
|
||||||
android:scaleType="centerCrop"
|
android:clickable="false">
|
||||||
android:src="@drawable/ic_share_black_24dp"
|
|
||||||
android:tint="@android:color/black"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintHorizontal_bias="0.5"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/browserBtn"
|
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
<ProgressBar
|
||||||
|
style="?android:attr/progressBarStyleLarge"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"
|
||||||
|
android:progressTint="?attr/colorAccent" />
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<RelativeLayout
|
<android.support.design.widget.CoordinatorLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
@ -22,23 +22,20 @@
|
|||||||
</android.support.design.widget.AppBarLayout>
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/activity_sources"
|
android:id="@+id/recyclerView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:scrollbars="vertical"
|
android:scrollbars="vertical"
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||||
</android.support.v7.widget.RecyclerView>
|
</android.support.v7.widget.RecyclerView>
|
||||||
|
|
||||||
<com.melnykov.fab.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fab"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="end|bottom|right"
|
android:layout_gravity="end|bottom|right"
|
||||||
android:src="@drawable/ic_add_black_24dp"
|
android:src="@drawable/ic_add"
|
||||||
android:tint="?android:textColorPrimary"
|
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:paddingBottom="@dimen/activity_vertical_margin"
|
||||||
android:paddingTop="@dimen/activity_vertical_margin"
|
android:paddingTop="@dimen/activity_vertical_margin"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
@ -46,5 +43,6 @@
|
|||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_marginBottom="16dp"
|
android:layout_marginBottom="16dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:layout_marginRight="16dp"/>
|
android:layout_marginRight="16dp"
|
||||||
</RelativeLayout>
|
app:layout_behavior="apps.amine.bou.readerforselfoss.utils.ScrollAwareFABBehavior" />
|
||||||
|
</android.support.design.widget.CoordinatorLayout>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
<item
|
<item
|
||||||
android:id="@+id/loging_debug"
|
android:id="@+id/login_debug"
|
||||||
android:checkable="true"
|
android:checkable="true"
|
||||||
android:checked="false"
|
android:checked="false"
|
||||||
android:icon="@drawable/ic_bug_report"
|
android:icon="@drawable/ic_bug_report"
|
||||||
|
25
app/src/main/res/menu/reader_toolbar.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/more_action"
|
||||||
|
android:icon="@drawable/ic_chrome_reader_mode"
|
||||||
|
android:title="@string/reader_action_more"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/open_action"
|
||||||
|
android:icon="@drawable/ic_open_in_browser"
|
||||||
|
android:iconTint="@color/white"
|
||||||
|
android:title="@string/reader_action_open"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/share_action"
|
||||||
|
android:icon="@drawable/ic_share_white_24dp"
|
||||||
|
android:title="@string/reader_action_share"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
|
|
||||||
|
</menu>
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">L’url de l’élément n’est pas valide. En attendant la résolution du problème, le lien ne s\'ouvrira pas.</string>
|
<string name="cant_open_invalid_url">L’url de l’élément n’est pas valide. En attendant la résolution du problème, le lien ne s\'ouvrira pas.</string>
|
||||||
<string name="drawer_report_bug">Signaler un bug</string>
|
<string name="drawer_report_bug">Signaler un bug</string>
|
||||||
<string name="items_number_should_be_number">Le nombre d\'articles doit être un entier.</string>
|
<string name="items_number_should_be_number">Le nombre d\'articles doit être un entier.</string>
|
||||||
|
<string name="reader_action_more">Lire plus</string>
|
||||||
|
<string name="reader_action_open">Ouvrir</string>
|
||||||
|
<string name="reader_action_share">Partager</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">A url está inválida. Estou tentando resolver esse problema para que o aplicativo não encerre.</string>
|
<string name="cant_open_invalid_url">A url está inválida. Estou tentando resolver esse problema para que o aplicativo não encerre.</string>
|
||||||
<string name="drawer_report_bug">Reportar erro</string>
|
<string name="drawer_report_bug">Reportar erro</string>
|
||||||
<string name="items_number_should_be_number">O número dos itens deve ser um número inteiro.</string>
|
<string name="items_number_should_be_number">O número dos itens deve ser um número inteiro.</string>
|
||||||
|
<string name="reader_action_more">Leia mais</string>
|
||||||
|
<string name="reader_action_open">Abrir no navegador</string>
|
||||||
|
<string name="reader_action_share">Compartilhar</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -155,4 +155,7 @@
|
|||||||
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
<string name="cant_open_invalid_url">The item url is invalid. I\'m looking into solving this issue so the app won\'t crash.</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -158,4 +158,7 @@
|
|||||||
<string name="report_github_repo" translatable="false">ReaderforSelfoss</string>
|
<string name="report_github_repo" translatable="false">ReaderforSelfoss</string>
|
||||||
<string name="drawer_report_bug">Report a bug</string>
|
<string name="drawer_report_bug">Report a bug</string>
|
||||||
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
<string name="items_number_should_be_number">The items number should be an integer.</string>
|
||||||
|
<string name="reader_action_more">Read more</string>
|
||||||
|
<string name="reader_action_open">Open in browser</string>
|
||||||
|
<string name="reader_action_share">Share</string>
|
||||||
</resources>
|
</resources>
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
android:key="loging_debug"
|
android:key="login_debug"
|
||||||
android:summaryOff="@string/login_debug_off"
|
android:summaryOff="@string/login_debug_off"
|
||||||
android:summaryOn="@string/login_debug_on"
|
android:summaryOn="@string/login_debug_on"
|
||||||
android:title="@string/login_debug_title" />
|
android:title="@string/login_debug_title" />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.1.51'
|
ext.kotlin_version = '1.1.60'
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
google()
|
google()
|
||||||
@ -10,12 +10,12 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.0.0'
|
classpath 'com.android.tools.build:gradle:3.0.1'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
classpath 'com.google.gms:google-services:3.1.0'
|
classpath 'com.google.gms:google-services:3.1.1'
|
||||||
|
|
||||||
// Not the official version https://stackoverflow.com/questions/46525040/sonarqube-android-not-working-for-gradle-3-0-0/46813528#46813528
|
// Not the official version https://stackoverflow.com/questions/46525040/sonarqube-android-not-working-for-gradle-3-0-0/46813528#46813528
|
||||||
classpath "com.github.Shusshu:sonar-scanner-gradle:feature~support-android-gradle-3-SNAPSHOT"
|
classpath "com.github.Shusshu:sonar-scanner-gradle:feature~support-android-gradle-3-SNAPSHOT"
|
||||||
|