From 298fed011d829dd7efdd878592c1647527c99c90 Mon Sep 17 00:00:00 2001 From: Balakrishnan Balasubramanian Date: Wed, 7 Aug 2024 18:07:41 -0400 Subject: [PATCH] Implement photo selector --- go.mod | 2 +- main.go | 34 ++++++++++++++++++++++++++-- web/choose.css | 47 +++++++++++++++++++++++++++++++++++++++ web/choose.html | 34 +++++++++++++++++++--------- web/choose.js | 59 ++++++++++++++++++++++++++++++++++++++++++++++--- 5 files changed, 160 insertions(+), 16 deletions(-) create mode 100644 web/choose.css diff --git a/go.mod b/go.mod index 8f385f8..851d87a 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module go.balki.me/collage-maker -go 1.21 +go 1.22 require ( go.balki.me/anyhttp v0.3.0 diff --git a/main.go b/main.go index 9ef1420..24b2bdb 100644 --- a/main.go +++ b/main.go @@ -58,8 +58,6 @@ func main() { } return photoPrismURL }() - copy := *photoPrismURL - fmt.Println(copy) collageNameGen = NewNameGen() imagesDirFs = os.DirFS(imagesDir) imagesURLPath := "images" @@ -147,6 +145,38 @@ func main() { w.Header().Set("Content-Type", "application/json") w.Write(jData) }) + + http.HandleFunc("/load-photos/{albumID}", func(w http.ResponseWriter, r *http.Request) { + albumID := r.PathValue("albumID") + photos, err := LoadPhotos(albumID) + if err != nil { + slog.Error("failed to load photos", "error", err, "album", albumID) + w.WriteHeader(http.StatusInternalServerError) + return + } + photoURLs := []string{} + for _, photo := range photos { + photoURLs = append(photoURLs, fmt.Sprintf("/%s/%s.jpg", photosPath, photo.FileUID)) + } + go func() { + for _, photo := range photos { + _, err := DownloadPhoto(&photo) + if err != nil { + slog.Error("failed to download photo", "error", err, "album", albumID, "photoID", photo.FileUID) + } + } + }() + + jData, err := json.Marshal(photoURLs) + if err != nil { + slog.Error("failed to marshal photoURLs", "error", err) + w.WriteHeader(http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.Write(jData) + }) + addrType, server, done, err := anyhttp.Serve(listenAddr, idle.WrapHandler(nil)) if err != nil { slog.Error("anyhttp Serve failed", "error", err) diff --git a/web/choose.css b/web/choose.css new file mode 100644 index 0000000..5e09e58 --- /dev/null +++ b/web/choose.css @@ -0,0 +1,47 @@ +#album_photos { + display: flex; + gap: 1rem; + flex-wrap: wrap; + background-color: lightblue; + padding: 1rem; +} + +#album_photos img { + width: 200px; + height: 200px; +} + +#selected_photos { + display: flex; + gap: 1rem; + flex-wrap: wrap; + background-color: lightyellow; + padding: 1rem; +} + +#selected_photos img { + width: 100px; + height: 100px; +} + +.container { + display: flex; + flex-direction: column; + gap: 1rem; +} + +.controls { + background-color: lightgrey; + display: flex; + gap: 1rem; + padding: 1rem; +} + +#album_selector { + width: 400px; +} + +.current { + border: 5px solid; + border-color: red; +} diff --git a/web/choose.html b/web/choose.html index 8be1e6e..48d3b0b 100644 --- a/web/choose.html +++ b/web/choose.html @@ -4,20 +4,34 @@ + - +

-
- - - -
+
+
+
+ + + +
+
+
1
+
2
+
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+
11
+
12
+
+
diff --git a/web/choose.js b/web/choose.js index 3216a04..6b38320 100644 --- a/web/choose.js +++ b/web/choose.js @@ -17,14 +17,38 @@ let noticeP /** @type {HTMLDialogElement} */ let noticeDialog +/** @type {HTMLDivElement} */ +let albumPhotosDiv + +/** @type {HTMLDivElement} */ +let selectedPhotosDiv + +/** @type {HTMLImageElement} */ +let selectedPhotoImg + function main() { albumSelect = document.getElementById("album_selector") loadAlbumsBtn = document.getElementById("load_albums_button") loadPhotosBtn = document.getElementById("load_photos_button") noticeDialog = document.getElementById("notice_dialog") + albumPhotosDiv = document.getElementById("album_photos") + selectedPhotosDiv = document.getElementById("selected_photos") noticeP = document.getElementById("notice_p") loadAlbumsBtn.onclick = () => loadAlbums() loadPhotosBtn.onclick = () => loadPhotos() + + /** + * @type HTMLImageElement[] + */ + const selectedPhotos = selectedPhotosDiv.getElementsByTagName("img") + for (const img of selectedPhotos) { + img.onclick = () => { + selectedPhotoImg?.classList.remove("current") + selectedPhotoImg = img + selectedPhotoImg.classList.add("current") + } + } + selectedPhotos[0].click() } function loadAlbums() { @@ -67,9 +91,38 @@ function loadPhotos() { return } const [elem] = selected - console.log(elem) - console.log(elem.text) - console.log(elem.value) + + (async () => { + try { + const resp = await fetch(`load-photos/${elem.value}`) + /** + * @type String[] + */ + const photos = await resp.json() + if(photos.length == 0) { + showNotice("No Photos found") + return + } + albumPhotosDiv.replaceChildren() + for(const url of photos) { + const img = new Image() + img.src = url + albumPhotosDiv.appendChild(img) + } + + /** + * @type HTMLImageElement[] + */ + const photoImgs = albumPhotosDiv.children + for(const photo of photoImgs) { + photo.onclick = () => { + selectedPhotoImg.src = photo.src + } + } + } catch(e) { + console.log(e) + } + })(); }