@@ -39,28 +39,24 @@ import androidx.compose.material3.MaterialTheme
39
39
import androidx.compose.material3.Scaffold
40
40
import androidx.compose.material3.Text
41
41
import androidx.compose.runtime.Composable
42
- import androidx.compose.runtime.DisposableEffect
43
42
import androidx.compose.runtime.mutableStateOf
44
43
import androidx.compose.runtime.remember
45
44
import androidx.compose.runtime.rememberCoroutineScope
46
45
import androidx.compose.ui.Alignment
47
46
import androidx.compose.ui.Modifier
48
47
import androidx.compose.ui.platform.LocalContext
48
+ import androidx.compose.ui.res.stringResource
49
49
import androidx.compose.ui.tooling.preview.Preview
50
50
import androidx.compose.ui.unit.dp
51
- import androidx.compose.ui.viewinterop.AndroidView
52
51
import androidx.compose.ui.window.Dialog
53
52
import androidx.compose.ui.window.DialogProperties
54
- import androidx.media3.common.MediaItem
55
- import androidx.media3.exoplayer.ExoPlayer
56
- import androidx.media3.ui.PlayerView
53
+ import coil.compose.AsyncImage
54
+ import com.arcgismaps.toolkit.popup.R
57
55
import kotlinx.coroutines.CoroutineScope
58
- import kotlinx.coroutines.Dispatchers
59
56
import kotlinx.coroutines.launch
60
- import kotlinx.coroutines.withContext
61
57
62
58
/* *
63
- * A file viewer that can display different type of images .
59
+ * A file viewer that can display different type of files .
64
60
*
65
61
* @since 200.5.0
66
62
*/
@@ -83,7 +79,7 @@ internal fun FileViewer(scope: CoroutineScope, fileState: ViewableFile, onDismis
83
79
IconButton (onClick = { onDismissRequest() }) {
84
80
Icon (
85
81
Icons .Rounded .Close ,
86
- contentDescription = " Back " ,
82
+ contentDescription = stringResource(id = R .string.close) ,
87
83
tint = MaterialTheme .colorScheme.onSurface
88
84
)
89
85
}
@@ -112,8 +108,14 @@ internal fun FileViewer(scope: CoroutineScope, fileState: ViewableFile, onDismis
112
108
contentAlignment = Alignment .Center
113
109
) {
114
110
when (fileState.type) {
115
- is ViewableFileType .Image -> ImageViewer (fileState.path)
116
- is ViewableFileType .Video -> VideoViewer (fileState.path)
111
+ is ViewableFileType .Image ->
112
+ AsyncImage (
113
+ modifier = Modifier .fillMaxSize(),
114
+ model = fileState.path,
115
+ contentDescription = stringResource(id = R .string.image),
116
+ )
117
+
118
+ is ViewableFileType .Video -> Text (" Video" )
117
119
is ViewableFileType .Other -> Text (" Other" )
118
120
}
119
121
}
@@ -131,70 +133,54 @@ private fun ViewerActions(
131
133
val expanded = remember { mutableStateOf(false ) }
132
134
Box (modifier = modifier) {
133
135
IconButton (onClick = { expanded.value = true }) {
134
- Icon (Icons .Rounded .MoreVert , contentDescription = " More" , tint = MaterialTheme .colorScheme.onSurface)
136
+ Icon (
137
+ Icons .Rounded .MoreVert ,
138
+ contentDescription = stringResource(id = R .string.more),
139
+ tint = MaterialTheme .colorScheme.onSurface
140
+ )
135
141
}
136
142
137
143
DropdownMenu (expanded = expanded.value, onDismissRequest = { expanded.value = false }) {
138
144
DropdownMenuItem (
139
- text = { Text (" Share " , color = MaterialTheme .colorScheme.onSurface) },
145
+ text = { Text (stringResource(id = R .string.more) , color = MaterialTheme .colorScheme.onSurface) },
140
146
onClick = {
141
147
expanded.value = false
142
- coroutineScope.launch( Dispatchers . IO ) { viewableFile.share(context) }
148
+ coroutineScope.launch { viewableFile.share(context) }
143
149
},
144
150
leadingIcon = {
145
- Icon (Icons .Rounded .Share , contentDescription = " Share" , tint = MaterialTheme .colorScheme.onSurface)
151
+ Icon (
152
+ Icons .Rounded .Share ,
153
+ contentDescription = stringResource(id = R .string.share),
154
+ tint = MaterialTheme .colorScheme.onSurface
155
+ )
146
156
}
147
157
)
148
158
149
159
DropdownMenuItem (
150
160
text = {
151
- Text (" Save " , color = MaterialTheme .colorScheme.onSurface)
161
+ Text (text = stringResource(id = R .string.save) , color = MaterialTheme .colorScheme.onSurface)
152
162
},
153
163
onClick = {
154
164
expanded.value = false
155
- coroutineScope.launch( Dispatchers . IO ) {
165
+ coroutineScope.launch {
156
166
val saveResult = viewableFile.saveToDevice(context)
157
- withContext(Dispatchers .Main ) {
158
- saveResult.onSuccess {
159
- Toast .makeText(context, " Save successful" , Toast .LENGTH_SHORT ).show()
160
- }.onFailure {
161
- Toast .makeText(context, " Save failed" , Toast .LENGTH_SHORT ).show()
162
- Log .e(" ArcGISMapsSDK" , " Failed to save file: $it " )
163
- }
167
+ saveResult.onSuccess {
168
+ Toast .makeText(context, context.getString(R .string.save_successful), Toast .LENGTH_SHORT )
169
+ .show()
170
+ }.onFailure {
171
+ Toast .makeText(context, context.getString(R .string.save_failed), Toast .LENGTH_SHORT ).show()
172
+ Log .e(" ArcGISMapsSDK" , " Failed to save file: $it " )
164
173
}
165
174
}
166
175
},
167
176
leadingIcon = {
168
- Icon (Icons .Rounded .Save , contentDescription = " Save" , tint = MaterialTheme .colorScheme.onSurface)
169
- }
170
- )
171
- }
172
- }
173
- }
174
-
175
- @Composable
176
- internal fun VideoViewer (path : String ) {
177
- val context = LocalContext .current
178
- val exoPlayer = remember {
179
- ExoPlayer .Builder (context).build().apply {
180
- val mediaItem = MediaItem .Builder ()
181
- .setUri(path)
182
- .build()
183
- setMediaItem(mediaItem)
184
- prepare()
185
- }
186
- }
187
-
188
- AndroidView (
189
- factory = {
190
- PlayerView (context).apply {
191
- player = exoPlayer
192
- }
177
+ Icon (
178
+ Icons .Rounded .Save ,
179
+ contentDescription = stringResource(id = R .string.save),
180
+ tint = MaterialTheme .colorScheme.onSurface
181
+ )
193
182
}
194
183
)
195
- DisposableEffect (Unit ) {
196
- onDispose {
197
- exoPlayer.release()
198
184
}
199
185
}
200
186
}
0 commit comments