168 lines
6.1 KiB
PHP
168 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers;
|
|
|
|
use App\Models\Scene;
|
|
use App\Models\UserSceneSetting;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class SceneController extends Controller
|
|
{
|
|
// CONSOLIDATED: everything the scene-settings screen needs in one call.
|
|
public function settings()
|
|
{
|
|
$settings = UserSceneSetting::with('activeScene.theme')
|
|
->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',
|
|
'is_premium' => 'nullable|boolean',
|
|
'image' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192',
|
|
'video' => 'nullable|file|extensions:mp4,mov,webm,mkv,avi,m4v,3gp|max:512000',
|
|
'sound' => 'nullable|file|extensions:mp3,wav,ogg,flac,aac,m4a,opus,mpga,wma|max:51200',
|
|
]);
|
|
|
|
$scene = Scene::create([
|
|
'name' => $data['name'],
|
|
'theme_id' => $data['theme_id'] ?? null,
|
|
'order' => $data['order'] ?? 0,
|
|
'is_active' => $data['is_active'] ?? true,
|
|
'is_premium' => $data['is_premium'] ?? false,
|
|
'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',
|
|
'is_premium' => 'nullable|boolean',
|
|
'image' => 'nullable|file|extensions:jpg,jpeg,png,gif,webp,bmp,svg|max:8192',
|
|
'video' => 'nullable|file|extensions:mp4,mov,webm,mkv,avi,m4v,3gp|max:512000',
|
|
'sound' => 'nullable|file|extensions:mp3,wav,ogg,flac,aac,m4a,opus,mpga,wma|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'];
|
|
}
|
|
if (array_key_exists('is_premium', $data)) {
|
|
$scene->is_premium = $data['is_premium'];
|
|
}
|
|
|
|
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']);
|
|
}
|
|
}
|