Some code cleaning.

This commit is contained in:
Amine 2017-11-04 11:33:22 +01:00
parent 133ba74548
commit deb789bc1b
10 changed files with 150 additions and 115 deletions

View File

@ -50,17 +50,22 @@ class AddSourceActivity : AppCompatActivity() {
mustLoginToAddSource() mustLoginToAddSource()
} }
val intent = intent maybeGetDetailsFromIntentSharing(intent, mSourceUri, mNameInput)
if (Intent.ACTION_SEND == intent.action && "text/plain" == intent.type) {
mSourceUri.setText(intent.getStringExtra(Intent.EXTRA_TEXT))
mNameInput.setText(intent.getStringExtra(Intent.EXTRA_TITLE))
}
mSaveBtn.setOnClickListener { mSaveBtn.setOnClickListener {
handleSaveSource(mTags, mNameInput.text.toString(), mSourceUri.text.toString(), api!!) handleSaveSource(mTags, mNameInput.text.toString(), mSourceUri.text.toString(), api!!)
} }
val config = Config(this)
if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid()) {
mustLoginToAddSource()
} else {
handleSpoutsSpinner(mSpoutsSpinner, api, mProgress, mForm)
}
}
private fun handleSpoutsSpinner(mSpoutsSpinner: Spinner, api: SelfossApi?, mProgress: ProgressBar, mForm: ConstraintLayout) {
val spoutsKV = HashMap<String, String>() val spoutsKV = HashMap<String, String>()
mSpoutsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { mSpoutsSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(adapterView: AdapterView<*>, view: View, i: Int, l: Long) { override fun onItemSelected(adapterView: AdapterView<*>, view: View, i: Int, l: Long) {
@ -73,48 +78,48 @@ class AddSourceActivity : AppCompatActivity() {
} }
} }
val config = Config(this) var items: Map<String, Spout>
api!!.spouts().enqueue(object : Callback<Map<String, Spout>> {
override fun onResponse(call: Call<Map<String, Spout>>, response: Response<Map<String, Spout>>) {
if (response.body() != null) {
items = response.body()!!
if (config.baseUrl.isEmpty() || !config.baseUrl.isBaseUrlValid()) { val itemsStrings = items.map { it.value.name }
mustLoginToAddSource() for ((key, value) in items) {
} else { spoutsKV.put(value.name, key)
var items: Map<String, Spout>
api!!.spouts().enqueue(object : Callback<Map<String, Spout>> {
override fun onResponse(call: Call<Map<String, Spout>>, response: Response<Map<String, Spout>>) {
if (response.body() != null) {
items = response.body()!!
val itemsStrings = items.map { it.value.name }
for ((key, value) in items) {
spoutsKV.put(value.name, key)
}
mProgress.visibility = View.GONE
mForm.visibility = View.VISIBLE
val spinnerArrayAdapter =
ArrayAdapter(
this@AddSourceActivity,
android.R.layout.simple_spinner_item,
itemsStrings)
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
mSpoutsSpinner.adapter = spinnerArrayAdapter
} else {
handleProblemWithSpouts()
} }
}
override fun onFailure(call: Call<Map<String, Spout>>, t: Throwable) { mProgress.visibility = View.GONE
mForm.visibility = View.VISIBLE
val spinnerArrayAdapter =
ArrayAdapter(
this@AddSourceActivity,
android.R.layout.simple_spinner_item,
itemsStrings)
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
mSpoutsSpinner.adapter = spinnerArrayAdapter
} else {
handleProblemWithSpouts() handleProblemWithSpouts()
} }
}
private fun handleProblemWithSpouts() { override fun onFailure(call: Call<Map<String, Spout>>, t: Throwable) {
Toast.makeText(this@AddSourceActivity, R.string.cant_get_spouts, Toast.LENGTH_SHORT).show() handleProblemWithSpouts()
mProgress.visibility = View.GONE }
}
}) private fun handleProblemWithSpouts() {
Toast.makeText(this@AddSourceActivity, R.string.cant_get_spouts, Toast.LENGTH_SHORT).show()
mProgress.visibility = View.GONE
}
})
}
private fun maybeGetDetailsFromIntentSharing(intent: Intent, mSourceUri: EditText, mNameInput: 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))
} }
} }
@ -127,7 +132,9 @@ class AddSourceActivity : AppCompatActivity() {
private fun handleSaveSource(mTags: EditText, title: String, url: String, api: SelfossApi) { private fun handleSaveSource(mTags: EditText, title: String, url: String, api: SelfossApi) {
if (title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()) { val sourceDetailsAvailable = title.isEmpty() || url.isEmpty() || mSpoutsValue == null || mSpoutsValue!!.isEmpty()
if (sourceDetailsAvailable) {
Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show() Toast.makeText(this, R.string.form_not_complete, Toast.LENGTH_SHORT).show()
} else { } else {
api.createSource( api.createSource(

View File

@ -62,6 +62,7 @@ import apps.amine.bou.readerforselfoss.utils.longHash
import com.ashokvarma.bottomnavigation.BottomNavigationBar import com.ashokvarma.bottomnavigation.BottomNavigationBar
import com.ashokvarma.bottomnavigation.BottomNavigationItem import com.ashokvarma.bottomnavigation.BottomNavigationItem
import com.ashokvarma.bottomnavigation.TextBadgeItem import com.ashokvarma.bottomnavigation.TextBadgeItem
import com.crashlytics.android.Crashlytics
import com.ftinc.scoop.Scoop import com.ftinc.scoop.Scoop
import com.heinrichreimersoftware.androidissuereporter.IssueReporterLauncher import com.heinrichreimersoftware.androidissuereporter.IssueReporterLauncher
import com.mikepenz.materialdrawer.AccountHeader import com.mikepenz.materialdrawer.AccountHeader
@ -172,6 +173,10 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
reloadLayoutManager() reloadLayoutManager()
handleSwipeRefreshLayout()
}
private fun handleSwipeRefreshLayout() {
swipeRefreshLayout.setColorSchemeResources( swipeRefreshLayout.setColorSchemeResources(
R.color.refresh_progress_1, R.color.refresh_progress_1,
R.color.refresh_progress_2, R.color.refresh_progress_2,
@ -189,7 +194,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
override fun onMove(recyclerView: RecyclerView, override fun onMove(recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder, viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder): Boolean = false target: RecyclerView.ViewHolder): Boolean = false
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) { override fun onSwiped(viewHolder: RecyclerView.ViewHolder, swipeDir: Int) {
try { try {
@ -219,7 +224,11 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
getElementsAccordingToTab(appendResults = true) getElementsAccordingToTab(appendResults = true)
} }
} catch (e: IndexOutOfBoundsException) {} } catch (e: IndexOutOfBoundsException) {
Crashlytics.setUserIdentifier(userIdentifier)
Crashlytics.log(100, "SWIPE_INDEX_OUT_OF_BOUND", "IndexOutOfBoundsException when swiping")
Crashlytics.logException(e)
}
} }
} }
@ -578,7 +587,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
drawer.addItem(PrimaryDrawerItem().withName(getString(R.string.drawer_loading)).withSelectable(false)) drawer.addItem(PrimaryDrawerItem().withName(getString(R.string.drawer_loading)).withSelectable(false))
val resultType = object : TypeToken<DrawerData>() {}.type val resultType = object : TypeToken<DrawerData>() {}.type //NOSONAR
Reservoir.getAsync("drawerData", resultType, object: ReservoirGetCallback<DrawerData> { Reservoir.getAsync("drawerData", resultType, object: ReservoirGetCallback<DrawerData> {
override fun onSuccess(maybeDrawerData: DrawerData?) { override fun onSuccess(maybeDrawerData: DrawerData?) {
handleDrawerData(maybeDrawerData, loadedFromCache = true) handleDrawerData(maybeDrawerData, loadedFromCache = true)
@ -605,31 +614,14 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
recyclerView.setHasFixedSize(true) recyclerView.setHasFixedSize(true)
if (infiniteScroll) { if (infiniteScroll) {
if (recyclerViewScrollListener == null) handleInfiniteScroll()
recyclerViewScrollListener = object: RecyclerView.OnScrollListener() {
override fun onScrolled(localRecycler: RecyclerView?, dx: Int, dy: Int) {
if (dy > 0) {
if (localRecycler != null) {
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)
}
}
}
}
}
recyclerView.clearOnScrollListeners()
recyclerView.addOnScrollListener(recyclerViewScrollListener)
} }
bottomBar.setTabSelectedListener(object: BottomNavigationBar.OnTabSelectedListener { handleBottomBarActions(mLayoutManager)
}
private fun handleBottomBarActions(mLayoutManager: RecyclerView.LayoutManager) {
bottomBar.setTabSelectedListener(object : BottomNavigationBar.OnTabSelectedListener {
override fun onTabUnselected(position: Int) = Unit override fun onTabUnselected(position: Int) = Unit
override fun onTabReselected(position: Int) = override fun onTabReselected(position: Int) =
@ -650,7 +642,7 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
} }
override fun onTabSelected(position: Int) = override fun onTabSelected(position: Int) =
when(position) { when (position) {
0 -> getUnRead() 0 -> getUnRead()
1 -> getRead() 1 -> getRead()
2 -> getStarred() 2 -> getStarred()
@ -660,6 +652,29 @@ class HomeActivity : AppCompatActivity(), SearchView.OnQueryTextListener {
}) })
} }
private fun handleInfiniteScroll() {
if (recyclerViewScrollListener == null)
recyclerViewScrollListener = object : RecyclerView.OnScrollListener() {
override fun onScrolled(localRecycler: RecyclerView?, dx: Int, dy: Int) {
if (localRecycler != null && dy > 0) {
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)
}
}
}
}
recyclerView.clearOnScrollListeners()
recyclerView.addOnScrollListener(recyclerViewScrollListener)
}
fun mayBeEmpty() = fun mayBeEmpty() =
if (items.isEmpty()) { if (items.isEmpty()) {
emptyText.visibility = View.VISIBLE emptyText.visibility = View.VISIBLE

View File

@ -60,16 +60,7 @@ class LoginActivity : AppCompatActivity() {
val toolbar: Toolbar = findViewById(R.id.toolbar) val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar) setSupportActionBar(toolbar)
if (intent.getBooleanExtra("baseUrlFail", false)) { handleBaseUrlFail()
val alertDialog = AlertDialog.Builder(this).create()
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.show()
}
settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE) settings = getSharedPreferences(Config.settingsName, Context.MODE_PRIVATE)
@ -91,6 +82,10 @@ class LoginActivity : AppCompatActivity() {
mLoginFormView = findViewById(R.id.login_form) mLoginFormView = findViewById(R.id.login_form)
mProgressView = findViewById(R.id.login_progress) mProgressView = findViewById(R.id.login_progress)
handleActions()
}
private fun handleActions() {
val mSwitch: Switch = findViewById(R.id.withLogin) val mSwitch: Switch = findViewById(R.id.withLogin)
val mHTTPSwitch: Switch = findViewById(R.id.withHttpLogin) val mHTTPSwitch: Switch = findViewById(R.id.withHttpLogin)
val mLoginLayout: TextInputLayout = findViewById(R.id.loginLayout) val mLoginLayout: TextInputLayout = findViewById(R.id.loginLayout)
@ -101,7 +96,7 @@ class LoginActivity : AppCompatActivity() {
val selfHostedSwitch: Switch = findViewById(R.id.withSelfhostedCert) val selfHostedSwitch: Switch = findViewById(R.id.withSelfhostedCert)
val warningTextview: TextView = findViewById(R.id.warningText) val warningTextview: TextView = findViewById(R.id.warningText)
selfHostedSwitch.setOnCheckedChangeListener {_, b -> selfHostedSwitch.setOnCheckedChangeListener { _, b ->
isWithSelfSignedCert = !isWithSelfSignedCert isWithSelfSignedCert = !isWithSelfSignedCert
val visi: Int = if (b) View.VISIBLE else View.GONE val visi: Int = if (b) View.VISIBLE else View.GONE
@ -135,6 +130,19 @@ class LoginActivity : AppCompatActivity() {
} }
} }
private fun handleBaseUrlFail() {
if (intent.getBooleanExtra("baseUrlFail", false)) {
val alertDialog = AlertDialog.Builder(this).create()
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.show()
}
}
private fun goToMain() { private fun goToMain() {
val intent = Intent(this, HomeActivity::class.java) val intent = Intent(this, HomeActivity::class.java)
startActivity(intent) startActivity(intent)
@ -244,9 +252,7 @@ class LoginActivity : AppCompatActivity() {
} }
} }
/**
* Shows the progress UI and hides the login form.
*/
private fun showProgress(show: Boolean) { private fun showProgress(show: Boolean) {
val shortAnimTime = resources.getInteger(android.R.integer.config_shortAnimTime) val shortAnimTime = resources.getInteger(android.R.integer.config_shortAnimTime)

View File

@ -24,7 +24,6 @@ import okhttp3.logging.HttpLoggingInterceptor
// codebeat:disable[ARITY,TOO_MANY_FUNCTIONS]
class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Boolean, shouldLog: Boolean) { class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Boolean, shouldLog: Boolean) {
private lateinit var service: SelfossService private lateinit var service: SelfossService
@ -148,5 +147,3 @@ class SelfossApi(c: Context, callingActivity: Activity, isWithSelfSignedCert: Bo
service.createSource(title, url, spout, tags, filter, userName, password) service.createSource(title, url, spout, tags, filter, userName, password)
} }
// codebeat:enable[ARITY,TOO_MANY_FUNCTIONS]

View File

@ -4,7 +4,6 @@ import retrofit2.Call
import retrofit2.http.* import retrofit2.http.*
// codebeat:disable[ARITY]
internal interface SelfossService { internal interface SelfossService {
@GET("login") @GET("login")
@ -98,4 +97,3 @@ internal interface SelfossService {
@Query("username") username: String, @Query("username") username: String,
@Query("password") password: String): Call<SuccessResponse> @Query("password") password: String): Call<SuccessResponse>
} }
// codebeat:disable[ARITY]

View File

@ -24,7 +24,7 @@ import com.ftinc.scoop.Scoop;
* A {@link PreferenceActivity} which implements and proxies the necessary calls * A {@link PreferenceActivity} which implements and proxies the necessary calls
* to be used with AppCompat. * to be used with AppCompat.
*/ */
public abstract class AppCompatPreferenceActivity extends PreferenceActivity { public abstract class AppCompatPreferenceActivity extends PreferenceActivity { //NOSONAR
private AppCompatDelegate mDelegate; private AppCompatDelegate mDelegate;
@ -116,6 +116,7 @@ public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
getDelegate().onDestroy(); getDelegate().onDestroy();
} }
@Override
public void invalidateOptionsMenu() { public void invalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu(); getDelegate().invalidateOptionsMenu();
} }

View File

@ -44,7 +44,7 @@ import com.ftinc.scoop.ui.ScoopSettingsActivity;
* href="http://developer.android.com/guide/topics/ui/settings.html">Settings * href="http://developer.android.com/guide/topics/ui/settings.html">Settings
* API Guide</a> for more information on developing a Settings UI. * API Guide</a> for more information on developing a Settings UI.
*/ */
public class SettingsActivity extends AppCompatPreferenceActivity { public class SettingsActivity extends AppCompatPreferenceActivity { //NOSONAR
/** /**
* A preference value change listener that updates the preference's summary * A preference value change listener that updates the preference's summary
* to reflect its new value. * to reflect its new value.
@ -126,6 +126,7 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
* This method stops fragment injection in malicious applications. * This method stops fragment injection in malicious applications.
* Make sure to deny any unknown fragments here. * Make sure to deny any unknown fragments here.
*/ */
@Override
protected boolean isValidFragment(String fragmentName) { protected boolean isValidFragment(String fragmentName) {
return PreferenceFragment.class.getName().equals(fragmentName) return PreferenceFragment.class.getName().equals(fragmentName)
|| GeneralPreferenceFragment.class.getName().equals(fragmentName) || GeneralPreferenceFragment.class.getName().equals(fragmentName)
@ -166,7 +167,9 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
int input = Integer.parseInt(dest.toString() + source.toString()); int input = Integer.parseInt(dest.toString() + source.toString());
if (input <= 200 && input >0) if (input <= 200 && input >0)
return null; return null;
} catch (NumberFormatException nfe) { } } catch (NumberFormatException nfe) {
Toast.makeText(getActivity(), R.string.items_number_should_be_number, Toast.LENGTH_LONG).show();
}
return ""; return "";
} }
} }

View File

@ -50,6 +50,35 @@ fun Context.buildCustomTabsIntent(): CustomTabsIntent {
return intentBuilder.build() return intentBuilder.build()
} }
fun Context.openItemUrlInternally(linkDecoded: 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)
intent.putExtra("url", linkDecoded)
app.startActivity(intent)
} else {
try {
CustomTabActivityHelper.openCustomTab(app, customTabsIntent, Uri.parse(linkDecoded)
) { _, uri ->
val intent = Intent(Intent.ACTION_VIEW, uri)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
} catch (e: Exception) {
openInBrowser(linkDecoded, app)
}
}
}
fun Context.openItemUrl(linkDecoded: String, fun Context.openItemUrl(linkDecoded: String,
customTabsIntent: CustomTabsIntent, customTabsIntent: CustomTabsIntent,
internalBrowser: Boolean, internalBrowser: Boolean,
@ -62,29 +91,7 @@ fun Context.openItemUrl(linkDecoded: String,
if (!internalBrowser) { if (!internalBrowser) {
openInBrowser(linkDecoded, app) openInBrowser(linkDecoded, app)
} else { } else {
if (articleViewer) { this.openItemUrlInternally(linkDecoded, customTabsIntent, articleViewer, app)
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)
intent.putExtra("url", linkDecoded)
app.startActivity(intent)
} else {
try {
CustomTabActivityHelper.openCustomTab(app, customTabsIntent, Uri.parse(linkDecoded)
) { _, uri ->
val intent = Intent(Intent.ACTION_VIEW, uri)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
} catch (e: Exception) {
openInBrowser(linkDecoded, app)
}
}
} }
} }
} }

View File

@ -101,7 +101,7 @@ class CustomTabsHelper {
List<ResolveInfo> handlers = pm.queryIntentActivities( List<ResolveInfo> handlers = pm.queryIntentActivities(
intent, intent,
PackageManager.GET_RESOLVED_FILTER); PackageManager.GET_RESOLVED_FILTER);
if (handlers == null || handlers.size() == 0) { if (handlers == null || handlers.isEmpty()) {
return false; return false;
} }
for (ResolveInfo resolveInfo : handlers) { for (ResolveInfo resolveInfo : handlers) {

View File

@ -157,4 +157,5 @@
<string name="report_github_user" translatable="false">aminecmi</string> <string name="report_github_user" translatable="false">aminecmi</string>
<string name="report_github_repo" translatable="false">ReaderforSelfoss</string> <string name="report_github_repo" translatable="false">ReaderforSelfoss</string>
<string name="drawer_report_bug">Report a bug</string> <string name="drawer_report_bug">Report a bug</string>
<string name="items_number_should_be_number">The items number should be an integer.</string>
</resources> </resources>