Skip to content

Commit

Permalink
feat: add option to specify a path for server (#194)
Browse files Browse the repository at this point in the history
Closes #193
  • Loading branch information
Yash-Garg authored Dec 8, 2022
1 parent d9dcac9 commit a86edf2
Show file tree
Hide file tree
Showing 9 changed files with 208 additions and 75 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ android {
applicationId = "dev.yashgarg.qbit"
minSdk = 24
targetSdk = 33
versionCode = 8
versionCode = 9
versionName = "v0.1.$versionCode-$commitHash"

multiDexEnabled = true
Expand Down
83 changes: 83 additions & 0 deletions app/schemas/dev.yashgarg.qbit.data.AppDatabase/3.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
{
"formatVersion": 1,
"database": {
"version": 3,
"identityHash": "fd3c97ded76419eef57c25570fef8bfb",
"entities": [
{
"tableName": "configs",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`config_id` INTEGER NOT NULL, `serverName` TEXT NOT NULL, `baseUrl` TEXT NOT NULL, `port` INTEGER, `path` TEXT, `username` TEXT NOT NULL, `password` TEXT NOT NULL, `connectionType` TEXT NOT NULL, `trustSelfSigned` INTEGER NOT NULL DEFAULT 0, PRIMARY KEY(`config_id`))",
"fields": [
{
"fieldPath": "configId",
"columnName": "config_id",
"affinity": "INTEGER",
"notNull": true
},
{
"fieldPath": "serverName",
"columnName": "serverName",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "baseUrl",
"columnName": "baseUrl",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "port",
"columnName": "port",
"affinity": "INTEGER",
"notNull": false
},
{
"fieldPath": "path",
"columnName": "path",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "username",
"columnName": "username",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "password",
"columnName": "password",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "connectionType",
"columnName": "connectionType",
"affinity": "TEXT",
"notNull": true
},
{
"fieldPath": "trustSelfSigned",
"columnName": "trustSelfSigned",
"affinity": "INTEGER",
"notNull": true,
"defaultValue": "0"
}
],
"primaryKey": {
"autoGenerate": false,
"columnNames": [
"config_id"
]
},
"indices": [],
"foreignKeys": []
}
],
"views": [],
"setupQueries": [
"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, 'fd3c97ded76419eef57c25570fef8bfb')"
]
}
}
4 changes: 2 additions & 2 deletions app/src/main/kotlin/dev/yashgarg/qbit/data/AppDatabase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ import dev.yashgarg.qbit.data.models.ServerConfig

@Database(
entities = [ServerConfig::class],
version = 2,
autoMigrations = [AutoMigration(from = 1, to = 2)],
version = 3,
autoMigrations = [AutoMigration(from = 1, to = 2), AutoMigration(from = 2, to = 3)],
exportSchema = true
)
abstract class AppDatabase : RoomDatabase() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,12 @@ constructor(
withContext(Dispatchers.IO) {
if (client == null) {
val config = configDao.getConfigAtIndex()!!
val port = if (config.port != null) ":${config.port}" else ""
val path = config.path ?: ""

client =
QBittorrentClient(
"${config.connectionType.toString().lowercase()}://${config.baseUrl}" +
if (config.port != null) ":${config.port}" else "",
"${config.connectionType.toString().lowercase()}://${config.baseUrl}$port$path",
config.username,
config.password,
syncInterval = ClientManager.syncInterval,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ data class ServerConfig(
val serverName: String,
val baseUrl: String,
val port: Int? = null,
val path: String? = null,
val username: String,
val password: String,
val connectionType: ConnectionType,
Expand Down
130 changes: 73 additions & 57 deletions app/src/main/kotlin/dev/yashgarg/qbit/ui/config/ConfigFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,20 @@ class ConfigFragment : Fragment(AppR.layout.config_fragment) {
setupActionbar()

val adapter = ArrayAdapter(requireContext(), AppR.layout.list_item, connectionTypes)
(binding.typeDropdown.editText as? AutoCompleteTextView)?.setAdapter(adapter)

binding.saveButton.setOnClickListener {
viewModel.validateForm(
binding.serverNameTil.editText?.text.toString(),
binding.serverHostTil.editText?.text.toString(),
binding.serverPortTil.editText?.text.toString(),
binding.typeDropdown.editText?.text.toString(),
binding.serverUsernameTil.editText?.text.toString(),
binding.serverPasswordTil.editText?.text.toString(),
)

with(binding) {
(typeDropdown.editText as? AutoCompleteTextView)?.setAdapter(adapter)

saveButton.setOnClickListener {
viewModel.validateForm(
serverNameTil.editText?.text.toString(),
serverHostTil.editText?.text.toString(),
serverPortTil.editText?.text.toString(),
typeDropdown.editText?.text.toString(),
serverUsernameTil.editText?.text.toString(),
serverPasswordTil.editText?.text.toString(),
)
}
}
}

Expand Down Expand Up @@ -112,13 +115,17 @@ class ConfigFragment : Fragment(AppR.layout.config_fragment) {
}

private fun enableFields(enabled: Boolean) {
binding.serverNameTiet.isEnabled = enabled
binding.serverHostTiet.isEnabled = enabled
binding.serverPortTiet.isEnabled = enabled
binding.typeDropdown.isEnabled = enabled
binding.serverUsernameTiet.isEnabled = enabled
binding.serverPasswordTiet.isEnabled = enabled
binding.saveButton.isEnabled = enabled
with(binding) {
enabled.apply {
serverNameTiet.isEnabled = this
serverHostTiet.isEnabled = this
serverPortTiet.isEnabled = this
typeDropdown.isEnabled = this
serverUsernameTiet.isEnabled = this
serverPasswordTiet.isEnabled = this
saveButton.isEnabled = this
}
}
}

private fun handleEvent(event: ConfigViewModel.ValidationEvent) {
Expand All @@ -133,50 +140,59 @@ class ConfigFragment : Fragment(AppR.layout.config_fragment) {
)
checkSnackbar.show()

viewLifecycleOwner.lifecycleScope.launch {
val port = binding.serverPortTil.editText?.text
val connectionResponse =
viewModel.testConfig(
"${binding.typeDropdown.editText?.text.toString().lowercase()}://${binding.serverHostTil.editText?.text}" +
if (!port.isNullOrEmpty()) ":$port" else "",
binding.serverUsernameTil.editText?.text.toString(),
binding.serverPasswordTil.editText?.text.toString(),
binding.trustCert.isChecked
)

when (connectionResponse) {
is Ok -> {
checkSnackbar.dismiss()
Toast.makeText(
context,
"Success! Client app version is ${connectionResponse.value}",
Toast.LENGTH_LONG
)
.show()

viewModel.insert(
binding.serverNameTil.editText?.text.toString(),
binding.serverHostTil.editText?.text.toString(),
binding.serverPortTil.editText?.text.toString(),
binding.typeDropdown.editText?.text.toString(),
binding.serverUsernameTil.editText?.text.toString(),
binding.serverPasswordTil.editText?.text.toString(),
binding.trustCert.isChecked
with(binding) {
viewLifecycleOwner.lifecycleScope.launch {
val connectionType = typeDropdown.editText?.text.toString().lowercase()
val serverHost = serverHostTil.editText?.text.toString()
val username = serverUsernameTil.editText?.text.toString()
val password = serverPasswordTil.editText?.text.toString()
val path = serverPathTil.editText?.text.toString()
val port = serverPortTil.editText?.text

val connectionResponse =
viewModel.testConfig(
"$connectionType://$serverHost${if (!port.isNullOrEmpty()) ":$port" else ""}" +
if (path.isNotEmpty()) "/$path" else "",
username,
password,
trustCert.isChecked
)

findNavController().navigateUp()
}
is Err -> {
Log.e(ClientManager.tag, connectionResponse.error.toString())
Snackbar.make(
requireView(),
"Failed! ${connectionResponse.error.message}",
Snackbar.LENGTH_LONG
when (connectionResponse) {
is Ok -> {
checkSnackbar.dismiss()
Toast.makeText(
context,
"Success! Client app version is ${connectionResponse.value}",
Toast.LENGTH_LONG
)
.show()

viewModel.insert(
serverNameTil.editText?.text.toString(),
serverHost,
port.toString(),
path,
connectionType,
username,
password,
trustCert.isChecked
)
.show()

findNavController().navigateUp()
}
is Err -> {
Log.e(ClientManager.tag, connectionResponse.error.toString())
Snackbar.make(
requireView(),
"Failed! ${connectionResponse.error.message}",
Snackbar.LENGTH_LONG
)
.show()
}
}
enableFields(true)
}
enableFields(true)
}
}
}
Expand Down
20 changes: 12 additions & 8 deletions app/src/main/kotlin/dev/yashgarg/qbit/ui/config/ConfigViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -166,21 +166,25 @@ class ConfigViewModel @Inject constructor(private val configDao: ConfigDao) : Vi
serverName: String,
serverHost: String,
port: String,
path: String,
connectionType: String,
username: String,
password: String,
trustSelfSigned: Boolean
) {
val config =
ServerConfig(
0,
serverName.trim(),
serverHost.trim(),
if (port.isEmpty()) null else port.trim().toInt(),
username.trim(),
password.trim(),
if (connectionType.trim() == "HTTP") ConnectionType.HTTP else ConnectionType.HTTPS,
trustSelfSigned
configId = 0,
serverName = serverName.trim(),
baseUrl = serverHost.trim(),
port = if (port.isEmpty()) null else port.trim().toInt(),
path = if (path.isEmpty()) null else "/$path",
username = username.trim(),
password = password.trim(),
connectionType =
if (connectionType.trim() == "http") ConnectionType.HTTP
else ConnectionType.HTTPS,
trustSelfSigned = trustSelfSigned
)

viewModelScope.launch { configDao.addConfig(config) }
Expand Down
36 changes: 31 additions & 5 deletions app/src/main/res/layout/config_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/server_host_til"
app:placeholderText="0 - 65535">
app:placeholderText="0 - 65535"
app:prefixText=":">

<com.google.android.material.textfield.TextInputEditText
android:id="@+id/server_port_tiet"
Expand All @@ -99,6 +100,30 @@

</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/server_path_til"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginHorizontal="15dp"
android:layout_marginVertical="5dp"
android:hint="@string/path"
app:errorEnabled="true"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/server_port_til"
app:placeholderText="your/path"
app:prefixText="/">

<com.google.android.material.textfield.TextInputEditText
android:id="@+id/server_path_tiet"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:inputType="text"
android:maxLines="1" />

</com.google.android.material.textfield.TextInputLayout>

<com.google.android.material.textfield.TextInputLayout
android:id="@+id/server_username_til"
style="@style/Widget.Material3.TextInputLayout.OutlinedBox"
Expand All @@ -108,9 +133,9 @@
android:layout_marginVertical="5dp"
android:hint="@string/username"
app:errorEnabled="true"
app:layout_constraintEnd_toEndOf="@id/server_port_til"
app:layout_constraintStart_toStartOf="@id/server_port_til"
app:layout_constraintTop_toBottomOf="@id/server_port_til"
app:layout_constraintEnd_toEndOf="@id/server_path_til"
app:layout_constraintStart_toStartOf="@id/server_path_til"
app:layout_constraintTop_toBottomOf="@id/server_path_til"
app:placeholderText="e.g. admin">

<com.google.android.material.textfield.TextInputEditText
Expand All @@ -134,7 +159,8 @@
app:errorEnabled="true"
app:layout_constraintEnd_toEndOf="@id/server_username_til"
app:layout_constraintStart_toStartOf="@id/server_username_til"
app:layout_constraintTop_toBottomOf="@id/server_username_til">
app:layout_constraintTop_toBottomOf="@id/server_username_til"
app:placeholderText="e.g. adminadmin">

<com.google.android.material.textfield.TextInputEditText
android:id="@+id/server_password_tiet"
Expand Down
1 change: 1 addition & 0 deletions common/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<string name="password">Password</string>
<string name="username">Username</string>
<string name="port">Port (optional)</string>
<string name="path">Path (optional)</string>
<string name="host_or_ip">Host or IP</string>
<string name="server_name">Server name</string>
<string name="save_and_test_cfg">Save and test config</string>
Expand Down

0 comments on commit a86edf2

Please sign in to comment.