Skip to content

Commit

Permalink
add layout setting for timeline and search
Browse files Browse the repository at this point in the history
  • Loading branch information
ildyria committed Nov 11, 2024
1 parent c6c423e commit d49a45f
Show file tree
Hide file tree
Showing 17 changed files with 141 additions and 60 deletions.
13 changes: 11 additions & 2 deletions app/Http/Controllers/Gallery/TimelineController.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

use App\Actions\Photo\Timeline;
use App\Http\Requests\Photo\GetTimelineRequest;
use App\Http\Resources\Collections\TimelineResource;
use App\Http\Resources\Timeline\InitResource;
use App\Http\Resources\Timeline\TimelineResource;
use App\Models\Configs;
use App\Models\Photo;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
Expand All @@ -25,7 +26,15 @@ public function __invoke(GetTimelineRequest $request, Timeline $timeline): Data
return TimelineResource::fromData($photoResults);
}

public function getLayout(): void
/**
* Return init Search.
*
* @param InitSearchRequest $request
*
* @return InitResource
*/
public function init(GetTimelineRequest $request): Data

Check failure on line 36 in app/Http/Controllers/Gallery/TimelineController.php

View workflow job for this annotation

GitHub Actions / 2️⃣ PHP 8.2 - PHPStan

PHPDoc tag @param for parameter $request with type App\Http\Controllers\Gallery\InitSearchRequest is not subtype of native type App\Http\Requests\Photo\GetTimelineRequest.

Check failure on line 36 in app/Http/Controllers/Gallery/TimelineController.php

View workflow job for this annotation

GitHub Actions / 2️⃣ PHP 8.2 - PHPStan

Parameter $request of method App\Http\Controllers\Gallery\TimelineController::init() has invalid type App\Http\Controllers\Gallery\InitSearchRequest.

Check failure on line 36 in app/Http/Controllers/Gallery/TimelineController.php

View workflow job for this annotation

GitHub Actions / 2️⃣ PHP 8.2 - PHPStan

PHPDoc tag @param for parameter $request with type App\Http\Controllers\Gallery\InitSearchRequest is not subtype of native type App\Http\Requests\Photo\GetTimelineRequest.

Check failure on line 36 in app/Http/Controllers/Gallery/TimelineController.php

View workflow job for this annotation

GitHub Actions / 2️⃣ PHP 8.2 - PHPStan

Parameter $request of method App\Http\Controllers\Gallery\TimelineController::init() has invalid type App\Http\Controllers\Gallery\InitSearchRequest.
{
return new InitResource();
}
}
3 changes: 3 additions & 0 deletions app/Http/Resources/Search/InitResource.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace App\Http\Resources\Search;

use App\Enum\PhotoLayoutType;
use App\Models\Configs;
use Spatie\LaravelData\Data;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;
Expand All @@ -13,9 +14,11 @@
class InitResource extends Data
{
public int $search_minimum_length = 3;
public PhotoLayoutType $photo_layout;

public function __construct()
{
$this->search_minimum_length = Configs::getValueAsInt('search_minimum_length_required');
$this->photo_layout = Configs::getValueAsEnum('search_photos_layout', PhotoLayoutType::class);
}
}
22 changes: 22 additions & 0 deletions app/Http/Resources/Timeline/InitResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Http\Resources\Timeline;

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

/**
* Initialization resource for the search.
*/
#[TypeScript()]
class InitResource extends Data
{
public PhotoLayoutType $photo_layout;

public function __construct()
{
$this->photo_layout = Configs::getValueAsEnum('timeline_photos_layout', PhotoLayoutType::class);
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

namespace App\Http\Resources\Collections;
namespace App\Http\Resources\Timeline;

use App\Enum\TimelinePhotoGranularity;
use App\Http\Resources\Models\PhotoResource;
Expand Down
15 changes: 15 additions & 0 deletions database/migrations/2024_10_30_064336_timeline_options.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
public const TIMELINE = 'Mod Timeline';
public const STRING_REQ = 'string_required';

public const SQUARE = 'square';
public const JUSTIFIED = 'justified';
public const MASONRY = 'masonry';
public const GRID = 'grid';

public function getConfigs(): array
{
return [
Expand Down Expand Up @@ -49,6 +54,16 @@ public function getConfigs(): array
'is_secret' => false,
'level' => 0,
],
[
'key' => 'timeline_photos_layout',
'value' => self::SQUARE,
'cat' => self::TIMELINE,
'type_range' => self::SQUARE . '|' . self::JUSTIFIED . '|' . self::MASONRY . '|' . self::GRID,
'description' => 'Photo layout for timeline page',
'details' => '',
'is_secret' => false,
'level' => 0,
],
[
'key' => 'timeline_photos_pagination_limit',
'value' => '200',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
use App\Models\Extensions\BaseConfigMigration;

return new class() extends BaseConfigMigration {
public const SQUARE = 'square';
public const JUSTIFIED = 'justified';
public const MASONRY = 'masonry';
public const GRID = 'grid';

public function getConfigs(): array
{
return [
Expand Down Expand Up @@ -46,6 +51,16 @@ public function getConfigs(): array
'is_secret' => false,
'level' => 0,
],
[
'key' => 'search_photos_layout',
'value' => self::SQUARE,
'cat' => 'Mod Search',
'type_range' => self::SQUARE . '|' . self::JUSTIFIED . '|' . self::MASONRY . '|' . self::GRID,
'description' => 'Photo layout for search page',
'details' => '',
'is_secret' => false,
'level' => 0,
],
[
'key' => 'hide_nsfw_in_rss',
'value' => '1', // safe default
Expand Down
3 changes: 1 addition & 2 deletions resources/js/components/settings/AllSettings.vue
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,8 @@
@filled="update"
@reset="reset"
/>

<SelectOptionsField
v-else-if="config.key === 'layout'"
v-else-if="config.type === 'square|justified|masonry|grid'"
:config="config"
:options="photoLayoutOptions"
:mapper="SelectBuilders.buildPhotoLayout"
Expand Down
3 changes: 3 additions & 0 deletions resources/js/composables/album/searchRefresher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export function useSearch(albumid: Ref<string>, lycheeStore: LycheeStateStore, s
const from = ref(0);
const per_page = ref(0);
const total = ref(0);
const layout = ref("square" as App.Enum.PhotoLayoutType);

const photoHeader = computed(() => {
return trans("lychee.PHOTOS") + " (" + total.value + ")";
Expand All @@ -24,6 +25,7 @@ export function useSearch(albumid: Ref<string>, lycheeStore: LycheeStateStore, s
function searchInit() {
SearchService.init(albumid.value).then((response) => {
searchMinimumLengh.value = response.data.search_minimum_length;
layout.value = response.data.photo_layout;
});
}

Expand Down Expand Up @@ -68,6 +70,7 @@ export function useSearch(albumid: Ref<string>, lycheeStore: LycheeStateStore, s
}

return {
layout,
albums,
photos,
noData,
Expand Down
20 changes: 15 additions & 5 deletions resources/js/layouts/PhotoLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useJustify } from "./useJustify";
import { useMasonry } from "./useMasonry";
import { useGrid } from "./useGrid";
import AlbumService from "@/services/album-service";
import TimelineService from "@/services/timeline-service";

export function useLayouts(
config: App.Http.Resources.GalleryConfigs.PhotoLayoutConfig,
Expand Down Expand Up @@ -53,17 +54,26 @@ export function useLayoutClass(layout: Ref<App.Enum.PhotoLayoutType>) {
};
}

export function useGetLayout() {
const layout = ref(null) as Ref<null | App.Http.Resources.GalleryConfigs.PhotoLayoutConfig>;
export function useGetLayoutConfig() {
const layoutConfig = ref(null) as Ref<null | App.Http.Resources.GalleryConfigs.PhotoLayoutConfig>;
const layout = ref("square") as Ref<App.Enum.PhotoLayoutType>;

function loadLayout() {
function loadLayoutConfig() {
AlbumService.getLayout().then((data) => {
layout.value = data.data;
layoutConfig.value = data.data;
});
}

function loadLayoutTimeline() {
TimelineService.init().then((data) => {
layout.value = data.data.photo_layout;
});
}

return {
layout,
loadLayout,
layoutConfig,
loadLayoutConfig,
loadLayoutTimeline,
};
}
9 changes: 0 additions & 9 deletions resources/js/layouts/useJustify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,7 @@ export function useJustify(el: HTMLElement, photoDefaultHeight: number = 320, is
return;
}
const containerDefaultWidth = parseInt(getComputedStyle(baseElem).width) - 86;

// const width = el.clientWidth;
// const body_width = document.body.scrollWidth;
// console.log("containerDefaultWidth: " + containerDefaultWidth);
// console.log("containerWidthBefore: " + parseInt(getComputedStyle(el).width));

const containerWidth = isTimeline ? Math.min(parseInt(getComputedStyle(el).width), containerDefaultWidth) : parseInt(getComputedStyle(el).width);
// console.log("containerWidth: " + containerWidth);
// console.log("width: " + width)
// console.log("body_width: " + body_width);

// @ts-expect-error
const justifiedItems: ChildNodeWithDataStyle[] = [...el.childNodes].filter((gridItem) => gridItem.nodeType === 1);
Expand Down
24 changes: 15 additions & 9 deletions resources/js/lychee.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,15 +104,6 @@ declare namespace App.Http.Resources.Collections {
config: App.Http.Resources.GalleryConfigs.RootConfig;
rights: App.Http.Resources.Rights.RootAlbumRightsResource;
};
export type TimelineResource = {
photos: App.Http.Resources.Models.PhotoResource[] | Array<any>;
current_page: number;
from: number;
last_page: number;
per_page: number;
to: number;
total: number;
};
}
declare namespace App.Http.Resources.Diagnostics {
export type CleaningState = {
Expand Down Expand Up @@ -589,6 +580,7 @@ declare namespace App.Http.Resources.Root {
declare namespace App.Http.Resources.Search {
export type InitResource = {
search_minimum_length: number;
photo_layout: App.Enum.PhotoLayoutType;
};
export type ResultsResource = {
albums: App.Http.Resources.Models.ThumbAlbumResource[] | Array<any>;
Expand Down Expand Up @@ -636,3 +628,17 @@ declare namespace App.Http.Resources.Statistics {
size: number;
};
}
declare namespace App.Http.Resources.Timeline {
export type InitResource = {
photo_layout: App.Enum.PhotoLayoutType;
};
export type TimelineResource = {
photos: App.Http.Resources.Models.PhotoResource[] | Array<any>;
current_page: number;
from: number;
last_page: number;
per_page: number;
to: number;
total: number;
};
}
4 changes: 0 additions & 4 deletions resources/js/services/photo-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,6 @@ const PhotoService = {
download(photo_ids: string[], download_type: App.Enum.DownloadVariantType = "ORIGINAL"): void {
window.open(`${Constants.getApiUrl()}Zip?photo_ids=${photo_ids.join(",")}&variant=${download_type}`, "_blank");
},

timeline(page: number = 1): Promise<AxiosResponse<App.Http.Resources.Collections.TimelineResource>> {
return axios.get(`${Constants.getApiUrl()}Timeline`, { params: { page: page }, data: {} });
},
};

export default PhotoService;
14 changes: 14 additions & 0 deletions resources/js/services/timeline-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import axios, { type AxiosResponse } from "axios";
import Constants from "./constants";

const TimelineService = {
timeline(page: number = 1): Promise<AxiosResponse<App.Http.Resources.Timeline.TimelineResource>> {
return axios.get(`${Constants.getApiUrl()}Timeline`, { params: { page: page }, data: {} });
},

init(): Promise<AxiosResponse<App.Http.Resources.Timeline.InitResource>> {
return axios.get(`${Constants.getApiUrl()}Timeline::init`, { data: {} });
},
};

export default TimelineService;
10 changes: 5 additions & 5 deletions resources/js/views/gallery-panels/Album.vue
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@
:is-timeline="config.is_album_timeline_enabled"
/>
<PhotoThumbPanel
v-if="layout !== null && photos !== null && photos.length > 0"
v-if="layoutConfig !== null && photos !== null && photos.length > 0"
header="lychee.PHOTOS"
:photos="photos"
:album="album"
:gallery-config="layout"
:gallery-config="layoutConfig"
:photo-layout="config.photo_layout"
:selected-photos="selectedPhotosIds"
@clicked="photoClick"
Expand Down Expand Up @@ -203,7 +203,7 @@ import Button from "primevue/button";
import { useMouseEvents } from "@/composables/album/uploadEvents";
import GalleryFooter from "@/components/footers/GalleryFooter.vue";
import AlbumStatistics from "@/components/drawers/AlbumStatistics.vue";
import { useGetLayout } from "@/layouts/PhotoLayout";
import { useGetLayoutConfig } from "@/layouts/PhotoLayout";
const route = useRoute();
const router = useRouter();
Expand Down Expand Up @@ -233,7 +233,7 @@ function toggleSlideShow() {
router.push({ name: "photo", params: { albumid: album.value.id, photoid: album.value.photos[0].id } });
}
const { layout, loadLayout } = useGetLayout();
const { layoutConfig, loadLayoutConfig } = useGetLayoutConfig();
// Set up Album ID reference. This one is updated at each page change.
const { isAlbumConsented, isPasswordProtected, user, modelAlbum, album, rights, photos, config, refresh } = useAlbumRefresher(
Expand Down Expand Up @@ -364,7 +364,7 @@ function consent() {
isAlbumConsented.value = true;
}
loadLayout();
loadLayoutConfig();
refresh();
Expand Down
14 changes: 8 additions & 6 deletions resources/js/views/gallery-panels/Search.vue
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,12 @@
<Paginator :total-records="total" :rows="per_page" v-model:first="from" @update:first="refresh" :always-show="false" />
</div>
<PhotoThumbPanel
v-if="layout !== null && photos.length > 0"
:photo-layout="configForMenu.photo_layout"
v-if="layoutConfig !== null && photos.length > 0"
:photo-layout="layout"
:header="photoHeader"
:photos="photos"
:album="undefined"
:gallery-config="layout"
:gallery-config="layoutConfig"
:selected-photos="selectedPhotosIds"
@clicked="photoClick"
@contexted="photoMenuOpen"
Expand Down Expand Up @@ -160,7 +160,7 @@ import MoveDialog from "@/components/forms/gallery-dialogs/MoveDialog.vue";
import DeleteDialog from "@/components/forms/gallery-dialogs/DeleteDialog.vue";
import PhotoService from "@/services/photo-service";
import AlbumService from "@/services/album-service";
import { useGetLayout } from "@/layouts/PhotoLayout";
import { useGetLayoutConfig } from "@/layouts/PhotoLayout";
const router = useRouter();
const props = defineProps<{
Expand All @@ -182,6 +182,7 @@ lycheeStore.init();
const { are_nsfw_visible, is_full_screen, search_page, search_term, is_login_open, nsfw_consented, is_upload_visible } = storeToRefs(lycheeStore);
const {
albums,
layout,
photos,
noData,
searchMinimumLengh,
Expand All @@ -196,7 +197,8 @@ const {
clear,
refresh,
} = useSearch(albumid, lycheeStore, search_term, search_page);
const { layout, loadLayout } = useGetLayout();
const { layoutConfig, loadLayoutConfig } = useGetLayoutConfig();
const { album, config, loadAlbum } = useAlbumRefresher(albumid, auth, is_login_open, nsfw_consented);
Expand Down Expand Up @@ -324,7 +326,7 @@ if (albumid.value !== "") {
}
searchInit();
loadLayout();
loadLayoutConfig();
if (lycheeStore.isSearchActive) {
search(lycheeStore.search_term);
Expand Down
Loading

0 comments on commit d49a45f

Please sign in to comment.