added "add media" buttons to prevent media picker opening automatically and added status captions
Sonarqube Scanner / Build and analyze (push) Successful in 1m2s

This commit is contained in:
Florian Zumpe
2026-09-27 17:38:24 +02:00
parent 18bb4682a0
commit 6b3f228ad8
4 changed files with 135 additions and 13 deletions
+41 -6
View File
@@ -11,6 +11,7 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
dialogTitle: 'editor-dialog-title',
newRoute: 'editor-new-route',
poiAudio: 'editor-poi-audio',
poiAudioAdd: 'editor-poi-audio-add',
poiCancel: 'editor-poi-cancel',
poiDescription: 'editor-poi-description',
poiForm: 'editor-poi-form',
@@ -18,9 +19,11 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
poiFormView: 'editor-poi-form-view',
poiId: 'editor-poi-id',
poiImages: 'editor-poi-images',
poiImagesAdd: 'editor-poi-images-add',
poiLat: 'editor-poi-lat',
poiList: 'editor-poi-list',
poiLon: 'editor-poi-lon',
poiMediaStatus: 'editor-poi-media-status',
poiRadius: 'editor-poi-radius',
poiSave: 'editor-poi-save',
poiTitle: 'editor-poi-title',
@@ -49,6 +52,9 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
form: 'editor-form',
iconButton: 'editor-icon-button',
iconRow: 'editor-icon-row',
mediaActions: 'editor-media-actions',
mediaButton: 'editor-media-button',
mediaIcon: 'editor-media-icon',
muted: 'editor-muted',
poiItem: 'editor-poi-item',
poiList: 'editor-poi-list',
@@ -449,6 +455,29 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
}
}
function updatePoiMediaStatus(poi = state.currentPoi) {
const status = byId(ids.poiMediaStatus);
if (!status) return;
const selectedAudio = byId(ids.poiAudio)?.files?.[0];
const selectedImages = Array.from(byId(ids.poiImages)?.files || []);
const hasExistingAudio = Boolean(poi?.audio || poi?.audioUrl || poi?.audio_path);
const existingImages = Array.isArray(poi?.images) ? poi.images.length : 0;
const parts = [];
if (selectedAudio) parts.push(`Audio ausgewählt: ${selectedAudio.name || 'Audiodatei'}`);
else if (hasExistingAudio) parts.push('Audio vorhanden');
if (selectedImages.length) parts.push(`${selectedImages.length} Bild${selectedImages.length === 1 ? '' : 'er'} ausgewählt`);
else if (existingImages) parts.push(`${existingImages} Bild${existingImages === 1 ? '' : 'er'} vorhanden`);
status.textContent = parts.length ? parts.join(' · ') : 'Noch keine neuen Medien ausgewählt.';
}
function openFilePicker(inputId) {
const input = byId(inputId);
if (input && typeof input.click === 'function') input.click();
}
function fillPoiForm(poi) {
byId(ids.poiId).value = poiId(poi);
byId(ids.poiTitle).value = poiTitle(poi) === 'Unbenannte Station' ? '' : poiTitle(poi);
@@ -458,6 +487,7 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
byId(ids.poiRadius).value = text(poi?.triggerRadiusM ?? poi?.radiusM ?? poi?.radius ?? 25);
byId(ids.poiAudio).value = '';
byId(ids.poiImages).value = '';
updatePoiMediaStatus(poi);
}
async function loadRoute(route) {
@@ -540,9 +570,9 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
state.currentRoute = { ...saved.route, id: saved.id, gpx: saved.gpx, _source: 'local' };
state.currentSource = 'local';
state.pois = saved.pois;
setStatus('Lokaler Entwurf gespeichert. Es wurden keine Daten an den Server übertragen.');
await loadRoutes();
await loadRoute({ id: saved.id, _source: 'local' });
setStatus('Strecke erfolgreich lokal gespeichert. Es wurden keine Daten an den Server übertragen.');
}
async function saveServerRoute(values) {
@@ -555,9 +585,9 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
: await sendJson(path, 'PUT', values);
const saved = payload.route || payload;
state.currentRoute = { ...saved, _source: 'server' };
setStatus('Veröffentlichte Strecke gespeichert. activated_at wurde nicht verändert.');
await loadRoutes();
await loadRoute({ id, _source: 'server' });
setStatus('Strecke erfolgreich gespeichert. activated_at wurde nicht verändert.');
}
async function saveRoute() {
@@ -643,18 +673,19 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
await loadRoute({ id: routeId(state.currentRoute), _source: 'local' });
}
async function uploadOne(path, file) {
async function uploadOne(path, fieldName, file) {
const data = new FormData();
data.append('file', file);
data.append(fieldName, file);
return sendForm(path, 'POST', data);
}
async function uploadPoiMedia(currentRouteId, currentPoiId) {
const audio = byId(ids.poiAudio)?.files?.[0];
const images = Array.from(byId(ids.poiImages)?.files || []);
if (audio) await uploadOne(`/routes/${encodeURIComponent(currentRouteId)}/pois/${encodeURIComponent(currentPoiId)}/audio`, audio);
const basePath = `/routes/${encodeURIComponent(currentRouteId)}/pois/${encodeURIComponent(currentPoiId)}`;
if (audio) await uploadOne(`${basePath}/audio`, 'audio', audio);
for (const image of images) {
await uploadOne(`/routes/${encodeURIComponent(currentRouteId)}/pois/${encodeURIComponent(currentPoiId)}/images`, image);
await uploadOne(`${basePath}/pictures`, 'picture', image);
}
}
@@ -764,6 +795,10 @@ globalThis.Wegwichtel = globalThis.Wegwichtel || {};
activate(byId(ids.newRoute), newRoute);
activate(byId(ids.routeBack), () => guarded(loadRoutes).then(showListView));
activate(byId(ids.addPoi), newPoi);
activate(byId(ids.poiAudioAdd), () => openFilePicker(ids.poiAudio));
activate(byId(ids.poiImagesAdd), () => openFilePicker(ids.poiImages));
byId(ids.poiAudio)?.addEventListener('change', () => updatePoiMediaStatus());
byId(ids.poiImages)?.addEventListener('change', () => updatePoiMediaStatus());
activate(byId(ids.poiCancel), showRouteView);
activate(byId(ids.routeList), event => guarded(() => routeListAction(event)));
activate(byId(ids.poiList), poiListAction);