Implement photo selector
This commit is contained in:
parent
12befa0ac3
commit
298fed011d
2
go.mod
2
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
|
||||
|
34
main.go
34
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)
|
||||
|
47
web/choose.css
Normal file
47
web/choose.css
Normal file
@ -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;
|
||||
}
|
@ -4,20 +4,34 @@
|
||||
<link rel="icon" href="data:;base64,iVBORw0KGgo=" />
|
||||
<!-- DEVONLY --> <script src="http://localhost:35729/livereload.js"></script>
|
||||
<script src="choose.js" defer></script>
|
||||
<link rel="stylesheet" href="choose.css" />
|
||||
</head>
|
||||
<body>
|
||||
<dialog id="notice_dialog">
|
||||
<dialog id="notice_dialog">
|
||||
<p id="notice_p"></p>
|
||||
<form><button type="submit" formmethod="dialog">X</button></form>
|
||||
</dialog>
|
||||
<label>
|
||||
<span>Select Album</span>
|
||||
<select id="album_selector" size="8">
|
||||
</select>
|
||||
</label>
|
||||
<button id="load_albums_button">Load Albums</button>
|
||||
<button id="load_photos_button">Load Photos</button>
|
||||
<div id="selected_photos"></div>
|
||||
</dialog>
|
||||
<div class="container">
|
||||
<div class="controls">
|
||||
<button id="load_albums_button">Load Albums</button>
|
||||
<select id="album_selector" size="8"> </select>
|
||||
<button id="load_photos_button">Load Photos</button>
|
||||
</div>
|
||||
<div id="selected_photos">
|
||||
<div>1<img src="stock.jpg" /> </div>
|
||||
<div>2<img src="stock.jpg" /> </div>
|
||||
<div>3<img src="stock.jpg" /> </div>
|
||||
<div>4<img src="stock.jpg" /> </div>
|
||||
<div>5<img src="stock.jpg" /> </div>
|
||||
<div>6<img src="stock.jpg" /> </div>
|
||||
<div>7<img src="stock.jpg" /> </div>
|
||||
<div>8<img src="stock.jpg" /> </div>
|
||||
<div>9<img src="stock.jpg" /> </div>
|
||||
<div>10<img src="stock.jpg" /> </div>
|
||||
<div>11<img src="stock.jpg" /> </div>
|
||||
<div>12<img src="stock.jpg" /> </div>
|
||||
</div>
|
||||
<div id="album_photos"></div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -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)
|
||||
}
|
||||
})();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user