@@ -11,6 +11,7 @@ import androidx.compose.foundation.background
1111import androidx.compose.foundation.clickable
1212import androidx.compose.foundation.combinedClickable
1313import androidx.compose.foundation.layout.Box
14+ import androidx.compose.foundation.layout.PaddingValues
1415import androidx.compose.foundation.layout.Row
1516import androidx.compose.foundation.layout.Spacer
1617import androidx.compose.foundation.layout.fillMaxSize
@@ -33,6 +34,7 @@ import androidx.compose.material3.CircularProgressIndicator
3334import androidx.compose.material3.ColorScheme
3435import androidx.compose.material3.DropdownMenu
3536import androidx.compose.material3.DropdownMenuItem
37+ import androidx.compose.material3.ExperimentalMaterial3Api
3638import androidx.compose.material3.FloatingActionButton
3739import androidx.compose.material3.HorizontalDivider
3840import androidx.compose.material3.Icon
@@ -44,6 +46,7 @@ import androidx.compose.material3.Scaffold
4446import androidx.compose.material3.SnackbarHost
4547import androidx.compose.material3.SnackbarHostState
4648import androidx.compose.material3.Text
49+ import androidx.compose.material3.pulltorefresh.PullToRefreshBox
4750import androidx.compose.runtime.Composable
4851import androidx.compose.runtime.LaunchedEffect
4952import androidx.compose.runtime.getValue
@@ -92,9 +95,11 @@ import com.nextcloud.android.common.ui.share.model.ui.filtered
9295import com.nextcloud.android.common.ui.share.model.ui.label
9396import com.nextcloud.android.common.ui.share.repository.ShareRemoteRepository
9497
98+ private val FIRST_ITEM_TOP_SPACING = 16 .dp
99+ private val ITEM_SPACING = 2 .dp
100+
95101@Composable
96102private fun ShareScreen (
97- sourceId : String ,
98103 internalLink : String ,
99104 viewModel : ShareViewModel
100105) {
@@ -105,7 +110,6 @@ private fun ShareScreen(
105110 val editorEntry by viewModel.editorEntry.collectAsStateWithLifecycle()
106111 val snackbarHostState = remember { SnackbarHostState () }
107112 val resources = LocalResources .current
108- val context = LocalContext .current
109113
110114 LaunchedEffect (errorMessageId) {
111115 errorMessageId?.let {
@@ -117,7 +121,7 @@ private fun ShareScreen(
117121 Scaffold (
118122 floatingActionButton = {
119123 FloatingActionButton (
120- onClick = { viewModel.createDraftShare(sourceId ) },
124+ onClick = { viewModel.createDraftShare() },
121125 ) {
122126 Icon (painterResource(R .drawable.ic_person_add), contentDescription = " Add" )
123127 }
@@ -137,53 +141,19 @@ private fun ShareScreen(
137141 }
138142 }
139143
140- is ShareScreenState .Empty -> {
141- ContentUnavailableView (
142- iconId = R .drawable.ic_person_add,
143- title = stringResource(R .string.share_view_empty_title),
144- )
145- }
146-
147- is ShareScreenState .Loaded -> {
148- LazyColumn (
149- modifier = Modifier
150- .padding(paddingValues)
151- .fillMaxWidth(),
152- horizontalAlignment = Alignment .CenterHorizontally
153- ) {
154- val shares = state.shares.filtered()
155- itemsIndexed(shares, key = { _, share -> share.id }) { index, share ->
156- val type = ShareItemType .type(index, shares.lastIndex)
157- val title = share.getHeadline(context, shares)
158-
159- if (index == 0 ) {
160- Spacer (modifier = Modifier .height(16 .dp))
161- } else {
162- Spacer (modifier = Modifier .height(2 .dp))
163- }
144+ is ShareScreenState .Empty -> ShareList (
145+ shares = emptyList(),
146+ permissionPresets = permissionPresets,
147+ paddingValues = paddingValues,
148+ viewModel = viewModel
149+ )
164150
165- ShareItem (
166- share = share,
167- title = title,
168- type = type,
169- permissionPresets = permissionPresets,
170- onSelectShare = { selected ->
171- viewModel.setActiveShare(selected, ShareEditorEntry .EDIT )
172- },
173- onCustomizeShare = { selected ->
174- viewModel.setActiveShare(selected, ShareEditorEntry .CUSTOMIZE_PERMISSION )
175- },
176- onChangePreset = { selected, preset ->
177- viewModel.updatePermissionPreset(selected.id, preset, updateActiveShare = false )
178- },
179- onDeleteShare = { viewModel.deleteShare(it.id) },
180- onSendEmail = { selected ->
181- viewModel.setActiveShare(selected, ShareEditorEntry .SEND_EMAIL )
182- }
183- )
184- }
185- }
186- }
151+ is ShareScreenState .Loaded -> ShareList (
152+ shares = state.shares.filtered(),
153+ permissionPresets = permissionPresets,
154+ paddingValues = paddingValues,
155+ viewModel = viewModel
156+ )
187157 }
188158 }
189159
@@ -202,6 +172,66 @@ private fun ShareScreen(
202172 }
203173}
204174
175+ @OptIn(ExperimentalMaterial3Api ::class )
176+ @Composable
177+ private fun ShareList (
178+ shares : List <Share >,
179+ permissionPresets : List <PermissionPreset >,
180+ paddingValues : PaddingValues ,
181+ viewModel : ShareViewModel
182+ ) {
183+ val context = LocalContext .current
184+ val isRefreshing by viewModel.isRefreshing.collectAsStateWithLifecycle()
185+
186+ PullToRefreshBox (
187+ isRefreshing = isRefreshing,
188+ onRefresh = viewModel::refreshShares,
189+ modifier = Modifier
190+ .fillMaxSize()
191+ .padding(paddingValues)
192+ ) {
193+ LazyColumn (
194+ modifier = Modifier .fillMaxSize(),
195+ horizontalAlignment = Alignment .CenterHorizontally
196+ ) {
197+ if (shares.isEmpty()) {
198+ item {
199+ Box (modifier = Modifier .fillParentMaxSize()) {
200+ ContentUnavailableView (
201+ iconId = R .drawable.ic_person_add,
202+ title = stringResource(R .string.share_view_empty_title),
203+ )
204+ }
205+ }
206+ }
207+
208+ itemsIndexed(shares, key = { _, share -> share.id }) { index, share ->
209+ Spacer (modifier = Modifier .height(if (index == 0 ) FIRST_ITEM_TOP_SPACING else ITEM_SPACING ))
210+
211+ ShareItem (
212+ share = share,
213+ title = share.getHeadline(context, shares),
214+ type = ShareItemType .type(index, shares.lastIndex),
215+ permissionPresets = permissionPresets,
216+ onSelectShare = { selected ->
217+ viewModel.setActiveShare(selected, ShareEditorEntry .EDIT )
218+ },
219+ onCustomizeShare = { selected ->
220+ viewModel.setActiveShare(selected, ShareEditorEntry .CUSTOMIZE_PERMISSION )
221+ },
222+ onChangePreset = { selected, preset ->
223+ viewModel.updatePermissionPreset(selected.id, preset, updateActiveShare = false )
224+ },
225+ onDeleteShare = { viewModel.deleteShare(it.id) },
226+ onSendEmail = { selected ->
227+ viewModel.setActiveShare(selected, ShareEditorEntry .SEND_EMAIL )
228+ }
229+ )
230+ }
231+ }
232+ }
233+ }
234+
205235@Composable
206236private fun ShareItem (
207237 share : Share ,
@@ -396,7 +426,7 @@ fun ComposeView.initShareScreen(
396426 credentials : ServerCredentials ,
397427 colorScheme : ColorScheme
398428) {
399- val factory = ShareViewModelFactory {
429+ val factory = ShareViewModelFactory (sourceId) {
400430 ShareRemoteRepository (NextcloudHttpClient .create(credentials))
401431 }
402432 val viewModel = ViewModelProvider .create(viewModelStoreOwner, factory)[ShareViewModel ::class ]
@@ -411,7 +441,7 @@ fun ComposeView.initShareScreen(
411441 MaterialTheme (
412442 colorScheme = colorScheme,
413443 content = {
414- ShareScreen (sourceId, internalLink, viewModel)
444+ ShareScreen (internalLink, viewModel)
415445 }
416446 )
417447 }
0 commit comments