This repository has been archived by the owner on Aug 20, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ForumPreviewScreen: Show user's inventory
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
- Loading branch information
1 parent
b331860
commit c1a3286
Showing
9 changed files
with
260 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
11 changes: 11 additions & 0 deletions
11
app/src/main/java/io/aayush/relabs/network/data/devices/Device.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package io.aayush.relabs.network.data.devices | ||
|
||
import io.aayush.relabs.network.data.node.Node | ||
|
||
data class Device( | ||
val Node: Node, | ||
val description: String, | ||
val device_id: Int, | ||
val name: String, | ||
val view_url: String | ||
) |
5 changes: 5 additions & 0 deletions
5
app/src/main/java/io/aayush/relabs/network/data/devices/Devices.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
package io.aayush.relabs.network.data.devices | ||
|
||
data class Devices( | ||
val devices: List<Device> | ||
) |
109 changes: 109 additions & 0 deletions
109
app/src/main/java/io/aayush/relabs/ui/components/NodePreviewItem.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package io.aayush.relabs.ui.components | ||
|
||
import android.text.format.DateUtils | ||
import androidx.compose.foundation.Image | ||
import androidx.compose.foundation.clickable | ||
import androidx.compose.foundation.layout.Arrangement | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.Row | ||
import androidx.compose.foundation.layout.Spacer | ||
import androidx.compose.foundation.layout.fillMaxWidth | ||
import androidx.compose.foundation.layout.requiredSize | ||
import androidx.compose.foundation.layout.width | ||
import androidx.compose.foundation.shape.RoundedCornerShape | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.draw.clip | ||
import androidx.compose.ui.res.painterResource | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.text.font.FontWeight | ||
import androidx.compose.ui.unit.dp | ||
import androidx.compose.ui.unit.sp | ||
import io.aayush.relabs.R | ||
import io.aayush.relabs.ui.extensions.shimmer | ||
import java.text.NumberFormat | ||
import java.util.Date | ||
import java.util.Locale | ||
|
||
@Composable | ||
fun NodePreviewItem( | ||
modifier: Modifier = Modifier, | ||
title: String = "", | ||
company: String = "", | ||
threads: Int = 0, | ||
lastUpdated: Int = 0, | ||
lastThreadTitle: String = "", | ||
unread: Boolean = false, | ||
onClicked: () -> Unit = {}, | ||
loading: Boolean = false | ||
) { | ||
Row( | ||
modifier = modifier | ||
.fillMaxWidth() | ||
.clickable { onClicked() }, | ||
verticalAlignment = Alignment.Top, | ||
horizontalArrangement = Arrangement.Start | ||
) { | ||
Image( | ||
painter = painterResource(id = R.drawable.ic_phone), | ||
contentDescription = "", | ||
modifier = Modifier | ||
.requiredSize(48.dp) | ||
.clip(RoundedCornerShape(20.dp)) | ||
.shimmer(loading) | ||
) | ||
Spacer(modifier = Modifier.width(10.dp)) | ||
Column( | ||
verticalArrangement = Arrangement.spacedBy(5.dp, Alignment.Top), | ||
horizontalAlignment = Alignment.Start | ||
) { | ||
Text( | ||
text = title, | ||
fontSize = 15.sp, | ||
fontWeight = if (unread) FontWeight.Medium else FontWeight.Light, | ||
modifier = Modifier | ||
.fillMaxWidth() | ||
.shimmer(loading) | ||
) | ||
Text( | ||
text = if (company.isNotBlank()) { | ||
stringResource( | ||
id = R.string.company_threads_lastPostDate, | ||
company, | ||
NumberFormat.getInstance(Locale.getDefault()).format(threads), | ||
if (lastUpdated != 0) { | ||
DateUtils.getRelativeTimeSpanString( | ||
lastUpdated.toLong() * 1000L, | ||
Date().time, | ||
DateUtils.MINUTE_IN_MILLIS | ||
).toString().lowercase() | ||
} else { | ||
String() | ||
} | ||
) | ||
} else { | ||
String() | ||
}, | ||
fontSize = 14.sp, | ||
fontWeight = if (unread) FontWeight.Normal else FontWeight.Light, | ||
modifier = Modifier | ||
.fillMaxWidth(if (company.isBlank()) 0.75F else 1F) | ||
.shimmer(loading) | ||
) | ||
Text( | ||
text = if (lastThreadTitle.isNotBlank()) { | ||
stringResource(id = R.string.last_thread, lastThreadTitle) | ||
} else { | ||
String() | ||
}, | ||
fontSize = 13.sp, | ||
fontWeight = FontWeight.Light, | ||
modifier = Modifier | ||
.fillMaxWidth(if (lastThreadTitle.isBlank()) 0.5F else 1F) | ||
.shimmer(loading) | ||
) | ||
} | ||
} | ||
} |
90 changes: 84 additions & 6 deletions
90
app/src/main/java/io/aayush/relabs/ui/screens/forumpreview/ForumPreviewScreen.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,112 @@ | ||
package io.aayush.relabs.ui.screens.forumpreview | ||
|
||
import androidx.compose.foundation.ExperimentalFoundationApi | ||
import androidx.compose.foundation.layout.Column | ||
import androidx.compose.foundation.layout.fillMaxHeight | ||
import androidx.compose.foundation.layout.fillMaxSize | ||
import androidx.compose.foundation.layout.padding | ||
import androidx.compose.foundation.lazy.LazyColumn | ||
import androidx.compose.foundation.lazy.items | ||
import androidx.compose.foundation.pager.HorizontalPager | ||
import androidx.compose.foundation.pager.rememberPagerState | ||
import androidx.compose.material3.ExperimentalMaterial3Api | ||
import androidx.compose.material3.Scaffold | ||
import androidx.compose.material3.Tab | ||
import androidx.compose.material3.TabRow | ||
import androidx.compose.material3.Text | ||
import androidx.compose.material3.TopAppBar | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.LaunchedEffect | ||
import androidx.compose.runtime.getValue | ||
import androidx.compose.runtime.rememberCoroutineScope | ||
import androidx.compose.runtime.snapshotFlow | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.res.stringResource | ||
import androidx.compose.ui.unit.dp | ||
import androidx.compose.ui.util.fastForEachIndexed | ||
import androidx.hilt.navigation.compose.hiltViewModel | ||
import androidx.lifecycle.compose.collectAsStateWithLifecycle | ||
import androidx.navigation.NavHostController | ||
import io.aayush.relabs.R | ||
import io.aayush.relabs.network.data.node.Node | ||
import io.aayush.relabs.ui.components.NodePreviewItem | ||
import kotlinx.coroutines.launch | ||
|
||
@Composable | ||
@OptIn(ExperimentalMaterial3Api::class) | ||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class) | ||
fun ForumPreviewScreen( | ||
navHostController: NavHostController, | ||
viewModel: ForumPreviewViewModel = hiltViewModel() | ||
) { | ||
Scaffold( | ||
modifier = Modifier.fillMaxSize(), | ||
topBar = { | ||
TopAppBar( | ||
title = { Text(text = stringResource(id = R.string.forum_preview)) } | ||
) | ||
} | ||
topBar = { TopAppBar(title = { Text(text = stringResource(id = R.string.forum_preview)) }) } | ||
) { | ||
val tabData = listOf(R.string.inventory, R.string.watched, R.string.whats_new) | ||
val pagerState = rememberPagerState( | ||
initialPage = 0, | ||
initialPageOffsetFraction = 0f, | ||
pageCount = { tabData.size } | ||
) | ||
val tabIndex = pagerState.currentPage | ||
val coroutineScope = rememberCoroutineScope() | ||
|
||
val loading: Boolean by viewModel.loading.collectAsStateWithLifecycle() | ||
val inventory: List<Node>? by viewModel.inventory.collectAsStateWithLifecycle() | ||
|
||
LaunchedEffect(key1 = pagerState) { | ||
snapshotFlow { pagerState.currentPage }.collect { page -> | ||
when (page) { | ||
0 -> viewModel.getInventory() | ||
} | ||
} | ||
} | ||
|
||
Column(modifier = Modifier.padding(it)) { | ||
TabRow(selectedTabIndex = tabIndex) { | ||
tabData.fastForEachIndexed { index, _ -> | ||
Tab(selected = tabIndex == index, onClick = { | ||
coroutineScope.launch { | ||
pagerState.animateScrollToPage(index) | ||
} | ||
}, text = { | ||
Text(text = stringResource(id = tabData[index])) | ||
}) | ||
} | ||
} | ||
HorizontalPager( | ||
state = pagerState | ||
) { | ||
if (loading) { | ||
LazyColumn(modifier = Modifier.fillMaxHeight()) { | ||
items(20) { | ||
NodePreviewItem(modifier = Modifier.padding(10.dp), loading = true) | ||
} | ||
} | ||
return@HorizontalPager | ||
} | ||
|
||
LazyColumn(modifier = Modifier.fillMaxHeight()) { | ||
items( | ||
items = when (it) { | ||
0 -> inventory ?: emptyList() | ||
|
||
else -> emptyList() | ||
}, | ||
key = { n -> n.node_id } | ||
) { node -> | ||
NodePreviewItem( | ||
modifier = Modifier.padding(10.dp), | ||
title = node.title, | ||
company = node.breadcrumbs.firstOrNull()?.title ?: String(), | ||
lastUpdated = node.type_data.last_post_date, | ||
lastThreadTitle = node.type_data.last_thread_title, | ||
unread = node.type_data.is_unread, | ||
threads = node.type_data.discussion_count | ||
) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} |
38 changes: 37 additions & 1 deletion
38
app/src/main/java/io/aayush/relabs/ui/screens/forumpreview/ForumPreviewViewModel.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,47 @@ | ||
package io.aayush.relabs.ui.screens.forumpreview | ||
|
||
import androidx.lifecycle.ViewModel | ||
import androidx.lifecycle.viewModelScope | ||
import dagger.hilt.android.lifecycle.HiltViewModel | ||
import io.aayush.relabs.network.XenforoRepository | ||
import io.aayush.relabs.network.data.node.Node | ||
import io.aayush.relabs.network.data.thread.Thread | ||
import kotlinx.coroutines.Dispatchers | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.asStateFlow | ||
import kotlinx.coroutines.launch | ||
import javax.inject.Inject | ||
|
||
@HiltViewModel | ||
class ForumPreviewViewModel @Inject constructor( | ||
private val xenforoRepository: XenforoRepository | ||
) : ViewModel() | ||
) : ViewModel() { | ||
|
||
private val _loading = MutableStateFlow(false) | ||
val loading = _loading.asStateFlow() | ||
|
||
private val _inventory = MutableStateFlow<List<Node>?>(emptyList()) | ||
val inventory = _inventory.asStateFlow() | ||
|
||
private val _trendingNodes = MutableStateFlow<List<Node>?>(emptyList()) | ||
val trendingNodes = _trendingNodes.asStateFlow() | ||
|
||
private val _watchedNodes = MutableStateFlow<List<Thread>?>(emptyList()) | ||
val watchedNodes = _watchedNodes.asStateFlow() | ||
|
||
fun getInventory() { | ||
if (!inventory.value.isNullOrEmpty()) return | ||
viewModelScope.launch(Dispatchers.IO) { | ||
fetch { _inventory.value = xenforoRepository.getInventory() } | ||
} | ||
} | ||
|
||
private inline fun <T> fetch(block: () -> T): T? { | ||
return try { | ||
_loading.value = true | ||
block() | ||
} finally { | ||
_loading.value = false | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters