Skip to content

Commit

Permalink
feat: initial implementation for listing multiple configs
Browse files Browse the repository at this point in the history
  • Loading branch information
Yash-Garg committed Nov 27, 2022
1 parent d6feeee commit 900c7d7
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ class ListTileTextView(context: Context, attrs: AttributeSet) : LinearLayout(con
private var titleTv: TextView
private var subtitleTv: TextView

var title: String? = null
set(value) {
titleTv.text = value
field = value
}

var subtitle: String? = null
set(value) {
subtitleTv.text = value
Expand All @@ -26,8 +32,8 @@ class ListTileTextView(context: Context, attrs: AttributeSet) : LinearLayout(con
subtitleTv = findViewById(R.id.subtitle)

try {
titleTv.text = typedArr.getString(R.styleable.ListTileTextView_title)
subtitleTv.text = subtitle
titleTv.text = title ?: typedArr.getString(R.styleable.ListTileTextView_title)
subtitleTv.text = subtitle ?: typedArr.getString(R.styleable.ListTileTextView_subtitle)

this.setOnLongClickListener {
ClipboardUtil.copyToClipboard(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ class ServerFragment : Fragment(R.layout.server_fragment) {
true
}
R.id.sort_list -> {
findNavController()
.navigate(R.id.action_serverFragment_to_serverManagerFragment)
true
}
R.id.speed_toggle -> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dev.yashgarg.qbit.ui.server.adapter

import android.annotation.SuppressLint
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import dev.yashgarg.qbit.R
import dev.yashgarg.qbit.data.models.ServerConfig
import dev.yashgarg.qbit.ui.common.ListTileTextView
import javax.inject.Inject

class ServerConfigAdapter @Inject constructor() :
RecyclerView.Adapter<ServerConfigAdapter.ViewHolder>() {

var configs = emptyList<ServerConfig>()
@SuppressLint("NotifyDataSetChanged")
set(value) {
notifyDataSetChanged()
field = value
}

class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val serverTitle: ListTileTextView = view.findViewById(R.id.server_title)
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.config_item, parent, false)

return ViewHolder(view)
}

override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val config = configs[position]

with(holder) {
serverTitle.apply {
title = config.serverName
subtitle = "${config.baseUrl}:${config.port}"
}
}
}

override fun getItemCount() = configs.size
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package dev.yashgarg.qbit.ui.server.manager

import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import androidx.fragment.app.viewModels
import androidx.lifecycle.flowWithLifecycle
import androidx.lifecycle.lifecycleScope
import com.google.android.material.transition.MaterialSharedAxis
import dagger.hilt.android.AndroidEntryPoint
import dev.yashgarg.qbit.R
import dev.yashgarg.qbit.databinding.ServerManagerFragmentBinding
import dev.yashgarg.qbit.ui.server.adapter.ServerConfigAdapter
import dev.yashgarg.qbit.utils.viewBinding
import javax.inject.Inject
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

@AndroidEntryPoint
class ServerManagerFragment : Fragment(R.layout.server_manager_fragment) {
private val binding by viewBinding(ServerManagerFragmentBinding::bind)
private val viewModel by viewModels<ServerManagerViewModel>()

@Inject lateinit var serverConfigAdapter: ServerConfigAdapter

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)

binding.serverRv.adapter = serverConfigAdapter
observeFlows()
}

private fun observeFlows() {
viewModel.uiState
.flowWithLifecycle(viewLifecycleOwner.lifecycle)
.onEach(::render)
.launchIn(viewLifecycleOwner.lifecycleScope)
}

private fun render(state: ServerManagerState) {
with(state) {
if (!configsLoading && !error && configs.isNotEmpty()) {
serverConfigAdapter.configs = configs
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package dev.yashgarg.qbit.ui.server.manager

import dev.yashgarg.qbit.data.models.ServerConfig

data class ServerManagerState(
val configsLoading: Boolean = true,
val configs: List<ServerConfig> = emptyList(),
val error: Boolean = false
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.yashgarg.qbit.ui.server.manager

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import dev.yashgarg.qbit.data.daos.ConfigDao
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch

@HiltViewModel
class ServerManagerViewModel @Inject constructor(private val configDao: ConfigDao) : ViewModel() {
private val _uiState = MutableStateFlow(ServerManagerState())
val uiState = _uiState.asStateFlow()

init {
viewModelScope.launch { loadConfigs() }
}

private suspend fun loadConfigs() {
val configs = configDao.getConfigs()
configs
.catch { _uiState.update { it.copy(error = true, configsLoading = false) } }
.collectLatest {
_uiState.update { state -> state.copy(configs = it, configsLoading = false) }
}
}
}
11 changes: 11 additions & 0 deletions app/src/main/res/layout/config_item.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">

<dev.yashgarg.qbit.ui.common.ListTileTextView
android:id="@+id/server_title"
android:layout_width="match_parent"
android:layout_height="80dp" />

</FrameLayout>
25 changes: 25 additions & 0 deletions app/src/main/res/layout/server_manager_fragment.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">

<com.google.android.material.appbar.MaterialToolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:elevation="0dp"
app:navigationIcon="?attr/homeAsUpIndicator"
app:title="@string/manage_configs" />

<androidx.recyclerview.widget.RecyclerView
android:id="@+id/server_rv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"
android:visibility="visible"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager" />
</LinearLayout>
7 changes: 7 additions & 0 deletions app/src/main/res/navigation/nav_graph.xml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
android:id="@+id/action_serverFragment_to_torrentInfoFragment"
app:destination="@id/torrentInfoFragment"
app:popUpTo="@id/serverFragment" />
<action
android:id="@+id/action_serverFragment_to_serverManagerFragment"
app:destination="@id/serverManagerFragment" />
</fragment>
<fragment
android:id="@+id/torrentInfoFragment"
Expand All @@ -54,4 +57,8 @@
android:name="torrentHash"
app:argType="string" />
</fragment>
<fragment
android:id="@+id/serverManagerFragment"
android:name="dev.yashgarg.qbit.ui.server.manager.ServerManagerFragment"
android:label="ServerManagerFragment" />
</navigation>
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 @@ -24,6 +24,7 @@
<string name="paused">Paused</string>
<string name="stalled">Stalled</string>
<string name="completed">Completed</string>
<string name="manage_configs">Manage configs</string>

<!-- Torrent Info Fragment -->
<!-- Titles-->
Expand Down

0 comments on commit 900c7d7

Please sign in to comment.