Skip to content

Commit 297db45

Browse files
committed
androidApp: Initial support for announcements
Signed-off-by: Aayush Gupta <aayushgupta219@gmail.com>
1 parent c79c36a commit 297db45

File tree

5 files changed

+147
-1
lines changed

5 files changed

+147
-1
lines changed

androidApp/src/main/java/app/opass/ccip/android/ui/navigation/NavGraph.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import androidx.navigation.NavHostController
1717
import androidx.navigation.compose.NavHost
1818
import androidx.navigation.compose.composable
1919
import androidx.navigation.toRoute
20+
import app.opass.ccip.android.ui.screens.announcement.AnnouncementScreen
2021
import app.opass.ccip.android.ui.screens.event.EventScreen
2122
import app.opass.ccip.android.ui.screens.eventpreview.EventPreviewScreen
2223
import app.opass.ccip.android.ui.screens.schedule.ScheduleScreen
@@ -56,6 +57,10 @@ fun SetupNavGraph(navHostController: NavHostController, startDestination: Screen
5657
composable<Screen.Ticket> { backStackEntry ->
5758
backStackEntry.toRoute<Screen.Ticket>().TicketScreen(navHostController)
5859
}
60+
61+
composable<Screen.Announcement> { backStackEntry ->
62+
backStackEntry.toRoute<Screen.Announcement>().AnnouncementScreen(navHostController)
63+
}
5964
}
6065
}
6166

androidApp/src/main/java/app/opass/ccip/android/ui/navigation/Screen.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,10 @@ sealed class Screen(@StringRes val title: Int, @DrawableRes val icon: Int) {
4242
title = R.string.ticket,
4343
icon = R.drawable.ic_ticket
4444
)
45+
46+
@Serializable
47+
data class Announcement(val eventId: String, val token: String? = null) : Screen(
48+
title = R.string.announcement,
49+
icon = R.drawable.ic_announcement
50+
)
4551
}
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 OPass
3+
* SPDX-License-Identifier: GPL-3.0-only
4+
*/
5+
6+
package app.opass.ccip.android.ui.screens.announcement
7+
8+
import androidx.compose.foundation.clickable
9+
import androidx.compose.foundation.layout.Column
10+
import androidx.compose.foundation.layout.PaddingValues
11+
import androidx.compose.foundation.layout.fillMaxSize
12+
import androidx.compose.foundation.layout.fillMaxWidth
13+
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.foundation.lazy.LazyColumn
15+
import androidx.compose.foundation.lazy.items
16+
import androidx.compose.material3.Icon
17+
import androidx.compose.material3.IconButton
18+
import androidx.compose.material3.MaterialTheme
19+
import androidx.compose.material3.Scaffold
20+
import androidx.compose.material3.Text
21+
import androidx.compose.runtime.Composable
22+
import androidx.compose.runtime.LaunchedEffect
23+
import androidx.compose.runtime.getValue
24+
import androidx.compose.ui.Modifier
25+
import androidx.compose.ui.platform.LocalContext
26+
import androidx.compose.ui.res.painterResource
27+
import androidx.compose.ui.res.stringResource
28+
import androidx.compose.ui.unit.dp
29+
import androidx.hilt.navigation.compose.hiltViewModel
30+
import androidx.lifecycle.compose.collectAsStateWithLifecycle
31+
import androidx.navigation.NavHostController
32+
import app.opass.ccip.android.R
33+
import app.opass.ccip.android.ui.components.TopAppBar
34+
import app.opass.ccip.android.ui.extensions.browse
35+
import app.opass.ccip.android.ui.navigation.Screen
36+
import app.opass.ccip.network.models.fastpass.Announcement
37+
38+
@Composable
39+
fun Screen.Announcement.AnnouncementScreen(
40+
navHostController: NavHostController,
41+
viewModel: AnnouncementViewModel = hiltViewModel()
42+
) {
43+
val context = LocalContext.current
44+
val announcements by viewModel.announcements.collectAsStateWithLifecycle()
45+
46+
LaunchedEffect(key1 = Unit) {
47+
viewModel.getAnnouncements(this@AnnouncementScreen.eventId, this@AnnouncementScreen.token)
48+
}
49+
50+
Scaffold(
51+
modifier = Modifier.fillMaxSize(),
52+
topBar = {
53+
TopAppBar(
54+
title = stringResource(this.title),
55+
navHostController = navHostController,
56+
actions = {
57+
IconButton(
58+
onClick = {
59+
viewModel.getAnnouncements(
60+
this@AnnouncementScreen.eventId,
61+
this@AnnouncementScreen.token,
62+
true
63+
)
64+
}
65+
) {
66+
Icon(
67+
painter = painterResource(id = R.drawable.ic_refresh),
68+
contentDescription = null
69+
)
70+
}
71+
}
72+
)
73+
}
74+
) { paddingValues ->
75+
LazyColumn(
76+
modifier = Modifier
77+
.fillMaxSize()
78+
.padding(paddingValues),
79+
contentPadding = PaddingValues(10.dp)
80+
) {
81+
items(announcements) { announcement: Announcement ->
82+
AnnouncementItem(announcement) {
83+
context.browse(announcement.url)
84+
}
85+
}
86+
}
87+
}
88+
}
89+
90+
@Composable
91+
fun AnnouncementItem(announcement: Announcement, onClicked: () -> Unit = {}) {
92+
Column(
93+
modifier = Modifier
94+
.fillMaxWidth()
95+
.padding(horizontal = 20.dp, vertical = 10.dp)
96+
.clickable(enabled = announcement.url.isNotBlank()) { onClicked() }
97+
) {
98+
Text(text = announcement.message, style = MaterialTheme.typography.bodyLarge)
99+
}
100+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2024 OPass
3+
* SPDX-License-Identifier: GPL-3.0-only
4+
*/
5+
6+
package app.opass.ccip.android.ui.screens.announcement
7+
8+
import androidx.lifecycle.ViewModel
9+
import androidx.lifecycle.viewModelScope
10+
import app.opass.ccip.helpers.PortalHelper
11+
import app.opass.ccip.network.models.fastpass.Announcement
12+
import dagger.hilt.android.lifecycle.HiltViewModel
13+
import kotlinx.coroutines.flow.MutableStateFlow
14+
import kotlinx.coroutines.flow.asStateFlow
15+
import kotlinx.coroutines.launch
16+
import javax.inject.Inject
17+
18+
@HiltViewModel
19+
class AnnouncementViewModel @Inject constructor(
20+
private val portalHelper: PortalHelper
21+
): ViewModel() {
22+
23+
private val _announcements: MutableStateFlow<List<Announcement>> = MutableStateFlow(emptyList())
24+
val announcements = _announcements.asStateFlow()
25+
26+
fun getAnnouncements(eventId: String, token: String? = null, forceReload: Boolean = false) {
27+
viewModelScope.launch {
28+
_announcements.value = portalHelper.getAnnouncements(eventId, token, forceReload)
29+
}
30+
}
31+
}

androidApp/src/main/java/app/opass/ccip/android/ui/screens/event/EventScreen.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,11 @@ fun Screen.Event.EventScreen(
142142
FeatureItem(
143143
label = stringResource(id = R.string.announcement),
144144
iconRes = R.drawable.ic_announcement
145-
)
145+
) {
146+
navHostController.navigate(
147+
Screen.Announcement(this@EventScreen.id, attendee?.token)
148+
)
149+
}
146150
}
147151

148152
FeatureType.FAST_PASS -> {

0 commit comments

Comments
 (0)