Add baseUrl to user, check "use another checkbox" if only one host, show keyboard

This commit is contained in:
Philipp Heckel 2022-01-28 10:19:12 -05:00
parent e7ecdc266e
commit 88b2576af0
4 changed files with 42 additions and 21 deletions

View file

@ -2,7 +2,7 @@
"formatVersion": 1, "formatVersion": 1,
"database": { "database": {
"version": 7, "version": 7,
"identityHash": "12fd7305f39828bf44164435d48b7e56", "identityHash": "f8551fac095d795a83ba7a95277e3f0f",
"entities": [ "entities": [
{ {
"tableName": "Subscription", "tableName": "Subscription",
@ -206,7 +206,7 @@
}, },
{ {
"tableName": "User", "tableName": "User",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL)", "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `baseUrl` TEXT NOT NULL, `username` TEXT NOT NULL, `password` TEXT NOT NULL)",
"fields": [ "fields": [
{ {
"fieldPath": "id", "fieldPath": "id",
@ -214,6 +214,12 @@
"affinity": "INTEGER", "affinity": "INTEGER",
"notNull": true "notNull": true
}, },
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{ {
"fieldPath": "username", "fieldPath": "username",
"columnName": "username", "columnName": "username",
@ -290,7 +296,7 @@
"views": [], "views": [],
"setupQueries": [ "setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '12fd7305f39828bf44164435d48b7e56')" "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'f8551fac095d795a83ba7a95277e3f0f')"
] ]
} }
} }

View file

@ -4,6 +4,7 @@ import android.content.Context
import androidx.room.* import androidx.room.*
import androidx.room.migration.Migration import androidx.room.migration.Migration
import androidx.sqlite.db.SupportSQLiteDatabase import androidx.sqlite.db.SupportSQLiteDatabase
import io.heckel.ntfy.util.shortUrl
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
@Entity(indices = [Index(value = ["baseUrl", "topic"], unique = true), Index(value = ["upConnectorToken"], unique = true)]) @Entity(indices = [Index(value = ["baseUrl", "topic"], unique = true), Index(value = ["upConnectorToken"], unique = true)])
@ -82,10 +83,17 @@ const val PROGRESS_DONE = 100
@Entity @Entity
data class User( data class User(
@PrimaryKey(autoGenerate = true) val id: Long, @PrimaryKey(autoGenerate = true) val id: Long,
@ColumnInfo(name = "baseUrl") val baseUrl: String,
@ColumnInfo(name = "username") val username: String, @ColumnInfo(name = "username") val username: String,
@ColumnInfo(name = "password") val password: String @ColumnInfo(name = "password") val password: String
) { ) {
override fun toString(): String = username override fun toString(): String {
return if (baseUrl == "") {
username
} else {
"$username (${shortUrl(baseUrl)})"
}
}
} }
@Entity(tableName = "Log") @Entity(tableName = "Log")

View file

@ -7,6 +7,8 @@ import android.os.Bundle
import android.text.Editable import android.text.Editable
import android.text.TextWatcher import android.text.TextWatcher
import android.view.View import android.view.View
import android.view.WindowManager
import android.view.inputmethod.InputMethodManager
import android.widget.* import android.widget.*
import androidx.fragment.app.DialogFragment import androidx.fragment.app.DialogFragment
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
@ -172,7 +174,7 @@ class AddFragment : DialogFragment() {
// Show/hide based on flavor // Show/hide based on flavor
subscribeInstantDeliveryBox.visibility = if (BuildConfig.FIREBASE_AVAILABLE) View.VISIBLE else View.GONE subscribeInstantDeliveryBox.visibility = if (BuildConfig.FIREBASE_AVAILABLE) View.VISIBLE else View.GONE
// Show/hide spinner and username/password fields // Show/hide drop-down and username/password fields
loginUsersSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { loginUsersSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
if (position == 0) { if (position == 0) {
@ -189,7 +191,7 @@ class AddFragment : DialogFragment() {
} }
// Build dialog // Build dialog
val alert = AlertDialog.Builder(activity) val dialog = AlertDialog.Builder(activity)
.setView(view) .setView(view)
.setPositiveButton(R.string.add_dialog_button_subscribe) { _, _ -> .setPositiveButton(R.string.add_dialog_button_subscribe) { _, _ ->
// This will be overridden below to avoid closing the dialog immediately // This will be overridden below to avoid closing the dialog immediately
@ -199,10 +201,11 @@ class AddFragment : DialogFragment() {
} }
.create() .create()
// Add logic to disable "Subscribe" button on invalid input // Show keyboard when the dialog is shown (see https://stackoverflow.com/a/19573049/1440785)
alert.setOnShowListener { dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
val dialog = it as AlertDialog
// Add logic to disable "Subscribe" button on invalid input
dialog.setOnShowListener {
subscribeButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE) subscribeButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE)
subscribeButton.isEnabled = false subscribeButton.isEnabled = false
subscribeButton.setOnClickListener { subscribeButton.setOnClickListener {
@ -241,9 +244,13 @@ class AddFragment : DialogFragment() {
} }
validateInput() validateInput()
} }
subscribeUseAnotherServerCheckbox.isChecked = this::baseUrls.isInitialized && baseUrls.count() == 1
// Focus topic text (keyboard is shown too, see above)
subscribeTopicText.requestFocus()
} }
return alert return dialog
} }
private fun subscribeButtonClick() { private fun subscribeButtonClick() {
@ -270,15 +277,14 @@ class AddFragment : DialogFragment() {
Log.w(TAG, "Anonymous access not allowed to topic ${topicUrl(baseUrl, topic)}, showing login dialog") Log.w(TAG, "Anonymous access not allowed to topic ${topicUrl(baseUrl, topic)}, showing login dialog")
requireActivity().runOnUiThread { requireActivity().runOnUiThread {
// Show/hide users dropdown // Show/hide users dropdown
if (users.isEmpty()) { val relevantUsers = users.filter { it.baseUrl == baseUrl }
if (relevantUsers.isEmpty()) {
loginUsersSpinner.visibility = View.GONE loginUsersSpinner.visibility = View.GONE
} else { } else {
val spinnerEntries = users.toMutableList() val spinnerEntries = relevantUsers.toMutableList()
spinnerEntries.add(0, User(0, getString(R.string.add_dialog_login_new_user), "")) spinnerEntries.add(0, User(0, "", getString(R.string.add_dialog_login_new_user), ""))
loginUsersSpinner.adapter = ArrayAdapter(requireActivity(), R.layout.fragment_add_dialog_dropdown_item, spinnerEntries) loginUsersSpinner.adapter = ArrayAdapter(requireActivity(), R.layout.fragment_add_dialog_dropdown_item, spinnerEntries)
loginUsersSpinner.setSelection(1) loginUsersSpinner.setSelection(1)
/*loginUsernameText.visibility = View.GONE
loginPasswordText.visibility = View.GONE*/
} }
// Show login page // Show login page
@ -309,6 +315,7 @@ class AddFragment : DialogFragment() {
} else { } else {
User( User(
id = Random.nextLong(), id = Random.nextLong(),
baseUrl = baseUrl,
username = loginUsernameText.text.toString(), username = loginUsernameText.text.toString(),
password = loginPasswordText.text.toString() password = loginPasswordText.text.toString()
) )

View file

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:paddingLeft="16dp" android:paddingLeft="16dp"
android:paddingRight="16dp"> android:paddingRight="16dp">
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent" android:layout_width="match_parent"