Files
photog/android/app/src/main/java/ws/inflo/photogallery/MainActivity.kt
T

122 lines
4.7 KiB
Kotlin
Raw Normal View History

2026-08-13 22:01:20 +02:00
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.PickVisualMedia(),
) { uri -> uri?.let(viewModel::selectImage) }
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,
onPickImage = {
picker.launch(
PickVisualMediaRequest(
ActivityResultContracts.PickVisualMedia.ImageOnly,
),
)
},
onCaptionChange = viewModel::setCaption,
onDateChange = viewModel::setDate,
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 a photo handed over by the share sheet. */
private fun consumeShareIntent(intent: Intent?) {
if (intent?.action != Intent.ACTION_SEND) return
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)
}
uri?.let(viewModel::selectImage)
}
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()
}
}
}