Skip to content

Commit 72613dd

Browse files
Enhance UI: Improve tag display and sorting, add OpenCountAndTags component (#304)
1 parent 5788818 commit 72613dd

File tree

8 files changed

+151
-107
lines changed

8 files changed

+151
-107
lines changed

app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/DeeprItem.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
1818
import androidx.compose.foundation.layout.height
1919
import androidx.compose.foundation.layout.padding
2020
import androidx.compose.foundation.layout.size
21+
import androidx.compose.foundation.shape.RoundedCornerShape
2122
import androidx.compose.material.icons.Icons
2223
import androidx.compose.material.icons.rounded.Star
2324
import androidx.compose.material.icons.rounded.StarBorder
@@ -253,6 +254,7 @@ fun DeeprItem(
253254
selected = isSelected,
254255
onClick = { onTagClick(tag.trim()) },
255256
label = { Text(tag.trim()) },
257+
shape = RoundedCornerShape(percent = 50),
256258
)
257259
}
258260
}

app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/DeeprItemCompact.kt

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -103,23 +103,8 @@ fun DeeprItemCompact(
103103
style = MaterialTheme.typography.bodySmall,
104104
color = getDeeprItemTextColor(account.isFavourite),
105105
)
106-
Row(modifier = Modifier.fillMaxWidth()) {
107-
Text(
108-
text = stringResource(R.string.opened_count, account.openedCount),
109-
style = MaterialTheme.typography.labelSmall,
110-
color = getDeeprItemTextColor(account.isFavourite),
111-
)
112-
Spacer(modifier = Modifier.weight(1f))
113-
account.tagsIds?.split(",")?.size?.let { tagsCount ->
114-
if (tagsCount > 0) {
115-
Text(
116-
text = stringResource(R.string.number_tags, tagsCount),
117-
style = MaterialTheme.typography.labelSmall,
118-
color = getDeeprItemTextColor(account.isFavourite),
119-
)
120-
}
121-
}
122-
}
106+
107+
OpenCountAndTags(account, Modifier.fillMaxWidth())
123108
}
124109
}
125110

app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/DeeprItemGrid.kt

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ fun DeeprItemGrid(
6868
modifier =
6969
Modifier
7070
.fillMaxWidth()
71-
.aspectRatio(1f)
71+
.aspectRatio(1.91f)
7272
.background(MaterialTheme.colorScheme.surfaceVariant),
7373
placeholder = null,
7474
error = null,
@@ -88,7 +88,7 @@ fun DeeprItemGrid(
8888
text = account.name,
8989
maxLines = 2,
9090
overflow = TextOverflow.Ellipsis,
91-
style = MaterialTheme.typography.titleMedium,
91+
style = MaterialTheme.typography.titleSmall,
9292
color = getDeeprItemTextColor(account.isFavourite),
9393
)
9494
Spacer(modifier = Modifier.height(4.dp))
@@ -109,22 +109,7 @@ fun DeeprItemGrid(
109109
horizontalArrangement = Arrangement.SpaceBetween,
110110
verticalAlignment = Alignment.CenterVertically,
111111
) {
112-
Column(modifier = Modifier.weight(1f)) {
113-
Text(
114-
text = stringResource(R.string.opened_count, account.openedCount),
115-
style = MaterialTheme.typography.bodySmall,
116-
color = getDeeprItemTextColor(account.isFavourite),
117-
)
118-
account.tagsIds?.split(",")?.size?.let { tagsCount ->
119-
if (tagsCount > 0) {
120-
Text(
121-
text = stringResource(R.string.number_tags, tagsCount),
122-
style = MaterialTheme.typography.labelSmall,
123-
color = getDeeprItemTextColor(account.isFavourite),
124-
)
125-
}
126-
}
127-
}
112+
OpenCountAndTags(account, Modifier.weight(1f))
128113
IconButton(onClick = {
129114
onItemClick(MenuItem.MoreOptionsBottomSheet(account))
130115
}) {

app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/FilterMenu.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ import androidx.compose.ui.res.stringResource
1616
import com.yogeshpaliyal.deepr.R
1717
import com.yogeshpaliyal.deepr.viewmodel.SortType
1818
import compose.icons.TablerIcons
19+
import compose.icons.tablericons.ArrowsSort
1920
import compose.icons.tablericons.Calendar
2021
import compose.icons.tablericons.CalendarEvent
2122
import compose.icons.tablericons.Eye
2223
import compose.icons.tablericons.EyeOff
23-
import compose.icons.tablericons.Filter
2424
import compose.icons.tablericons.SortAscending
2525
import compose.icons.tablericons.SortDescending
2626

@@ -32,7 +32,7 @@ fun FilterMenu(
3232
var expanded by remember { mutableStateOf(false) }
3333
Box(modifier) {
3434
IconButton(onClick = { expanded = true }) {
35-
Icon(TablerIcons.Filter, contentDescription = stringResource(R.string.filter))
35+
Icon(TablerIcons.ArrowsSort, contentDescription = stringResource(R.string.filter))
3636
}
3737
DropdownMenu(
3838
expanded = expanded,

app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/Home.kt

Lines changed: 74 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import androidx.compose.foundation.layout.padding
2929
import androidx.compose.foundation.layout.size
3030
import androidx.compose.foundation.lazy.LazyColumn
3131
import androidx.compose.foundation.lazy.LazyListState
32+
import androidx.compose.foundation.lazy.LazyRow
33+
import androidx.compose.foundation.lazy.items
3234
import androidx.compose.foundation.lazy.rememberLazyListState
3335
import androidx.compose.foundation.lazy.staggeredgrid.LazyStaggeredGridState
3436
import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid
@@ -59,9 +61,6 @@ import androidx.compose.material3.PlainTooltip
5961
import androidx.compose.material3.Scaffold
6062
import androidx.compose.material3.SearchBarDefaults
6163
import androidx.compose.material3.SearchBarValue
62-
import androidx.compose.material3.SegmentedButton
63-
import androidx.compose.material3.SegmentedButtonDefaults
64-
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
6564
import androidx.compose.material3.Surface
6665
import androidx.compose.material3.Text
6766
import androidx.compose.material3.TextButton
@@ -139,7 +138,6 @@ import compose.icons.tablericons.Refresh
139138
import compose.icons.tablericons.Search
140139
import compose.icons.tablericons.Tag
141140
import compose.icons.tablericons.Trash
142-
import compose.icons.tablericons.X
143141
import dev.chrisbanes.haze.HazeState
144142
import dev.chrisbanes.haze.hazeEffect
145143
import dev.chrisbanes.haze.hazeSource
@@ -181,6 +179,12 @@ class Dashboard2(
181179
}
182180
}
183181

182+
data class FilterTagItem(
183+
val name: String,
184+
val count: Long,
185+
val isSelected: Boolean,
186+
)
187+
184188
@OptIn(
185189
ExperimentalMaterial3Api::class,
186190
ExperimentalHazeMaterialsApi::class,
@@ -200,6 +204,7 @@ fun HomeScreen(
200204
val currentViewType by viewModel.viewType.collectAsStateWithLifecycle()
201205
val localNavigator = LocalNavigator.current
202206
val hapticFeedback = LocalHapticFeedback.current
207+
val tags = viewModel.allTagsWithCount.collectAsStateWithLifecycle()
203208

204209
var selectedLink by remember { mutableStateOf<GetLinksAndTags?>(mSelectedLink) }
205210
val selectedTag by viewModel.selectedTagFilter.collectAsStateWithLifecycle()
@@ -212,7 +217,9 @@ fun HomeScreen(
212217
val totalLinks by viewModel.countOfLinks.collectAsStateWithLifecycle()
213218
val favouriteLinks by viewModel.countOfFavouriteLinks.collectAsStateWithLifecycle()
214219
val favouriteFilter by viewModel.favouriteFilter.collectAsStateWithLifecycle()
215-
val listState = if (currentViewType == ViewType.GRID) rememberLazyStaggeredGridState() else rememberLazyListState()
220+
var finalTagsInfo by remember { mutableStateOf<List<FilterTagItem>?>(listOf()) }
221+
val listState =
222+
if (currentViewType == ViewType.GRID) rememberLazyStaggeredGridState() else rememberLazyListState()
216223
val isExpanded by remember(listState) {
217224
// Example: expanded only when at the very top of the list
218225
derivedStateOf {
@@ -252,6 +259,33 @@ fun HomeScreen(
252259
}
253260
}
254261

262+
LaunchedEffect(selectedTag, tags.value) {
263+
// Get unique tags by merging both but first items should be selected tag and then tags
264+
val allTagsList = tags.value
265+
val mergedList = mutableListOf<FilterTagItem>()
266+
val mapOfSelectedList = HashMap<String, Long>()
267+
268+
val alreadyAdded = HashSet<String>()
269+
270+
allTagsList.forEach { tag ->
271+
mapOfSelectedList.put(tag.name, tag.linkCount)
272+
}
273+
274+
selectedTag.forEach { tag ->
275+
alreadyAdded.add(tag.name)
276+
val count = mapOfSelectedList[tag.name] ?: 0L
277+
mergedList.add(FilterTagItem(tag.name, count, true))
278+
}
279+
280+
allTagsList.forEach { tag ->
281+
if (alreadyAdded.contains(tag.name).not()) {
282+
alreadyAdded.add(tag.name)
283+
mergedList.add(FilterTagItem(tag.name, tag.linkCount, false))
284+
}
285+
}
286+
finalTagsInfo = mergedList
287+
}
288+
255289
LaunchedEffect(textFieldState.text) {
256290
viewModel.search(textFieldState.text.toString())
257291
}
@@ -311,11 +345,11 @@ fun HomeScreen(
311345
TooltipDefaults.rememberTooltipPositionProvider(
312346
TooltipAnchorPosition.Below,
313347
),
314-
tooltip = { PlainTooltip { Text(stringResource(R.string.sorting)) } },
348+
tooltip = { PlainTooltip { Text("View Type") } },
315349
state = rememberTooltipState(),
316350
) {
317-
FilterMenu(onSortOrderChange = {
318-
viewModel.setSortOrder(it)
351+
ViewTypeMenu(currentViewType, {
352+
viewModel.setViewType(it)
319353
})
320354
}
321355

@@ -324,11 +358,11 @@ fun HomeScreen(
324358
TooltipDefaults.rememberTooltipPositionProvider(
325359
TooltipAnchorPosition.Below,
326360
),
327-
tooltip = { PlainTooltip { Text("View Type") } },
361+
tooltip = { PlainTooltip { Text(stringResource(R.string.sorting)) } },
328362
state = rememberTooltipState(),
329363
) {
330-
ViewTypeMenu(currentViewType, {
331-
viewModel.setViewType(it)
364+
FilterMenu(onSortOrderChange = {
365+
viewModel.setSortOrder(it)
332366
})
333367
}
334368
}
@@ -376,69 +410,37 @@ fun HomeScreen(
376410
},
377411
)
378412

379-
// Favourite filter tabs
380-
SingleChoiceSegmentedButtonRow(
413+
LazyRow(
381414
modifier =
382415
Modifier
383416
.fillMaxWidth()
384417
.padding(8.dp),
418+
horizontalArrangement = Arrangement.spacedBy(8.dp),
419+
contentPadding = PaddingValues(horizontal = 8.dp),
385420
) {
386-
SegmentedButton(
387-
shape =
388-
SegmentedButtonDefaults.itemShape(
389-
index = 0,
390-
count = 2,
391-
),
392-
onClick = { viewModel.setFavouriteFilter(-1) },
393-
selected = favouriteFilter == -1,
394-
label = { Text(stringResource(R.string.all) + " (${totalLinks ?: 0})") },
395-
)
396-
SegmentedButton(
397-
shape =
398-
SegmentedButtonDefaults.itemShape(
399-
index = 1,
400-
count = 2,
401-
),
402-
onClick = { viewModel.setFavouriteFilter(1) },
403-
selected = favouriteFilter == 1,
404-
label = { Text(stringResource(R.string.favourites) + " (${favouriteLinks ?: 0})") },
405-
)
406-
}
421+
item {
422+
FilterChip(selectedTag.isEmpty() && favouriteFilter == -1, {
423+
viewModel.setFavouriteFilter(-1)
424+
viewModel.setTagFilter(null)
425+
}, label = {
426+
Text(stringResource(R.string.all) + " (${totalLinks ?: 0})")
427+
}, modifier = Modifier.animateItem(), shape = RoundedCornerShape(percent = 50))
428+
}
429+
item {
430+
FilterChip(selectedTag.isEmpty() && favouriteFilter == 1, {
431+
viewModel.setFavouriteFilter(1)
432+
viewModel.setTagFilter(null)
433+
}, label = {
434+
Text(stringResource(R.string.favourites) + " (${favouriteLinks ?: 0})")
435+
}, modifier = Modifier.animateItem(), shape = RoundedCornerShape(percent = 50))
436+
}
407437

408-
// Selected tags filter chips
409-
AnimatedVisibility(
410-
visible = selectedTag.isNotEmpty(),
411-
enter = expandVertically(expandFrom = Alignment.Top),
412-
exit = shrinkVertically(shrinkTowards = Alignment.Top),
413-
) {
414-
FlowRow(
415-
modifier =
416-
Modifier
417-
.fillMaxWidth()
418-
.padding(horizontal = 8.dp, vertical = 4.dp),
419-
horizontalArrangement = Arrangement.spacedBy(4.dp),
420-
) {
421-
selectedTag.forEach { tag ->
422-
FilterChip(
423-
selected = true,
424-
onClick = { viewModel.setTagFilter(tag) },
425-
label = { Text(tag.name) },
426-
leadingIcon = {
427-
Icon(
428-
TablerIcons.Tag,
429-
contentDescription = null,
430-
modifier = Modifier.size(16.dp),
431-
)
432-
},
433-
trailingIcon = {
434-
Icon(
435-
TablerIcons.X,
436-
contentDescription = stringResource(R.string.remove_tag),
437-
modifier = Modifier.size(18.dp),
438-
)
439-
},
440-
)
441-
}
438+
items(finalTagsInfo ?: listOf()) {
439+
FilterChip(it.isSelected, {
440+
viewModel.setSelectedTagByName(it.name)
441+
}, label = {
442+
Text(it.name + " (${it.count})")
443+
}, modifier = Modifier.animateItem(), shape = RoundedCornerShape(percent = 50))
442444
}
443445
}
444446
}
@@ -818,6 +820,7 @@ fun Content(
818820
showMoreSelectedItem = null
819821
},
820822
label = { Text(tag.trim()) },
823+
shape = RoundedCornerShape(percent = 50),
821824
)
822825
}
823826
}
@@ -1019,7 +1022,9 @@ fun DeeprList(
10191022

10201023
ViewType.GRID -> {
10211024
LazyVerticalStaggeredGrid(
1022-
state = listState as? LazyStaggeredGridState ?: rememberLazyStaggeredGridState(),
1025+
state =
1026+
listState as? LazyStaggeredGridState
1027+
?: rememberLazyStaggeredGridState(),
10231028
columns = StaggeredGridCells.Adaptive(minSize = 160.dp),
10241029
modifier = modifier,
10251030
contentPadding = contentPaddingValues,

app/src/main/java/com/yogeshpaliyal/deepr/ui/screens/home/HomeBottomContent.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,7 @@ fun HomeBottomContent(
427427
)
428428
}
429429
},
430+
shape = RoundedCornerShape(percent = 50),
430431
)
431432
}
432433
}
@@ -454,6 +455,7 @@ fun HomeBottomContent(
454455
SuggestionChip(
455456
onClick = { selectedTags.add(tag) },
456457
label = { Text(tag.name) },
458+
shape = RoundedCornerShape(percent = 50),
457459
)
458460
}
459461
}

0 commit comments

Comments
 (0)