Compare commits
37 Commits
Author | SHA1 | Date | |
---|---|---|---|
68098f4d84 | |||
080d52893e | |||
b02334a8d4 | |||
27118add22 | |||
2a6f98a1e8 | |||
1f67f2fdee | |||
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.
|
||||
|
||||
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.
|
||||
|
||||
@ -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.
|
||||
* 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.
|
||||
* 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.
|
||||
* Always check your changes and discard the ones that are irrelevant to your feature or bugfix.
|
||||
* Have meaningful commit messages.
|
||||
|
58
CHANGELOG.md
@ -1,3 +1,61 @@
|
||||
**1.5.4.17**
|
||||
|
||||
- Fixed the last bug with infinite scroll.
|
||||
|
||||
**1.5.4.16**
|
||||
|
||||
- Fixing list view displaying issues.
|
||||
|
||||
- Endless scroll is not in beta anymore.
|
||||
|
||||
**1.5.4.15**
|
||||
|
||||
- Fixed an issue with the sources list.
|
||||
|
||||
**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**
|
||||
|
||||
- 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-extensions'
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url 'https://maven.fabric.io/public'
|
||||
@ -38,12 +40,12 @@ repositories {
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 26
|
||||
buildToolsVersion '26.0.2'
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion '27.0.0'
|
||||
defaultConfig {
|
||||
applicationId "apps.amine.bou.readerforselfoss"
|
||||
minSdkVersion 16
|
||||
targetSdkVersion 26
|
||||
targetSdkVersion 27
|
||||
versionCode versionCodeFromGit()
|
||||
versionName versionNameFromGit()
|
||||
|
||||
@ -107,13 +109,13 @@ dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
|
||||
|
||||
// Android Support
|
||||
compile 'com.android.support:appcompat-v7:26.1.0'
|
||||
compile 'com.android.support:design:26.1.0'
|
||||
compile 'com.android.support:recyclerview-v7:26.1.0'
|
||||
compile 'com.android.support:support-v4:26.1.0'
|
||||
compile 'com.android.support:support-vector-drawable:26.1.0'
|
||||
compile 'com.android.support:customtabs:26.1.0'
|
||||
compile 'com.android.support:cardview-v7:26.1.0'
|
||||
compile 'com.android.support:appcompat-v7:27.0.0'
|
||||
compile 'com.android.support:design:27.0.0'
|
||||
compile 'com.android.support:recyclerview-v7:27.0.0'
|
||||
compile 'com.android.support:support-v4:27.0.0'
|
||||
compile 'com.android.support:support-vector-drawable:27.0.0'
|
||||
compile 'com.android.support:customtabs:27.0.0'
|
||||
compile 'com.android.support:cardview-v7:27.0.0'
|
||||
compile 'com.android.support.constraint:constraint-layout:1.0.2'
|
||||
|
||||
// Firebase + crashlytics
|
||||
@ -131,7 +133,7 @@ dependencies {
|
||||
compile 'agency.tango.android:material-intro-screen:0.0.5'
|
||||
|
||||
// About
|
||||
compile('com.mikepenz:aboutlibraries:5.9.7@aar') {
|
||||
compile('com.mikepenz:aboutlibraries:6.0.0@aar') {
|
||||
transitive = true
|
||||
}
|
||||
|
||||
@ -143,7 +145,6 @@ dependencies {
|
||||
|
||||
// Material-ish things
|
||||
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.amulyakhare:com.amulyakhare.textdrawable:1.0.1'
|
||||
compile 'org.sufficientlysecure:html-textview:3.5'
|
||||
@ -159,9 +160,7 @@ dependencies {
|
||||
compile 'com.klinkerapps:drag-dismiss-activity:1.5.0'
|
||||
|
||||
// Drawer
|
||||
compile('com.mikepenz:materialdrawer:5.9.5@aar') {
|
||||
transitive = true
|
||||
}
|
||||
implementation 'co.zsmb:materialdrawer-kt:1.2.1'
|
||||
compile 'com.anupcowkur:reservoir:3.1.0'
|
||||
|
||||
// Themes
|
||||
@ -169,6 +168,8 @@ dependencies {
|
||||
|
||||
// Github issues reporter
|
||||
compile 'com.heinrichreimersoftware:android-issue-reporter:1.3.1'
|
||||
|
||||
compile 'com.github.rubensousa:floatingtoolbar:1.5.1'
|
||||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
|
@ -32,18 +32,18 @@ class LoginActivityEspressoTest {
|
||||
@Rule @JvmField
|
||||
val rule = ActivityTestRule(LoginActivity::class.java, true, false)
|
||||
|
||||
lateinit var context: Context
|
||||
lateinit var url: String
|
||||
lateinit var username: String
|
||||
lateinit var password: String
|
||||
private lateinit var context: Context
|
||||
private lateinit var url: String
|
||||
private lateinit var username: String
|
||||
private lateinit var password: String
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
val editor =
|
||||
context
|
||||
.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
context
|
||||
.getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
|
||||
.edit()
|
||||
editor.clear()
|
||||
editor.commit()
|
||||
|
||||
@ -77,12 +77,12 @@ class LoginActivityEspressoTest {
|
||||
fun wrongLoginUrl() {
|
||||
rule.launchActivity(Intent())
|
||||
|
||||
onView(withId(R.id.login_progress))
|
||||
.check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)))
|
||||
onView(withId(R.id.loginProgress))
|
||||
.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()))
|
||||
}
|
||||
@ -94,24 +94,24 @@ class LoginActivityEspressoTest {
|
||||
|
||||
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.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.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.email_sign_in_button)).perform(click())
|
||||
onView(withId(R.id.signInButton)).perform(click())
|
||||
|
||||
onView(withId(R.id.passwordLayout)).check(
|
||||
matches(
|
||||
isHintOrErrorEnabled())
|
||||
matches(
|
||||
isHintOrErrorEnabled())
|
||||
)
|
||||
|
||||
}
|
||||
@ -121,15 +121,15 @@ class LoginActivityEspressoTest {
|
||||
|
||||
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.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.loginLayout)).check(matches(isHintOrErrorEnabled()))
|
||||
@ -142,15 +142,15 @@ class LoginActivityEspressoTest {
|
||||
|
||||
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.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))
|
||||
|
||||
|
@ -65,8 +65,7 @@
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ReaderActivity"
|
||||
android:theme="@style/DragDismissTheme">
|
||||
android:name=".ReaderActivity">
|
||||
</activity>
|
||||
|
||||
<meta-data
|
||||
|
@ -5,11 +5,9 @@ import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.support.constraint.ConstraintLayout
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.view.View
|
||||
import android.widget.AdapterView
|
||||
import android.widget.ArrayAdapter
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import android.widget.ProgressBar
|
||||
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.isBaseUrlValid
|
||||
import com.ftinc.scoop.Scoop
|
||||
import kotlinx.android.synthetic.main.activity_add_source.*
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
@ -34,31 +33,29 @@ class AddSourceActivity : AppCompatActivity() {
|
||||
super.onCreate(savedInstanceState)
|
||||
Scoop.getInstance().apply(this)
|
||||
setContentView(R.layout.activity_add_source)
|
||||
val toolbar: Toolbar = findViewById(R.id.toolbar)
|
||||
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||
|
||||
val mProgress: ProgressBar = findViewById(R.id.progress)
|
||||
val mForm: ConstraintLayout = findViewById(R.id.formContainer)
|
||||
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
|
||||
|
||||
try {
|
||||
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) {
|
||||
mustLoginToAddSource()
|
||||
}
|
||||
|
||||
maybeGetDetailsFromIntentSharing(intent, mSourceUri, mNameInput)
|
||||
maybeGetDetailsFromIntentSharing(intent, sourceUri, nameInput)
|
||||
|
||||
mSaveBtn.setOnClickListener {
|
||||
handleSaveSource(mTags, mNameInput.text.toString(), mSourceUri.text.toString(), api!!)
|
||||
saveBtn.setOnClickListener {
|
||||
handleSaveSource(tags, nameInput.text.toString(), sourceUri.text.toString(), api!!)
|
||||
}
|
||||
|
||||
val config = Config(this)
|
||||
@ -66,13 +63,13 @@ class AddSourceActivity : AppCompatActivity() {
|
||||
if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid()) {
|
||||
mustLoginToAddSource()
|
||||
} 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>()
|
||||
mSpoutsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
spoutsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
|
||||
override fun onItemSelected(adapterView: AdapterView<*>, view: View, i: Int, l: Long) {
|
||||
val spoutName = (view as TextView).text.toString()
|
||||
mSpoutsValue = spoutsKV[spoutName]
|
||||
@ -95,15 +92,15 @@ class AddSourceActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
mProgress.visibility = View.GONE
|
||||
mForm.visibility = View.VISIBLE
|
||||
formContainer.visibility = View.VISIBLE
|
||||
|
||||
val spinnerArrayAdapter =
|
||||
ArrayAdapter(
|
||||
this@AddSourceActivity,
|
||||
android.R.layout.simple_spinner_item,
|
||||
itemsStrings)
|
||||
ArrayAdapter(
|
||||
this@AddSourceActivity,
|
||||
android.R.layout.simple_spinner_item,
|
||||
itemsStrings)
|
||||
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
|
||||
mSpoutsSpinner.adapter = spinnerArrayAdapter
|
||||
spoutsSpinner.adapter = spinnerArrayAdapter
|
||||
|
||||
} else {
|
||||
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) {
|
||||
mSourceUri.setText(intent.getStringExtra(Intent.EXTRA_TEXT))
|
||||
mNameInput.setText(intent.getStringExtra(Intent.EXTRA_TITLE))
|
||||
sourceUri.setText(intent.getStringExtra(Intent.EXTRA_TEXT))
|
||||
nameInput.setText(intent.getStringExtra(Intent.EXTRA_TITLE))
|
||||
}
|
||||
}
|
||||
|
||||
@ -135,7 +132,7 @@ class AddSourceActivity : AppCompatActivity() {
|
||||
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()
|
||||
|
||||
@ -143,11 +140,11 @@ class AddSourceActivity : AppCompatActivity() {
|
||||
Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show()
|
||||
} else {
|
||||
api.createSource(
|
||||
title,
|
||||
url,
|
||||
mSpoutsValue!!,
|
||||
mTags.text.toString(),
|
||||
""
|
||||
title,
|
||||
url,
|
||||
mSpoutsValue!!,
|
||||
tags.text.toString(),
|
||||
""
|
||||
).enqueue(object : Callback<SuccessResponse> {
|
||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
||||
if (response.body() != null && response.body()!!.isSuccess) {
|
||||
|
@ -9,20 +9,13 @@ import android.graphics.drawable.GradientDrawable
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import android.preference.PreferenceManager
|
||||
import android.support.design.widget.CoordinatorLayout
|
||||
import android.support.v4.view.MenuItemCompat
|
||||
import android.support.v4.widget.SwipeRefreshLayout
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.GridLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.support.v7.widget.SearchView
|
||||
import android.support.v7.widget.StaggeredGridLayoutManager
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.support.v7.widget.*
|
||||
import android.support.v7.widget.helper.ItemTouchHelper
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import apps.amine.bou.readerforselfoss.adapters.ItemCardAdapter
|
||||
import apps.amine.bou.readerforselfoss.adapters.ItemListAdapter
|
||||
@ -41,6 +34,11 @@ import apps.amine.bou.readerforselfoss.utils.checkApkVersion
|
||||
import apps.amine.bou.readerforselfoss.utils.customtabs.CustomTabActivityHelper
|
||||
import apps.amine.bou.readerforselfoss.utils.drawer.CustomUrlPrimaryDrawerItem
|
||||
import apps.amine.bou.readerforselfoss.utils.longHash
|
||||
import 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.ReservoirGetCallback
|
||||
import com.anupcowkur.reservoir.ReservoirPutCallback
|
||||
@ -51,7 +49,6 @@ import com.crashlytics.android.Crashlytics
|
||||
import com.crashlytics.android.answers.Answers
|
||||
import com.crashlytics.android.answers.InviteEvent
|
||||
import com.ftinc.scoop.Scoop
|
||||
import com.github.stkent.amplify.prompt.DefaultLayoutPromptView
|
||||
import com.github.stkent.amplify.tracking.Amplify
|
||||
import com.google.android.gms.appinvite.AppInviteInvitation
|
||||
import com.google.android.gms.common.ConnectionResult
|
||||
@ -61,20 +58,15 @@ import com.google.gson.reflect.TypeToken
|
||||
import com.heinrichreimersoftware.androidissuereporter.IssueReporterLauncher
|
||||
import com.mikepenz.aboutlibraries.Libs
|
||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
||||
import com.mikepenz.materialdrawer.AccountHeader
|
||||
import com.mikepenz.materialdrawer.AccountHeaderBuilder
|
||||
import com.mikepenz.materialdrawer.Drawer
|
||||
import com.mikepenz.materialdrawer.DrawerBuilder
|
||||
import com.mikepenz.materialdrawer.holder.BadgeStyle
|
||||
import com.mikepenz.materialdrawer.model.DividerDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.ProfileDrawerItem
|
||||
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import java.lang.Exception
|
||||
|
||||
import kotlinx.android.synthetic.main.activity_home.*
|
||||
|
||||
class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
|
||||
@ -106,15 +98,9 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
private var displayAccountHeader: 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 tabArchiveBadge: TextBadgeItem
|
||||
private lateinit var tabStarredBadge: TextBadgeItem
|
||||
private lateinit var toolbar: Toolbar
|
||||
private lateinit var drawer: Drawer
|
||||
private lateinit var api: SelfossApi
|
||||
private lateinit var customTabActivityHelper: CustomTabActivityHelper
|
||||
@ -127,6 +113,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
private var recyclerViewScrollListener: RecyclerView.OnScrollListener? = null
|
||||
private lateinit var settings: SharedPreferences
|
||||
|
||||
private var badgeNew: Int = -1
|
||||
private var badgeAll: Int = -1
|
||||
private var badgeFavs: Int = -1
|
||||
|
||||
|
||||
|
||||
|
||||
@ -141,16 +131,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
Scoop.getInstance().apply(this)
|
||||
|
||||
setContentView(R.layout.activity_home)
|
||||
|
||||
toolbar = findViewById(R.id.toolbar)
|
||||
setSupportActionBar(toolbar)
|
||||
|
||||
setSupportActionBar(toolBar)
|
||||
if (savedInstanceState == null) {
|
||||
val promptView: DefaultLayoutPromptView = findViewById(R.id.prompt_view)
|
||||
Amplify.getSharedInstance().promptIfReady(promptView)
|
||||
}
|
||||
|
||||
@ -168,122 +153,114 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
appColors = AppColors(this@HomeActivity)
|
||||
|
||||
handleBottomBar()
|
||||
|
||||
handleDrawer()
|
||||
|
||||
coordinatorLayout = findViewById(R.id.coordLayout)
|
||||
swipeRefreshLayout = findViewById(R.id.swipeRefreshLayout)
|
||||
recyclerView = findViewById(R.id.my_recycler_view)
|
||||
|
||||
emptyText = findViewById(R.id.emptyText)
|
||||
|
||||
reloadLayoutManager()
|
||||
|
||||
handleSwipeRefreshLayout()
|
||||
}
|
||||
|
||||
private fun handleSwipeRefreshLayout() {
|
||||
swipeRefreshLayout.setColorSchemeResources(
|
||||
R.color.refresh_progress_1,
|
||||
R.color.refresh_progress_2,
|
||||
R.color.refresh_progress_3)
|
||||
R.color.refresh_progress_1,
|
||||
R.color.refresh_progress_2,
|
||||
R.color.refresh_progress_3)
|
||||
swipeRefreshLayout.setOnRefreshListener {
|
||||
handleDrawerItems()
|
||||
getElementsAccordingToTab()
|
||||
}
|
||||
|
||||
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 =
|
||||
if (elementsShown != UNREAD_SHOWN) 0 else super.getSwipeDirs(recyclerView, viewHolder)
|
||||
override fun getSwipeDirs(recyclerView: RecyclerView?, viewHolder: RecyclerView.ViewHolder?): Int =
|
||||
if (elementsShown != UNREAD_SHOWN) 0 else super.getSwipeDirs(recyclerView, viewHolder)
|
||||
|
||||
override fun onMove(recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder): Boolean = false
|
||||
override fun onMove(recyclerView: RecyclerView,
|
||||
viewHolder: RecyclerView.ViewHolder,
|
||||
target: RecyclerView.ViewHolder): Boolean = false
|
||||
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
|
||||
try {
|
||||
val i = items[viewHolder.adapterPosition]
|
||||
val position = items.indexOf(i)
|
||||
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
|
||||
try {
|
||||
val i = items[viewHolder.adapterPosition]
|
||||
val position = items.indexOf(i)
|
||||
|
||||
val adapter = recyclerView.adapter
|
||||
when (adapter) {
|
||||
is ItemCardAdapter -> adapter.removeItemAtIndex(position)
|
||||
is ItemListAdapter -> adapter.removeItemAtIndex(position)
|
||||
val adapter = recyclerView.adapter
|
||||
when (adapter) {
|
||||
is ItemCardAdapter -> 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)
|
||||
}
|
||||
|
||||
private fun handleBottomBar() {
|
||||
|
||||
bottomBar = findViewById(R.id.bottomBar)
|
||||
|
||||
tabNewBadge = TextBadgeItem()
|
||||
.setText("")
|
||||
.setHideOnSelect(false).hide(false)
|
||||
.setBackgroundColor(appColors.primary)
|
||||
.setText("")
|
||||
.setHideOnSelect(false).hide(false)
|
||||
.setBackgroundColor(appColors.primary)
|
||||
tabArchiveBadge = TextBadgeItem()
|
||||
.setText("")
|
||||
.setHideOnSelect(false).hide(false)
|
||||
.setBackgroundColor(appColors.primary)
|
||||
.setText("")
|
||||
.setHideOnSelect(false).hide(false)
|
||||
.setBackgroundColor(appColors.primary)
|
||||
tabStarredBadge = TextBadgeItem()
|
||||
.setText("")
|
||||
.setHideOnSelect(false).hide(false)
|
||||
.setBackgroundColor(appColors.primary)
|
||||
.setText("")
|
||||
.setHideOnSelect(false).hide(false)
|
||||
.setBackgroundColor(appColors.primary)
|
||||
|
||||
val tabNew =
|
||||
BottomNavigationItem(
|
||||
R.drawable.ic_fiber_new_black_24dp,
|
||||
getString(R.string.tab_new)
|
||||
).setActiveColor(appColors.accent)
|
||||
.setBadgeItem(tabNewBadge)
|
||||
BottomNavigationItem(
|
||||
R.drawable.ic_fiber_new_black_24dp,
|
||||
getString(R.string.tab_new)
|
||||
).setActiveColor(appColors.accent)
|
||||
.setBadgeItem(tabNewBadge)
|
||||
val tabArchive =
|
||||
BottomNavigationItem(
|
||||
R.drawable.ic_archive_black_24dp,
|
||||
getString(R.string.tab_read)
|
||||
).setActiveColor(appColors.dark)
|
||||
.setBadgeItem(tabArchiveBadge)
|
||||
BottomNavigationItem(
|
||||
R.drawable.ic_archive_black_24dp,
|
||||
getString(R.string.tab_read)
|
||||
).setActiveColor(appColors.dark)
|
||||
.setBadgeItem(tabArchiveBadge)
|
||||
val tabStarred =
|
||||
BottomNavigationItem(
|
||||
R.drawable.ic_favorite_black_24dp,
|
||||
getString(R.string.tab_favs)
|
||||
).setActiveColorResource(R.color.pink)
|
||||
.setBadgeItem(tabStarredBadge)
|
||||
BottomNavigationItem(
|
||||
R.drawable.ic_favorite_black_24dp,
|
||||
getString(R.string.tab_favs)
|
||||
).setActiveColorResource(R.color.pink)
|
||||
.setBadgeItem(tabStarredBadge)
|
||||
|
||||
bottomBar
|
||||
.addItem(tabNew)
|
||||
.addItem(tabArchive)
|
||||
.addItem(tabStarred)
|
||||
.setFirstSelectedPosition(0)
|
||||
.initialise()
|
||||
.addItem(tabNew)
|
||||
.addItem(tabArchive)
|
||||
.addItem(tabStarred)
|
||||
.setFirstSelectedPosition(0)
|
||||
.initialise()
|
||||
|
||||
bottomBar.setMode(BottomNavigationBar.MODE_SHIFTING)
|
||||
bottomBar.setBackgroundStyle(BottomNavigationBar.BACKGROUND_STYLE_STATIC)
|
||||
@ -331,86 +308,68 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
|
||||
private fun handleDrawer() {
|
||||
displayAccountHeader =
|
||||
PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getBoolean("account_header_displaying", false)
|
||||
val headerResult: AccountHeader? = if (displayAccountHeader) {
|
||||
AccountHeaderBuilder()
|
||||
.withActivity(this)
|
||||
.withHeaderBackground(R.drawable.bg)
|
||||
.addProfiles(
|
||||
ProfileDrawerItem()
|
||||
.withName(
|
||||
settings.getString("url", "")
|
||||
PreferenceManager.getDefaultSharedPreferences(this)
|
||||
.getBoolean("account_header_displaying", false)
|
||||
|
||||
drawer = drawer {
|
||||
rootViewRes = R.id.drawer_layout
|
||||
toolbar = toolBar
|
||||
actionBarDrawerToggleEnabled = true
|
||||
actionBarDrawerToggleAnimated = true
|
||||
showOnFirstLaunch = true
|
||||
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))
|
||||
)
|
||||
.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)
|
||||
false
|
||||
}
|
||||
|
||||
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 +378,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
fun handleTags(maybeTags: List<Tag>?) {
|
||||
if (maybeTags == null) {
|
||||
if (loadedFromCache)
|
||||
|
||||
drawer.addItem(
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_error_loading_tags))
|
||||
.withSelectable(false))
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_error_loading_tags))
|
||||
.withSelectable(false))
|
||||
}
|
||||
else {
|
||||
for (tag in maybeTags) {
|
||||
@ -432,20 +392,20 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
gd.setSize(30, 30)
|
||||
gd.cornerRadius = 30F
|
||||
drawer.addItem(
|
||||
PrimaryDrawerItem()
|
||||
.withName(tag.tag)
|
||||
.withIdentifier(tag.tag.longHash())
|
||||
.withIcon(gd)
|
||||
.withBadge("${tag.unread}")
|
||||
.withBadgeStyle(
|
||||
BadgeStyle().withTextColor(Color.WHITE)
|
||||
.withColor(appColors.accent)
|
||||
)
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
maybeTagFilter = tag
|
||||
getElementsAccordingToTab()
|
||||
false
|
||||
}
|
||||
PrimaryDrawerItem()
|
||||
.withName(tag.tag)
|
||||
.withIdentifier(tag.tag.longHash())
|
||||
.withIcon(gd)
|
||||
.withBadge("${tag.unread}")
|
||||
.withBadgeStyle(
|
||||
BadgeStyle().withTextColor(Color.WHITE)
|
||||
.withColor(appColors.accent)
|
||||
)
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
maybeTagFilter = tag
|
||||
getElementsAccordingToTab()
|
||||
false
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -456,22 +416,22 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
if (maybeSources == null) {
|
||||
if (loadedFromCache)
|
||||
drawer.addItem(
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_error_loading_sources))
|
||||
.withSelectable(false))
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_error_loading_sources))
|
||||
.withSelectable(false))
|
||||
}
|
||||
else
|
||||
for (tag in maybeSources)
|
||||
drawer.addItem(
|
||||
CustomUrlPrimaryDrawerItem()
|
||||
.withName(tag.title)
|
||||
.withIdentifier(tag.id.toLong())
|
||||
.withIcon(tag.getIcon(this@HomeActivity))
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
maybeSourceFilter = tag
|
||||
getElementsAccordingToTab()
|
||||
false
|
||||
}
|
||||
CustomUrlPrimaryDrawerItem()
|
||||
.withName(tag.title)
|
||||
.withIdentifier(tag.id.toLong())
|
||||
.withIcon(tag.getIcon(this@HomeActivity))
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
maybeSourceFilter = tag
|
||||
getElementsAccordingToTab()
|
||||
false
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
@ -479,58 +439,58 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
drawer.removeAllItems()
|
||||
if (maybeDrawerData != null) {
|
||||
drawer.addItem(
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_item_filters))
|
||||
.withSelectable(false)
|
||||
.withIdentifier(DRAWER_ID_FILTERS)
|
||||
.withBadge(getString(R.string.drawer_action_clear))
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
maybeSourceFilter = null
|
||||
maybeTagFilter = null
|
||||
getElementsAccordingToTab()
|
||||
false
|
||||
}
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_item_filters))
|
||||
.withSelectable(false)
|
||||
.withIdentifier(DRAWER_ID_FILTERS)
|
||||
.withBadge(getString(R.string.drawer_action_clear))
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
maybeSourceFilter = null
|
||||
maybeTagFilter = null
|
||||
getElementsAccordingToTab()
|
||||
false
|
||||
}
|
||||
)
|
||||
drawer.addItem(DividerDrawerItem())
|
||||
drawer.addItem(
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_item_tags))
|
||||
.withIdentifier(DRAWER_ID_TAGS)
|
||||
.withSelectable(false))
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_item_tags))
|
||||
.withIdentifier(DRAWER_ID_TAGS)
|
||||
.withSelectable(false))
|
||||
handleTags(maybeDrawerData.tags)
|
||||
drawer.addItem(DividerDrawerItem())
|
||||
drawer.addItem(
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_item_sources))
|
||||
.withIdentifier(DRAWER_ID_TAGS)
|
||||
.withBadge(getString(R.string.drawer_action_edit))
|
||||
.withSelectable(false)
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
startActivity(Intent(this, SourcesActivity::class.java))
|
||||
false
|
||||
}
|
||||
SecondaryDrawerItem()
|
||||
.withName(getString(R.string.drawer_item_sources))
|
||||
.withIdentifier(DRAWER_ID_TAGS)
|
||||
.withBadge(getString(R.string.drawer_action_edit))
|
||||
.withSelectable(false)
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
startActivity(Intent(this, SourcesActivity::class.java))
|
||||
false
|
||||
}
|
||||
)
|
||||
handleSources(maybeDrawerData.sources)
|
||||
drawer.addItem(DividerDrawerItem())
|
||||
drawer.addItem(
|
||||
PrimaryDrawerItem()
|
||||
.withName(R.string.action_about)
|
||||
.withSelectable(false)
|
||||
.withIcon(R.drawable.ic_info_outline)
|
||||
.withIconTintingEnabled(true)
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
LibsBuilder()
|
||||
.withActivityStyle(
|
||||
if (appColors.isDarkTheme)
|
||||
Libs.ActivityStyle.LIGHT_DARK_TOOLBAR
|
||||
else
|
||||
Libs.ActivityStyle.DARK
|
||||
)
|
||||
.withAboutIconShown(true)
|
||||
.withAboutVersionShown(true)
|
||||
.start(this@HomeActivity)
|
||||
false
|
||||
})
|
||||
PrimaryDrawerItem()
|
||||
.withName(R.string.action_about)
|
||||
.withSelectable(false)
|
||||
.withIcon(R.drawable.ic_info_outline)
|
||||
.withIconTintingEnabled(true)
|
||||
.withOnDrawerItemClickListener { _, _, _ ->
|
||||
LibsBuilder()
|
||||
.withActivityStyle(
|
||||
if (appColors.isDarkTheme)
|
||||
Libs.ActivityStyle.LIGHT_DARK_TOOLBAR
|
||||
else
|
||||
Libs.ActivityStyle.DARK
|
||||
)
|
||||
.withAboutIconShown(true)
|
||||
.withAboutVersionShown(true)
|
||||
.start(this@HomeActivity)
|
||||
false
|
||||
})
|
||||
|
||||
|
||||
if (!loadedFromCache)
|
||||
@ -544,15 +504,15 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
} else {
|
||||
if (!loadedFromCache) {
|
||||
drawer.addItem(
|
||||
PrimaryDrawerItem()
|
||||
.withName(getString(R.string.no_tags_loaded))
|
||||
.withIdentifier(DRAWER_ID_TAGS)
|
||||
.withSelectable(false))
|
||||
PrimaryDrawerItem()
|
||||
.withName(getString(R.string.no_tags_loaded))
|
||||
.withIdentifier(DRAWER_ID_TAGS)
|
||||
.withSelectable(false))
|
||||
drawer.addItem(
|
||||
PrimaryDrawerItem()
|
||||
.withName(getString(R.string.no_sources_loaded))
|
||||
.withIdentifier(DRAWER_ID_SOURCES)
|
||||
.withSelectable(false))
|
||||
PrimaryDrawerItem()
|
||||
.withName(getString(R.string.no_sources_loaded))
|
||||
.withIdentifier(DRAWER_ID_SOURCES)
|
||||
.withSelectable(false))
|
||||
}
|
||||
}
|
||||
|
||||
@ -631,29 +591,31 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
override fun onTabUnselected(position: Int) = Unit
|
||||
|
||||
override fun onTabReselected(position: Int) =
|
||||
when (mLayoutManager) {
|
||||
is StaggeredGridLayoutManager ->
|
||||
if (mLayoutManager.findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
|
||||
getElementsAccordingToTab()
|
||||
} else {
|
||||
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
||||
}
|
||||
is GridLayoutManager ->
|
||||
if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
|
||||
getElementsAccordingToTab()
|
||||
} else {
|
||||
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
when (mLayoutManager) {
|
||||
is StaggeredGridLayoutManager ->
|
||||
if (mLayoutManager.findFirstCompletelyVisibleItemPositions(null)[0] == 0) {
|
||||
getElementsAccordingToTab()
|
||||
} else {
|
||||
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
||||
}
|
||||
is GridLayoutManager ->
|
||||
if (mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0) {
|
||||
getElementsAccordingToTab()
|
||||
} else {
|
||||
mLayoutManager.scrollToPositionWithOffset(0, 0)
|
||||
}
|
||||
else -> Unit
|
||||
}
|
||||
|
||||
override fun onTabSelected(position: Int) =
|
||||
override fun onTabSelected(position: Int) {
|
||||
offset = 0
|
||||
when (position) {
|
||||
0 -> getUnRead()
|
||||
1 -> getRead()
|
||||
2 -> getStarred()
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
@ -670,7 +632,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
else -> 0
|
||||
}
|
||||
|
||||
if (lastVisibleItem == (items.size - 1)) {
|
||||
if (lastVisibleItem == (items.size - 1) && items.size < maxItemNumber()) {
|
||||
getElementsAccordingToTab(appendResults = true)
|
||||
}
|
||||
}
|
||||
@ -681,22 +643,30 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
recyclerView.addOnScrollListener(recyclerViewScrollListener)
|
||||
}
|
||||
|
||||
fun mayBeEmpty() =
|
||||
if (items.isEmpty()) {
|
||||
emptyText.visibility = View.VISIBLE
|
||||
recyclerView.visibility = View.GONE
|
||||
} else {
|
||||
emptyText.visibility = View.GONE
|
||||
recyclerView.visibility = View.VISIBLE
|
||||
}
|
||||
private fun mayBeEmpty() =
|
||||
if (items.isEmpty()) {
|
||||
emptyText.visibility = View.VISIBLE
|
||||
recyclerView.visibility = View.GONE
|
||||
} else {
|
||||
emptyText.visibility = View.GONE
|
||||
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) {
|
||||
UNREAD_SHOWN -> getUnRead(appendResults)
|
||||
READ_SHOWN -> getRead(appendResults)
|
||||
FAV_SHOWN -> getStarred(appendResults)
|
||||
else -> getUnRead(appendResults)
|
||||
}
|
||||
}
|
||||
|
||||
private fun doCallTo(appendResults: Boolean, toastMessage: Int, call: (String?, Long?, String?) -> Call<List<Item>>) {
|
||||
fun handleItemsResponse(response: Response<List<Item>>) {
|
||||
@ -723,38 +693,29 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
swipeRefreshLayout.post { swipeRefreshLayout.isRefreshing = true }
|
||||
|
||||
call(maybeTagFilter?.tag, maybeSourceFilter?.id?.toLong(), maybeSearchFilter)
|
||||
.enqueue(object : Callback<List<Item>> {
|
||||
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
||||
handleItemsResponse(response)
|
||||
}
|
||||
.enqueue(object : Callback<List<Item>> {
|
||||
override fun onResponse(call: Call<List<Item>>, response: Response<List<Item>>) {
|
||||
handleItemsResponse(response)
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
Toast.makeText(this@HomeActivity, toastMessage, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
override fun onFailure(call: Call<List<Item>>, t: Throwable) {
|
||||
swipeRefreshLayout.isRefreshing = false
|
||||
Toast.makeText(this@HomeActivity, toastMessage, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun getUnRead(appendResults: Boolean = false) {
|
||||
offset = if (appendResults) (offset + itemsNumber)
|
||||
else 0
|
||||
firstVisible = if (appendResults) firstVisible else 0
|
||||
elementsShown = UNREAD_SHOWN
|
||||
doCallTo(appendResults, R.string.cant_get_new_elements){t, id, f -> api.newItems(t, id, f, itemsNumber, offset)}
|
||||
}
|
||||
|
||||
private fun getRead(appendResults: Boolean = false) {
|
||||
offset = if (appendResults) (offset + itemsNumber)
|
||||
else 0
|
||||
firstVisible = if (appendResults) firstVisible else 0
|
||||
elementsShown = READ_SHOWN
|
||||
doCallTo(appendResults, R.string.cant_get_read){t, id, f -> api.readItems(t, id, f, itemsNumber, offset)}
|
||||
}
|
||||
|
||||
private fun getStarred(appendResults: Boolean = false) {
|
||||
offset = if (appendResults) (offset + itemsNumber)
|
||||
else 0
|
||||
firstVisible = if (appendResults) firstVisible else 0
|
||||
elementsShown = FAV_SHOWN
|
||||
doCallTo(appendResults, R.string.cant_get_favs){t, id, f -> api.starredItems(t, id, f, itemsNumber, offset)}
|
||||
}
|
||||
@ -774,29 +735,32 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
val mAdapter: RecyclerView.Adapter<*>
|
||||
if (shouldBeCardView) {
|
||||
mAdapter =
|
||||
ItemCardAdapter(
|
||||
this,
|
||||
items,
|
||||
api,
|
||||
customTabActivityHelper,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
fullHeightCards,
|
||||
appColors,
|
||||
debugReadingItems,
|
||||
userIdentifier)
|
||||
ItemCardAdapter(
|
||||
this,
|
||||
items,
|
||||
api,
|
||||
customTabActivityHelper,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
fullHeightCards,
|
||||
appColors,
|
||||
debugReadingItems,
|
||||
userIdentifier)
|
||||
} else {
|
||||
mAdapter =
|
||||
ItemListAdapter(
|
||||
this,
|
||||
items,
|
||||
api,
|
||||
customTabActivityHelper,
|
||||
clickBehavior,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
debugReadingItems,
|
||||
userIdentifier)
|
||||
ItemListAdapter(
|
||||
this,
|
||||
items,
|
||||
api,
|
||||
customTabActivityHelper,
|
||||
clickBehavior,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
debugReadingItems,
|
||||
userIdentifier)
|
||||
|
||||
recyclerView.addItemDecoration(DividerItemDecoration(this@HomeActivity,
|
||||
DividerItemDecoration.VERTICAL))
|
||||
}
|
||||
recyclerView.adapter = mAdapter
|
||||
mAdapter.notifyDataSetChanged()
|
||||
@ -813,26 +777,38 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
api.stats.enqueue(object : Callback<Stats> {
|
||||
override fun onResponse(call: Call<Stats>, response: Response<Stats>) {
|
||||
if (response.body() != null) {
|
||||
if (displayUnreadCount)
|
||||
tabNewBadge
|
||||
.setText(response.body()!!.unread.toString())
|
||||
.maybeShow()
|
||||
if (displayAllCount) {
|
||||
tabArchiveBadge
|
||||
.setText(response.body()!!.total.toString())
|
||||
.maybeShow()
|
||||
tabStarredBadge
|
||||
.setText(response.body()!!.starred.toString())
|
||||
.maybeShow()
|
||||
} else {
|
||||
tabArchiveBadge.removeBadge()
|
||||
tabStarredBadge.removeBadge()
|
||||
}
|
||||
|
||||
badgeNew = response.body()!!.unread
|
||||
badgeAll = response.body()!!.total
|
||||
badgeFavs = response.body()!!.starred
|
||||
reloadBadgeContent()
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
tabNewBadge.removeBadge()
|
||||
tabArchiveBadge.removeBadge()
|
||||
@ -895,8 +871,8 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
api.update().enqueue(object : Callback<String> {
|
||||
override fun onResponse(call: Call<String>, response: Response<String>) {
|
||||
Toast.makeText(this@HomeActivity,
|
||||
R.string.refresh_success_response, Toast.LENGTH_LONG)
|
||||
.show()
|
||||
R.string.refresh_success_response, Toast.LENGTH_LONG)
|
||||
.show()
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<String>, t: Throwable) {
|
||||
@ -941,17 +917,17 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
R.id.action_share_the_app -> {
|
||||
if (GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == ConnectionResult.SUCCESS) {
|
||||
val share = AppInviteInvitation.IntentBuilder(getString(R.string.invitation_title))
|
||||
.setMessage(getString(R.string.invitation_message))
|
||||
.setDeepLink(Uri.parse("https://ymbh5.app.goo.gl/qbvQ"))
|
||||
.setCallToActionText(getString(R.string.invitation_cta))
|
||||
.build()
|
||||
.setMessage(getString(R.string.invitation_message))
|
||||
.setDeepLink(Uri.parse("https://ymbh5.app.goo.gl/qbvQ"))
|
||||
.setCallToActionText(getString(R.string.invitation_cta))
|
||||
.build()
|
||||
startActivityForResult(share, REQUEST_INVITE)
|
||||
} else {
|
||||
val sendIntent = Intent()
|
||||
sendIntent.action = Intent.ACTION_SEND
|
||||
sendIntent.putExtra(
|
||||
Intent.EXTRA_TEXT,
|
||||
getString(R.string.invitation_message) + " https://ymbh5.app.goo.gl/qbvQ"
|
||||
Intent.EXTRA_TEXT,
|
||||
getString(R.string.invitation_message) + " https://ymbh5.app.goo.gl/qbvQ"
|
||||
)
|
||||
sendIntent.type = "text/plain"
|
||||
startActivityForResult(sendIntent, REQUEST_INVITE_BYMAIL)
|
||||
@ -961,4 +937,12 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
|
||||
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.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.support.design.widget.TextInputLayout
|
||||
import android.support.v7.app.AlertDialog
|
||||
import android.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.Toolbar
|
||||
@ -15,9 +14,6 @@ import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.widget.Button
|
||||
import android.widget.EditText
|
||||
import android.widget.Switch
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
||||
@ -32,6 +28,8 @@ import com.mikepenz.aboutlibraries.LibsBuilder
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import kotlinx.android.synthetic.main.activity_login.*
|
||||
|
||||
|
||||
|
||||
class LoginActivity : AppCompatActivity() {
|
||||
@ -43,14 +41,7 @@ class LoginActivity : AppCompatActivity() {
|
||||
|
||||
private lateinit var settings: SharedPreferences
|
||||
private lateinit var editor: SharedPreferences.Editor
|
||||
private lateinit var mFirebaseAnalytics: FirebaseAnalytics
|
||||
private lateinit var mUrlView: EditText
|
||||
private lateinit var mLoginView: TextView
|
||||
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 firebaseAnalytics: FirebaseAnalytics
|
||||
private lateinit var userIdentifier: String
|
||||
private var logErrors: Boolean = false
|
||||
|
||||
@ -61,7 +52,6 @@ class LoginActivity : AppCompatActivity() {
|
||||
Scoop.getInstance().apply(this)
|
||||
setContentView(R.layout.activity_login)
|
||||
|
||||
val toolbar: Toolbar = findViewById(R.id.toolbar)
|
||||
setSupportActionBar(toolbar)
|
||||
|
||||
handleBaseUrlFail()
|
||||
@ -69,7 +59,7 @@ class LoginActivity : AppCompatActivity() {
|
||||
|
||||
settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
|
||||
userIdentifier = settings.getString("unique_id", "")
|
||||
logErrors = settings.getBoolean("loging_debug", false)
|
||||
logErrors = settings.getBoolean("login_debug", false)
|
||||
|
||||
editor = settings.edit()
|
||||
|
||||
@ -77,60 +67,44 @@ class LoginActivity : AppCompatActivity() {
|
||||
goToMain()
|
||||
}
|
||||
|
||||
mFirebaseAnalytics = 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)
|
||||
firebaseAnalytics = FirebaseAnalytics.getInstance(this)
|
||||
|
||||
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
|
||||
val visi: Int = if (b) View.VISIBLE else View.GONE
|
||||
|
||||
warningTextview.visibility = visi
|
||||
warningText.visibility = visi
|
||||
}
|
||||
|
||||
mPasswordView.setOnEditorActionListener(TextView.OnEditorActionListener { _, id, _ ->
|
||||
if (id == R.id.login || id == EditorInfo.IME_NULL) {
|
||||
passwordView.setOnEditorActionListener(TextView.OnEditorActionListener { _, id, _ ->
|
||||
if (id == R.id.loginView || id == EditorInfo.IME_NULL) {
|
||||
attemptLogin()
|
||||
return@OnEditorActionListener true
|
||||
}
|
||||
false
|
||||
})
|
||||
|
||||
mEmailSignInButton.setOnClickListener { attemptLogin() }
|
||||
signInButton.setOnClickListener { attemptLogin() }
|
||||
|
||||
mSwitch.setOnCheckedChangeListener { _, b ->
|
||||
withLogin.setOnCheckedChangeListener { _, b ->
|
||||
isWithLogin = !isWithLogin
|
||||
val visi: Int = if (b) View.VISIBLE else View.GONE
|
||||
|
||||
mLoginLayout.visibility = visi
|
||||
mPasswordLayout.visibility = visi
|
||||
loginLayout.visibility = visi
|
||||
passwordLayout.visibility = visi
|
||||
}
|
||||
|
||||
mHTTPSwitch.setOnCheckedChangeListener { _, b ->
|
||||
withHttpLogin.setOnCheckedChangeListener { _, b ->
|
||||
isWithHTTPLogin = !isWithHTTPLogin
|
||||
val visi: Int = if (b) View.VISIBLE else View.GONE
|
||||
|
||||
mHTTPLoginLayout.visibility = visi
|
||||
mHTTPPasswordLayout.visibility = visi
|
||||
httpLoginInput.visibility = visi
|
||||
httpPasswordInput.visibility = visi
|
||||
}
|
||||
}
|
||||
|
||||
@ -140,9 +114,9 @@ class LoginActivity : AppCompatActivity() {
|
||||
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
||||
alertDialog.setMessage(getString(R.string.base_url_error))
|
||||
alertDialog.setButton(
|
||||
AlertDialog.BUTTON_NEUTRAL,
|
||||
"OK",
|
||||
{ dialog, _ -> dialog.dismiss() })
|
||||
AlertDialog.BUTTON_NEUTRAL,
|
||||
"OK",
|
||||
{ dialog, _ -> dialog.dismiss() })
|
||||
alertDialog.show()
|
||||
}
|
||||
}
|
||||
@ -156,25 +130,25 @@ class LoginActivity : AppCompatActivity() {
|
||||
private fun attemptLogin() {
|
||||
|
||||
// Reset errors.
|
||||
mUrlView.error = null
|
||||
mLoginView.error = null
|
||||
mHTTPLoginView.error = null
|
||||
mPasswordView.error = null
|
||||
mHTTPPasswordView.error = null
|
||||
urlView.error = null
|
||||
loginView.error = null
|
||||
httpLoginView.error = null
|
||||
passwordView.error = null
|
||||
httpPasswordView.error = null
|
||||
|
||||
// Store values at the time of the login attempt.
|
||||
val url = mUrlView.text.toString()
|
||||
val login = mLoginView.text.toString()
|
||||
val httpLogin = mHTTPLoginView.text.toString()
|
||||
val password = mPasswordView.text.toString()
|
||||
val httpPassword = mHTTPPasswordView.text.toString()
|
||||
val url = urlView.text.toString()
|
||||
val login = loginView.text.toString()
|
||||
val httpLogin = httpLoginView.text.toString()
|
||||
val password = passwordView.text.toString()
|
||||
val httpPassword = httpPasswordView.text.toString()
|
||||
|
||||
var cancel = false
|
||||
var focusView: View? = null
|
||||
|
||||
if (!url.isBaseUrlValid()) {
|
||||
mUrlView.error = getString(R.string.login_url_problem)
|
||||
focusView = mUrlView
|
||||
urlView.error = getString(R.string.login_url_problem)
|
||||
focusView = urlView
|
||||
cancel = true
|
||||
inValidCount++
|
||||
if (inValidCount == 3) {
|
||||
@ -182,9 +156,9 @@ class LoginActivity : AppCompatActivity() {
|
||||
alertDialog.setTitle(getString(R.string.warning_wrong_url))
|
||||
alertDialog.setMessage(getString(R.string.text_wrong_url))
|
||||
alertDialog.setButton(
|
||||
AlertDialog.BUTTON_NEUTRAL,
|
||||
"OK",
|
||||
{ dialog, _ -> dialog.dismiss() })
|
||||
AlertDialog.BUTTON_NEUTRAL,
|
||||
"OK",
|
||||
{ dialog, _ -> dialog.dismiss() })
|
||||
alertDialog.show()
|
||||
inValidCount = 0
|
||||
}
|
||||
@ -192,14 +166,14 @@ class LoginActivity : AppCompatActivity() {
|
||||
|
||||
if (isWithLogin || isWithHTTPLogin) {
|
||||
if (TextUtils.isEmpty(password)) {
|
||||
mPasswordView.error = getString(R.string.error_invalid_password)
|
||||
focusView = mPasswordView
|
||||
passwordView.error = getString(R.string.error_invalid_password)
|
||||
focusView = passwordView
|
||||
cancel = true
|
||||
}
|
||||
|
||||
if (TextUtils.isEmpty(login)) {
|
||||
mLoginView.error = getString(R.string.error_field_required)
|
||||
focusView = mLoginView
|
||||
loginView.error = getString(R.string.error_field_required)
|
||||
focusView = loginView
|
||||
cancel = true
|
||||
}
|
||||
}
|
||||
@ -226,11 +200,11 @@ class LoginActivity : AppCompatActivity() {
|
||||
editor.remove("password")
|
||||
editor.remove("httpPassword")
|
||||
editor.apply()
|
||||
mUrlView.error = getString(R.string.wrong_infos)
|
||||
mLoginView.error = getString(R.string.wrong_infos)
|
||||
mPasswordView.error = getString(R.string.wrong_infos)
|
||||
mHTTPLoginView.error = getString(R.string.wrong_infos)
|
||||
mHTTPPasswordView.error = getString(R.string.wrong_infos)
|
||||
urlView.error = getString(R.string.wrong_infos)
|
||||
loginView.error = getString(R.string.wrong_infos)
|
||||
passwordView.error = getString(R.string.wrong_infos)
|
||||
httpLoginView.error = getString(R.string.wrong_infos)
|
||||
httpPasswordView.error = getString(R.string.wrong_infos)
|
||||
if (logErrors) {
|
||||
Crashlytics.setUserIdentifier(userIdentifier)
|
||||
Crashlytics.log(100, "LOGIN_DEBUG_ERRROR", t.message)
|
||||
@ -242,7 +216,7 @@ class LoginActivity : AppCompatActivity() {
|
||||
|
||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
||||
if (response.body() != null && response.body()!!.isSuccess) {
|
||||
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, Bundle())
|
||||
firebaseAnalytics.logEvent(FirebaseAnalytics.Event.LOGIN, Bundle())
|
||||
goToMain()
|
||||
} else {
|
||||
preferenceError(Exception("No response body..."))
|
||||
@ -260,34 +234,34 @@ class LoginActivity : AppCompatActivity() {
|
||||
private fun showProgress(show: Boolean) {
|
||||
val shortAnimTime = resources.getInteger(android.R.integer.config_shortAnimTime)
|
||||
|
||||
mLoginFormView.visibility = if (show) View.GONE else View.VISIBLE
|
||||
mLoginFormView
|
||||
.animate()
|
||||
.setDuration(shortAnimTime.toLong())
|
||||
.alpha(
|
||||
if (show) 0F else 1F
|
||||
).setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
mLoginFormView.visibility = if (show) View.GONE else View.VISIBLE
|
||||
}
|
||||
})
|
||||
loginForm.visibility = if (show) View.GONE else View.VISIBLE
|
||||
loginForm
|
||||
.animate()
|
||||
.setDuration(shortAnimTime.toLong())
|
||||
.alpha(
|
||||
if (show) 0F else 1F
|
||||
).setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
loginForm.visibility = if (show) View.GONE else View.VISIBLE
|
||||
}
|
||||
})
|
||||
|
||||
mProgressView.visibility = if (show) View.VISIBLE else View.GONE
|
||||
mProgressView
|
||||
.animate()
|
||||
.setDuration(shortAnimTime.toLong())
|
||||
.alpha(
|
||||
if (show) 1F else 0F
|
||||
).setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
mProgressView.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
})
|
||||
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
|
||||
loginProgress
|
||||
.animate()
|
||||
.setDuration(shortAnimTime.toLong())
|
||||
.alpha(
|
||||
if (show) 1F else 0F
|
||||
).setListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
loginProgress.visibility = if (show) View.VISIBLE else View.GONE
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||
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
|
||||
}
|
||||
|
||||
@ -295,17 +269,17 @@ class LoginActivity : AppCompatActivity() {
|
||||
when (item.itemId) {
|
||||
R.id.about -> {
|
||||
LibsBuilder()
|
||||
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
|
||||
.withAboutIconShown(true)
|
||||
.withAboutVersionShown(true)
|
||||
.start(this)
|
||||
.withActivityStyle(Libs.ActivityStyle.LIGHT_DARK_TOOLBAR)
|
||||
.withAboutIconShown(true)
|
||||
.withAboutVersionShown(true)
|
||||
.start(this)
|
||||
return true
|
||||
}
|
||||
R.id.loging_debug -> {
|
||||
R.id.login_debug -> {
|
||||
val newState = !item.isChecked
|
||||
item.isChecked = newState
|
||||
logErrors = newState
|
||||
editor.putBoolean("loging_debug", newState)
|
||||
editor.putBoolean("login_debug", newState)
|
||||
editor.apply()
|
||||
return true
|
||||
}
|
||||
|
@ -1,114 +1,190 @@
|
||||
package apps.amine.bou.readerforselfoss
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
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.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.ParsedContent
|
||||
import apps.amine.bou.readerforselfoss.utils.buildCustomTabsIntent
|
||||
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.shareLink
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.request.RequestOptions
|
||||
import com.crashlytics.android.Crashlytics
|
||||
import com.ftinc.scoop.Scoop
|
||||
import com.github.rubensousa.floatingtoolbar.FloatingToolbar
|
||||
import org.sufficientlysecure.htmltextview.HtmlHttpImageGetter
|
||||
import org.sufficientlysecure.htmltextview.HtmlTextView
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
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 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() {
|
||||
super.onStop()
|
||||
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)
|
||||
val v = inflater.inflate(R.layout.activity_reader, parent, false)
|
||||
showProgressBar()
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(this)
|
||||
setContentView(R.layout.activity_reader)
|
||||
|
||||
val image: ImageView = v.findViewById(R.id.imageView)
|
||||
val source: TextView = v.findViewById(R.id.source)
|
||||
val title: TextView = v.findViewById(R.id.title)
|
||||
val content: HtmlTextView = v.findViewById(R.id.content)
|
||||
val url = intent.getStringExtra("url")
|
||||
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)
|
||||
url = intent.getStringExtra("url")
|
||||
contentText = intent.getStringExtra("content")
|
||||
contentTitle = intent.getStringExtra("title")
|
||||
contentImage = intent.getStringExtra("image")
|
||||
contentSource = intent.getStringExtra("source")
|
||||
|
||||
fab = findViewById(R.id.fab)
|
||||
val mFloatingToolbar: FloatingToolbar = findViewById(R.id.floatingToolbar)
|
||||
mFloatingToolbar.attachFab(fab)
|
||||
|
||||
val customTabsIntent = this@ReaderActivity.buildCustomTabsIntent()
|
||||
mCustomTabActivityHelper = CustomTabActivityHelper()
|
||||
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> {
|
||||
override fun onResponse(call: Call<ParsedContent>, response: Response<ParsedContent>) {
|
||||
if (response.body() != null && response.body()!!.content != null && response.body()!!.content.isNotEmpty()) {
|
||||
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()) {
|
||||
try {
|
||||
content.setHtml(response.body()!!.content, HtmlHttpImageGetter(content, null, true))
|
||||
} catch (e: IndexOutOfBoundsException) {
|
||||
openInBrowserAfterFailing()
|
||||
}
|
||||
tryToHandleHtml(response.body()!!.content, customTabsIntent, prefs)
|
||||
}
|
||||
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
|
||||
.with(baseContext)
|
||||
.asBitmap()
|
||||
.load(response.body()!!.lead_image_url)
|
||||
.apply(RequestOptions.fitCenterTransform())
|
||||
.into(image)
|
||||
|
||||
shareBtn.setOnClickListener {
|
||||
this@ReaderActivity.shareLink(response.body()!!.url)
|
||||
.with(baseContext)
|
||||
.asBitmap()
|
||||
.load(response.body()!!.lead_image_url)
|
||||
.apply(RequestOptions.fitCenterTransform())
|
||||
.into(imageView)
|
||||
} else {
|
||||
imageView.visibility = View.GONE
|
||||
}
|
||||
|
||||
browserBtn.setOnClickListener {
|
||||
this@ReaderActivity.openItemUrl(
|
||||
response.body()!!.url,
|
||||
customTabsIntent,
|
||||
false,
|
||||
false,
|
||||
this@ReaderActivity)
|
||||
}
|
||||
nestedScrollView.scrollTo(0, 0)
|
||||
|
||||
hideProgressBar()
|
||||
} else openInBrowserAfterFailing()
|
||||
progressBar.visibility = View.GONE
|
||||
} else openInBrowserAfterFailing(customTabsIntent)
|
||||
}
|
||||
|
||||
override fun onFailure(call: Call<ParsedContent>, t: Throwable) = openInBrowserAfterFailing()
|
||||
|
||||
private fun openInBrowserAfterFailing() {
|
||||
this@ReaderActivity.openItemUrl(
|
||||
url,
|
||||
customTabsIntent,
|
||||
true,
|
||||
false,
|
||||
this@ReaderActivity
|
||||
)
|
||||
finish()
|
||||
}
|
||||
override fun onFailure(call: Call<ParsedContent>, t: Throwable) = openInBrowserAfterFailing(customTabsIntent)
|
||||
})
|
||||
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.support.v7.app.AppCompatActivity
|
||||
import android.support.v7.widget.LinearLayoutManager
|
||||
import android.support.v7.widget.RecyclerView
|
||||
import android.support.v7.widget.Toolbar
|
||||
import android.widget.Toast
|
||||
import apps.amine.bou.readerforselfoss.adapters.SourcesListAdapter
|
||||
import apps.amine.bou.readerforselfoss.api.selfoss.SelfossApi
|
||||
import apps.amine.bou.readerforselfoss.api.selfoss.Sources
|
||||
import com.ftinc.scoop.Scoop
|
||||
import com.melnykov.fab.FloatingActionButton
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
|
||||
import kotlinx.android.synthetic.main.activity_sources.*
|
||||
|
||||
class SourcesActivity : AppCompatActivity() {
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
Scoop.getInstance().apply(this)
|
||||
setContentView(R.layout.activity_sources)
|
||||
val toolbar: Toolbar = findViewById(R.id.toolbar)
|
||||
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
recyclerView.clearOnScrollListeners()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
val mFab: FloatingActionButton = findViewById(R.id.fab)
|
||||
val mRecyclerView: RecyclerView = findViewById(R.id.activity_sources)
|
||||
val mLayoutManager = LinearLayoutManager(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))
|
||||
var items: ArrayList<Sources> = ArrayList()
|
||||
|
||||
mFab.attachToRecyclerView(mRecyclerView)
|
||||
mRecyclerView.setHasFixedSize(true)
|
||||
mRecyclerView.layoutManager = mLayoutManager
|
||||
recyclerView.setHasFixedSize(true)
|
||||
recyclerView.layoutManager = mLayoutManager
|
||||
|
||||
api.sources.enqueue(object : Callback<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>
|
||||
}
|
||||
val mAdapter = SourcesListAdapter(this@SourcesActivity, items, api)
|
||||
mRecyclerView.adapter = mAdapter
|
||||
recyclerView.adapter = mAdapter
|
||||
mAdapter.notifyDataSetChanged()
|
||||
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))
|
||||
}
|
||||
}
|
||||
|
@ -9,8 +9,6 @@ import android.support.v7.widget.RecyclerView
|
||||
import android.text.Html
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.ImageView.ScaleType
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
@ -38,6 +36,7 @@ import com.like.OnLikeListener
|
||||
import retrofit2.Call
|
||||
import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import kotlinx.android.synthetic.main.card_item.view.*
|
||||
|
||||
class ItemCardAdapter(private val app: Activity,
|
||||
private val items: ArrayList<Item>,
|
||||
@ -61,32 +60,32 @@ class ItemCardAdapter(private val app: Activity,
|
||||
val itm = items[position]
|
||||
|
||||
|
||||
holder.saveBtn.isLiked = itm.starred
|
||||
holder.title.text = Html.fromHtml(itm.title)
|
||||
holder.mView.favButton.isLiked = itm.starred
|
||||
holder.mView.title.text = Html.fromHtml(itm.title)
|
||||
|
||||
holder.sourceTitleAndDate.text = itm.sourceAndDateText()
|
||||
holder.mView.sourceTitleAndDate.text = itm.sourceAndDateText()
|
||||
|
||||
if (itm.getThumbnail(c).isEmpty()) {
|
||||
Glide.with(c).clear(holder.itemImage)
|
||||
holder.itemImage.setImageDrawable(null)
|
||||
Glide.with(c).clear(holder.mView.itemImage)
|
||||
holder.mView.itemImage.setImageDrawable(null)
|
||||
} else {
|
||||
c.bitmapCenterCrop(itm.getThumbnail(c), holder.itemImage)
|
||||
c.bitmapCenterCrop(itm.getThumbnail(c), holder.mView.itemImage)
|
||||
}
|
||||
|
||||
if (itm.getIcon(c).isEmpty()) {
|
||||
val color = generator.getColor(itm.sourcetitle)
|
||||
|
||||
val drawable =
|
||||
TextDrawable
|
||||
.builder()
|
||||
.round()
|
||||
.build(itm.sourcetitle.toTextDrawableString(), color)
|
||||
holder.sourceImage.setImageDrawable(drawable)
|
||||
TextDrawable
|
||||
.builder()
|
||||
.round()
|
||||
.build(itm.sourcetitle.toTextDrawableString(), color)
|
||||
holder.mView.sourceImage.setImageDrawable(drawable)
|
||||
} 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 {
|
||||
@ -128,13 +127,13 @@ class ItemCardAdapter(private val app: Activity,
|
||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
||||
if (!response.succeeded() && debugReadingItems) {
|
||||
val message =
|
||||
"message: ${response.message()} " +
|
||||
"response isSuccess: ${response.isSuccessful} " +
|
||||
"response code: ${response.code()} " +
|
||||
"response message: ${response.message()} " +
|
||||
"response errorBody: ${response.errorBody()?.string()} " +
|
||||
"body success: ${response.body()?.success} " +
|
||||
"body isSuccess: ${response.body()?.isSuccess}"
|
||||
"message: ${response.message()} " +
|
||||
"response isSuccess: ${response.isSuccessful} " +
|
||||
"response code: ${response.code()} " +
|
||||
"response message: ${response.message()} " +
|
||||
"response errorBody: ${response.errorBody()?.string()} " +
|
||||
"body success: ${response.body()?.success} " +
|
||||
"body isSuccess: ${response.body()?.isSuccess}"
|
||||
Crashlytics.setUserIdentifier(userIdentifier)
|
||||
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
||||
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
||||
@ -160,14 +159,6 @@ class ItemCardAdapter(private val app: Activity,
|
||||
}
|
||||
|
||||
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 {
|
||||
mView.setCardBackgroundColor(appColors.cardBackground)
|
||||
handleClickListeners()
|
||||
@ -175,27 +166,20 @@ class ItemCardAdapter(private val app: Activity,
|
||||
}
|
||||
|
||||
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) {
|
||||
itemImage.maxHeight = c.resources.getDimension(R.dimen.card_image_max_height).toInt()
|
||||
itemImage.scaleType = ScaleType.CENTER_CROP
|
||||
mView.itemImage.maxHeight = c.resources.getDimension(R.dimen.card_image_max_height).toInt()
|
||||
mView.itemImage.scaleType = ScaleType.CENTER_CROP
|
||||
}
|
||||
|
||||
saveBtn.setOnLikeListener(object : OnLikeListener {
|
||||
mView.favButton.setOnLikeListener(object : OnLikeListener {
|
||||
override fun liked(likeButton: LikeButton) {
|
||||
val (id) = items[adapterPosition]
|
||||
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
||||
|
||||
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()
|
||||
}
|
||||
})
|
||||
@ -207,18 +191,18 @@ class ItemCardAdapter(private val app: Activity,
|
||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
||||
|
||||
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()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
shareBtn.setOnClickListener {
|
||||
mView.shareBtn.setOnClickListener {
|
||||
c.shareLink(items[adapterPosition].getLinkDecoded())
|
||||
}
|
||||
|
||||
browserBtn.setOnClickListener {
|
||||
mView.browserBtn.setOnClickListener {
|
||||
c.openInBrowserAsNewTask(items[adapterPosition])
|
||||
}
|
||||
}
|
||||
@ -229,10 +213,14 @@ class ItemCardAdapter(private val app: Activity,
|
||||
|
||||
mView.setOnClickListener {
|
||||
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
|
||||
customTabsIntent,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
app)
|
||||
items[adapterPosition].content,
|
||||
items[adapterPosition].getThumbnail(c),
|
||||
items[adapterPosition].title,
|
||||
items[adapterPosition].sourceAndDateText(),
|
||||
customTabsIntent,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
app)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,9 +12,6 @@ import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
import android.widget.RelativeLayout
|
||||
import android.widget.TextView
|
||||
import android.widget.Toast
|
||||
import apps.amine.bou.readerforselfoss.R
|
||||
@ -40,7 +37,7 @@ import retrofit2.Callback
|
||||
import retrofit2.Response
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
import kotlinx.android.synthetic.main.list_item.view.*
|
||||
|
||||
class ItemListAdapter(private val app: Activity,
|
||||
private val items: ArrayList<Item>,
|
||||
@ -64,27 +61,27 @@ class ItemListAdapter(private val app: Activity,
|
||||
val itm = items[position]
|
||||
|
||||
|
||||
holder.saveBtn.isLiked = itm.starred
|
||||
holder.title.text = Html.fromHtml(itm.title)
|
||||
holder.mView.favButton.isLiked = itm.starred
|
||||
holder.mView.title.text = Html.fromHtml(itm.title)
|
||||
|
||||
holder.sourceTitleAndDate.text = itm.sourceAndDateText()
|
||||
holder.mView.sourceTitleAndDate.text = itm.sourceAndDateText()
|
||||
|
||||
if (itm.getThumbnail(c).isEmpty()) {
|
||||
val sizeInInt = 46
|
||||
val sizeInDp = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP, sizeInInt.toFloat(), c.resources
|
||||
.displayMetrics).toInt()
|
||||
TypedValue.COMPLEX_UNIT_DIP, sizeInInt.toFloat(), c.resources
|
||||
.displayMetrics).toInt()
|
||||
|
||||
val marginInInt = 16
|
||||
val marginInDp = TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP, marginInInt.toFloat(), c.resources
|
||||
.displayMetrics).toInt()
|
||||
|
||||
val params = holder.sourceImage.layoutParams as ViewGroup.MarginLayoutParams
|
||||
val params = holder.mView.itemImage.layoutParams as ViewGroup.MarginLayoutParams
|
||||
params.height = sizeInDp
|
||||
params.width = sizeInDp
|
||||
params.setMargins(marginInDp, 0, 0, 0)
|
||||
holder.sourceImage.layoutParams = params
|
||||
holder.mView.itemImage.layoutParams = params
|
||||
|
||||
if (itm.getIcon(c).isEmpty()) {
|
||||
val color = generator.getColor(itm.sourcetitle)
|
||||
@ -96,17 +93,17 @@ class ItemListAdapter(private val app: Activity,
|
||||
val builder = TextDrawable.builder().round()
|
||||
|
||||
val drawable = builder.build(textDrawable.toString(), color)
|
||||
holder.sourceImage.setImageDrawable(drawable)
|
||||
holder.mView.itemImage.setImageDrawable(drawable)
|
||||
} else {
|
||||
c.circularBitmapDrawable(itm.getIcon(c), holder.sourceImage)
|
||||
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.itemImage)
|
||||
}
|
||||
} 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
|
||||
@ -147,13 +144,13 @@ class ItemListAdapter(private val app: Activity,
|
||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {
|
||||
if (!response.succeeded() && debugReadingItems) {
|
||||
val message =
|
||||
"message: ${response.message()} " +
|
||||
"response isSuccess: ${response.isSuccessful} " +
|
||||
"response code: ${response.code()} " +
|
||||
"response message: ${response.message()} " +
|
||||
"response errorBody: ${response.errorBody()?.string()} " +
|
||||
"body success: ${response.body()?.success} " +
|
||||
"body isSuccess: ${response.body()?.isSuccess}"
|
||||
"message: ${response.message()} " +
|
||||
"response isSuccess: ${response.isSuccessful} " +
|
||||
"response code: ${response.code()} " +
|
||||
"response message: ${response.message()} " +
|
||||
"response errorBody: ${response.errorBody()?.string()} " +
|
||||
"body success: ${response.body()?.success} " +
|
||||
"body isSuccess: ${response.body()?.isSuccess}"
|
||||
Crashlytics.setUserIdentifier(userIdentifier)
|
||||
Crashlytics.log(100, "READ_DEBUG_SUCCESS", message)
|
||||
Crashlytics.logException(Exception("Was success, but did it work ?"))
|
||||
@ -179,13 +176,6 @@ class ItemListAdapter(private val app: Activity,
|
||||
}
|
||||
|
||||
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 {
|
||||
handleClickListeners()
|
||||
@ -193,23 +183,15 @@ class ItemListAdapter(private val app: Activity,
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
|
||||
saveBtn.setOnLikeListener(object : OnLikeListener {
|
||||
mView.favButton.setOnLikeListener(object : OnLikeListener {
|
||||
override fun liked(likeButton: LikeButton) {
|
||||
val (id) = items[adapterPosition]
|
||||
api.starrItem(id).enqueue(object : Callback<SuccessResponse> {
|
||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
||||
|
||||
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()
|
||||
}
|
||||
})
|
||||
@ -221,18 +203,18 @@ class ItemListAdapter(private val app: Activity,
|
||||
override fun onResponse(call: Call<SuccessResponse>, response: Response<SuccessResponse>) {}
|
||||
|
||||
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()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
shareBtn.setOnClickListener {
|
||||
mView.shareBtn.setOnClickListener {
|
||||
c.shareLink(items[adapterPosition].getLinkDecoded())
|
||||
}
|
||||
|
||||
browserBtn.setOnClickListener {
|
||||
mView.browserBtn.setOnClickListener {
|
||||
c.openInBrowserAsNewTask(items[adapterPosition])
|
||||
|
||||
}
|
||||
@ -247,10 +229,14 @@ class ItemListAdapter(private val app: Activity,
|
||||
if (!clickBehavior) {
|
||||
mView.setOnClickListener {
|
||||
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
|
||||
customTabsIntent,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
app)
|
||||
items[adapterPosition].content,
|
||||
items[adapterPosition].getThumbnail(c),
|
||||
items[adapterPosition].title,
|
||||
items[adapterPosition].sourceAndDateText(),
|
||||
customTabsIntent,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
app)
|
||||
}
|
||||
mView.setOnLongClickListener {
|
||||
actionBarShowHide()
|
||||
@ -260,10 +246,14 @@ class ItemListAdapter(private val app: Activity,
|
||||
mView.setOnClickListener { actionBarShowHide() }
|
||||
mView.setOnLongClickListener {
|
||||
c.openItemUrl(items[adapterPosition].getLinkDecoded(),
|
||||
customTabsIntent,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
app)
|
||||
items[adapterPosition].content,
|
||||
items[adapterPosition].getThumbnail(c),
|
||||
items[adapterPosition].title,
|
||||
items[adapterPosition].sourceAndDateText(),
|
||||
customTabsIntent,
|
||||
internalBrowser,
|
||||
articleViewer,
|
||||
app)
|
||||
true
|
||||
}
|
||||
}
|
||||
@ -271,7 +261,11 @@ class ItemListAdapter(private val app: Activity,
|
||||
|
||||
private fun actionBarShowHide() {
|
||||
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.Callback
|
||||
import retrofit2.Response
|
||||
import kotlinx.android.synthetic.main.source_list_item.view.*
|
||||
|
||||
|
||||
class SourcesListAdapter(private val app: Activity,
|
||||
@ -41,34 +42,27 @@ class SourcesListAdapter(private val app: Activity,
|
||||
val color = generator.getColor(itm.title)
|
||||
|
||||
val drawable =
|
||||
TextDrawable
|
||||
.builder()
|
||||
.round()
|
||||
.build(itm.title.toTextDrawableString(), color)
|
||||
holder.sourceImage.setImageDrawable(drawable)
|
||||
TextDrawable
|
||||
.builder()
|
||||
.round()
|
||||
.build(itm.title.toTextDrawableString(), color)
|
||||
holder.mView.itemImage.setImageDrawable(drawable)
|
||||
} else {
|
||||
c.circularBitmapDrawable(itm.getIcon(c), holder.sourceImage)
|
||||
c.circularBitmapDrawable(itm.getIcon(c), holder.mView.itemImage)
|
||||
}
|
||||
|
||||
holder.sourceTitle.text = itm.title
|
||||
holder.mView.sourceTitle.text = itm.title
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return items.size
|
||||
}
|
||||
override fun getItemCount(): Int = items.size
|
||||
|
||||
inner class ViewHolder(internal val mView: ConstraintLayout) : RecyclerView.ViewHolder(mView) {
|
||||
lateinit var sourceImage: ImageView
|
||||
lateinit var sourceTitle: TextView
|
||||
|
||||
init {
|
||||
|
||||
handleClickListeners()
|
||||
}
|
||||
|
||||
private fun handleClickListeners() {
|
||||
sourceImage = mView.findViewById(R.id.itemImage)
|
||||
sourceTitle = mView.findViewById(R.id.sourceTitle)
|
||||
|
||||
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,
|
||||
@SerializedName("datetime") val datetime: String,
|
||||
@SerializedName("title") val title: String,
|
||||
@SerializedName("content") val content: String,
|
||||
@SerializedName("unread") val unread: Boolean,
|
||||
@SerializedName("starred") val starred: Boolean,
|
||||
@SerializedName("thumbnail") val thumbnail: String,
|
||||
@ -72,15 +73,16 @@ data class Item(@SerializedName("id") val id: String,
|
||||
}
|
||||
|
||||
constructor(source: Parcel) : this(
|
||||
id = source.readString(),
|
||||
datetime = source.readString(),
|
||||
title = source.readString(),
|
||||
unread = 0.toByte() != source.readByte(),
|
||||
starred = 0.toByte() != source.readByte(),
|
||||
thumbnail = source.readString(),
|
||||
icon = source.readString(),
|
||||
link = source.readString(),
|
||||
sourcetitle = source.readString()
|
||||
id = source.readString(),
|
||||
datetime = source.readString(),
|
||||
title = source.readString(),
|
||||
content = source.readString(),
|
||||
unread = 0.toByte() != source.readByte(),
|
||||
starred = 0.toByte() != source.readByte(),
|
||||
thumbnail = source.readString(),
|
||||
icon = source.readString(),
|
||||
link = source.readString(),
|
||||
sourcetitle = source.readString()
|
||||
)
|
||||
|
||||
override fun describeContents() = 0
|
||||
@ -89,6 +91,7 @@ data class Item(@SerializedName("id") val id: String,
|
||||
dest.writeString(id)
|
||||
dest.writeString(datetime)
|
||||
dest.writeString(title)
|
||||
dest.writeString(content)
|
||||
dest.writeByte((if (unread) 1 else 0))
|
||||
dest.writeByte((if (starred) 1 else 0))
|
||||
dest.writeString(thumbnail)
|
||||
|
@ -51,19 +51,28 @@ fun Context.buildCustomTabsIntent(): CustomTabsIntent {
|
||||
}
|
||||
|
||||
fun Context.openItemUrlInternally(linkDecoded: String,
|
||||
content: String,
|
||||
image: String,
|
||||
title: String,
|
||||
source: String,
|
||||
customTabsIntent: CustomTabsIntent,
|
||||
articleViewer: Boolean,
|
||||
app: Activity) {
|
||||
if (articleViewer) {
|
||||
val intent = Intent(this, ReaderActivity::class.java)
|
||||
|
||||
DragDismissIntentBuilder(this)
|
||||
.setFullscreenOnTablets(true) // defaults to false, tablets will have padding on each side
|
||||
.setDragElasticity(DragDismissIntentBuilder.DragElasticity.NORMAL) // Larger elasticities will make it easier to dismiss.
|
||||
.setDrawUnderStatusBar(true)
|
||||
.build(intent)
|
||||
/*DragDismissIntentBuilder(this)
|
||||
.setFullscreenOnTablets(true) // defaults to false, tablets will have padding on each side
|
||||
.setDragElasticity(DragDismissIntentBuilder.DragElasticity.NORMAL) // Larger elasticities will make it easier to dismiss.
|
||||
.setDrawUnderStatusBar(true)
|
||||
.build(intent)*/
|
||||
|
||||
|
||||
intent.putExtra("url", linkDecoded)
|
||||
intent.putExtra("content", content)
|
||||
intent.putExtra("title", title)
|
||||
intent.putExtra("image", image)
|
||||
intent.putExtra("source", source)
|
||||
app.startActivity(intent)
|
||||
} else {
|
||||
try {
|
||||
@ -80,6 +89,10 @@ fun Context.openItemUrlInternally(linkDecoded: String,
|
||||
}
|
||||
|
||||
fun Context.openItemUrl(linkDecoded: String,
|
||||
content: String,
|
||||
image: String,
|
||||
title: String,
|
||||
source: String,
|
||||
customTabsIntent: CustomTabsIntent,
|
||||
internalBrowser: Boolean,
|
||||
articleViewer: Boolean,
|
||||
@ -91,7 +104,7 @@ fun Context.openItemUrl(linkDecoded: String,
|
||||
if (!internalBrowser) {
|
||||
openInBrowser(linkDecoded, app)
|
||||
} 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 =
|
||||
HttpUrl.parse(this) != null && Patterns.WEB_URL.matcher(this).matches()
|
||||
HttpUrl.parse(this) != null && Patterns.WEB_URL.matcher(this).matches()
|
||||
|
||||
fun String.isBaseUrlValid(): Boolean {
|
||||
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">
|
||||
|
||||
<com.github.stkent.amplify.prompt.DefaultLayoutPromptView
|
||||
android:id="@+id/prompt_view"
|
||||
android:id="@+id/promptView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:prompt_view_user_opinion_question_title="@string/rating_prompt_title"
|
||||
@ -34,7 +34,7 @@
|
||||
android:id="@+id/coordLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_below="@id/prompt_view">
|
||||
android:layout_below="@id/promptView">
|
||||
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
android:id="@+id/intern_coordLayout"
|
||||
@ -51,7 +51,7 @@
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:id="@+id/toolBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:theme="@style/ToolBarStyle"
|
||||
@ -89,7 +89,7 @@
|
||||
android:background="@color/transparent"
|
||||
android:visibility="gone" />
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/my_recycler_view"
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/transparent"
|
||||
|
@ -28,7 +28,7 @@
|
||||
android:paddingTop="@dimen/activity_vertical_margin">
|
||||
<!-- Login progress -->
|
||||
<ProgressBar
|
||||
android:id="@+id/login_progress"
|
||||
android:id="@+id/loginProgress"
|
||||
style="?android:attr/progressBarStyleLarge"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
@ -36,7 +36,7 @@
|
||||
android:visibility="gone"/>
|
||||
|
||||
<ScrollView
|
||||
android:id="@+id/login_form"
|
||||
android:id="@+id/loginForm"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
@ -52,14 +52,13 @@
|
||||
>
|
||||
|
||||
<EditText
|
||||
android:id="@+id/url"
|
||||
android:id="@+id/urlView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/prompt_url"
|
||||
android:imeOptions="actionUnspecified"
|
||||
android:inputType="textUri"
|
||||
android:maxLines="1"
|
||||
/>
|
||||
android:maxLines="1" />
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
@ -77,13 +76,12 @@
|
||||
android:visibility="gone">
|
||||
|
||||
<AutoCompleteTextView
|
||||
android:id="@+id/login"
|
||||
android:id="@+id/loginView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/prompt_login"
|
||||
android:inputType="text"
|
||||
android:maxLines="1"
|
||||
/>
|
||||
android:maxLines="1" />
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
@ -94,13 +92,12 @@
|
||||
android:visibility="gone">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/password"
|
||||
android:id="@+id/passwordView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/prompt_password"
|
||||
android:inputType="textPassword"
|
||||
android:maxLines="1"
|
||||
/>
|
||||
android:maxLines="1" />
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
@ -118,7 +115,7 @@
|
||||
android:visibility="gone">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/httpLogin"
|
||||
android:id="@+id/httpLoginView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:hint="@string/prompt_http_login" />
|
||||
@ -131,11 +128,11 @@
|
||||
android:visibility="gone">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/httpPassword"
|
||||
android:id="@+id/httpPasswordView"
|
||||
android:layout_width="match_parent"
|
||||
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>
|
||||
|
||||
<Switch
|
||||
@ -153,7 +150,7 @@
|
||||
android:visibility="gone" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/email_sign_in_button"
|
||||
android:id="@+id/signInButton"
|
||||
style="?android:textAppearanceSmall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -1,126 +1,148 @@
|
||||
<?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:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context="apps.amine.bou.readerforselfoss.ReaderActivity"
|
||||
android:background="?android:attr/windowBackground">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<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/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.support.v4.widget.NestedScrollView
|
||||
android:id="@+id/nestedScrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="35dp"
|
||||
android:layout_marginBottom="0dp"
|
||||
android:layout_marginEnd="0dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:background="#BBBBBB"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<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_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/content"
|
||||
app:layout_constraintVertical_bias="1.0">
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
android:layout_gravity="end|bottom|right">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/browserBtn"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:layout_centerVertical="true"
|
||||
<com.github.rubensousa.floatingtoolbar.FloatingToolbar
|
||||
android:id="@+id/floatingToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
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_marginRight="16dp"
|
||||
android:layout_toLeftOf="@+id/shareBtn"
|
||||
android:layout_toStartOf="@+id/shareBtn"
|
||||
android:adjustViewBounds="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:elevation="5dp"
|
||||
android:padding="4dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/ic_open_in_browser_black_24dp"
|
||||
android:tint="@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" />
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:src="@drawable/ic_add"
|
||||
app:backgroundTint="?attr/colorAccent"
|
||||
app:fabSize="mini"
|
||||
app:rippleColor="?attr/colorAccentDark" />
|
||||
</FrameLayout>
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/shareBtn"
|
||||
android:layout_width="35dp"
|
||||
android:layout_height="35dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:background="@android:color/transparent"
|
||||
android:elevation="5dp"
|
||||
android:padding="4dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/ic_share_black_24dp"
|
||||
android:tint="@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" />
|
||||
<FrameLayout
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="gone"
|
||||
android:animateLayoutChanges="true"
|
||||
android:alpha="0.8"
|
||||
android:background="@color/black"
|
||||
android:clickable="false">
|
||||
|
||||
</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"?>
|
||||
|
||||
<RelativeLayout
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
@ -22,23 +22,19 @@
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/activity_sources"
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:scrollbars="vertical"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
</android.support.v7.widget.RecyclerView>
|
||||
|
||||
<com.melnykov.fab.FloatingActionButton
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="end|bottom|right"
|
||||
android:src="@drawable/ic_add_black_24dp"
|
||||
android:tint="?android:textColorPrimary"
|
||||
fab:fab_colorNormal="?attr/colorAccent"
|
||||
fab:fab_colorPressed="?attr/colorAccentDark"
|
||||
fab:fab_colorRipple="@color/pink"
|
||||
android:src="@drawable/ic_add"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:layout_alignParentBottom="true"
|
||||
@ -46,5 +42,6 @@
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginRight="16dp"/>
|
||||
</RelativeLayout>
|
||||
android:layout_marginRight="16dp"
|
||||
app:layout_behavior="apps.amine.bou.readerforselfoss.utils.ScrollAwareFABBehavior" />
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
@ -1,55 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="88dp">
|
||||
|
||||
|
||||
<android.support.constraint.Guideline
|
||||
android:id="@+id/guideline4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintGuide_begin="99dp" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/itemImage"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="88dp"
|
||||
android:src="@color/about_libraries_accent"
|
||||
app:layout_constraintBottom_toTopOf="@+id/actionBar"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
/>
|
||||
app:layout_constraintBottom_toTopOf="@+id/guideline4"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:fontFamily="sans-serif"
|
||||
android:gravity="start"
|
||||
android:maxLines="3"
|
||||
android:ellipsize="end"
|
||||
android:textAlignment="viewStart"
|
||||
android:textAllCaps="false"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/sourceTitleAndDate"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintLeft_toRightOf="@+id/itemImage"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/itemImage"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
tools:text="Titre" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/sourceTitleAndDate"
|
||||
android:textSize="14sp"
|
||||
tools:text="Google Actualité Il y a 5h"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:gravity="start"
|
||||
android:textAlignment="viewStart"
|
||||
app:layout_constraintTop_toBottomOf="@+id/title"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintLeft_toLeftOf="@+id/title"
|
||||
android:gravity="start" />
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/guideline4"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toEndOf="@+id/itemImage"
|
||||
tools:text="Google Actualité Il y a 5h" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/actionBar"
|
||||
@ -58,9 +69,11 @@
|
||||
android:background="#BBBBBB"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/sourceTitleAndDate">
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/guideline4"
|
||||
app:layout_constraintVertical_bias="1.0"
|
||||
tools:visibility="visible">
|
||||
|
||||
<com.like.LikeButton
|
||||
android:id="@+id/favButton"
|
||||
@ -68,7 +81,6 @@
|
||||
android:layout_height="35dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentRight="true"
|
||||
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
@ -110,7 +122,7 @@
|
||||
android:padding="4dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/ic_open_in_browser_black_24dp" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
@ -3,7 +3,7 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<item
|
||||
android:id="@+id/loging_debug"
|
||||
android:id="@+id/login_debug"
|
||||
android:checkable="true"
|
||||
android:checked="false"
|
||||
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>
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Übersetzung</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Log de tous les appels à l\'API</string>
|
||||
<string name="login_everything_on">Tous les appels à l\'API vont êtres logués</string>
|
||||
<string name="login_everything_off">Aucun appel à l\'API ne sera logué</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Charger plus d\'articles au scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Charger plus d\'articles au scroll</string>
|
||||
<string name="translation">Traduction</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Vertaling</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Registrando todas as chamadas a api</string>
|
||||
<string name="login_everything_on">Isso registrará todas as chamadas api para fins de depuração.</string>
|
||||
<string name="login_everything_off">Nenhuma chamada a api será registrada</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Carregar mais artigos ao realizar o scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Carregar mais artigos ao realizar o scroll</string>
|
||||
<string name="translation">Traduções</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -150,9 +150,12 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="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>
|
||||
|
@ -151,11 +151,14 @@
|
||||
<string name="login_everything_title">Logging every api calls</string>
|
||||
<string name="login_everything_on">This will log every api call for debug purpose.</string>
|
||||
<string name="login_everything_off">No api call will be logged</string>
|
||||
<string name="pref_general_infinite_loading_title">(BETA) Load more articles on scroll</string>
|
||||
<string name="pref_general_infinite_loading_title">Load more articles on scroll</string>
|
||||
<string name="translation">Translation</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="report_github_user" translatable="false">aminecmi</string>
|
||||
<string name="report_github_repo" translatable="false">ReaderforSelfoss</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="reader_action_more">Read more</string>
|
||||
<string name="reader_action_open">Open in browser</string>
|
||||
<string name="reader_action_share">Share</string>
|
||||
</resources>
|
@ -10,7 +10,7 @@
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="loging_debug"
|
||||
android:key="login_debug"
|
||||
android:summaryOff="@string/login_debug_off"
|
||||
android:summaryOn="@string/login_debug_on"
|
||||
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.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.1.51'
|
||||
ext.kotlin_version = '1.1.60'
|
||||
repositories {
|
||||
jcenter()
|
||||
google()
|
||||
@ -10,12 +10,12 @@ buildscript {
|
||||
}
|
||||
}
|
||||
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"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// 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
|
||||
classpath "com.github.Shusshu:sonar-scanner-gradle:feature~support-android-gradle-3-SNAPSHOT"
|
||||
|