392 lines
26 KiB
Plaintext
392 lines
26 KiB
Plaintext
@using Microsoft.IdentityModel.Tokens
|
|
@using WatchIt.Common.Model.Movies
|
|
@using WatchIt.Common.Model.Photos
|
|
@using WatchIt.Common.Model.Series
|
|
|
|
@page "/media/{id:long}/edit"
|
|
@page "/media/new/{type}"
|
|
|
|
|
|
<PageTitle>
|
|
WatchIt -
|
|
@if (_loaded)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_error) && _user?.IsAdmin == true)
|
|
{
|
|
if (_media is not null)
|
|
{
|
|
@($"Edit \"")@(_media.Title)@("\"")
|
|
}
|
|
else
|
|
{
|
|
if (_movieRequest is null)
|
|
{
|
|
@("New TV series")
|
|
}
|
|
else
|
|
{
|
|
@("New movie")
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
@("Error")
|
|
}
|
|
}
|
|
else
|
|
{
|
|
@("Loading")
|
|
}
|
|
</PageTitle>
|
|
|
|
<div class="container-fluid">
|
|
@if (_loaded)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(_error))
|
|
{
|
|
if (_user?.IsAdmin == true)
|
|
{
|
|
<div class="row">
|
|
<div class="col">
|
|
<div class="rounded-3 panel panel-regular p-2">
|
|
<h2 class="m-0 mx-2 mb-1 p-0">@(_media is not null ? "Edit" : "Create new") @(_movieRequest is not null ? "movie" : "series")@(_media is not null ? $" \"{_media.Title}\"" : string.Empty)</h2>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-3 gx-3">
|
|
<div class="col-auto">
|
|
<div class="rounded-3 panel panel-regular p-4 h-100">
|
|
<div class="container-fluid p-0">
|
|
<div class="row">
|
|
<div class="col">
|
|
<img class="rounded-2 shadow object-fit-cover" src="@(_mediaPosterRequest is not null ? _mediaPosterRequest.ToString() : "assets/poster.png")" alt="poster" width="300" height="500"/>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-4">
|
|
<div class="col">
|
|
<InputFile class="form-control" OnChange="LoadPoster" disabled="@(_media is null)" autocomplete="off" style="width: 300px;"/>
|
|
</div>
|
|
</div>
|
|
@if (_mediaPosterChanged || _mediaPosterSaved is not null)
|
|
{
|
|
<div class="row mt-4 gx-1" style="width: 300px;">
|
|
@if (_mediaPosterChanged)
|
|
{
|
|
<div class="col">
|
|
<button type="button" class="btn btn-secondary btn-block btn-stretch-x" @onclick="SavePoster" disabled=@(!Id.HasValue || _mediaPosterSaving || _mediaPosterDeleting) autocomplete="off">
|
|
@if (!_mediaPosterSaving)
|
|
{
|
|
<span class="sr-only">Save poster</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
<span class="sr-only">Saving...</span>
|
|
}
|
|
</button>
|
|
</div>
|
|
<div class="col">
|
|
<button type="button" class="btn btn-danger btn-block btn-stretch-x" @onclick="CancelPoster" disabled=@(!Id.HasValue || _mediaPosterSaving || _mediaPosterDeleting) autocomplete="off">Drop changes</button>
|
|
</div>
|
|
}
|
|
else if (_mediaPosterSaved is not null)
|
|
{
|
|
<div class="col">
|
|
<button type="button" class="btn btn-danger btn-block btn-stretch-x" @onclick="DeletePoster" disabled=@(!Id.HasValue || _mediaPosterSaving || _mediaPosterDeleting) autocomplete="off">
|
|
@if (!_mediaPosterSaving)
|
|
{
|
|
<span class="sr-only">Delete poster</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
<span class="sr-only">Deleting...</span>
|
|
}
|
|
</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="col">
|
|
<div class="rounded-3 panel panel-regular p-4 h-100">
|
|
<EditForm Model="_mediaRequest">
|
|
<AntiforgeryToken/>
|
|
<div class="container-fluid p-0">
|
|
<div class="row form-group mb-1">
|
|
<label for="title" class="col-2 col-form-label">Title*</label>
|
|
<div class="col-10">
|
|
<InputText id="title" class="form-control" @bind-Value="_mediaRequest!.Title"/>
|
|
</div>
|
|
</div>
|
|
<div class="row form-group my-1">
|
|
<label for="og-title" class="col-2 col-form-label">Original title</label>
|
|
<div class="col-10">
|
|
<InputText id="og-title" class="form-control" @bind-Value="_mediaRequest!.OriginalTitle"/>
|
|
</div>
|
|
</div>
|
|
<div class="row form-group my-1">
|
|
<label for="desc" class="col-2 col-form-label">Description</label>
|
|
<div class="col-10">
|
|
<InputTextArea id="desc" class="form-control" @bind-Value="_mediaRequest!.Description"/>
|
|
</div>
|
|
</div>
|
|
<div class="row form-group my-1">
|
|
<label for="rel-date" class="col-2 col-form-label">Release date</label>
|
|
<div class="col-4">
|
|
<InputDate TValue="DateOnly?" id="rel-date" class="form-control" @bind-Value="_mediaRequest!.ReleaseDate"/>
|
|
</div>
|
|
<label for="length" class="col-2 col-form-label">Length</label>
|
|
<div class="col-4">
|
|
<InputNumber TValue="short?" id="length" class="form-control" @bind-Value="_mediaRequest!.Length"/>
|
|
</div>
|
|
</div>
|
|
@if (_mediaRequest is MovieRequest)
|
|
{
|
|
<div class="row form-group mt-1">
|
|
<label for="budget" class="col-2 col-form-label">Budget</label>
|
|
<div class="col-10">
|
|
<InputNumber TValue="decimal?" id="budget" class="form-control" @bind-Value="((MovieRequest)_mediaRequest)!.Budget"/>
|
|
</div>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="row form-group mt-1">
|
|
<label class="col-2 col-form-label">Has ended</label>
|
|
<div class="col-10 col-form-label">
|
|
<div class="d-flex gap-3">
|
|
<InputRadioGroup TValue="bool" @bind-Value="((SeriesRequest)_mediaRequest)!.HasEnded">
|
|
<div class="d-flex gap-2">
|
|
<InputRadio TValue="bool" Value="true"/>
|
|
Yes
|
|
</div>
|
|
<div class="d-flex gap-2">
|
|
<InputRadio TValue="bool" Value="false"/>
|
|
No
|
|
</div>
|
|
</InputRadioGroup>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
<div class="row mt-4">
|
|
<div class="col">
|
|
<div class="d-flex justify-content-end align-items-center gap-3">
|
|
@if (!string.IsNullOrWhiteSpace(_basicDataError))
|
|
{
|
|
<div class="text-danger">@_basicDataError</div>
|
|
}
|
|
<button type="button" class="btn btn-secondary" @onclick="SaveBasicData">
|
|
@if (!_basicDataSaving)
|
|
{
|
|
<span class="sr-only">Save</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
<span class="sr-only">Saving...</span>
|
|
}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</EditForm>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-3">
|
|
<div class="col">
|
|
<div class="rounded-3 panel panel-regular p-4">
|
|
<div class="container-fluid p-0">
|
|
<div class="row mb-3">
|
|
<div class="col">
|
|
<div class="d-flex align-items-center h-100">
|
|
<h4 class="m-0"><strong>Photos</strong></h4>
|
|
</div>
|
|
</div>
|
|
<div class="col-auto">
|
|
@if (!_photoEditMode)
|
|
{
|
|
<button type="button" class="btn btn-secondary" disabled="@(!Id.HasValue)" @onclick="() => InitEditPhoto(null)">Add new photo</button>
|
|
}
|
|
else
|
|
{
|
|
<div class="d-flex gap-3 align-items-center">
|
|
@if (!string.IsNullOrWhiteSpace(_photoEditError))
|
|
{
|
|
<div class="text-danger">
|
|
@_photoEditError
|
|
</div>
|
|
}
|
|
<button type="button" class="btn btn-secondary" disabled="@(_photoEditSaving)" @onclick="SaveEditPhoto">
|
|
@if (!_photoEditSaving)
|
|
{
|
|
<span class="sr-only">Save</span>
|
|
}
|
|
else
|
|
{
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
<span class="sr-only">Saving...</span>
|
|
}
|
|
</button>
|
|
<button type="button" class="btn btn-secondary" disabled="@(_photoEditSaving)" @onclick="CancelEditPhoto">Cancel</button>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col">
|
|
@if (!_photoEditMode)
|
|
{
|
|
if (!_photos.IsNullOrEmpty())
|
|
{
|
|
<div id="scrollPhotos" class="d-flex p-3 gap-3" data-bs-spy="scroll" tabindex="0">
|
|
@foreach (PhotoResponse photo in _photos)
|
|
{
|
|
<div class="container-fluid p-0 m-0 photo-container">
|
|
<div class="row">
|
|
<div class="col">
|
|
<img class="rounded-1 shadow object-fit-cover photo-default-aspect-ratio" src="@(photo.ToString())" alt="photo" width="350"/>
|
|
</div>
|
|
</div>
|
|
<div class="row mt-2 gx-2">
|
|
@if (photo.Background is not null)
|
|
{
|
|
<div class="col-auto">
|
|
<div class="d-flex align-items-center">
|
|
<div id="backgroundIndicator" class="border rounded-circle circle-@(photo.Background.IsUniversalBackground ? "blue" : "grey") p-1" data-toggle="tooltip" data-placement="top" title="@(photo.Background.IsUniversalBackground ? "Universal" : "Media-only") background">
|
|
<img class="no-vertical-align" src="assets/icons/background.png" alt="background_icon" height="20px" width="20px"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
<div class="col">
|
|
<div class="d-flex align-items-center h-100 text-size-upload-date">
|
|
Upload: @(photo.UploadDate.ToString())
|
|
</div>
|
|
</div>
|
|
<div class="col-auto">
|
|
<button type="button" class="btn btn-secondary btn-sm" @onclick="() => InitEditPhoto(photo.Id)" disabled="@(_photoDeleting.Contains(photo.Id))">
|
|
<img src="assets/icons/edit.png" alt="edit_icon" height="20px" width="20px"/>
|
|
</button>
|
|
</div>
|
|
<div class="col-auto">
|
|
<button type="button" class="btn btn-danger btn-sm" disabled="@(_photoDeleting.Contains(photo.Id))" @onclick="() => DeletePhoto(photo.Id)">
|
|
@if (!_photoDeleting.Contains(photo.Id))
|
|
{
|
|
<img src="assets/icons/delete.png" alt="delete_icon" height="20px" width="20px"/>
|
|
}
|
|
else
|
|
{
|
|
<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
|
|
}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<div class="d-flex justify-content-center">
|
|
Photo list is empty
|
|
</div>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<div class="container-fluid p-0 m-0">
|
|
<div class="row">
|
|
<div class="col-auto">
|
|
<div class="container-fluid p-0 m-0">
|
|
<div class="row">
|
|
<div class="col">
|
|
<img class="rounded-1 shadow object-fit-cover photo-default-aspect-ratio" src="@(_photoEditRequest is null ? "assets/photo.png" : _photoEditRequest.ToString())" alt="edit_photo" width="300px"/>
|
|
</div>
|
|
</div>
|
|
@if (_photoEditId is null)
|
|
{
|
|
<div class="row mt-2">
|
|
<div class="col">
|
|
<InputFile class="form-control" OnChange="LoadPhoto" autocomplete="off" style="width: 300px;"/>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
<div class="col">
|
|
<div class="container-fluid p-0 m-0">
|
|
<div class="row form-group">
|
|
<div class="col">
|
|
<div class="form-check">
|
|
<InputCheckbox class="form-check-input" @bind-Value="_photoEditIsBackground"/>
|
|
<label class="form-check-label">Use as background</label>
|
|
</div>
|
|
</div>
|
|
<div class="col">
|
|
<div class="form-check">
|
|
<InputCheckbox class="form-check-input" @bind-Value="_photoEditBackgroundData.IsUniversalBackground" disabled="@(!_photoEditIsBackground)"/>
|
|
<label class="form-check-label">Use as universal background</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row form-group my-1">
|
|
<label for="first-gradient-color" class="col-4 col-form-label">First gradient color</label>
|
|
<div class="col-8">
|
|
<input type="color" class="form-control form-control-color w-100" id="first-gradient-color" value="#@(Convert.ToHexString(_photoEditBackgroundData.FirstGradientColor))" disabled="@(!_photoEditIsBackground)" @onchange="EditPhotoFirstGradientColorChanged">
|
|
</div>
|
|
</div>
|
|
<div class="row form-group">
|
|
<label for="second-gradient-color" class="col-4 col-form-label">Second gradient color</label>
|
|
<div class="col-8">
|
|
<input type="color" class="form-control form-control-color w-100" id="second-gradient-color" value="#@(Convert.ToHexString(_photoEditBackgroundData.SecondGradientColor))" disabled="@(!_photoEditIsBackground)" @onchange="EditPhotoSecondGradientColorChanged">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
}
|
|
else
|
|
{
|
|
<ErrorComponent ErrorMessage="You do not have permission to view this site"/>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<ErrorComponent ErrorMessage="@_error"/>
|
|
}
|
|
}
|
|
else
|
|
{
|
|
<LoadingComponent/>
|
|
}
|
|
</div>
|
|
|
|
|
|
|
|
@if (_background is not null)
|
|
{
|
|
<style>
|
|
body {
|
|
background-image: url('@(_background.ToString())') !important;
|
|
}
|
|
|
|
.logo, .main-button {
|
|
background-image: linear-gradient(45deg, @($"#{BitConverter.ToString(_background.Background.FirstGradientColor).Replace("-", string.Empty)}"), @($"#{BitConverter.ToString(_background.Background.SecondGradientColor).Replace("-", string.Empty)}")) !important;
|
|
}
|
|
</style>
|
|
} |