Skip to content

Commit

Permalink
improve lightbox
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffreybakker committed Aug 5, 2024
1 parent 8b84af5 commit 9e692e2
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 24 deletions.
Binary file removed projects/kick-in/public/favicon.ico
Binary file not shown.
Binary file added projects/kick-in/public/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions projects/kick-in/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
8 changes: 4 additions & 4 deletions projects/kick-in/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>KickIn</title>
<title>Kick-In Media</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="icon" href="/favicon.png">
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">

<!-- TODO: Pre-connect to image CDN -->
<!-- <link rel="preconnect" href="" />-->
<!-- Pre-connect to image CDN -->
<link rel="preconnect" href="https://photos.dev.kick-in.media/" />
</head>
<body>
<app-root></app-root>
Expand Down
18 changes: 9 additions & 9 deletions src/app/album/album-page.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,6 @@ export class AlbumPageComponent {
protected overlay: Overlay,
protected albumService: AlbumService,
) {
// Open lightbox whenever the `lightbox` query param appears in the URL
activatedRoute.queryParamMap.pipe(
map(params => params.get("lightbox")),
startWith(null),
pairwise(),
).subscribe(([prev, next]) => {
if (next && !prev) this.openLightbox(next);
});

this.breadcrumb$ = this.albumService.album.data$.pipe(
map(album => {
return [
Expand All @@ -76,6 +67,15 @@ export class AlbumPageComponent {
this.photos$ = albumService.album.data$.pipe(
map(album => album ? album.photos : null),
);

// Open lightbox whenever the `lightbox` query param appears in the URL
activatedRoute.queryParamMap.pipe(
map(params => params.get("lightbox")),
startWith(null),
pairwise(),
).subscribe(([prev, next]) => {
if (next && !prev) this.openLightbox(next);
});
}

editAlbum() {
Expand Down
8 changes: 1 addition & 7 deletions src/app/event/event-page.component.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,5 @@
<title-section
[breadcrumb]="[
{ title: 'Events', url: '/event' },
{
title: (eventService.event.data$ | async)!.name,
url: '/event/' + (eventService.id$ | async) + '/' + ((eventService.event.data$ | async)!.name | slug)
},
]"
[breadcrumb]="breadcrumb$ | async"
[title]="(eventService.event.data$ | async)?.name"
>
<button mat-stroked-button (click)="createAlbum()">
Expand Down
16 changes: 15 additions & 1 deletion src/app/event/event-page.component.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component } from '@angular/core';
import { MatButtonModule } from "@angular/material/button";
import { MatIconModule } from "@angular/material/icon";
import { TitleSectionComponent } from "../components/title-section/title-section.component";
import { Breadcrumb, TitleSectionComponent } from "../components/title-section/title-section.component";
import { EventService } from "../../services/api/event.service";
import { AsyncPipe, NgForOf, NgIf } from "@angular/common";
import { MatMenuModule } from "@angular/material/menu";
Expand Down Expand Up @@ -38,6 +38,8 @@ import slugify from "slugify";
})
export class EventPageComponent {

protected breadcrumb$: Observable<Breadcrumb[] | undefined>;

// Yields albums indexed by date-strings or ""
protected albums$: Observable<{ [key: string]: Album[] }>;

Expand All @@ -47,6 +49,18 @@ export class EventPageComponent {
protected configService: ConfigService,
protected eventService: EventService,
) {
this.breadcrumb$ = this.eventService.event.data$.pipe(
map(event => {
return [
{ title: 'Events', url: '/event' },
{
title: event?.name,
url: event ? `/event/${event.id}/${slugify(event.name)}` : undefined
},
];
}),
);

this.albums$ = this.eventService.albums.data$.pipe(
map((albums: Album[]) => albums.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime())),
map((albums: Album[]) => groupBy(albums, configService.config.albums.groupIndex)),
Expand Down
43 changes: 42 additions & 1 deletion src/app/lightbox/lightbox.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,46 @@
</mat-toolbar>

<div class="content">
<p>lightbox works!</p>
<!-- Go through photo album... -->
<button
*ngIf="photos && index > 0"
mat-icon-button
class="previous"
(click)="go(-1)"
>
<mat-icon>chevron_left</mat-icon>
</button>
<button
*ngIf="photos && index < photos.length - 1"
mat-icon-button
class="next"
(click)="go(1)"
>
<mat-icon>chevron_right</mat-icon>
</button>

<!-- Current image -->
<!--suppress AngularNgOptimizedImage -->
<img
*ngIf="photo"
class="current mat-elevation-z8"
[src]="getPhotoSrc(photo)"
loading="eager"
/>

<!-- Preload previous and next images -->
<!--suppress AngularNgOptimizedImage -->
<img
*ngIf="photos && index >= 1"
class="preview"
[src]="getPhotoSrc(photos[index-1])"
loading="eager"
/>
<!--suppress AngularNgOptimizedImage -->
<img
*ngIf="photos && index < photos.length - 1"
class="preview"
[src]="getPhotoSrc(photos[index+1])"
loading="eager"
/>
</div>
45 changes: 44 additions & 1 deletion src/app/lightbox/lightbox.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
}

mat-toolbar {
flex-shrink: 0;
padding: 0 1rem;

display: flex;
Expand All @@ -22,7 +23,7 @@ mat-toolbar {
border-bottom: 1px solid rgba(0, 0, 0, 0.25);
filter: drop-shadow(1px 1px 1px black);

button, mat-chip, mat-chip mat-icon {
> button, mat-chip mat-icon {
color: white;
}

Expand All @@ -40,4 +41,46 @@ mat-toolbar {

div.content {
flex-grow: 1;
flex-shrink: 1;

position: relative;
}

div.content img.current {
max-width: calc(100% - 2rem);
max-height: calc(100% - 2rem);

position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);

background: rgba(255, 255, 255, 0.1);
}

div.content img.preview {
width: 0;
height: 0;
display: none;
}

div.content button[mat-icon-button] {
position: absolute;
top: 50%;
transform: translateY(-50%);

color: white;
background: rgba(255, 255, 255, 0.05);

&:hover {
background: rgba(255, 255, 255, 0.1);
}

&.previous {
left: 1rem;
}

&.next {
right: 1rem;
}
}
36 changes: 35 additions & 1 deletion src/app/lightbox/lightbox.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import { Component } from '@angular/core';

import { PhotoService } from "../../services/api/photo.service";
import { MatToolbar } from "@angular/material/toolbar";
import { Observable } from "rxjs";
import { filter, first, Observable } from "rxjs";
import { Photo } from "../../util/types";
import { MatIcon } from "@angular/material/icon";
import { MatIconButton } from "@angular/material/button";
import { MatTooltip } from "@angular/material/tooltip";
import { MatChipsModule } from "@angular/material/chips";
import { NgIf } from "@angular/common";
import { ImageQualityService } from "../../services/image-quality.service";

@Component({
selector: 'lightbox',
Expand All @@ -18,6 +20,7 @@ import { MatChipsModule } from "@angular/material/chips";
MatIconButton,
MatTooltip,
MatChipsModule,
NgIf,
],
templateUrl: './lightbox.component.html',
styleUrl: './lightbox.component.scss'
Expand All @@ -31,18 +34,49 @@ export class LightboxComponent {
protected closeOverlay: (() => void) | null = null;

constructor(
protected imageQualityService: ImageQualityService,
protected photoService: PhotoService,
) {
// If the PhotoService is able to resolve the photo's detailed info before
// the photo array is loaded, then preview it asap
photoService.photo.data$.pipe(
filter(photo => photo !== null),
first(),
).subscribe(photo => {
if (this.photo === null) this.photo = photo;
});
}

onOpen(close: () => void, initialPhotoId: string, photos$: Observable<Photo[] | null>) {
this.closeOverlay = close;
this.photoService.setCurrentPhoto(initialPhotoId);

// Listen to the first result of the `photos$` observable and save it
photos$.pipe(
filter(photos => photos !== null),
first(),
).subscribe(photos => {
this.photos = photos;
});

photos$.subscribe(console.log);
}

go(direction: -1 | 1) {
if (!this.photos) return;

this.index += direction;
this.photo = this.photos[this.index];
this.photoService.setCurrentPhoto(this.photo.id);
}

close() {
if (!this.closeOverlay) return;
this.closeOverlay();
}

protected getPhotoSrc(photo: Photo): string | null {
return photo.img_urls[this.imageQualityService.lightboxQuality];
}

}
1 change: 1 addition & 0 deletions src/services/api/album.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class AlbumService extends BaseService {
this.id$,
id => this.fetchAlbum(id),
null,
true,
);
}

Expand Down
4 changes: 4 additions & 0 deletions src/services/image-quality.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,8 @@ export class ImageQualityService {
return "small";
}

get lightboxQuality(): Exclude<keyof Photo["img_urls"], "original"> {
return "large";
}

}

0 comments on commit 9e692e2

Please sign in to comment.