Skip to content

Commit

Permalink
done
Browse files Browse the repository at this point in the history
  • Loading branch information
ildyria committed Oct 21, 2024
1 parent 785c503 commit abec2ed
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 114 deletions.
26 changes: 24 additions & 2 deletions app/Actions/Statistics/Spaces.php
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,18 @@ public function getSpacePerSizeVariantTypePerAlbum(string $album_id): Collection
public function getSpacePerAlbum(?string $album_id = null, ?int $owner_id = null)
{
$query = DB::table('albums')
->when($album_id !== null, fn ($query) => $query->where('albums.id', '=', $album_id))
->when($album_id !== null,
fn ($query) => $query
->joinSub(
query: DB::table('albums', 'parent')->select('parent.id', 'parent._lft', 'parent._rgt'),
as: 'parent',
first: function (JoinClause $join) {
$join->on('albums._lft', '>=', 'parent._lft')
->on('albums._rgt', '<=', 'parent._rgt');
}
)
->where('parent.id', '=', $album_id)
)
->when($owner_id !== null, fn ($query) => $query->joinSub(
query: DB::table('base_albums')->select(['base_albums.id', 'base_albums.owner_id']),
as: 'base_albums',
Expand Down Expand Up @@ -258,7 +269,18 @@ public function getTotalSpacePerAlbum(?string $album_id = null, ?int $owner_id =
public function getPhotoCountPerAlbum(?string $album_id = null, ?int $owner_id = null)
{
$query = DB::table('albums')
->when($album_id !== null, fn ($query) => $query->where('albums.id', '=', $album_id))
->when($album_id !== null,
fn ($query) => $query
->joinSub(
query: DB::table('albums', 'parent')->select('parent.id', 'parent._lft', 'parent._rgt'),
as: 'parent',
first: function (JoinClause $join) {
$join->on('albums._lft', '>=', 'parent._lft')
->on('albums._rgt', '<=', 'parent._rgt');
}
)
->where('parent.id', '=', $album_id)
)
->joinSub(
query: DB::table('base_albums')->select(['base_albums.id', 'base_albums.owner_id', 'base_albums.title', 'base_albums.is_nsfw']),
as: 'base_albums',
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Requests/Statistics/SpacePerAlbumRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function authorize(): bool
return Gate::check(SettingsPolicy::CAN_SEE_STATISTICS, [Configs::class]);
}

return Gate::check(AlbumPolicy::CAN_ACCESS, [AbstractAlbum::class, $this->album]);
return Auth::check() && Gate::check(AlbumPolicy::CAN_ACCESS, [AbstractAlbum::class, $this->album]);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion app/Http/Requests/Statistics/SpaceSizeVariantRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public function authorize(): bool
return Gate::check(UserPolicy::CAN_EDIT, [User::class]);
}

return Gate::check(AlbumPolicy::CAN_ACCESS, [AbstractAlbum::class, $this->album]);
return Auth::check() && Gate::check(AlbumPolicy::CAN_ACCESS, [AbstractAlbum::class, $this->album]);
}

/**
Expand Down
126 changes: 53 additions & 73 deletions resources/js/components/drawers/AlbumStatistics.vue
Original file line number Diff line number Diff line change
@@ -1,91 +1,82 @@
<template>
<Collapse class="w-full flex justify-center flex-wrap flex-row-reverse" :when="areStatisticsOpen">
<Panel class="border-0 w-full" :pt:content:class="'flex justify-evenly flex-wrap'">
<Card v-if="total !== undefined" class="max-w-xs w-full">
<template #content>
<div class="flex flex-wrap">
<span class="w-full font-bold text-xl">{{ "Total" }}</span>
<span class="w-20 text-muted-color-emphasis">{{ "Photos" }}:</span>
<span class="w-[calc(100%-5rem)] font-bold">{{ total.num_photos }}</span>
<span class="w-20 text-muted-color-emphasis">{{ "Albums" }}:</span>
<span class="w-[calc(100%-5rem)] font-bold">{{ total.num_albums }}</span>
<span class="w-20 text-muted-color-emphasis">{{ "Size" }}:</span>
<span class="w-[calc(100%-5rem)] font-bold">{{ sizeToUnit(total.size) }}</span>
</div>
</template>
</Card>

<Collapse class="w-full flex flex-wrap justify-center" :when="areStatisticsOpen">
<Panel class="border-0 w-full" :pt:header:class="'hidden'" :pt:content:class="'flex sm:justify-center flex-wrap justify-start'">
<TotalCard v-if="total !== undefined" :total="total" />
<SizeVariantMeter v-if="props.config.is_model_album" :album-id="props.album.id" />

</Panel>
<Panel
class="border-0 w-full max-w-6xl"
:pt:header:class="'hidden'"
:pt:content:class="'flex justify-evenly shadow-inner shad shadow-black/10 rounded-xl p-4 bg-surface-50 dark:bg-surface-950/20'"
v-if="photos.length > 0"
>
<DataTable
v-if="photosData.lens.length > 1"
:value="photosData.lens"
scrollable
size="small"
scrollHeight="13rem"
class="max-w-xs w-full"
class="max-w-xs w-full border-r-surface-300 dark:border-r-surface-700 border-r"
:dt="dtScheme"
>
<Column field="key" header="Lens"></Column>
<Column field="value" header="Count"></Column>
<Column field="value" header=""></Column>
<template #empty> No data. </template>
</DataTable>
<DataTable
v-if="photosData.shutter.length > 1"
:value="photosData.shutter"
scrollable
size="small"
scrollHeight="13rem"
class="max-w-xs w-full"
class="max-w-xs w-full border-r-surface-300 dark:border-r-surface-700 border-r"
:dt="dtScheme"
>
<Column field="key" header="Shutter speed"></Column>
<Column field="value" header="Count"></Column>
<Column field="value" header=""></Column>
<template #empty> No data. </template>
</DataTable>
<DataTable
v-if="photosData.aperture.length > 1"
:value="photosData.aperture"
scrollable
size="small"
scrollHeight="13rem"
class="max-w-xs w-full"
class="max-w-xs w-full border-r-surface-300 dark:border-r-surface-700 border-r"
:dt="dtScheme"
>
<Column field="key" header="Aperture"></Column>
<Column field="value" header="Count"></Column>
</DataTable>
<DataTable v-if="photosData.iso.length > 1" :value="photosData.iso" scrollable size="small" scrollHeight="13rem" class="max-w-xs w-full">
<Column field="key" header="ISO"></Column>
<Column field="value" header="Count"></Column>
<Column field="value" header=""></Column>
<template #empty> No data. </template>
</DataTable>
<DataTable
v-if="photosData.model.length > 1"
:value="photosData.model"
:value="photosData.iso"
scrollable
size="small"
scrollHeight="13rem"
class="max-w-xs w-full"
class="max-w-xs w-full border-r-surface-300 dark:border-r-surface-700 border-r"
:dt="dtScheme"
>
<Column field="key" header="ISO"></Column>
<Column field="value" header=""></Column>
<template #empty> No data. </template>
</DataTable>
<DataTable :value="photosData.model" scrollable size="small" scrollHeight="13rem" class="max-w-xs w-full" :dt="dtScheme">
<Column field="key" header="ISO"></Column>
<Column field="value" header="Count"></Column>
<template #empty> No data. </template>
</DataTable>
</Panel>
</Collapse>
</template>
<script setup lang="ts">
import StatisticsService from "@/services/statistics-service";
import { useLycheeStateStore } from "@/stores/LycheeState";
import { sizeToUnit } from "@/utils/StatsSizeVariantToColours";
import { storeToRefs } from "pinia";
import Card from "primevue/card";
import Column from "primevue/column";
import DataTable from "primevue/datatable";
import Panel from "primevue/panel";
import { computed, Ref, ref } from "vue";
import { Ref, ref } from "vue";
import { Collapse } from "vue-collapsed";
import { TotalAlbum } from "../statistics/TotalCard.vue";
import TotalCard, { TotalAlbum } from "../statistics/TotalCard.vue";
import { useAlbumsStatistics } from "@/composables/album/albumStatistics";
import SizeVariantMeter from "../statistics/SizeVariantMeter.vue";
const lycheeStore = useLycheeStateStore();
const { are_nsfw_visible } = storeToRefs(lycheeStore);
const areStatisticsOpen = defineModel("visible", { default: false }) as Ref<boolean>;
const props = defineProps<{
Expand All @@ -97,40 +88,29 @@ const props = defineProps<{
const { getStatistics } = useAlbumsStatistics();
const photosData = ref(getStatistics(props.photos));
const albumSpace = ref(undefined as undefined | App.Http.Resources.Statistics.Album[]);
const totalAlbumSpace = ref(undefined as undefined | App.Http.Resources.Statistics.Album[]);
const total = computed(() => {
if (albumSpace.value === undefined) {
return undefined;
}
const sumData: TotalAlbum = {
size: 0,
num_photos: 0,
num_albums: 0,
};
albumSpace.value
?.filter((a) => !a.is_nsfw || are_nsfw_visible.value)
?.reduce((acc, a) => {
sumData.size += a.size;
sumData.num_photos += a.num_photos;
return acc;
}, sumData);
const totalAlbumSpace = ref(undefined as undefined | App.Http.Resources.Statistics.Album);
sumData.num_albums = albumSpace.value?.filter((a) => !a.is_nsfw || are_nsfw_visible.value)?.length ?? 0;
return sumData;
});
if (props.config.is_base_album) {
StatisticsService.getAlbumSpace(props.album.id).then((response) => {
albumSpace.value = response.data;
});
const total = ref(undefined as undefined | TotalAlbum);
if (props.config.is_model_album) {
StatisticsService.getTotalAlbumSpace(props.album.id).then((response) => {
totalAlbumSpace.value = response.data;
totalAlbumSpace.value = response.data[0];
total.value = {
num_photos: totalAlbumSpace.value.num_photos,
num_albums: totalAlbumSpace.value.num_descendants,
size: totalAlbumSpace.value.size,
};
});
}
const dtScheme = {
colorScheme: {
light: {
headerCellBackground: "{surface-50}",
},
dark: {
headerCellBackground: "color-mix(in srgb, {surface-900}, {surface-950} 20%)",
},
},
};
</script>
7 changes: 5 additions & 2 deletions resources/js/components/gallery/AlbumHero.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,14 @@
<i class="pi pi-share-alt" />
</a>
<a
v-if="is_se_enabled"
v-if="is_se_enabled && user?.id !== null"
class="flex-shrink-0 px-3 cursor-pointer inline-block transform duration-300 hover:scale-150 hover:text-color"
v-on:click="openStatistics"
>
<i class="pi pi-chart-scatter text-primary-emphasis" />
</a>
<a
v-if="is_se_preview_enabled"
v-if="is_se_preview_enabled && user?.id !== null"
class="flex-shrink-0 px-3 cursor-not-allowed text-primary-emphasis"
v-tooltip.left="'Statistics available in the Supporter Edition'"
>
Expand All @@ -70,12 +70,15 @@
</template>
<script setup lang="ts">
import AlbumService from "@/services/album-service";
import { useAuthStore } from "@/stores/Auth";
import { useLycheeStateStore } from "@/stores/LycheeState";
import { storeToRefs } from "pinia";
import Card from "primevue/card";
const auth = useAuthStore();
const lycheeStore = useLycheeStateStore();
const { is_se_enabled, is_se_preview_enabled } = storeToRefs(lycheeStore);
const { user } = storeToRefs(auth);
const props = defineProps<{
album: App.Http.Resources.Models.AlbumResource | App.Http.Resources.Models.TagAlbumResource | App.Http.Resources.Models.SmartAlbumResource;
Expand Down
23 changes: 4 additions & 19 deletions resources/js/components/statistics/AlbumsTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,12 @@ import StatisticsService from "@/services/statistics-service";
import { useLycheeStateStore } from "@/stores/LycheeState";
import { storeToRefs } from "pinia";
import { usePreviewData } from "@/composables/preview/getPreviewInfo";
import { useAlbumsStatistics } from "@/composables/album/albumStatistics";
const lycheeStore = useLycheeStateStore();
const { is_se_preview_enabled, are_nsfw_visible } = storeToRefs(lycheeStore);
const { getAlbumSizeData } = usePreviewData();
const { computeTotal } = useAlbumsStatistics();
const props = defineProps<{
showUsername: boolean;
Expand All @@ -50,12 +52,12 @@ function loadAlbumSpace() {
if (is_se_preview_enabled.value === true) {
getAlbumSizeData().then(function (data) {
albumSpace.value = data;
emits("total", getTotalAlbumData());
emits("total", computeTotal(data));
});
} else {
StatisticsService.getAlbumSpace().then(function (response) {
albumSpace.value = response.data;
emits("total", getTotalAlbumData());
emits("total", computeTotal(response.data));
});
}
}
Expand All @@ -68,23 +70,6 @@ function loadTotalAlbumSpace() {
}
}
function getTotalAlbumData(): TotalAlbum {
const sumData: TotalAlbum = {
size: 0,
num_photos: 0,
num_albums: 0,
};
albumData.value?.reduce((acc, a) => {
sumData.size += a.size;
sumData.num_photos += a.num_photos;
return acc;
}, sumData);
sumData.num_albums = albumData.value?.length ?? 0;
return sumData;
}
if (props.isTotal) {
loadTotalAlbumSpace();
} else {
Expand Down
10 changes: 5 additions & 5 deletions resources/js/components/statistics/SizeVariantMeter.vue
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<template>
<MeterGroup :value="sizeVariantSpaceMeter" v-if="sizeVariantSpaceMeter && sizeVariantSpaceMeter.length > 0">
<template #label="{ value }">
<div class="flex flex-wrap gap-4 w-full sm:justify-between justify-center">
<div class="flex flex-wrap gap-2 xl:gap-6 w-full sm:justify-between justify-center">
<template v-for="val of value" :key="val.label">
<Card class="w-2/5 sm:w-auto border border-surface shadow-none">
<template #content>
<div class="flex justify-between gap-8">
<div class="flex gap-1 flex-col">
<span class="text-xs sm:text-sm"
><span class="rounded-full h-3 w-3 inline-block mr-1 sm:mr-2" :style="'background-color: ' + val.color"></span
>{{ val.label }}</span
>
<span class="text-xs sm:text-sm">
<span class="rounded-full h-3 w-3 inline-block mr-1 sm:mr-2" :style="'background-color: ' + val.color" />
{{ val.label }}
</span>
<span class="font-bold text-base">{{ val.size }}</span>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions resources/js/components/statistics/TotalCard.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<Card>
<Card class="w-56 flex-shrink-0" :pt:body:class="'p-0 pb-4'">
<template #content>
<div class="flex flex-wrap">
<div class="flex flex-wrap w-full">
<span class="w-full font-bold text-xl">{{ "Total" }}</span>
<span class="w-20 text-muted-color-emphasis">{{ "Photos" }}:</span>
<span class="w-[calc(100%-5rem)] font-bold">{{ props.total.num_photos }}</span>
Expand Down
20 changes: 20 additions & 0 deletions resources/js/composables/album/albumStatistics.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TotalAlbum } from "@/components/statistics/TotalCard.vue";

export type DataForTable = { key: string; value: number };

export type PhotoStats = {
Expand Down Expand Up @@ -83,7 +85,25 @@ export function useAlbumsStatistics() {
return data.sort((a, b) => b.value - a.value);
}

function computeTotal(albumsStats: App.Http.Resources.Statistics.Album[]): TotalAlbum {
const sumData: TotalAlbum = {
size: 0,
num_photos: 0,
num_albums: 0,
};

albumsStats.reduce((acc, a) => {
sumData.size += a.size;
sumData.num_photos += a.num_photos;
return acc;
}, sumData);

sumData.num_albums = albumsStats.length;
return sumData;
}

return {
getStatistics,
computeTotal,
};
}
Loading

0 comments on commit abec2ed

Please sign in to comment.