@@ -10,16 +10,21 @@ import androidx.compose.animation.*
10
10
import androidx.compose.foundation.layout.*
11
11
import androidx.compose.foundation.lazy.LazyColumn
12
12
import androidx.compose.foundation.lazy.items
13
- import androidx.compose.material3.Scaffold
13
+ import androidx.compose.material3.*
14
14
import androidx.compose.runtime.*
15
15
import androidx.compose.ui.Alignment
16
16
import androidx.compose.ui.Modifier
17
+ import androidx.compose.ui.draw.alpha
18
+ import androidx.compose.ui.draw.shadow
19
+ import androidx.compose.ui.res.stringResource
17
20
import androidx.compose.ui.unit.dp
21
+ import androidx.compose.ui.unit.sp
18
22
import androidx.lifecycle.compose.LifecycleResumeEffect
19
23
import cafe.adriel.voyager.core.screen.Screen
20
24
import cafe.adriel.voyager.koin.getScreenModel
21
25
import cafe.adriel.voyager.navigator.LocalNavigator
22
26
import cafe.adriel.voyager.navigator.currentOrThrow
27
+ import com.aliucord.manager.R
23
28
import com.aliucord.manager.ui.components.AnimatedVersionDisplay
24
29
import com.aliucord.manager.ui.components.ProjectHeader
25
30
import com.aliucord.manager.ui.components.dialogs.NetworkWarningDialog
@@ -70,56 +75,171 @@ class HomeScreen : Screen {
70
75
71
76
Scaffold (
72
77
topBar = { HomeAppBar () },
73
- ) { paddingValues ->
74
- LazyColumn (
78
+ ) { padding ->
79
+ when (model.installations) {
80
+ is InstallsState .Fetching ,
81
+ is InstallsState .Fetched ,
82
+ -> PresentInstallsContent (
83
+ model = model,
84
+ padding = padding,
85
+ onClickInstall = onClickInstall,
86
+ )
87
+
88
+ InstallsState .None -> NoInstallsContent (
89
+ supportedVersion = model.supportedVersion,
90
+ onClickInstall = onClickInstall,
91
+ modifier = Modifier
92
+ .padding(padding.exclude(PaddingValuesSides .Bottom )),
93
+ )
94
+
95
+ InstallsState .Error -> {
96
+ // This is ugly asf but it should never happen
97
+ Box (
98
+ contentAlignment = Alignment .Center ,
99
+ modifier = Modifier .padding(padding),
100
+ ) {
101
+ Text (
102
+ text = " Failed to fetch installations" ,
103
+ style = MaterialTheme .typography.labelMedium,
104
+ )
105
+ }
106
+ }
107
+ }
108
+ }
109
+ }
110
+ }
111
+
112
+ @Composable
113
+ fun PresentInstallsContent (
114
+ model : HomeModel ,
115
+ padding : PaddingValues ,
116
+ onClickInstall : () -> Unit ,
117
+ ) {
118
+ LazyColumn (
119
+ verticalArrangement = Arrangement .spacedBy(6 .dp),
120
+ horizontalAlignment = Alignment .CenterHorizontally ,
121
+ contentPadding = padding
122
+ .exclude(PaddingValuesSides .Horizontal + PaddingValuesSides .Top ),
123
+ modifier = Modifier
124
+ .fillMaxSize()
125
+ .padding(padding.exclude(PaddingValuesSides .Bottom ))
126
+ .padding(top = 16 .dp, start = 16 .dp, end = 16 .dp),
127
+ ) {
128
+ item(key = " PROJECT_HEADER" ) {
129
+ ProjectHeader ()
130
+ }
131
+
132
+ item(key = " ADD_INSTALL_BUTTON" ) {
133
+ InstallButton (
134
+ onClick = onClickInstall,
135
+ modifier = Modifier
136
+ .fillMaxWidth()
137
+ .padding(top = 10 .dp)
138
+ )
139
+ }
140
+
141
+ item(key = " SUPPORTED_VERSION" ) {
142
+ AnimatedVersionDisplay (
143
+ version = model.supportedVersion,
144
+ modifier = Modifier .padding(bottom = 22 .dp),
145
+ )
146
+ }
147
+
148
+ val installations = (model.installations as ? InstallsState .Fetched )?.data
149
+ ? : return @LazyColumn
150
+
151
+ items(installations, key = { it.packageName }) {
152
+ AnimatedVisibility (
153
+ enter = fadeIn() + slideInHorizontally { it * - 2 },
154
+ exit = fadeOut() + slideOutHorizontally { it * 2 },
155
+ visible = model.supportedVersion !is DiscordVersion .None ,
156
+ ) {
157
+ val navigator = LocalNavigator .currentOrThrow
158
+
159
+ InstalledItemCard (
160
+ data = it,
161
+ onUpdate = ::TODO , // TODO: prefilled install options screen
162
+ onOpenApp = { model.launchApp(it.packageName) },
163
+ onOpenInfo = { model.openAppInfo(it.packageName) },
164
+ onOpenPlugins = { navigator.push(PluginsScreen ()) }, // TODO: install-specific plugins
165
+ modifier = Modifier .fillMaxWidth()
166
+ )
167
+ }
168
+ }
169
+ }
170
+ }
171
+
172
+ @Composable
173
+ fun NoInstallsContent (
174
+ supportedVersion : DiscordVersion ,
175
+ onClickInstall : () -> Unit ,
176
+ modifier : Modifier = Modifier ,
177
+ ) {
178
+ Column (
179
+ verticalArrangement = Arrangement .spacedBy(6 .dp),
180
+ horizontalAlignment = Alignment .CenterHorizontally ,
181
+ modifier = modifier
182
+ .fillMaxSize()
183
+ .padding(top = 16 .dp, start = 16 .dp, end = 16 .dp),
184
+ ) {
185
+ ProjectHeader ()
186
+
187
+ InstallButton (
188
+ onClick = onClickInstall,
189
+ modifier = Modifier
190
+ .fillMaxWidth()
191
+ .padding(top = 10 .dp)
192
+ )
193
+
194
+ AnimatedVersionDisplay (
195
+ version = supportedVersion,
196
+ modifier = Modifier .padding(bottom = 22 .dp),
197
+ )
198
+
199
+ Box (
200
+ modifier = Modifier .fillMaxSize(),
201
+ ) {
202
+ Column (
75
203
verticalArrangement = Arrangement .spacedBy(6 .dp),
76
- horizontalAlignment = Alignment .CenterHorizontally ,
77
- contentPadding = paddingValues
78
- .exclude(PaddingValuesSides .Horizontal + PaddingValuesSides .Top ),
79
204
modifier = Modifier
205
+ .alpha(.1f )
80
206
.fillMaxSize()
81
- .padding(paddingValues.exclude(PaddingValuesSides .Bottom ))
82
- .padding(top = 16 .dp, start = 16 .dp, end = 16 .dp),
83
207
) {
84
- item(key = " PROJECT_HEADER" ) {
85
- ProjectHeader ()
86
- }
87
-
88
- item(key = " ADD_INSTALL_BUTTON" ) {
89
- InstallButton (
90
- onClick = onClickInstall,
208
+ for (i in 0 .. < 3 ) key(i) {
209
+ Surface (
210
+ content = {},
211
+ shape = MaterialTheme .shapes.medium,
212
+ tonalElevation = 2 .dp,
91
213
modifier = Modifier
92
214
.fillMaxWidth()
93
- .padding(top = 10 .dp)
94
- )
95
- }
96
-
97
- item(key = " SUPPORTED_VERSION" ) {
98
- AnimatedVersionDisplay (
99
- version = model.supportedVersion,
100
- modifier = Modifier .padding(bottom = 22 .dp),
215
+ .height(195 .dp)
216
+ .shadow(
217
+ clip = false ,
218
+ elevation = 2 .dp,
219
+ shape = MaterialTheme .shapes.medium,
220
+ ),
101
221
)
102
222
}
223
+ }
103
224
104
- val installations = (model.installations as ? InstallsState .Fetched )?.data
105
- ? : return @LazyColumn
225
+ Column (
226
+ verticalArrangement = Arrangement .spacedBy(14 .dp),
227
+ horizontalAlignment = Alignment .CenterHorizontally ,
228
+ modifier = Modifier
229
+ .alpha(.8f )
230
+ .align(Alignment .Center )
231
+ .padding(bottom = 80 .dp),
232
+ ) {
233
+ Text (
234
+ text = """ /ᐠﹷ ‸ ﹷ ᐟ\ノ""" ,
235
+ style = MaterialTheme .typography.labelLarge
236
+ .copy(fontSize = 38 .sp),
237
+ )
106
238
107
- items(installations, key = { it.packageName }) {
108
- AnimatedVisibility (
109
- enter = fadeIn() + slideInHorizontally { it * - 2 },
110
- exit = fadeOut() + slideOutHorizontally { it * 2 },
111
- visible = model.supportedVersion !is DiscordVersion .None ,
112
- ) {
113
- InstalledItemCard (
114
- data = it,
115
- onUpdate = ::TODO , // TODO: prefilled install options screen
116
- onOpenApp = { model.launchApp(it.packageName) },
117
- onOpenInfo = { model.openAppInfo(it.packageName) },
118
- onOpenPlugins = { navigator.push(PluginsScreen ()) }, // TODO: install-specific plugins
119
- modifier = Modifier .fillMaxWidth()
120
- )
121
- }
122
- }
239
+ Text (
240
+ text = stringResource(R .string.installs_no_installs),
241
+ style = MaterialTheme .typography.labelMedium,
242
+ )
123
243
}
124
244
}
125
245
}
0 commit comments