Skip to content

Commit 66420d5

Browse files
committed
Added filtering to the list views [#163]
1 parent 8842283 commit 66420d5

File tree

16 files changed

+359
-78
lines changed

16 files changed

+359
-78
lines changed

androidVariant/src/main/java/org/comixedproject/variant/android/MainActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,8 @@ class MainActivity : ComponentActivity() {
9393
variantViewModel.username = username
9494
variantViewModel.password = password
9595
},
96+
onToggleFiltering = { toggle -> variantViewModel.toggleFiltering(toggle) },
97+
onUpdateFilterText = { text -> variantViewModel.updateFilterText(text) },
9698
)
9799
}
98100
}

androidVariant/src/main/java/org/comixedproject/variant/android/view/HomeView.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ fun HomeView(
5757
username: String,
5858
password: String,
5959
onLoadDirectory: (String, Boolean) -> Unit,
60+
onToggleFiltering: (Boolean) -> Unit,
61+
onUpdateFilterText: (String) -> Unit,
6062
onDownloadFile: (String, String) -> Unit,
6163
onReadComicBook: (ComicBook?) -> Unit,
6264
onSetSelectionMode: (Boolean) -> Unit,
@@ -128,6 +130,8 @@ fun HomeView(
128130
onLoadDirectory = { path, reload -> onLoadDirectory(path, reload) },
129131
onDownloadFile = { path, filename -> onDownloadFile(path, filename) },
130132
modifier = Modifier.fillMaxSize(),
133+
onToggleFiltering = onToggleFiltering,
134+
onUpdateFilterText = onUpdateFilterText,
131135
)
132136

133137
AppDestination.SETTINGS ->
@@ -139,8 +143,8 @@ fun HomeView(
139143
Log.info(
140144
TAG,
141145
"Updating server settings: address=${address} username=${username} password=${
142-
password.first()
143-
}*****",
146+
password.first()
147+
}*****",
144148
)
145149
onSaveSettings(address, username, password)
146150
currentDestination = AppDestination.COMICS
@@ -160,14 +164,16 @@ fun HomeViewPreview() {
160164
HomeView(
161165
COMIC_BOOK_LIST.get(0),
162166
COMIC_BOOK_LIST,
163-
BrowsingState("", "", "", listOf(), listOf()),
167+
BrowsingState("", "", false, "", "", listOf(), listOf()),
164168
false,
165169
false,
166170
listOf(),
167171
"http://www.comixedproject.org:7171",
168172
169173
"my!password",
170174
onLoadDirectory = { _, _ -> },
175+
onToggleFiltering = {},
176+
onUpdateFilterText = {},
171177
onDownloadFile = { _, _ -> },
172178
onReadComicBook = { _ -> },
173179
onSetSelectionMode = { _ -> },

androidVariant/src/main/java/org/comixedproject/variant/android/view/comics/ComicBookListView.kt

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,12 @@ import androidx.compose.material3.Text
2929
import androidx.compose.runtime.Composable
3030
import androidx.compose.ui.Modifier
3131
import androidx.compose.ui.res.pluralStringResource
32-
import androidx.compose.ui.res.stringResource
3332
import androidx.compose.ui.tooling.preview.Preview
3433
import androidx.compose.ui.unit.dp
3534
import org.comixedproject.variant.android.COMIC_BOOK_LIST
3635
import org.comixedproject.variant.android.R
3736
import org.comixedproject.variant.android.VariantTheme
3837
import org.comixedproject.variant.model.library.ComicBook
39-
import org.comixedproject.variant.platform.Log
4038

4139
private val TAG = "ComicBookListView"
4240

@@ -55,26 +53,21 @@ fun ComicBookListView(
5553
)
5654
},
5755
content = { padding ->
58-
if (comicBookList.isEmpty()) {
59-
Log.debug(TAG, "No comics to display")
60-
Text(stringResource(R.string.emptyComicListText))
61-
} else {
62-
LazyVerticalStaggeredGrid(
63-
columns = StaggeredGridCells.Adaptive(minSize = 128.dp),
64-
verticalItemSpacing = 4.dp,
65-
horizontalArrangement = Arrangement.spacedBy(4.dp),
66-
content = {
67-
items(comicBookList) { comicBook ->
68-
ComicBookListItemView(
69-
comicBook,
70-
selectionList.contains(comicBook.path),
71-
onClick = { onClick(it) },
72-
)
73-
}
74-
},
75-
modifier = modifier.padding(padding),
76-
)
77-
}
56+
LazyVerticalStaggeredGrid(
57+
columns = StaggeredGridCells.Adaptive(minSize = 128.dp),
58+
verticalItemSpacing = 4.dp,
59+
horizontalArrangement = Arrangement.spacedBy(4.dp),
60+
content = {
61+
items(comicBookList) { comicBook ->
62+
ComicBookListItemView(
63+
comicBook,
64+
selectionList.contains(comicBook.path),
65+
onClick = { onClick(it) },
66+
)
67+
}
68+
},
69+
modifier = modifier.padding(padding),
70+
)
7871
},
7972
modifier = modifier.padding(8.dp),
8073
)
@@ -85,3 +78,9 @@ fun ComicBookListView(
8578
fun ComicBookListViewPreview() {
8679
VariantTheme { ComicBookListView(COMIC_BOOK_LIST, emptyList(), onClick = {}) }
8780
}
81+
82+
@Composable
83+
@Preview
84+
fun ComicBookListViewPreviewWithOneComics() {
85+
VariantTheme { ComicBookListView(listOf(COMIC_BOOK_LIST[0]), emptyList(), onClick = {}) }
86+
}

androidVariant/src/main/java/org/comixedproject/variant/android/view/comics/ComicBookView.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ fun ComicBookViewPreview() {
110110

111111
@Composable
112112
@Preview
113-
fun ComicBookViewWithSelectionsPreview() {
113+
fun ComicBookViewPreviewWithSelections() {
114114
VariantTheme {
115115
ComicBookView(
116116
COMIC_BOOK_LIST,

androidVariant/src/main/java/org/comixedproject/variant/android/view/server/BrowseServerView.kt

Lines changed: 96 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,17 @@ import androidx.compose.material3.IconButton
3030
import androidx.compose.material3.MaterialTheme
3131
import androidx.compose.material3.Scaffold
3232
import androidx.compose.material3.Text
33+
import androidx.compose.material3.TextField
3334
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
3435
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
3536
import androidx.compose.runtime.Composable
3637
import androidx.compose.ui.Alignment
3738
import androidx.compose.ui.Modifier
3839
import androidx.compose.ui.res.painterResource
3940
import androidx.compose.ui.res.stringResource
41+
import androidx.compose.ui.text.intl.Locale
4042
import androidx.compose.ui.text.style.TextOverflow
43+
import androidx.compose.ui.text.toLowerCase
4144
import androidx.compose.ui.tooling.preview.Preview
4245
import org.comixedproject.variant.android.DIRECTORY_LIST
4346
import org.comixedproject.variant.android.R
@@ -49,18 +52,27 @@ import org.comixedproject.variant.platform.Log
4952

5053
private const val TAG = "BrowseServerView"
5154

55+
fun checkFiltering(filterText: String, entry: DirectoryEntry): Boolean {
56+
return entry.title.toLowerCase(Locale.current).contains(filterText) ||
57+
entry.filename.toLowerCase(Locale.current).contains(filterText)
58+
}
59+
5260
@OptIn(ExperimentalMaterial3Api::class)
5361
@Composable
5462
fun BrowseServerView(
5563
path: String,
5664
title: String,
5765
parentPath: String,
66+
filtering: Boolean,
67+
filterText: String,
5868
contents: List<DirectoryEntry>,
5969
comicBookList: List<ComicBook>,
6070
downloadingState: List<DownloadingState>,
6171
loading: Boolean,
6272
onLoadDirectory: (String, Boolean) -> Unit,
6373
onDownloadFile: (String, String) -> Unit,
74+
onToggleFiltering: (Boolean) -> Unit,
75+
onUpdateFilterText: (String) -> Unit,
6476
modifier: Modifier = Modifier,
6577
) {
6678
val pullToRefreshState = rememberPullToRefreshState()
@@ -78,19 +90,45 @@ fun BrowseServerView(
7890
Icon(painterResource(R.drawable.ic_back), contentDescription = parentPath)
7991
}
8092

81-
val displayedTitle =
82-
when (title.isEmpty()) {
83-
false -> title
84-
true -> stringResource(R.string.rootDirectoryTitle)
85-
}
93+
if (filtering) {
94+
TextField(
95+
value = filterText,
96+
placeholder = { Text(stringResource(R.string.filter_list_placeholder)) },
97+
maxLines = 1,
98+
onValueChange = { text ->
99+
Log.debug(TAG, "Filter text=${text}")
100+
onUpdateFilterText(text)
101+
},
102+
modifier = Modifier.weight(1f),
103+
)
104+
} else {
105+
val displayedTitle =
106+
when (title.isEmpty()) {
107+
false -> title
108+
true -> stringResource(R.string.rootDirectoryTitle)
109+
}
110+
111+
Text(
112+
displayedTitle,
113+
maxLines = 1,
114+
overflow = TextOverflow.Ellipsis,
115+
style = MaterialTheme.typography.headlineMedium,
116+
modifier = Modifier.weight(1f),
117+
)
118+
}
86119

87-
Text(
88-
"${displayedTitle} [${downloadingState.size}]",
89-
maxLines = 1,
90-
overflow = TextOverflow.Ellipsis,
91-
style = MaterialTheme.typography.headlineMedium,
92-
modifier = Modifier.weight(1f),
93-
)
120+
IconButton(
121+
onClick = {
122+
Log.debug(TAG, "Toggle filtering")
123+
onToggleFiltering(!filtering)
124+
},
125+
enabled = !parentPath.isEmpty(),
126+
) {
127+
Icon(
128+
painterResource(R.drawable.ic_filter_text),
129+
contentDescription = stringResource(R.string.filter_list),
130+
)
131+
}
94132
}
95133
},
96134
content = { padding ->
@@ -100,7 +138,11 @@ fun BrowseServerView(
100138
onRefresh = { onLoadDirectory(path, true) },
101139
content = {
102140
LazyColumn(modifier = Modifier.padding(padding).fillMaxWidth()) {
103-
items(contents) { entry ->
141+
items(
142+
contents.filter {
143+
!filtering || checkFiltering(filterText.toLowerCase(Locale.current), it)
144+
}
145+
) { entry ->
104146
when (entry.isDirectory) {
105147
true ->
106148
DirectoryItemView(
@@ -128,56 +170,92 @@ fun BrowseServerView(
128170

129171
@Composable
130172
@Preview
131-
fun BrowseServerViewPreviewDirectories() {
173+
fun BrowseServerViewPreviewWithFiles() {
174+
var directory = DIRECTORY_LIST.filter { it.isDirectory }.first()
175+
VariantTheme {
176+
BrowseServerView(
177+
"http://www.comixedproject.org:7171",
178+
directory.title,
179+
directory.parent,
180+
false,
181+
"",
182+
DIRECTORY_LIST.filter { !it.isDirectory },
183+
emptyList(),
184+
emptyList(),
185+
false,
186+
onLoadDirectory = { _, _ -> },
187+
onDownloadFile = { _, _ -> },
188+
onToggleFiltering = {},
189+
onUpdateFilterText = {},
190+
)
191+
}
192+
}
193+
194+
@Composable
195+
@Preview
196+
fun BrowseServerViewPreviewWithDirectories() {
132197
VariantTheme {
133198
BrowseServerView(
134199
"http://www.comixedproject.org:7171",
135200
"",
136201
"",
202+
false,
203+
"",
137204
DIRECTORY_LIST.filter { it.isDirectory },
138205
emptyList(),
139206
emptyList(),
140207
false,
141208
onLoadDirectory = { _, _ -> },
142209
onDownloadFile = { _, _ -> },
210+
onToggleFiltering = {},
211+
onUpdateFilterText = {},
143212
)
144213
}
145214
}
146215

147216
@Composable
148217
@Preview
149-
fun BrowseServerViewPreviewFiles() {
218+
fun BrowseServerViewPreviewRefreshing() {
150219
val directory = DIRECTORY_LIST.get(0)
151220
VariantTheme {
152221
BrowseServerView(
153222
"http://www.comixedproject.org:7171",
154223
directory.title,
155224
directory.parent,
225+
false,
226+
"",
156227
DIRECTORY_LIST.filter { !it.isDirectory },
157228
emptyList(),
158229
emptyList(),
159-
false,
230+
true,
160231
onLoadDirectory = { _, _ -> },
161232
onDownloadFile = { _, _ -> },
233+
onToggleFiltering = {},
234+
onUpdateFilterText = {},
162235
)
163236
}
164237
}
165238

166239
@Composable
167240
@Preview
168-
fun BrowseServerViewPreviewRefreshing() {
241+
fun BrowseServerViewPreviewFiltering() {
169242
val directory = DIRECTORY_LIST.get(0)
243+
val filterText = directory.title.substring(0, 3)
170244
VariantTheme {
171245
BrowseServerView(
172246
"http://www.comixedproject.org:7171",
173247
directory.title,
174248
directory.parent,
175-
DIRECTORY_LIST.filter { !it.isDirectory },
249+
true,
250+
filterText,
251+
DIRECTORY_LIST,
176252
emptyList(),
177253
emptyList(),
178254
true,
179255
onLoadDirectory = { _, _ -> },
180256
onDownloadFile = { _, _ -> },
257+
onToggleFiltering = {},
258+
onUpdateFilterText = {},
181259
)
182260
}
183261
}

androidVariant/src/main/java/org/comixedproject/variant/android/view/server/ServerView.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,19 +35,25 @@ fun ServerView(
3535
loading: Boolean,
3636
onLoadDirectory: (String, Boolean) -> Unit,
3737
onDownloadFile: (String, String) -> Unit,
38+
onToggleFiltering: (Boolean) -> Unit,
39+
onUpdateFilterText: (String) -> Unit,
3840
modifier: Modifier = Modifier,
3941
) {
4042
BrowseServerView(
4143
browsingState.currentPath,
4244
browsingState.title,
4345
browsingState.parentPath,
46+
browsingState.filtering,
47+
browsingState.filterText,
4448
browsingState.contents,
4549
comicBookList,
4650
browsingState.downloadingState,
4751
loading,
4852
modifier = modifier,
4953
onLoadDirectory = { path, reload -> onLoadDirectory(path, reload) },
5054
onDownloadFile = { path, filename -> onDownloadFile(path, filename) },
55+
onToggleFiltering = onToggleFiltering,
56+
onUpdateFilterText = onUpdateFilterText,
5157
)
5258
}
5359

@@ -56,11 +62,13 @@ fun ServerView(
5662
fun ServerViewPreview() {
5763
VariantTheme {
5864
ServerView(
59-
BrowsingState("", "", "", listOf(), listOf()),
65+
BrowsingState("", "", false, "", "", listOf(), listOf()),
6066
COMIC_BOOK_LIST,
6167
false,
6268
onLoadDirectory = { _, _ -> },
6369
onDownloadFile = { _, _ -> },
70+
onToggleFiltering = {},
71+
onUpdateFilterText = {},
6472
)
6573
}
6674
}

0 commit comments

Comments
 (0)