Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stacked 14: Allow to chose the photo layout per album #2575

Merged
merged 4 commits into from
Oct 25, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions app/Contracts/Http/Requests/HasPhotoLayout.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace App\Contracts\Http\Requests;

use App\Enum\PhotoLayoutType;

interface HasPhotoLayout
{
/**
* @return PhotoLayoutType|null
*/
public function photoLayout(): ?PhotoLayoutType;
}
1 change: 1 addition & 0 deletions app/Contracts/Http/Requests/RequestAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ class RequestAttribute
public const PHOTO_SORTING_ORDER_ATTRIBUTE = 'photo_sorting_order';
public const ALBUM_SORTING_COLUMN_ATTRIBUTE = 'album_sorting_column';
public const ALBUM_SORTING_ORDER_ATTRIBUTE = 'album_sorting_order';
public const ALBUM_PHOTO_LAYOUT = 'photo_layout';

public const PERMISSION_ID = 'perm_id';
public const IS_COMPACT_ATTRIBUTE = 'is_compact';
Expand Down
2 changes: 2 additions & 0 deletions app/Http/Controllers/Gallery/AlbumController.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ public function updateAlbum(UpdateAlbumRequest $request, SetHeader $setHeader):
$album->copyright = $request->copyright();
$album->photo_sorting = $request->photoSortingCriterion();
$album->album_sorting = $request->albumSortingCriterion();
$album->photo_layout = $request->photoLayout();

$album = $setHeader->do(
album: $album,
Expand All @@ -131,6 +132,7 @@ public function updateTagAlbum(UpdateTagAlbumRequest $request): EditableBaseAlbu
$album->show_tags = $request->tags();
$album->copyright = $request->copyright();
$album->photo_sorting = $request->photoSortingCriterion();
$album->photo_layout = $request->photoLayout();
$album->save();

return EditableBaseAlbumResource::fromModel($album);
Expand Down
8 changes: 7 additions & 1 deletion app/Http/Requests/Album/UpdateAlbumRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use App\Contracts\Http\Requests\HasDescription;
use App\Contracts\Http\Requests\HasLicense;
use App\Contracts\Http\Requests\HasPhoto;
use App\Contracts\Http\Requests\HasPhotoLayout;
use App\Contracts\Http\Requests\HasPhotoSortingCriterion;
use App\Contracts\Http\Requests\HasTitle;
use App\Contracts\Http\Requests\RequestAttribute;
Expand All @@ -20,6 +21,7 @@
use App\Enum\ColumnSortingPhotoType;
use App\Enum\LicenseType;
use App\Enum\OrderSortingType;
use App\Enum\PhotoLayoutType;
use App\Http\Requests\BaseApiRequest;
use App\Http\Requests\Traits\HasAlbumSortingCriterionTrait;
use App\Http\Requests\Traits\HasAlbumTrait;
Expand All @@ -28,6 +30,7 @@
use App\Http\Requests\Traits\HasCopyrightTrait;
use App\Http\Requests\Traits\HasDescriptionTrait;
use App\Http\Requests\Traits\HasLicenseTrait;
use App\Http\Requests\Traits\HasPhotoLayoutTrait;
use App\Http\Requests\Traits\HasPhotoSortingCriterionTrait;
use App\Http\Requests\Traits\HasPhotoTrait;
use App\Http\Requests\Traits\HasTitleTrait;
Expand All @@ -42,7 +45,7 @@
use Illuminate\Validation\Rules\Enum;
use Illuminate\Validation\ValidationException;

class UpdateAlbumRequest extends BaseApiRequest implements HasAlbum, HasTitle, HasDescription, HasLicense, HasPhotoSortingCriterion, HasAlbumSortingCriterion, HasCopyright, HasPhoto, HasCompactBoolean
class UpdateAlbumRequest extends BaseApiRequest implements HasAlbum, HasTitle, HasDescription, HasLicense, HasPhotoSortingCriterion, HasAlbumSortingCriterion, HasCopyright, HasPhoto, HasCompactBoolean, HasPhotoLayout
{
use HasAlbumTrait;
use HasLicenseTrait;
Expand All @@ -54,6 +57,7 @@ class UpdateAlbumRequest extends BaseApiRequest implements HasAlbum, HasTitle, H
use HasPhotoSortingCriterionTrait;
use HasAlbumSortingCriterionTrait;
use HasCopyrightTrait;
use HasPhotoLayoutTrait;

public function authorize(): bool
{
Expand Down Expand Up @@ -84,6 +88,7 @@ public function rules(): array
'nullable', new Enum(OrderSortingType::class),
],
RequestAttribute::ALBUM_ASPECT_RATIO_ATTRIBUTE => ['present', 'nullable', new Enum(AspectRatioType::class)],
RequestAttribute::ALBUM_PHOTO_LAYOUT => ['present', 'nullable', new Enum(PhotoLayoutType::class)],
RequestAttribute::COPYRIGHT_ATTRIBUTE => ['present', 'nullable', new CopyrightRule()],
RequestAttribute::IS_COMPACT_ATTRIBUTE => ['required', 'boolean'],
RequestAttribute::HEADER_ID_ATTRIBUTE => ['present', new RandomIDRule(true)],
Expand Down Expand Up @@ -123,6 +128,7 @@ protected function processValidatedValues(array $values, array $files): void
new AlbumSortingCriterion($albumColumn->toColumnSortingType(), $albumOrder);

$this->aspectRatio = AspectRatioType::tryFrom($values[RequestAttribute::ALBUM_ASPECT_RATIO_ATTRIBUTE]);
$this->photoLayout = PhotoLayoutType::tryFrom($values[RequestAttribute::ALBUM_PHOTO_LAYOUT]);
$this->copyright = $values[RequestAttribute::COPYRIGHT_ATTRIBUTE];

$this->is_compact = static::toBoolean($values[RequestAttribute::IS_COMPACT_ATTRIBUTE]);
Expand Down
8 changes: 7 additions & 1 deletion app/Http/Requests/Album/UpdateTagAlbumRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Contracts\Http\Requests\HasCopyright;
use App\Contracts\Http\Requests\HasDescription;
use App\Contracts\Http\Requests\HasPhotoLayout;
use App\Contracts\Http\Requests\HasPhotoSortingCriterion;
use App\Contracts\Http\Requests\HasTagAlbum;
use App\Contracts\Http\Requests\HasTags;
Expand All @@ -12,10 +13,12 @@
use App\DTO\PhotoSortingCriterion;
use App\Enum\ColumnSortingPhotoType;
use App\Enum\OrderSortingType;
use App\Enum\PhotoLayoutType;
use App\Http\Requests\BaseApiRequest;
use App\Http\Requests\Traits\Authorize\AuthorizeCanEditAlbumTrait;
use App\Http\Requests\Traits\HasCopyrightTrait;
use App\Http\Requests\Traits\HasDescriptionTrait;
use App\Http\Requests\Traits\HasPhotoLayoutTrait;
use App\Http\Requests\Traits\HasPhotoSortingCriterionTrait;
use App\Http\Requests\Traits\HasTagAlbumTrait;
use App\Http\Requests\Traits\HasTagsTrait;
Expand All @@ -28,14 +31,15 @@
use Illuminate\Validation\Rules\Enum;
use Illuminate\Validation\ValidationException;

class UpdateTagAlbumRequest extends BaseApiRequest implements HasTagAlbum, HasTitle, HasDescription, HasPhotoSortingCriterion, HasCopyright, HasTags
class UpdateTagAlbumRequest extends BaseApiRequest implements HasTagAlbum, HasTitle, HasDescription, HasPhotoSortingCriterion, HasCopyright, HasTags, HasPhotoLayout
{
use HasTagAlbumTrait;
use HasTitleTrait;
use HasDescriptionTrait;
use HasPhotoSortingCriterionTrait;
use HasCopyrightTrait;
use HasTagsTrait;
use HasPhotoLayoutTrait;
use AuthorizeCanEditAlbumTrait;

/**
Expand All @@ -55,6 +59,7 @@ public function rules(): array
RequestAttribute::TAGS_ATTRIBUTE => 'required|array|min:1',
RequestAttribute::TAGS_ATTRIBUTE . '.*' => 'required|string|min:1',
RequestAttribute::COPYRIGHT_ATTRIBUTE => ['present', 'nullable', new CopyrightRule()],
RequestAttribute::ALBUM_PHOTO_LAYOUT => ['present', 'nullable', new Enum(PhotoLayoutType::class)],
];
}

Expand Down Expand Up @@ -82,6 +87,7 @@ protected function processValidatedValues(array $values, array $files): void
null :
new PhotoSortingCriterion($photoColumn->toColumnSortingType(), $photoOrder);

$this->photoLayout = PhotoLayoutType::tryFrom($values[RequestAttribute::ALBUM_PHOTO_LAYOUT]);
$this->copyright = $values[RequestAttribute::COPYRIGHT_ATTRIBUTE];
$this->tags = $values[RequestAttribute::TAGS_ATTRIBUTE];
}
Expand Down
18 changes: 18 additions & 0 deletions app/Http/Requests/Traits/HasPhotoLayoutTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

namespace App\Http\Requests\Traits;

use App\Enum\PhotoLayoutType;

trait HasPhotoLayoutTrait
{
protected ?PhotoLayoutType $photoLayout = null;

/**
* @return PhotoLayoutType|null
*/
public function photoLayout(): ?PhotoLayoutType
{
return $this->photoLayout;
}
}
3 changes: 3 additions & 0 deletions app/Http/Resources/Editable/EditableBaseAlbumResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\DTO\PhotoSortingCriterion;
use App\Enum\AspectRatioType;
use App\Enum\LicenseType;
use App\Enum\PhotoLayoutType;
use App\Models\Album;
use App\Models\TagAlbum;
use Spatie\LaravelData\Data;
Expand All @@ -22,6 +23,7 @@ class EditableBaseAlbumResource extends Data
public ?PhotoSortingCriterion $photo_sorting;
public ?AlbumSortingCriterion $album_sorting;
public ?AspectRatioType $aspect_ratio;
public ?PhotoLayoutType $photo_layout;
public ?string $header_id;
public ?string $cover_id;
/** @var string[] */
Expand All @@ -40,6 +42,7 @@ public function __construct(Album|TagAlbum $album)
$this->album_sorting = null;
$this->header_id = null;
$this->cover_id = null;
$this->photo_layout = $album->photo_layout;

if ($album instanceof Album) {
$this->is_model_album = true;
Expand Down
4 changes: 4 additions & 0 deletions app/Http/Resources/GalleryConfigs/AlbumConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use App\Contracts\Models\AbstractAlbum;
use App\Enum\AspectRatioCSSType;
use App\Enum\AspectRatioType;
use App\Enum\PhotoLayoutType;
use App\Models\Album;
use App\Models\Configs;
use App\Models\Extensions\BaseAlbum;
Expand All @@ -26,6 +27,7 @@ class AlbumConfig extends Data
public bool $is_search_accessible;
public bool $is_nsfw_warning_visible;
public AspectRatioCSSType $album_thumb_css_aspect_ratio;
public PhotoLayoutType $photo_layout;

public function __construct(AbstractAlbum $album)
{
Expand All @@ -49,6 +51,8 @@ public function __construct(AbstractAlbum $album)
} else {
$this->album_thumb_css_aspect_ratio = Configs::getValueAsEnum('default_album_thumb_aspect_ratio', AspectRatioType::class)->css();
}

$this->photo_layout = (($album instanceof BaseAlbum) ? $album->photo_layout : null) ?? Configs::getValueAsEnum('layout', PhotoLayoutType::class);
}

public function setIsMapAccessible(): void
Expand Down
3 changes: 0 additions & 3 deletions app/Http/Resources/GalleryConfigs/PhotoLayoutConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,13 @@

namespace App\Http\Resources\GalleryConfigs;

use App\Enum\PhotoLayoutType;
use App\Models\Configs;
use Spatie\LaravelData\Data;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;

#[TypeScript()]
class PhotoLayoutConfig extends Data
{
public PhotoLayoutType $photos_layout;
public int $photo_layout_justified_row_height;
public int $photo_layout_masonry_column_width;
public int $photo_layout_grid_column_width;
Expand All @@ -24,6 +22,5 @@ public function __construct()
$this->photo_layout_grid_column_width = Configs::getValueAsInt('photo_layout_grid_column_width');
$this->photo_layout_square_column_width = Configs::getValueAsInt('photo_layout_square_column_width');
$this->photo_layout_gap = Configs::getValueAsInt('photo_layout_gap');
$this->photos_layout = Configs::getValueAsEnum('layout', PhotoLayoutType::class);
}
}
4 changes: 4 additions & 0 deletions app/Models/BaseAlbumImpl.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use App\DTO\PhotoSortingCriterion;
use App\Enum\ColumnSortingType;
use App\Enum\OrderSortingType;
use App\Enum\PhotoLayoutType;
use App\Models\Builders\BaseAlbumImplBuilder;
use App\Models\Extensions\HasAttributesPatch;
use App\Models\Extensions\HasBidirectionalRelationships;
Expand Down Expand Up @@ -94,6 +95,7 @@
* @property Carbon $updated_at
* @property string $title
* @property string|null $description
* @property PhotoLayoutType|null $photo_layout
* @property int $owner_id
* @property User $owner
* @property bool $is_nsfw
Expand Down Expand Up @@ -178,6 +180,7 @@ class BaseAlbumImpl extends Model implements HasRandomID
'copyright' => null,
// Special visibility attributes
'is_nsfw' => false,
'photo_layout' => null,
];

/**
Expand All @@ -190,6 +193,7 @@ class BaseAlbumImpl extends Model implements HasRandomID
'updated_at' => 'datetime',
'is_nsfw' => 'boolean',
'owner_id' => 'integer',
'photo_layout' => PhotoLayoutType::class,
];

/**
Expand Down
2 changes: 2 additions & 0 deletions app/Models/Extensions/BaseAlbum.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use App\Contracts\Models\AbstractAlbum;
use App\Contracts\Models\HasRandomID;
use App\DTO\PhotoSortingCriterion;
use App\Enum\PhotoLayoutType;
use App\Models\AccessPermission;
use App\Models\BaseAlbumImpl;
use App\Models\User;
Expand All @@ -30,6 +31,7 @@
* @property string|null $description
* @property bool $is_nsfw
* @property string|null $copyright
* @property PhotoLayoutType|null $photo_layout
* @property int $owner_id
* @property User $owner
* @property Collection<int,AccessPermission> $access_permissions
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class() extends Migration {
private const BASE_ALBUM = 'base_albums';
private const PHOTO_LAYOUT_COLUMN_NAME = 'photo_layout';

/**
* Run the migrations.
*/
public function up(): void
{
Schema::table(self::BASE_ALBUM, function ($table) {
$table->string(self::PHOTO_LAYOUT_COLUMN_NAME, 20)->nullable()->default(null)->after('copyright');
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table(self::BASE_ALBUM, function (Blueprint $table) {
$table->dropColumn(self::PHOTO_LAYOUT_COLUMN_NAME);
});
}
};
29 changes: 29 additions & 0 deletions resources/js/components/forms/album/AlbumProperties.vue
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,30 @@
</FloatLabel>
</div>
</template>
<div class="h-10 my-2 pt-4">
<FloatLabel variant="on">
<Select
id="photoLayout"
class="w-72 border-none"
v-model="photoLayout"
:options="photoLayoutOptions"
optionLabel="label"
showClear
>
<template #value="slotProps">
<div v-if="slotProps.value" class="flex items-center">
<div>{{ $t(slotProps.value.label) }}</div>
</div>
</template>
<template #option="slotProps">
<div class="flex items-center">
<div>{{ $t(slotProps.option.label) }}</div>
</div>
</template>
</Select>
<label for="photoLayout">Set photo layout</label>
</FloatLabel>
</div>
<div v-if="!is_model_album" class="mb-8 h-10">
<FloatLabel variant="on">
<AutoComplete
Expand Down Expand Up @@ -217,6 +241,7 @@ import {
sortingOrdersOptions,
licenseOptions,
aspectRationOptions,
photoLayoutOptions,
SelectOption,
SelectBuilders,
} from "@/config/constants";
Expand Down Expand Up @@ -244,6 +269,7 @@ const photoSortingColumn = ref(undefined as SelectOption<App.Enum.ColumnSortingP
const photoSortingOrder = ref(undefined as SelectOption<App.Enum.OrderSortingType> | undefined);
const albumSortingColumn = ref(undefined as SelectOption<App.Enum.ColumnSortingAlbumType> | undefined);
const albumSortingOrder = ref(undefined as SelectOption<App.Enum.OrderSortingType> | undefined);
const photoLayout = ref(undefined as SelectOption<App.Enum.PhotoLayoutType> | undefined);
const license = ref(undefined as SelectOption<App.Enum.LicenseType> | undefined);
const copyright = ref(undefined as undefined | string);
const tags = ref([] as string[]);
Expand Down Expand Up @@ -294,6 +320,7 @@ function load(editable: App.Http.Resources.Editable.EditableBaseAlbumResource, p
photoSortingOrder.value = SelectBuilders.buildSortingOrder(editable.photo_sorting?.order);
albumSortingColumn.value = SelectBuilders.buildAlbumSorting(editable.album_sorting?.column);
albumSortingOrder.value = SelectBuilders.buildSortingOrder(editable.album_sorting?.order);
photoLayout.value = SelectBuilders.buildPhotoLayout(editable.photo_layout);
license.value = SelectBuilders.buildLicense(editable.license);
aspectRatio.value = SelectBuilders.buildAspectRatio(editable.aspect_ratio);
header_id.value = buildHeaderId(editable.header_id, photos);
Expand Down Expand Up @@ -324,6 +351,7 @@ function saveAlbum() {
copyright: copyright.value ?? null,
header_id: header_id.value?.id === "compact" ? null : (header_id.value?.id ?? null),
is_compact: header_id.value?.id === "compact",
photo_layout: photoLayout.value?.value ?? null,
};
AlbumService.updateAlbum(data)
.then(() => {
Expand All @@ -349,6 +377,7 @@ function saveTagAlbum() {
photo_sorting_column: photoSortingColumn.value?.value ?? null,
photo_sorting_order: photoSortingOrder.value?.value ?? null,
copyright: copyright.value ?? null,
photo_layout: photoLayout.value?.value ?? null,
};
AlbumService.updateTag(data)
.then(() => {
Expand Down
Loading