package ws.inflo.photogallery import android.Manifest import android.content.Intent import android.content.pm.PackageManager import android.net.Uri import android.os.Build import android.os.Bundle import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.result.PickVisualMediaRequest import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.viewModels import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.runtime.saveable.rememberSaveable import androidx.core.content.ContextCompat import androidx.core.net.toUri import ws.inflo.photogallery.ui.PhotoGalleryTheme import ws.inflo.photogallery.ui.PostScreen import ws.inflo.photogallery.ui.SettingsScreen import ws.inflo.photogallery.ui.UploadViewModel class MainActivity : ComponentActivity() { private val viewModel: UploadViewModel by viewModels() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) consumeShareIntent(intent) setContent { PhotoGalleryTheme { // Land on settings until there is somewhere to post to. var showSettings by rememberSaveable { mutableStateOf(!viewModel.isConfigured) } val picker = rememberLauncherForActivityResult( ActivityResultContracts.PickMultipleVisualMedia(), ) { uris -> if (uris.isNotEmpty()) viewModel.selectImages(uris) } val notificationPermission = rememberLauncherForActivityResult( ActivityResultContracts.RequestPermission(), ) { /* Upload works either way; this only affects the progress notification. */ } LaunchedEffect(Unit) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && ContextCompat.checkSelfPermission( this@MainActivity, Manifest.permission.POST_NOTIFICATIONS, ) != PackageManager.PERMISSION_GRANTED ) { notificationPermission.launch(Manifest.permission.POST_NOTIFICATIONS) } } if (showSettings) { SettingsScreen( state = viewModel.config, onBaseUrlChange = viewModel::setBaseUrl, onUsernameChange = viewModel::setUsername, onPasswordChange = viewModel::setPassword, onSave = viewModel::saveAndTest, onBack = if (viewModel.isConfigured) { { showSettings = false } } else { null }, ) } else { PostScreen( state = viewModel.post, onPickImages = { picker.launch( PickVisualMediaRequest( ActivityResultContracts.PickVisualMedia.ImageOnly, ), ) }, onCaptionChange = viewModel::setCaption, onDateChange = viewModel::setDate, onRemove = viewModel::removeItem, onSubmit = viewModel::submit, onReset = viewModel::clear, onOpenSettings = { showSettings = true }, onOpenUrl = ::openUrl, ) } } } } override fun onNewIntent(intent: Intent) { super.onNewIntent(intent) setIntent(intent) consumeShareIntent(intent) } /** Picks up one or several photos handed over by the share sheet. */ private fun consumeShareIntent(intent: Intent?) { val uris: List = when (intent?.action) { Intent.ACTION_SEND -> { val uri: Uri? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { intent.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java) } else { @Suppress("DEPRECATION") intent.getParcelableExtra(Intent.EXTRA_STREAM) } listOfNotNull(uri) } Intent.ACTION_SEND_MULTIPLE -> { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM, Uri::class.java) } else { @Suppress("DEPRECATION") intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM) }.orEmpty() } else -> return } if (uris.isNotEmpty()) viewModel.selectImages(uris) } private fun openUrl(url: String) { if (url.isBlank()) return try { startActivity(Intent(Intent.ACTION_VIEW, url.toUri())) } catch (_: Exception) { Toast.makeText(this, "No browser to open $url", Toast.LENGTH_SHORT).show() } } }