Merge branch 'style-gallery-laravel12'

This commit is contained in:
soeren
2025-11-13 20:02:39 +01:00
11 changed files with 136 additions and 107 deletions

View File

@@ -5,7 +5,6 @@ namespace App\Http\Controllers;
use App\Models\Image;
use App\Settings\GeneralSettings;
use Carbon\Carbon;
use Illuminate\Support\Facades\Lang;
use Inertia\Inertia;
class HomeController extends Controller
@@ -14,11 +13,6 @@ class HomeController extends Controller
public function index()
{
$locale = app()->getLocale();
$translations = array_merge(
Lang::get('api', [], $locale),
Lang::get('settings', [], $locale)
);
$galleryHeading = $this->settings->gallery_heading;
$newImageTimespanMinutes = $this->settings->new_image_timespan_minutes;
@@ -30,7 +24,6 @@ class HomeController extends Controller
});
return Inertia::render('Home', [
'translations' => $translations,
'galleryHeading' => $galleryHeading,
'images' => $images,
]);

View File

@@ -2,19 +2,19 @@
<div class="space-y-4">
<p
v-if="!images.length"
class="rounded-3xl border border-dashed border-white/20 bg-white/5 px-4 py-10 text-center text-sm text-slate-300"
class="rounded-3xl border border-dashed border-slate-300 bg-white px-4 py-10 text-center text-sm text-slate-500 dark:border-white/20 dark:bg-white/5 dark:text-slate-300"
>
{{ props.translations.empty_gallery || 'Noch keine Bilder vorhanden.' }}
{{ __('api.gallery.empty') }}
</p>
<div
v-else
class="grid grid-cols-2 gap-4 sm:grid-cols-3 sm:gap-6 xl:grid-cols-4 2xl:grid-cols-5"
class="grid grid-cols-2 gap-3 sm:grid-cols-3 sm:gap-5 xl:grid-cols-4 2xl:grid-cols-5"
>
<button
v-for="image in images"
:key="image.id ?? image.name"
type="button"
class="group relative aspect-[3/4] overflow-hidden rounded-[1.75rem] border border-white/10 bg-slate-900/30 shadow-2xl ring-1 ring-white/5 transition-all hover:border-emerald-300 focus:outline-none focus-visible:ring-4 focus-visible:ring-emerald-400"
class="group relative aspect-[4/3] overflow-hidden rounded-[1.75rem] border border-slate-200 bg-white shadow-2xl ring-1 ring-slate-100 transition-all hover:border-emerald-300 focus:outline-none focus-visible:ring-4 focus-visible:ring-emerald-400 dark:border-white/10 dark:bg-slate-900/30 dark:ring-white/5"
@click="$emit('imageTapped', image, $event)"
:aria-label="fallbackLabel(image)"
>
@@ -31,9 +31,9 @@
<span class="h-1.5 w-1.5 rounded-full bg-emerald-800"></span>
{{ __('new') }}
</span>
<div class="pointer-events-none absolute inset-x-0 bottom-0 bg-gradient-to-t from-slate-950/70 via-slate-950/10 to-transparent p-4 text-left">
<p class="text-base font-semibold text-white drop-shadow">{{ fallbackLabel(image) }}</p>
<p class="text-xs uppercase tracking-[0.3em] text-white/70">Tap to open</p>
<div class="pointer-events-none absolute inset-x-0 bottom-0 bg-gradient-to-t from-slate-900/80 via-slate-900/10 to-transparent p-4 text-left text-white">
<p class="text-base font-semibold drop-shadow">{{ fallbackLabel(image) }}</p>
<p class="text-xs uppercase tracking-[0.3em] text-white/70">{{ __('api.gallery.tap_to_open') }}</p>
</div>
</button>
</div>
@@ -48,17 +48,9 @@ const props = defineProps({
type: Array,
required: true,
},
translations: {
type: Object,
required: true,
},
});
const emits = defineEmits(['imageTapped']);
const __ = (key) => {
return props.translations[key] || key;
};
const fallbackLabel = (image) => image?.name || props.translations.image || 'Bild';
const fallbackLabel = (image) => image?.name || 'Bild';
</script>

View File

@@ -2,7 +2,7 @@
<div class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50">
<div class="bg-white p-6 rounded-lg shadow-lg text-center flex flex-col items-center">
<div class="loader ease-linear rounded-full border-4 border-t-4 border-gray-200 h-12 w-12 mb-4"></div>
<p class="text-gray-700 text-lg">{{ __('loading_spinner.processing_image') }}</p>
<p class="text-gray-700 text-lg">{{ __('api.loading_spinner.processing_image') }}</p>
<p v-if="progress > 0" class="text-gray-700 text-sm mt-2">{{ progress }}%</p>
</div>
</div>

View File

@@ -1,31 +1,31 @@
<template>
<nav class="rounded-3xl border border-white/10 bg-white/5 p-5 text-white shadow-2xl backdrop-blur">
<nav class="rounded-3xl border border-slate-200 bg-white p-5 text-slate-900 shadow-2xl backdrop-blur transition-colors dark:border-white/10 dark:bg-white/5 dark:text-white">
<div class="flex flex-wrap items-center justify-between gap-4">
<div class="flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-slate-300">
<div class="flex items-center gap-2 text-xs uppercase tracking-[0.4em] text-slate-500 dark:text-slate-300">
Seite
<span class="text-xl font-semibold text-white">{{ currentPage }}</span>
<span class="text-slate-500">/</span>
<span class="text-lg text-slate-200">{{ totalPages }}</span>
<span class="text-xl font-semibold text-slate-900 dark:text-white">{{ currentPage }}</span>
<span class="text-slate-400 dark:text-slate-500">/</span>
<span class="text-lg text-slate-700 dark:text-slate-200">{{ totalPages }}</span>
</div>
<div class="flex flex-wrap items-center gap-3">
<button
type="button"
class="inline-flex items-center gap-2 rounded-full border border-white/20 bg-white/10 px-4 py-2 text-sm font-semibold text-white transition hover:border-cyan-300 hover:text-cyan-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-cyan-300 disabled:opacity-50"
class="inline-flex items-center gap-2 rounded-full border border-slate-300 bg-white px-4 py-2 text-sm font-semibold text-slate-900 transition hover:border-cyan-300 hover:text-cyan-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-cyan-300 disabled:opacity-50 dark:border-white/20 dark:bg-white/10 dark:text-white dark:hover:text-cyan-200"
@click="$emit('prevPage')"
:disabled="currentPage === 1"
>
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="m15.75 19.5-7.5-7.5 7.5-7.5" />
</svg>
{{ __('navigation.previous') }}
{{ __('api.navigation.previous') }}
</button>
<button
type="button"
class="inline-flex items-center gap-2 rounded-full border border-emerald-300 bg-emerald-400/20 px-4 py-2 text-sm font-semibold text-emerald-100 transition hover:bg-emerald-400/40 focus:outline-none focus-visible:ring-2 focus-visible:ring-emerald-300 disabled:opacity-50"
class="inline-flex items-center gap-2 rounded-full border border-emerald-300 bg-emerald-50 px-4 py-2 text-sm font-semibold text-emerald-700 transition hover:bg-emerald-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-emerald-300 disabled:opacity-50 dark:bg-emerald-400/20 dark:text-emerald-100 dark:hover:bg-emerald-400/40"
@click="$emit('nextPage')"
:disabled="currentPage === totalPages"
>
{{ __('navigation.next') }}
{{ __('api.navigation.next') }}
<svg class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
<path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
</svg>

View File

@@ -1,6 +1,6 @@
<template>
<div class="fixed inset-0 z-[120] flex items-center justify-center bg-slate-950/70 px-6 py-10 backdrop-blur" @click.self="$emit('close')">
<div class="w-full max-w-md rounded-[2.5rem] border border-white/10 bg-gradient-to-b from-slate-900 via-slate-900/90 to-slate-950 p-8 text-white shadow-[0_35px_80px_rgba(2,6,23,0.65)]">
<div class="fixed inset-0 z-[120] flex items-center justify-center bg-slate-900/30 px-6 py-10 backdrop-blur dark:bg-slate-950/70" @click.self="$emit('close')">
<div class="w-full max-w-md rounded-[2.5rem] border border-slate-200 bg-gradient-to-b from-white via-white to-slate-50 p-8 text-slate-900 shadow-[0_35px_80px_rgba(2,6,23,0.15)] transition-colors dark:border-white/10 dark:from-slate-900 dark:via-slate-900/90 dark:to-slate-950 dark:text-white dark:shadow-[0_35px_80px_rgba(2,6,23,0.65)]">
<div class="flex items-start justify-between gap-4">
<div>
<p class="text-xs uppercase tracking-[0.5em] text-slate-400">{{ __('api.print_dialog.title') }}</p>
@@ -12,7 +12,7 @@
</div>
<button
type="button"
class="rounded-full border border-white/10 p-2 text-slate-200 transition hover:border-rose-300 hover:text-rose-300"
class="rounded-full border border-slate-200 p-2 text-slate-500 transition hover:border-rose-300 hover:text-rose-400 dark:border-white/10 dark:text-slate-200"
@click="$emit('close')"
:aria-label="__('api.print_dialog.cancel_button')"
>
@@ -23,12 +23,12 @@
</div>
<div class="mt-8 flex flex-col gap-6">
<div class="rounded-3xl border border-white/10 bg-white/5 p-6 text-center text-slate-200">
<div class="rounded-3xl border border-slate-200 bg-white p-6 text-center text-slate-600 dark:border-white/10 dark:bg-white/5 dark:text-slate-200">
<p class="text-sm uppercase tracking-[0.4em] text-slate-400">Anzahl</p>
<div class="mt-4 flex items-center justify-center gap-6">
<button
type="button"
class="flex h-14 w-14 items-center justify-center rounded-2xl border border-white/20 bg-white/10 text-3xl font-semibold text-white transition hover:border-emerald-300 hover:text-emerald-200"
class="flex h-14 w-14 items-center justify-center rounded-2xl border border-slate-200 bg-white text-3xl font-semibold text-slate-900 transition hover:border-emerald-300 hover:text-emerald-600 dark:border-white/20 dark:bg-white/10 dark:text-white dark:hover:text-emerald-200"
@click="decrementQuantity"
aria-label="-1"
>
@@ -37,7 +37,7 @@
<div class="min-w-[4rem] text-6xl font-bold tracking-tight text-white">{{ quantity }}</div>
<button
type="button"
class="flex h-14 w-14 items-center justify-center rounded-2xl border border-white/20 bg-white/10 text-3xl font-semibold text-white transition hover:border-emerald-300 hover:text-emerald-200"
class="flex h-14 w-14 items-center justify-center rounded-2xl border border-slate-200 bg-white text-3xl font-semibold text-slate-900 transition hover:border-emerald-300 hover:text-emerald-600 dark:border-white/20 dark:bg-white/10 dark:text-white dark:hover:text-emerald-200"
@click="incrementQuantity"
aria-label="+1"
>
@@ -46,7 +46,7 @@
</div>
</div>
<p class="text-center text-xs uppercase tracking-[0.4em] text-slate-400">
<p class="text-center text-xs uppercase tracking-[0.4em] text-slate-500 dark:text-slate-400">
Du steuerst direkt den Sofortdruck.
</p>
</div>
@@ -54,14 +54,14 @@
<div class="mt-8 flex flex-wrap gap-3">
<button
type="button"
class="flex-1 rounded-full border border-white/20 bg-white/5 px-5 py-3 text-center text-sm font-semibold uppercase tracking-[0.2em] text-slate-200 transition hover:border-rose-300 hover:text-rose-200"
class="flex-1 rounded-full border border-slate-300 bg-white px-5 py-3 text-center text-sm font-semibold uppercase tracking-[0.2em] text-slate-600 transition hover:border-rose-300 hover:text-rose-400 dark:border-white/20 dark:bg-white/5 dark:text-slate-200 dark:hover:text-rose-200"
@click="$emit('close')"
>
{{ __('api.print_dialog.cancel_button') }}
</button>
<button
type="button"
class="flex-1 rounded-full border border-emerald-300 bg-emerald-400/20 px-5 py-3 text-center text-sm font-semibold uppercase tracking-[0.2em] text-emerald-100 transition hover:bg-emerald-400/40"
class="flex-1 rounded-full border border-emerald-400 bg-emerald-50 px-5 py-3 text-center text-sm font-semibold uppercase tracking-[0.2em] text-emerald-700 transition hover:bg-emerald-100 dark:bg-emerald-400/20 dark:text-emerald-100 dark:hover:bg-emerald-400/40"
@click="confirmPrint"
>
{{ __('api.print_dialog.print_button') }}

View File

@@ -1,10 +1,10 @@
<template>
<div class="flex h-full flex-col gap-4 rounded-3xl border border-white/10 bg-white/5 p-4 text-white">
<div class="flex items-center justify-between gap-2 text-xs uppercase tracking-[0.3em] text-slate-300">
<div class="flex h-full flex-col gap-4 rounded-3xl border border-slate-200 bg-white p-4 text-slate-900 dark:border-white/10 dark:bg-white/5 dark:text-white">
<div class="flex items-center justify-between gap-2 text-xs uppercase tracking-[0.3em] text-slate-500 dark:text-slate-300">
<span>Varianten</span>
<button
type="button"
class="rounded-full border border-white/20 p-1 text-white/70 transition hover:border-rose-300 hover:text-rose-300"
class="rounded-full border border-slate-200 p-1 text-slate-500 transition hover:border-rose-300 hover:text-rose-400 dark:border-white/20 dark:text-white/70 dark:hover:text-rose-300"
@click="$emit('close')"
aria-label="Auswahl schließen"
>
@@ -15,10 +15,10 @@
</div>
<div class="flex-1 space-y-3 overflow-y-auto pr-1">
<p v-if="isLoading" class="rounded-2xl border border-white/10 bg-white/5 px-4 py-3 text-center text-sm text-slate-300">
<p v-if="isLoading" class="rounded-2xl border border-slate-200 bg-white px-4 py-3 text-center text-sm text-slate-500 dark:border-white/10 dark:bg-white/5 dark:text-slate-300">
Stile werden geladen
</p>
<p v-else-if="loadError" class="rounded-2xl border border-rose-400/40 bg-rose-500/10 px-4 py-3 text-center text-sm text-rose-100">
<p v-else-if="loadError" class="rounded-2xl border border-rose-200 bg-rose-50 px-4 py-3 text-center text-sm text-rose-500 dark:border-rose-400/40 dark:bg-rose-500/10 dark:text-rose-100">
{{ loadError }}
</p>
<template v-else>
@@ -26,7 +26,7 @@
v-for="style in styles"
:key="style.id"
type="button"
class="group flex w-full items-center gap-4 rounded-2xl border border-white/10 bg-white/5 p-3 text-left transition hover:border-emerald-300"
class="group flex w-full items-center gap-4 rounded-2xl border border-slate-200 bg-white/90 p-3 text-left text-slate-900 transition hover:border-emerald-300 hover:bg-emerald-50/50 dark:border-white/10 dark:bg-white/5 dark:text-white"
@click="selectStyle(style)"
>
<img
@@ -38,13 +38,13 @@
/>
<div
v-else
class="flex h-24 w-24 flex-none items-center justify-center rounded-2xl border border-dashed border-white/20 text-[0.65rem] uppercase tracking-[0.4em] text-slate-400"
class="flex h-24 w-24 flex-none items-center justify-center rounded-2xl border border-dashed border-slate-200 text-[0.65rem] uppercase tracking-[0.4em] text-slate-500 dark:border-white/20 dark:text-slate-400"
>
AI
</div>
<div class="flex flex-col">
<p class="text-base font-semibold text-white">{{ style.title }}</p>
<p class="text-sm text-slate-200">{{ style.description }}</p>
<p class="text-base font-semibold text-slate-900 dark:text-white">{{ style.title }}</p>
<p class="text-sm text-slate-500 dark:text-slate-200">{{ style.description }}</p>
</div>
</button>
</template>

View File

@@ -1,20 +1,20 @@
<template>
<div class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50">
<div class="bg-white p-4 rounded-lg shadow-lg max-w-3xl w-full text-center">
<h2 class="text-xl font-bold mb-4">{{ __('styled_image_display.title') }}</h2>
<h2 class="text-xl font-bold mb-4">{{ __('api.styled_image_display.title') }}</h2>
<img :src="image.path" alt="Styled Image" class="max-w-full h-auto mx-auto mb-4 rounded-md" />
<div class="flex justify-center space-x-4">
<button
@click="$emit('keep', image)"
class="px-6 py-2 bg-green-500 text-white rounded-md hover:bg-green-600 focus:outline-hidden focus:ring-2 focus:ring-green-500 focus:ring-opacity-50"
>
{{ __('styled_image_display.keep_button') }}
{{ __('api.styled_image_display.keep_button') }}
</button>
<button
@click="$emit('delete', image)"
class="px-6 py-2 bg-red-500 text-white rounded-md hover:bg-red-600 focus:outline-hidden focus:ring-2 focus:ring-red-500 focus:ring-opacity-50"
>
{{ __('styled_image_display.delete_button') }}
{{ __('api.styled_image_display.delete_button') }}
</button>
</div>
</div>

View File

@@ -1,20 +1,19 @@
<template>
<Head title="Start" />
<div class="min-h-screen bg-gradient-to-br from-slate-950 via-slate-900 to-slate-950 text-slate-100">
<div class="mx-auto flex w-full max-w-7xl flex-col gap-6 px-4 py-8 sm:px-6 lg:px-8">
<header class="rounded-3xl border border-white/10 bg-white/5 p-6 shadow-2xl backdrop-blur">
<div class="min-h-screen bg-gradient-to-br from-slate-100 via-white to-slate-200 text-slate-900 transition-colors duration-500 dark:from-slate-950 dark:via-slate-900 dark:to-slate-950 dark:text-slate-100">
<div class="mx-auto flex w-full max-w-7xl flex-col gap-6 px-2 py-8 sm:px-4 lg:px-6">
<header class="rounded-3xl border border-slate-200 bg-white/90 p-6 text-slate-900 shadow-2xl backdrop-blur transition-colors duration-300 dark:border-white/10 dark:bg-white/5 dark:text-white">
<div class="flex flex-wrap items-start justify-between gap-6">
<div>
<p class="text-xs uppercase tracking-[0.35em] text-slate-400">Live Gallery</p>
<h1 class="mt-2 text-3xl font-semibold text-white sm:text-4xl">
<p class="text-xs uppercase tracking-[0.35em] text-slate-500 dark:text-slate-400">Live Gallery</p>
<h1 class="mt-1 text-3xl font-semibold text-slate-900 dark:text-white sm:text-4xl">
{{ props.galleryHeading }}
</h1>
<p class="mt-1 text-sm text-slate-400">Touch-friendly wall with the freshest images.</p>
</div>
<div class="flex flex-wrap items-center gap-3">
<button
type="button"
class="inline-flex items-center gap-2 rounded-full border border-white/20 bg-white/10 px-4 py-2 text-sm font-semibold text-white transition hover:border-emerald-400 hover:text-emerald-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-emerald-400 disabled:opacity-60"
class="inline-flex items-center gap-2 rounded-full border border-slate-300 bg-white px-4 py-2 text-sm font-semibold text-slate-900 shadow-sm transition hover:border-emerald-400 hover:text-emerald-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-emerald-400 disabled:opacity-60 dark:border-white/20 dark:bg-white/10 dark:text-white dark:hover:text-emerald-200"
@click="handleManualRefresh"
:disabled="isRefreshing"
>
@@ -36,7 +35,7 @@
</button>
<button
type="button"
class="inline-flex items-center gap-2 rounded-full border border-white/10 bg-white/5 px-4 py-2 text-sm font-semibold text-white transition hover:border-cyan-300 hover:text-cyan-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-cyan-400"
class="inline-flex items-center gap-2 rounded-full border border-slate-300 bg-white px-4 py-2 text-sm font-semibold text-slate-900 shadow-sm transition hover:border-cyan-400 hover:text-cyan-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-cyan-400 dark:border-white/10 dark:bg-white/5 dark:text-white dark:hover:text-cyan-200"
@click="toggleTheme"
>
<svg v-if="currentTheme === 'light'" class="h-4 w-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
@@ -53,9 +52,9 @@
</button>
</div>
</div>
<div class="mt-4 flex flex-wrap items-center gap-4 text-xs text-slate-300">
<div class="inline-flex items-center gap-2 rounded-full bg-emerald-400/10 px-3 py-1 text-emerald-200">
<span class="h-2 w-2 rounded-full bg-emerald-400 animate-pulse"></span>
<div class="mt-4 flex flex-wrap items-center gap-4 text-xs text-slate-500 dark:text-slate-300">
<div class="inline-flex items-center gap-2 rounded-full bg-emerald-500/10 px-3 py-1 text-emerald-700 dark:text-emerald-200">
<span class="h-2 w-2 rounded-full bg-emerald-500 animate-pulse"></span>
Auto-Refresh · alle {{ refreshIntervalSeconds }}s
</div>
<div class="flex items-center gap-2">
@@ -72,12 +71,12 @@
</header>
<section
class="rounded-3xl border border-white/5 bg-white/5 p-4 shadow-2xl backdrop-blur touch-pan-y"
class="rounded-3xl border border-slate-200 bg-white/80 p-3 shadow-2xl backdrop-blur transition-colors duration-300 touch-pan-y dark:border-white/5 dark:bg-white/5 sm:p-4"
@touchstart.passive="handleTouchStart"
@touchmove.passive="handleTouchMove"
@touchend="handleTouchEnd"
>
<GalleryGrid :images="paginatedImages" @imageTapped="showContextMenu" :translations="props.translations" />
<GalleryGrid :images="paginatedImages" @imageTapped="showContextMenu" />
</section>
<Navigation :currentPage="currentPage" :totalPages="totalPages" @prevPage="prevPage" @nextPage="nextPage" />
@@ -133,10 +132,6 @@ const props = defineProps({
type: String,
default: 'Gallery',
},
translations: {
type: Object,
default: () => ({}),
},
images: {
type: Array,
default: () => [],

View File

@@ -16,6 +16,20 @@ library.add(faPrint, faMagicWandSparkles, faXmark);
const appName = import.meta.env.VITE_APP_NAME || 'Laravel';
const resolveTranslation = (source, path) => {
if (!source || !path) {
return undefined;
}
return path.split('.').reduce((acc, segment) => {
if (acc && Object.prototype.hasOwnProperty.call(acc, segment)) {
return acc[segment];
}
return undefined;
}, source);
};
createInertiaApp({
title: (title) => `${title} - ${appName}`,
resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
@@ -27,18 +41,29 @@ createInertiaApp({
.component('font-awesome-icon', FontAwesomeIcon) // Register Font Awesome component
.mixin({
methods: {
__: (key, replace = {}) => {
let translation = props.initialPage.props.translations[key];
__: function (key, replace = {}) {
const sources = [
this?.$page?.props?.translations,
props.initialPage.props.translations,
];
if (translation === undefined) {
translation = key; // Fallback to key if translation not found
let translation;
for (const source of sources) {
const value = resolveTranslation(source, key);
if (value !== undefined) {
translation = value;
break;
}
}
for (let placeholder in replace) {
translation = translation.replace(`:${placeholder}`, replace[placeholder]);
}
let output = translation ?? key;
return translation;
Object.entries(replace).forEach(([placeholder, val]) => {
output = output.replace(`:${placeholder}`, val);
});
return output;
},
},
})
@@ -47,4 +72,4 @@ createInertiaApp({
progress: {
color: '#4B5563',
},
});
});

View File

@@ -8,23 +8,35 @@ return [
'image_deleted_successfully' => 'Bild erfolgreich gelöscht.',
'image_or_provider_not_found' => 'Bild oder API-Anbieter nicht gefunden.',
'no_styles_available' => 'Keine Stile oder API-Anbieter aktiviert/verfügbar.',
'api.dark_mode' => 'Dunkler Modus',
'api.light_mode' => 'Heller Modus',
'dark_mode' => 'Dunkler Modus',
'light_mode' => 'Heller Modus',
'gallery_title' => 'Eure Bilder aus der Fotobox',
'navigation.previous' => 'Zurück',
'navigation.next' => 'Weiter',
'navigation.page_of' => 'Seite :currentPage von :totalPages',
'loading_spinner.processing_image' => 'Bild wird verarbeitet...',
'styled_image_display.title' => 'Neu gestyltes Bild',
'styled_image_display.keep_button' => 'Behalten',
'styled_image_display.delete_button' => 'Löschen',
'navigation' => [
'previous' => 'Zurück',
'next' => 'Weiter',
'page_of' => 'Seite :currentPage von :totalPages',
],
'loading_spinner' => [
'processing_image' => 'Bild wird verarbeitet...',
],
'styled_image_display' => [
'title' => 'Neu gestyltes Bild',
'keep_button' => 'Behalten',
'delete_button' => 'Löschen',
],
'print_command_sent_successfully' => 'Druckbefehl erfolgreich gesendet.',
'failed_to_send_print_command' => 'Druckbefehl konnte nicht gesendet werden.',
'api.print_dialog.title' => 'Bild drucken',
'api.print_dialog.quantity_prompt' => 'Wie viele Kopien möchten Sie drucken?',
'api.print_dialog.cancel_button' => 'Abbrechen',
'api.print_dialog.print_button' => 'Drucken',
'api.download_button' => 'Herunterladen',
'api.download_success' => 'Download gestartet!',
'api.download_error' => 'Download fehlgeschlagen.',
'print_dialog' => [
'title' => 'Bild drucken',
'quantity_prompt' => 'Wie viele Kopien möchtest du drucken?',
'cancel_button' => 'Abbrechen',
'print_button' => 'Drucken',
],
'download_button' => 'Herunterladen',
'download_success' => 'Download gestartet!',
'download_error' => 'Download fehlgeschlagen.',
'gallery' => [
'tap_to_open' => 'Zum Öffnen tippen',
'empty' => 'Noch keine Bilder vorhanden.',
],
];

View File

@@ -11,20 +11,32 @@ return [
'dark_mode' => 'Dark Mode',
'light_mode' => 'Light Mode',
'gallery_title' => 'Your images from the photobooth',
'navigation.previous' => 'Previous',
'navigation.next' => 'Next',
'navigation.page_of' => 'Page :currentPage of :totalPages',
'loading_spinner.processing_image' => 'Processing image...',
'styled_image_display.title' => 'Newly Styled Image',
'styled_image_display.keep_button' => 'Keep',
'styled_image_display.delete_button' => 'Delete',
'navigation' => [
'previous' => 'Previous',
'next' => 'Next',
'page_of' => 'Page :currentPage of :totalPages',
],
'loading_spinner' => [
'processing_image' => 'Processing image...',
],
'styled_image_display' => [
'title' => 'Newly Styled Image',
'keep_button' => 'Keep',
'delete_button' => 'Delete',
],
'print_command_sent_successfully' => 'Print command sent successfully.',
'failed_to_send_print_command' => 'Failed to send print command.',
'print_dialog.title' => 'Print Image',
'print_dialog.quantity_prompt' => 'How many copies would you like to print?',
'print_dialog.cancel_button' => 'Cancel',
'print_dialog.print_button' => 'Print',
'print_dialog' => [
'title' => 'Print Image',
'quantity_prompt' => 'How many copies would you like to print?',
'cancel_button' => 'Cancel',
'print_button' => 'Print',
],
'download_button' => 'Download',
'download_success' => 'Download started!',
'download_error' => 'Download failed.',
'gallery' => [
'tap_to_open' => 'Tap to open',
'empty' => 'No images available yet.',
],
];