Skip to content

Commit

Permalink
squash
Browse files Browse the repository at this point in the history
  • Loading branch information
ildyria committed Nov 15, 2024
1 parent 630f78b commit 80b2da0
Show file tree
Hide file tree
Showing 13 changed files with 485 additions and 1 deletion.
44 changes: 44 additions & 0 deletions app/Actions/Photo/Timeline.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace App\Actions\Photo;

use App\Eloquent\FixedQueryBuilder;
use App\Enum\ColumnSortingPhotoType;
use App\Enum\OrderSortingType;
use App\Models\Configs;
use App\Models\Photo;
use App\Policies\PhotoQueryPolicy;
use Illuminate\Database\Eloquent\Builder;

class Timeline
{
protected PhotoQueryPolicy $photoQueryPolicy;

public function __construct(PhotoQueryPolicy $photoQueryPolicy)
{
$this->photoQueryPolicy = $photoQueryPolicy;
}

/**
* Create the query manually.
*
* @return FixedQueryBuilder<Photo>
*/
public function do(): Builder
{
$order = Configs::getValueAsEnum('timeline_photos_order', ColumnSortingPhotoType::class);

// Safe default (should not be needed).
// @codeCoverageIgnoreStart
if (!in_array($order, [ColumnSortingPhotoType::CREATED_AT, ColumnSortingPhotoType::TAKEN_AT], true)) {
$order = ColumnSortingPhotoType::TAKEN_AT;
}
// @codeCoverageIgnoreEnd

return $this->photoQueryPolicy->applySearchabilityFilter(
query: Photo::query()->with(['album', 'size_variants', 'size_variants.sym_links']),
origin: null,
include_nsfw: !Configs::getValueAsBool('hide_nsfw_in_timeline')
)->orderBy($order->value, OrderSortingType::DESC->value);
}
}
40 changes: 40 additions & 0 deletions app/Http/Controllers/Gallery/TimelineController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

namespace App\Http\Controllers\Gallery;

use App\Actions\Photo\Timeline;
use App\Http\Requests\Photo\GetTimelineRequest;
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;
use Illuminate\Routing\Controller;
use Spatie\LaravelData\Data;

/**
* Controller responsible for the Timeline data.
*/
class TimelineController extends Controller
{
public function __invoke(GetTimelineRequest $request, Timeline $timeline): Data
{
/** @var LengthAwarePaginator<Photo> $photoResults */
/** @disregard P1013 Undefined method withQueryString() (stupid intelephense) */
$photoResults = $timeline->do()->paginate(Configs::getValueAsInt('timeline_photos_pagination_limit'));

return TimelineResource::fromData($photoResults);
}

/**
* Return init Search.
*
* @param GetTimelineRequest $request
*
* @return InitResource
*/
public function init(GetTimelineRequest $request): Data
{
return new InitResource();
}
}
22 changes: 22 additions & 0 deletions app/Http/Requests/Photo/GetTimelineRequest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace App\Http\Requests\Photo;

use App\Http\Requests\AbstractEmptyRequest;
use App\Models\Configs;
use Illuminate\Support\Facades\Auth;

class GetTimelineRequest extends AbstractEmptyRequest
{
/**
* {@inheritDoc}
*/
public function authorize(): bool
{
if (!Auth::check() && !Configs::getValueAsBool('timeline_photos_public')) {
return false;
}

return Configs::getValueAsBool('timeline_photos_enabled');
}
}
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);
}
}
77 changes: 77 additions & 0 deletions app/Http/Resources/Timeline/TimelineResource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace App\Http\Resources\Timeline;

use App\Enum\TimelinePhotoGranularity;
use App\Http\Resources\Models\PhotoResource;
use App\Http\Resources\Models\Utils\TimelineData;
use App\Http\Resources\Traits\HasPrepPhotoCollection;
use App\Models\Configs;
use App\Models\Photo;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Support\Collection;
use Spatie\LaravelData\Data;
use Spatie\TypeScriptTransformer\Attributes\LiteralTypeScriptType;
use Spatie\TypeScriptTransformer\Attributes\TypeScript;

/**
* Result of a Search query.
*/
#[TypeScript()]
class TimelineResource extends Data
{
use HasPrepPhotoCollection;

/** @var Collection<int,PhotoResource> */
#[LiteralTypeScriptType('App.Http.Resources.Models.PhotoResource[]')]
public Collection $photos;

public int $current_page;
public int $from;
public int $last_page;
public int $per_page;
public int $to;
public int $total;

/**
* @param LengthAwarePaginator<PhotoResource>&Paginator<PhotoResource> $photos
*
* @return void
*/
public function __construct(
LengthAwarePaginator $photos,
) {
$this->photos = collect($photos->items());
$this->current_page = $photos->currentPage();
$this->from = $photos->firstItem() ?? 0;
$this->last_page = $photos->lastPage();
$this->per_page = $photos->perPage();
$this->to = $photos->lastItem() ?? 0;
$this->total = $photos->total();

// We do it manually this time.
$previous_photo = null;
$this->photos->each(function (PhotoResource &$photo) use (&$previous_photo) {
if ($previous_photo !== null) {
$previous_photo->next_photo_id = $photo->id;
}
$photo->previous_photo_id = $previous_photo?->id;
$previous_photo = $photo;
});
$photo_granularity = Configs::getValueAsEnum('timeline_photos_granularity', TimelinePhotoGranularity::class);
$this->photos = TimelineData::setTimeLineDataForPhotos($this->photos, $photo_granularity);
}

/**
* @param LengthAwarePaginator<Photo> $photos
*
* @return TimelineResource
*/
public static function fromData(LengthAwarePaginator $photos): self
{
return new self(
photos: PhotoResource::collect($photos), // @phpstan-ignore-line
);
}
}
8 changes: 8 additions & 0 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 @@ -63,9 +64,16 @@ export function useGetLayoutConfig() {
});
}

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

return {
layout,
layoutConfig,
loadLayoutConfig,
loadLayoutTimeline,
};
}
14 changes: 14 additions & 0 deletions resources/js/lychee.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -628,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;
};
}
6 changes: 6 additions & 0 deletions resources/js/router/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Albums from "@/views/gallery-panels/Albums.vue";
import Photo from "@/views/gallery-panels/Photo.vue";

const Landing = () => import("@/views/Landing.vue");
const Timeline = () => import("@/views/gallery-panels/Timeline.vue");
const Frame = () => import("@/views/gallery-panels/Frame.vue");
const Search = () => import("@/views/gallery-panels/Search.vue");
const MapView = () => import("@/views/gallery-panels/Map.vue");
Expand Down Expand Up @@ -45,6 +46,11 @@ const routes_ = [
component: Frame,
props: true,
},
{
name: "timeline",
path: "/timeline",
component: Timeline,
},
{
name: "frame",
path: "/frame",
Expand Down
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;
3 changes: 3 additions & 0 deletions resources/js/stores/LycheeState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ export const useLycheeStateStore = defineStore("lychee-store", {
search_album_id: undefined as string | undefined,
search_page: 1,

// Timeline stuff
timeline_page: 1,

// configs for nsfw
are_nsfw_visible: false,
is_nsfw_background_blurred: false,
Expand Down
Loading

0 comments on commit 80b2da0

Please sign in to comment.