From a4a60c596d397ccf5e808eb468ee793343ab11f1 Mon Sep 17 00:00:00 2001 From: Josh Sharp Date: Thu, 30 Jul 2020 16:15:51 +1000 Subject: [PATCH] add swiperefreshlayout --- build.gradle | 4 +- .../com/joshsharp/wishkobone/LoginActivity.kt | 6 +- .../com/joshsharp/wishkobone/MainActivity.kt | 78 +++++++++++++++++-- src/main/res/layout/activity_login.xml | 17 ++++ src/main/res/layout/activity_main.xml | 75 ++++++++++++++---- src/main/res/layout/drawer_header.xml | 24 ++++++ src/main/res/menu/menu_nav.xml | 5 ++ src/main/res/values/colors.xml | 3 +- src/main/res/values/strings.xml | 2 + src/main/res/values/styles.xml | 2 +- 10 files changed, 191 insertions(+), 25 deletions(-) create mode 100644 src/main/res/layout/drawer_header.xml create mode 100644 src/main/res/menu/menu_nav.xml diff --git a/build.gradle b/build.gradle index 78c31e6..f0033ca 100644 --- a/build.gradle +++ b/build.gradle @@ -40,11 +40,13 @@ dependencies { implementation 'androidx.core:core-ktx:1.3.0' implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + implementation "androidx.drawerlayout:drawerlayout:1.1.0" implementation "com.squareup.okhttp3:okhttp:4.7.2" implementation 'androidx.recyclerview:recyclerview:1.1.0' implementation "io.coil-kt:coil:0.11.0" - implementation 'com.quiph.ui:recyclerviewfastscroller:0.1.3' + implementation 'com.quiph.ui:recyclerviewfastscroller:0.2.0' implementation 'com.google.android.material:material:1.1.0' + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' diff --git a/src/main/java/au/com/joshsharp/wishkobone/LoginActivity.kt b/src/main/java/au/com/joshsharp/wishkobone/LoginActivity.kt index b571509..22bae1d 100644 --- a/src/main/java/au/com/joshsharp/wishkobone/LoginActivity.kt +++ b/src/main/java/au/com/joshsharp/wishkobone/LoginActivity.kt @@ -15,6 +15,7 @@ class LoginActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) + setSupportActionBar(toolbar) supportActionBar?.title = "Login to Kobo to continue" val cookieManager = CookieManager.getInstance() @@ -22,7 +23,6 @@ class LoginActivity : AppCompatActivity() { cookieManager.setAcceptThirdPartyCookies(web, true) web.settings.javaScriptEnabled = true; - web.loadUrl("https://www.kobo.com/account/wishlist") web.webViewClient = object: WebViewClient() { override fun onPageFinished(view: WebView?, url: String?) { super.onPageFinished(view, url) @@ -38,6 +38,10 @@ class LoginActivity : AppCompatActivity() { } } } + + cookieManager.removeAllCookies { + web.loadUrl("https://www.kobo.com/account/wishlist") + } } fun getCookie(siteName: String, name: String): String? { diff --git a/src/main/java/au/com/joshsharp/wishkobone/MainActivity.kt b/src/main/java/au/com/joshsharp/wishkobone/MainActivity.kt index b3f4157..ed8c782 100644 --- a/src/main/java/au/com/joshsharp/wishkobone/MainActivity.kt +++ b/src/main/java/au/com/joshsharp/wishkobone/MainActivity.kt @@ -16,6 +16,7 @@ import android.view.ViewGroup import android.widget.ImageView import android.widget.TextView import android.widget.Toast +import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.SearchView import androidx.core.content.ContextCompat.startActivity @@ -38,12 +39,36 @@ class MainActivity : AppCompatActivity() { var hasCookie = false val viewAdapter = BookAdapter(ArrayList()) var totalPages = 1 + var refreshing = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) + val app = application as WishkoboneApplication + + setSupportActionBar(toolbar) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.title = "Your wishlist" + val toggle = + ActionBarDrawerToggle(this, drawerlayout, toolbar, R.string.open, R.string.close) + drawerlayout.addDrawerListener(toggle) + toggle.isDrawerIndicatorEnabled = true + toggle.syncState() + + navigation.setCheckedItem(R.id.home) + navigation.setNavigationItemSelectedListener { + if (it.itemId == R.id.logout) { + app.invalidateCookie() + hasCookie = false + drawerlayout.closeDrawers() + doLogin() + return@setNavigationItemSelectedListener true + } + false + } + val viewManager = LinearLayoutManager(this) status_text.text = "Loading..." @@ -60,8 +85,33 @@ class MainActivity : AppCompatActivity() { adapter = viewAdapter } + fastscroller.setHandleStateListener(object : RecyclerViewFastScroller.HandleStateListener { + override fun onDragged(offset: Float, position: Int) { + Log.d("scroller", "dragged: $position") + super.onDragged(offset, position) + } - val app = application as WishkoboneApplication + override fun onEngaged() { + Log.d("scroller", "engaged") + super.onEngaged() + } + + override fun onReleased() { + Log.d("scroller", "released") + super.onReleased() + } + }) + + refresher.setOnRefreshListener { + if (!refreshing) { + viewAdapter.books.clear() + viewAdapter.filteredBooks.clear() + viewAdapter.notifyDataSetChanged() + refresher.isRefreshing = false + loadBooks() + } + + } val cookie = app.getCookie() if (cookie != null) { @@ -71,10 +121,9 @@ class MainActivity : AppCompatActivity() { doLogin() } - } - fun doLogin(){ + fun doLogin() { val login = Intent(this, LoginActivity::class.java) startActivity(login); } @@ -86,7 +135,7 @@ class MainActivity : AppCompatActivity() { val app = application as WishkoboneApplication val cookie = app.getCookie() if (cookie != null) { // we just got this via login - + viewAdapter.books.clear() loadBooks() } } @@ -128,7 +177,9 @@ class MainActivity : AppCompatActivity() { @SuppressLint("SetTextI18n") private fun loadBooks(page: Int = 1) { + refreshing = true runOnUiThread { + snackbar_spinner.visibility = View.VISIBLE status.visibility = View.VISIBLE status_text.text = "Loading page $page of $totalPages" } @@ -145,7 +196,7 @@ class MainActivity : AppCompatActivity() { } override fun onResponse(call: Call, r: Response, response: JSONObject) { - if (!response.has("TotalNumPages")){ + if (!response.has("TotalNumPages")) { // must be unauthenticated hasCookie = false runOnUiThread { @@ -200,10 +251,20 @@ class MainActivity : AppCompatActivity() { } else { // the end! runOnUiThread { + refreshing = false + snackbar_spinner.visibility = View.INVISIBLE status_text.text = "Load complete! ${viewAdapter.books.size} items shown." status.postDelayed({ - status.visibility = View.GONE + status.animate() + .translationY(status.height.toFloat()) + .setDuration(500) + .withEndAction { + status.visibility = View.GONE + status.translationY = 0F + } + .start() + }, 3000) } } @@ -211,6 +272,7 @@ class MainActivity : AppCompatActivity() { override fun onFailureResponse(call: Call, r: Response, response: JSONObject) { hasCookie = false + refreshing = false } }); } @@ -222,7 +284,7 @@ class MainActivity : AppCompatActivity() { // Complex data items may need more than one view per item, and // you provide access to all the views for a data item in a view holder. // Each data item is just a string in this case that is shown in a TextView. - private var filteredBooks: ArrayList = ArrayList() + var filteredBooks: ArrayList = ArrayList() init { filteredBooks.addAll(books) @@ -308,6 +370,7 @@ class MainActivity : AppCompatActivity() { } holder.itemView.setOnClickListener { + Log.d("click", book.url) val intent = Intent(Intent.ACTION_VIEW, Uri.parse(book.url)) intent.addFlags(FLAG_ACTIVITY_NEW_TASK) startActivity(it.context, intent, null) @@ -319,6 +382,7 @@ class MainActivity : AppCompatActivity() { } override fun onChange(position: Int): CharSequence { + Log.d("scroller", "$position") return filteredBooks[position].formattedPrice() } diff --git a/src/main/res/layout/activity_login.xml b/src/main/res/layout/activity_login.xml index 9be7df8..c497f75 100644 --- a/src/main/res/layout/activity_login.xml +++ b/src/main/res/layout/activity_login.xml @@ -4,8 +4,25 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + android:id="@+id/coordinator" tools:context=".LoginActivity"> + + + + + + - + - + + + + + + - - + - + app:popupDrawable="@drawable/scroller_popup" + app:handleDrawable="@drawable/scroller_thumb" + app:layout_constraintBottom_toBottomOf="@id/coordinator" + app:layout_constraintTop_toBottomOf="@id/appbar" + android:layout_marginTop="?attr/actionBarSize" + app:supportSwipeToRefresh="true" + app:handleHeight="32dp"> + + + + + - \ No newline at end of file + + + \ No newline at end of file diff --git a/src/main/res/layout/drawer_header.xml b/src/main/res/layout/drawer_header.xml new file mode 100644 index 0000000..01ca725 --- /dev/null +++ b/src/main/res/layout/drawer_header.xml @@ -0,0 +1,24 @@ + + + + + diff --git a/src/main/res/menu/menu_nav.xml b/src/main/res/menu/menu_nav.xml new file mode 100644 index 0000000..c4a955e --- /dev/null +++ b/src/main/res/menu/menu_nav.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/src/main/res/values/colors.xml b/src/main/res/values/colors.xml index f4eda99..51264dd 100644 --- a/src/main/res/values/colors.xml +++ b/src/main/res/values/colors.xml @@ -2,7 +2,8 @@ #bf2026 #ab1d22 - #4218bb + #ab1d22 #e0e0e0 #888888 + #444444 \ No newline at end of file diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index d706f96..42ef543 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -1,3 +1,5 @@ Wishkobone + Open drawer + Close drawer \ No newline at end of file diff --git a/src/main/res/values/styles.xml b/src/main/res/values/styles.xml index b2cfe55..e4ff3e8 100644 --- a/src/main/res/values/styles.xml +++ b/src/main/res/values/styles.xml @@ -1,6 +1,6 @@ -