Add an edit/delete manage screen to the Android app

A new Manage screen (reached from the Post screen) lists published posts with
thumbnails and lets you edit a post's caption, date and tags or delete it to the
server's trash, over the same /api/photos, /api/edit and /api/delete endpoints
the web /manage uses.

UploadClient gains listPhotos/editPost/deletePost/fetchThumbnail, parsing JSON
with the built-in org.json (no new dependency) and posting edits/deletes as
urlencoded forms. The app sends no Origin or Sec-Fetch-Site header, so it passes
the server's same-origin CSRF check as a non-browser client; Basic auth is
already attached on every request. UploadViewModel holds the manage state,
loads the list, fetches thumbnails in the background, and applies edits/deletes
optimistically.
This commit is contained in:
puttaalu committed 2026-10-18 23:23:39 +02:00
1 parent e67d25b191
commit 225bdc9b4f
7 files changed
+585 -11

No files matched your search

@@ -20,6 +20,7 @@ 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.ManageScreen
import ws.inflo.photogallery.ui.PhotoGalleryTheme
import ws.inflo.photogallery.ui.PostScreen
import ws.inflo.photogallery.ui.SettingsScreen
@@ -37,6 +38,7 @@ class MainActivity : ComponentActivity() {
PhotoGalleryTheme {
// Land on settings until there is somewhere to post to.
var showSettings by rememberSaveable { mutableStateOf(!viewModel.isConfigured) }
var showManage by rememberSaveable { mutableStateOf(false) }
val picker = rememberLauncherForActivityResult(
ActivityResultContracts.PickMultipleVisualMedia(),
@@ -57,8 +59,8 @@ class MainActivity : ComponentActivity() {
}
}
if (showSettings) {
SettingsScreen(
when {
showSettings -> SettingsScreen(
state = viewModel.config,
onBaseUrlChange = viewModel::setBaseUrl,
onUsernameChange = viewModel::setUsername,
@@ -70,8 +72,17 @@ class MainActivity : ComponentActivity() {
null
},
)
} else {
PostScreen(
showManage -> ManageScreen(
state = viewModel.manage,
onBack = { showManage = false },
onRefresh = viewModel::loadManage,
onSave = viewModel::saveEdit,
onDelete = viewModel::deletePost,
onDismissNotice = viewModel::clearManageNotice,
)
else -> PostScreen(
state = viewModel.post,
onPickImages = {
picker.launch(
@@ -87,6 +98,10 @@ class MainActivity : ComponentActivity() {
onSubmit = viewModel::submit,
onReset = viewModel::clear,
onOpenSettings = { showSettings = true },
onOpenManage = {
viewModel.loadManage()
showManage = true
},
onOpenUrl = ::openUrl,
)
}