Das Abschalten des Aufgaben-Modus wird nun sauber in der App reflektiert- die UI passt sich an und der Admin erhält einen Hinweis, dass die Aufgabenverwaltung nicht verfügbar ist
This commit is contained in:
@@ -659,6 +659,25 @@ class EventPublicController extends BaseController
|
||||
return $trimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
*/
|
||||
private function normalizeSettings(array|string|null $settings): array
|
||||
{
|
||||
if (is_array($settings)) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
if (is_string($settings)) {
|
||||
$decoded = json_decode($settings, true);
|
||||
if (is_array($decoded)) {
|
||||
return $decoded;
|
||||
}
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
private function buildDeterministicSeed(?string $identifier): int
|
||||
{
|
||||
if ($identifier === null || trim($identifier) === '') {
|
||||
@@ -1757,6 +1776,8 @@ class EventPublicController extends BaseController
|
||||
];
|
||||
|
||||
$branding = $this->buildGalleryBranding($event);
|
||||
$settings = $this->normalizeSettings($event->settings ?? []);
|
||||
$engagementMode = $settings['engagement_mode'] ?? 'tasks';
|
||||
|
||||
if ($joinToken) {
|
||||
$this->joinTokenService->incrementUsage($joinToken);
|
||||
@@ -1774,6 +1795,7 @@ class EventPublicController extends BaseController
|
||||
'photobooth_enabled' => (bool) $event->photobooth_enabled,
|
||||
'branding' => $branding,
|
||||
'guest_upload_visibility' => Arr::get($event->settings ?? [], 'guest_upload_visibility', 'review'),
|
||||
'engagement_mode' => $engagementMode,
|
||||
])->header('Cache-Control', 'no-store');
|
||||
}
|
||||
|
||||
@@ -2365,7 +2387,7 @@ class EventPublicController extends BaseController
|
||||
|
||||
public function stats(Request $request, string $token)
|
||||
{
|
||||
$result = $this->resolvePublishedEvent($request, $token, ['id']);
|
||||
$result = $this->resolvePublishedEvent($request, $token, ['id', 'settings']);
|
||||
|
||||
if ($result instanceof JsonResponse) {
|
||||
return $result;
|
||||
@@ -2374,6 +2396,8 @@ class EventPublicController extends BaseController
|
||||
[$event, $joinToken] = $result;
|
||||
$eventId = $event->id;
|
||||
$eventModel = Event::with('storageAssignments.storageTarget')->findOrFail($eventId);
|
||||
$settings = $this->normalizeSettings($event->settings ?? null);
|
||||
$engagementMode = $settings['engagement_mode'] ?? 'tasks';
|
||||
|
||||
// Approximate online guests as distinct recent uploaders in last 10 minutes.
|
||||
$tenMinutesAgo = CarbonImmutable::now()->subMinutes(10);
|
||||
@@ -2384,7 +2408,9 @@ class EventPublicController extends BaseController
|
||||
->count('guest_name');
|
||||
|
||||
// Tasks solved as number of photos linked to a task (proxy metric).
|
||||
$tasksSolved = DB::table('photos')->where('event_id', $eventId)->whereNotNull('task_id')->count();
|
||||
$tasksSolved = $engagementMode === 'photo_only'
|
||||
? 0
|
||||
: DB::table('photos')->where('event_id', $eventId)->whereNotNull('task_id')->count();
|
||||
|
||||
$latestPhotoAt = DB::table('photos')->where('event_id', $eventId)->max('created_at');
|
||||
|
||||
@@ -2392,6 +2418,7 @@ class EventPublicController extends BaseController
|
||||
'online_guests' => $onlineGuests,
|
||||
'tasks_solved' => $tasksSolved,
|
||||
'latest_photo_at' => $latestPhotoAt,
|
||||
'engagement_mode' => $engagementMode,
|
||||
];
|
||||
|
||||
$etag = sha1(json_encode($payload));
|
||||
@@ -2472,7 +2499,7 @@ class EventPublicController extends BaseController
|
||||
|
||||
public function tasks(Request $request, string $token)
|
||||
{
|
||||
$result = $this->resolvePublishedEvent($request, $token, ['id', 'default_locale']);
|
||||
$result = $this->resolvePublishedEvent($request, $token, ['id', 'default_locale', 'settings']);
|
||||
|
||||
if ($result instanceof JsonResponse) {
|
||||
return $result;
|
||||
@@ -2480,8 +2507,35 @@ class EventPublicController extends BaseController
|
||||
|
||||
[$event, $joinToken] = $result;
|
||||
|
||||
$settings = $this->normalizeSettings($event->settings ?? null);
|
||||
$engagementMode = $settings['engagement_mode'] ?? 'tasks';
|
||||
|
||||
[$resolvedLocale] = $this->resolveGuestLocale($request, $event);
|
||||
|
||||
$page = max(1, (int) $request->query('page', 1));
|
||||
$perPage = max(1, min(100, (int) $request->query('per_page', 20)));
|
||||
|
||||
if ($engagementMode === 'photo_only') {
|
||||
$payload = [
|
||||
'data' => [],
|
||||
'meta' => [
|
||||
'total' => 0,
|
||||
'per_page' => $perPage,
|
||||
'current_page' => $page,
|
||||
'last_page' => 1,
|
||||
'has_more' => false,
|
||||
'seed' => null,
|
||||
],
|
||||
'engagement_mode' => $engagementMode,
|
||||
];
|
||||
|
||||
return response()->json($payload)
|
||||
->header('Cache-Control', 'public, max-age=120')
|
||||
->header('Vary', 'Accept-Language, X-Locale')
|
||||
->header('X-Content-Locale', $resolvedLocale)
|
||||
->header('X-Engagement-Mode', $engagementMode);
|
||||
}
|
||||
|
||||
$cached = $this->eventTasksCache->remember((int) $event->id, $resolvedLocale, function () use ($event, $resolvedLocale) {
|
||||
return $this->buildLocalizedTasksPayload((int) $event->id, $resolvedLocale, $event->default_locale ?? null);
|
||||
});
|
||||
@@ -2489,9 +2543,6 @@ class EventPublicController extends BaseController
|
||||
$tasks = $cached['tasks'];
|
||||
$baseHash = $cached['hash'] ?? sha1(json_encode($tasks));
|
||||
|
||||
$page = max(1, (int) $request->query('page', 1));
|
||||
$perPage = max(1, min(100, (int) $request->query('per_page', 20)));
|
||||
|
||||
// Shuffle per request for unpredictability; stable when seeded by guest/device or explicit seed.
|
||||
$seedParam = $request->query('seed');
|
||||
$guestIdentifier = $this->determineGuestIdentifier($request);
|
||||
|
||||
Reference in New Issue
Block a user