1
0
Fork 0
mirror of https://github.com/seanmorley15/AdventureLog.git synced 2025-07-24 23:39:37 +02:00

feat: add primary image functionality to AdventureImage model and update related components

This commit is contained in:
Sean Morley 2025-01-02 23:25:58 -05:00
parent 991efa8d08
commit c6fa603a93
8 changed files with 112 additions and 5 deletions

View file

@ -21,7 +21,7 @@
let query: string = '';
let places: OpenStreetMapPlace[] = [];
let images: { id: string; image: string }[] = [];
let images: { id: string; image: string; is_primary: boolean }[] = [];
let warningMessage: string = '';
let constrainDates: boolean = false;
@ -34,6 +34,9 @@
import MarkdownEditor from './MarkdownEditor.svelte';
import ImmichSelect from './ImmichSelect.svelte';
import Star from '~icons/mdi/star';
import Crown from '~icons/mdi/crown';
let wikiError: string = '';
let noPlaces: boolean = false;
@ -179,6 +182,25 @@
}
}
async function makePrimaryImage(image_id: string) {
let res = await fetch(`/api/images/${image_id}/toggle_primary`, {
method: 'POST'
});
if (res.ok) {
images = images.map((image) => {
if (image.id === image_id) {
image.is_primary = true;
} else {
image.is_primary = false;
}
return image;
});
adventure.images = images;
} else {
console.error('Error in makePrimaryImage:', res);
}
}
async function fetchImage() {
try {
let res = await fetch(url);
@ -208,7 +230,8 @@
// Assuming the first object in the array is the new image
let newImage = {
id: rawData[1],
image: rawData[2] // This is the URL for the image
image: rawData[2], // This is the URL for the image
is_primary: false
};
console.log('New Image:', newImage);
@ -249,7 +272,7 @@
if (res2.ok) {
let newData = deserialize(await res2.text()) as { data: { id: string; image: string } };
console.log(newData);
let newImage = { id: newData.data.id, image: newData.data.image };
let newImage = { id: newData.data.id, image: newData.data.image, is_primary: false };
console.log(newImage);
images = [...images, newImage];
adventure.images = images;
@ -1038,6 +1061,21 @@ it would also work to just use on:click on the MapLibre component itself. -->
>
</button>
{#if !image.is_primary}
<button
type="button"
class="absolute top-1 left-1 btn btn-success btn-xs z-10"
on:click={() => makePrimaryImage(image.id)}
>
<Star class="h-4 w-4" />
</button>
{:else}
<!-- crown icon -->
<div class="absolute top-1 left-1 bg-warning text-white rounded-full p-1 z-10">
<Crown class="h-4 w-4" />
</div>
{/if}
<img
src={image.image}
alt={image.id}

View file

@ -9,7 +9,11 @@
let image_url: string | null = null;
$: adventure_images = adventures.flatMap((adventure) =>
adventure.images.map((image) => ({ image: image.image, adventure: adventure }))
adventure.images.map((image) => ({
image: image.image,
adventure: adventure,
is_primary: image.is_primary
}))
);
$: {
@ -18,6 +22,19 @@
}
}
$: {
// sort so that any image in adventure_images .is_primary is first
adventure_images.sort((a, b) => {
if (a.is_primary && !b.is_primary) {
return -1;
} else if (!a.is_primary && b.is_primary) {
return 1;
} else {
return 0;
}
});
}
function changeSlide(direction: string) {
if (direction === 'next' && currentSlide < adventure_images.length - 1) {
currentSlide = currentSlide + 1;

View file

@ -24,6 +24,7 @@ export type Adventure = {
images: {
id: string;
image: string;
is_primary: boolean;
}[];
visits: {
id: string;

View file

@ -34,6 +34,16 @@
onMount(() => {
if (data.props.adventure) {
adventure = data.props.adventure;
// sort so that any image in adventure_images .is_primary is first
adventure.images.sort((a, b) => {
if (a.is_primary && !b.is_primary) {
return -1;
} else if (!a.is_primary && b.is_primary) {
return 1;
} else {
return 0;
}
});
} else {
notFound = true;
}