Show gallery cover on the edit panel (#5935)

This commit is contained in:
sezzim 2025-09-24 22:26:24 -07:00 committed by GitHub
parent 724d438721
commit c9ca40152f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 60 additions and 11 deletions

View file

@ -9,12 +9,14 @@ import (
type GalleryURLBuilder struct {
BaseURL string
GalleryID string
UpdatedAt string
}
func NewGalleryURLBuilder(baseURL string, gallery *models.Gallery) GalleryURLBuilder {
return GalleryURLBuilder{
BaseURL: baseURL,
GalleryID: strconv.Itoa(gallery.ID),
UpdatedAt: strconv.FormatInt(gallery.UpdatedAt.Unix(), 10),
}
}
@ -23,5 +25,5 @@ func (b GalleryURLBuilder) GetPreviewURL() string {
}
func (b GalleryURLBuilder) GetCoverURL() string {
return b.BaseURL + "/gallery/" + b.GalleryID + "/cover"
return b.BaseURL + "/gallery/" + b.GalleryID + "/cover?t=" + b.UpdatedAt
}

View file

@ -162,6 +162,21 @@ export const GalleryEditPanel: React.FC<IProps> = ({
);
}, [scrapers]);
const cover = useMemo(() => {
if (gallery?.paths?.cover) {
return (
<div className="gallery-cover">
<img
src={gallery.paths.cover}
alt={intl.formatMessage({ id: "cover_image" })}
/>
</div>
);
}
return <div></div>;
}, [gallery?.paths?.cover, intl]);
async function onSave(input: InputValues) {
setIsLoading(true);
try {
@ -463,6 +478,12 @@ export const GalleryEditPanel: React.FC<IProps> = ({
</Col>
<Col lg={5} xl={12}>
{renderDetailsField()}
<Form.Group controlId="cover_image">
<Form.Label>
<FormattedMessage id="cover_image" />
</Form.Label>
{cover}
</Form.Group>
</Col>
</Row>
</Form>

View file

@ -206,6 +206,21 @@ $galleryTabWidth: 450px;
}
}
.gallery-cover {
aspect-ratio: 4 / 3;
display: block;
height: auto;
width: 100%;
}
.gallery-cover img {
height: auto;
max-height: 100%;
max-width: 100%;
object-fit: contain;
width: auto;
}
div.GalleryWall {
display: flex;
flex-wrap: wrap;

View file

@ -1613,17 +1613,30 @@ export const mutateAddGalleryImages = (input: GQL.GalleryAddInput) =>
},
});
function evictCover(cache: ApolloCache<GQL.Gallery>, gallery_id: string) {
const fields: Pick<Modifiers<GQL.Gallery>, "paths" | "cover"> = {};
fields.paths = (paths) => {
if (!("cover" in paths)) {
return paths;
}
const coverUrl = new URL(paths.cover);
coverUrl.search = "?t=" + Math.floor(Date.now() / 1000);
return { ...paths, cover: coverUrl.toString() };
};
fields.cover = (_value, { DELETE }) => DELETE;
cache.modify({
id: cache.identify({ __typename: "Gallery", id: gallery_id }),
fields,
});
}
export const mutateSetGalleryCover = (input: GQL.GallerySetCoverInput) =>
client.mutate<GQL.SetGalleryCoverMutation>({
mutation: GQL.SetGalleryCoverDocument,
variables: input,
update(cache, result) {
if (!result.data?.setGalleryCover) return;
cache.evict({
id: cache.identify({ __typename: "Gallery", id: input.gallery_id }),
fieldName: "cover",
});
evictCover(cache, input.gallery_id);
},
});
@ -1633,11 +1646,7 @@ export const mutateResetGalleryCover = (input: GQL.GalleryResetCoverInput) =>
variables: input,
update(cache, result) {
if (!result.data?.resetGalleryCover) return;
cache.evict({
id: cache.identify({ __typename: "Gallery", id: input.gallery_id }),
fieldName: "cover",
});
evictCover(cache, input.gallery_id);
},
});

View file

@ -13,6 +13,8 @@ For best results, images in zip file should be stored without compression (copy,
If a filename of an image in the gallery zip file ends with `cover.jpg`, it will be treated like a cover and presented first in the gallery view page and as a gallery cover in the gallery list view. If more than one images match the name the first one found in natural sort order is selected.
You can also manually select any image from a gallery as its cover. On the gallery details page, select the desired cover image, and then select **Set as Cover** in the ⋯ menu.
## Image clips/gifs
Images can also be clips/gifs. These are meant to be short video loops. Right now they are not possible in zipfiles. To declare video files to be images, there are two ways: