firstOrNew(['user_id' => auth()->id()]); return response()->json([ 'scenes' => Scene::with('theme')->where('is_active', true)->orderBy('order')->get(), 'settings' => [ 'active_scene_id' => $settings->active_scene_id, 'active_scene' => $settings->activeScene, 'scene_volume' => $settings->scene_volume ?? 100, 'background_play_seconds' => $settings->background_play_seconds ?? 0, 'video_enabled' => (bool) ($settings->video_enabled ?? false), ], ]); } // Persist the current user's scene preferences. public function updateSettings(Request $request) { $data = $request->validate([ 'active_scene_id' => 'nullable|exists:scenes,id', 'scene_volume' => 'nullable|integer|min:0|max:100', 'background_play_seconds' => 'nullable|integer|min:0', 'video_enabled' => 'nullable|boolean', ]); $settings = UserSceneSetting::firstOrNew(['user_id' => auth()->id()]); foreach (['active_scene_id', 'scene_volume', 'background_play_seconds', 'video_enabled'] as $field) { if ($request->has($field)) { $settings->$field = $data[$field] ?? ($field === 'video_enabled' ? false : null); } } $settings->save(); return response()->json([ 'message' => 'Settings saved successfully', 'settings' => $settings->load('activeScene'), ]); } public function index(Request $request) { $query = Scene::query()->with('theme'); if (!$request->boolean('include_inactive')) { $query->where('is_active', true); } return response()->json($query->orderBy('order')->get()); } public function show($id) { return response()->json(Scene::with('theme')->findOrFail($id)); } // CREATE a scene with its image / video / sound uploads. public function store(Request $request) { $data = $request->validate([ 'name' => 'required|string|max:255', 'theme_id' => 'nullable|exists:themes,id', 'order' => 'nullable|integer', 'is_active' => 'nullable|boolean', 'image' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192', 'video' => 'nullable|mimes:mp4,mov,webm|max:512000', 'sound' => 'nullable|mimes:mp3,wav,ogg,flac|max:51200', ]); $scene = Scene::create([ 'name' => $data['name'], 'theme_id' => $data['theme_id'] ?? null, 'order' => $data['order'] ?? 0, 'is_active' => $data['is_active'] ?? true, 'image_path' => $request->hasFile('image') ? $request->file('image')->store('scenes/images', 'public') : null, 'video_path' => $request->hasFile('video') ? $request->file('video')->store('scenes/videos', 'public') : null, 'sound_path' => $request->hasFile('sound') ? $request->file('sound')->store('scenes/sounds', 'public') : null, ]); return response()->json([ 'message' => 'Scene created successfully', 'scene' => $scene->load('theme'), ], 201); } // UPDATE a scene; any uploaded file replaces the old one (POST for multipart support). public function update(Request $request, $id) { $scene = Scene::findOrFail($id); $data = $request->validate([ 'name' => 'sometimes|string|max:255', 'theme_id' => 'nullable|exists:themes,id', 'order' => 'nullable|integer', 'is_active' => 'nullable|boolean', 'image' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192', 'video' => 'nullable|mimes:mp4,mov,webm|max:512000', 'sound' => 'nullable|mimes:mp3,wav,ogg,flac|max:51200', ]); if (array_key_exists('name', $data)) { $scene->name = $data['name']; } if (array_key_exists('theme_id', $data)) { $scene->theme_id = $data['theme_id']; } if (array_key_exists('order', $data)) { $scene->order = $data['order']; } if (array_key_exists('is_active', $data)) { $scene->is_active = $data['is_active']; } foreach (['image' => 'scenes/images', 'video' => 'scenes/videos', 'sound' => 'scenes/sounds'] as $field => $folder) { if ($request->hasFile($field)) { $column = $field === 'image' ? 'image_path' : ($field === 'video' ? 'video_path' : 'sound_path'); if ($scene->$column) { Storage::disk('public')->delete($scene->$column); } $scene->$column = $request->file($field)->store($folder, 'public'); } } $scene->save(); return response()->json([ 'message' => 'Scene updated successfully', 'scene' => $scene->load('theme'), ]); } public function destroy($id) { $scene = Scene::findOrFail($id); foreach (['image_path', 'video_path', 'sound_path'] as $column) { if ($scene->$column) { Storage::disk('public')->delete($scene->$column); } } $scene->delete(); return response()->json(['message' => 'Scene deleted successfully']); } }