summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/albums.js16
-rw-r--r--src/connector.js19
-rw-r--r--src/icons.js7
-rw-r--r--src/icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg1
-rw-r--r--src/icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg1
-rw-r--r--src/icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg1
-rwxr-xr-xsrc/icons/removefill.sh3
-rw-r--r--src/icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg1
-rw-r--r--src/icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg1
-rw-r--r--src/index.js2
-rw-r--r--src/slides.js37
-rw-r--r--src/style.css97
12 files changed, 161 insertions, 25 deletions
diff --git a/src/albums.js b/src/albums.js
index e10dd54..19602df 100644
--- a/src/albums.js
+++ b/src/albums.js
@@ -8,7 +8,8 @@ export default async function initAlbums(albumsPageContainer) {
async function createAlbum(res) {
console.log(res.albumName, res.id, res.startDate, res.endDate, res.assetCount, res.shared)
const albumClone = albumTemplate.content.cloneNode(true)
- albumClone.querySelector(".album-thumb").src = apiConnector.albumThumbSrc(res.albumThumbnailAssetId)
+ albumClone.querySelector(".album").dataset.key = res.id
+ albumClone.querySelector(".album-thumb").src = apiConnector.assetThumbnailSrc(res.albumThumbnailAssetId)
albumClone.querySelector(".album-name").textContent = res.albumName
albumClone.querySelector(".album-assets-count").textContent = res.assetCount.toLocaleString()
if (!res.shared)
@@ -22,5 +23,18 @@ export default async function initAlbums(albumsPageContainer) {
for (const res of albumsResponse)
createAlbum(res)
+ albumsContainer.addEventListener("click", e => {
+ // find album element
+ let album = e.target
+ while (album && !album.classList.contains("album"))
+ album = album.parentElement
+
+ if (album === null)
+ return
+
+ console.log(album)
+ album.classList.toggle("selected")
+ })
+
return true
}
diff --git a/src/connector.js b/src/connector.js
index 6c557a8..03e6f3d 100644
--- a/src/connector.js
+++ b/src/connector.js
@@ -6,16 +6,14 @@ class APIConnector {
this.socket = io(url)
this.asset_index = 0
- this.asset = null
- this.prevAssets = null
- this.nextAssets = null
+ this.movement = 0
+ this.assets = null
this.seekCallbacks = []
this.socket.on("seek", e => {
- this.asset_index = e.asset_index
- this.asset = e.asset
- this.prevAssets = e.prev_assets
- this.nextAssets = e.next_assets
+ this.assetIndex = e.asset_index
+ this.movement = e.movement
+ this.assets = e.assets
for (const cb of this.seekCallbacks)
cb()
})
@@ -46,12 +44,11 @@ class APIConnector {
}
fetchAlbums() {
- return this.fetch("/albums/get")
+ return this.fetch("/albums")
}
- albumThumbSrc(key) {
- return `${this.url}/api/albums/thumb/${key}`
- }
+ assetSrc(key) { return `${this.url}/api/asset/${key}` }
+ assetThumbnailSrc(key) { return `${this.url}/api/asset/${key}/thumbnail` }
}
const apiConnector = new APIConnector("http://localhost:5000")
diff --git a/src/icons.js b/src/icons.js
index dd75a4a..099db45 100644
--- a/src/icons.js
+++ b/src/icons.js
@@ -1,11 +1,16 @@
+import "./icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg"
+import "./icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg"
import "./icons/download_24dp_FFFFFF_FILL0_wght400_GRAD0_opsz24.svg"
import "./icons/image_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg"
+import "./icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg"
import "./icons/pause_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg"
import "./icons/photo_album_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg"
import "./icons/photo_frame_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg"
import "./icons/play_arrow_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg"
-import "./icons/share_24dp_FFFFFF_FILL0_wght400_GRAD0_opsz24.svg"
+import "./icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg"
+import "./icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg"
import "./icons/settings_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg"
+import "./icons/share_24dp_FFFFFF_FILL0_wght400_GRAD0_opsz24.svg"
import "./icons/skip_next_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg"
import "./icons/skip_previous_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg"
import "./icons/slideshow_24dp_FFFFFF_FILL1_wght400_GRAD0_opsz24.svg"
diff --git a/src/icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg b/src/icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg
new file mode 100644
index 0000000..028526b
--- /dev/null
+++ b/src/icons/check_circle_24dp_E3E3E3_FILL1_wght400_GRAD0_opsz24.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="m424-296 282-282-56-56-226 226-114-114-56 56 170 170Zm56 216q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Z"/></svg> \ No newline at end of file
diff --git a/src/icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg b/src/icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg
new file mode 100644
index 0000000..dd46e14
--- /dev/null
+++ b/src/icons/deselect_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M791-56 567-280H280v-287L56-791l56-57 736 736-57 56ZM360-360h127L360-487v127Zm320-33-80-80v-127H473l-80-80h287v287ZM200-200v80q-33 0-56.5-23.5T120-200h80Zm-80-80v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160v-80h80v80h-80Zm160 480v-80h80v80h-80Zm0-640v-80h80v80h-80Zm160 640v-80h80v80h-80Zm0-640v-80h80v80h-80Zm160 640v-80h80v80h-80Zm0-640v-80h80v80h-80Zm160 480v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160v-80q33 0 56.5 23.5T840-760h-80Z"/></svg> \ No newline at end of file
diff --git a/src/icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg b/src/icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg
new file mode 100644
index 0000000..12e0802
--- /dev/null
+++ b/src/icons/open_in_new_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h280v80H200v560h560v-280h80v280q0 33-23.5 56.5T760-120H200Zm188-212-56-56 372-372H560v-80h280v280h-80v-144L388-332Z"/></svg> \ No newline at end of file
diff --git a/src/icons/removefill.sh b/src/icons/removefill.sh
index c61fd98..399e8e4 100755
--- a/src/icons/removefill.sh
+++ b/src/icons/removefill.sh
@@ -1,3 +1,6 @@
#!/bin/sh
# Google Material Icons -- complete default settings
sed -Ei 's/ ?fill="#[0-9a-fA-F]{6}"//' *.svg
+for svg in *.svg; do
+ echo "import \"./icons/$svg\""
+done
diff --git a/src/icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg b/src/icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg
new file mode 100644
index 0000000..1d95298
--- /dev/null
+++ b/src/icons/search_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M784-120 532-372q-30 24-69 38t-83 14q-109 0-184.5-75.5T120-580q0-109 75.5-184.5T380-840q109 0 184.5 75.5T640-580q0 44-14 83t-38 69l252 252-56 56ZM380-400q75 0 127.5-52.5T560-580q0-75-52.5-127.5T380-760q-75 0-127.5 52.5T200-580q0 75 52.5 127.5T380-400Z"/></svg> \ No newline at end of file
diff --git a/src/icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg b/src/icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg
new file mode 100644
index 0000000..3a6618e
--- /dev/null
+++ b/src/icons/select_all_24dp_E3E3E3_FILL0_wght400_GRAD0_opsz24.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 -960 960 960" width="24px"><path d="M280-280v-400h400v400H280Zm80-80h240v-240H360v240ZM200-200v80q-33 0-56.5-23.5T120-200h80Zm-80-80v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160v-80h80v80h-80Zm80-160h-80q0-33 23.5-56.5T200-840v80Zm80 640v-80h80v80h-80Zm0-640v-80h80v80h-80Zm160 640v-80h80v80h-80Zm0-640v-80h80v80h-80Zm160 640v-80h80v80h-80Zm0-640v-80h80v80h-80Zm160 640v-80h80q0 33-23.5 56.5T760-120Zm0-160v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160v-80h80v80h-80Zm0-160v-80q33 0 56.5 23.5T840-760h-80Z"/></svg> \ No newline at end of file
diff --git a/src/index.js b/src/index.js
index a6d2130..d27c8db 100644
--- a/src/index.js
+++ b/src/index.js
@@ -20,7 +20,7 @@ function softRedirect(e) {
e.preventDefault()
let a = e.target
if (a === null) return
- while (a.tagName !== "A" && a !== null)
+ while (a !== null && a.tagName !== "A")
a = a.parentElement
if (a === null) return
Page.softRedirect(a.href)
diff --git a/src/slides.js b/src/slides.js
index 94af74e..fad6472 100644
--- a/src/slides.js
+++ b/src/slides.js
@@ -6,11 +6,19 @@ class Slides {
constructor(slidesContainer) {
/* previous selected index */
this.selectedIndex = 0
+ this.assetIndex = 0
this.slidesContainer = slidesContainer
+ /* append 11 cells to carousel */
+ const carousel = this.slidesContainer.querySelector("#slideshow-carousel")
+ const cellTemplate = this.slidesContainer.querySelector("#carousel-cell-template")
+ this.cells = []
+ for (let i = 0; i < 11; i++)
+ carousel.appendChild(cellTemplate.content.cloneNode(true))
+
/* initialize slides */
- this.flickity = new Flickity("#slideshow-carousel", {
+ this.flickity = new Flickity(carousel, {
wrapAround: true,
prevNextButtons: false,
pageDots: false,
@@ -29,6 +37,9 @@ class Slides {
seekPrevButton.addEventListener("click", () => { this.flickity.previous() ; this.seek() })
seekNextButton.addEventListener("click", () => { this.flickity.next() ; this.seek() })
+
+ /* initialize seek callback */
+ apiConnector.seekCallbacks.push(c => { this.seekCallback() })
}
seek() {
@@ -40,9 +51,31 @@ class Slides {
this.flickity.cells.length - this.selectedIndex, // wrap forwards (-1 -> 0)
].reduce((key, v) => Math.abs(v) < Math.abs(key) ? v : key)
this.selectedIndex = this.flickity.selectedIndex
+ this.assetIndex += increment
apiConnector.seek(increment)
}
+ seekCallback() {
+ let i
+ if (this.assetIndex !== apiConnector.assetIndex) {
+ this.assetIndex = apiConnector.assetIndex
+ i = apiConnector.movement
+
+ for (; i > 0; i--) this.flickity.next()
+ for (; i < 0; i++) this.flickity.previous()
+ this.selectedIndex = this.flickity.selectedIndex
+ }
+
+ // load new imgs
+ // TODO need to make the 11 cells a constant somehow
+ for (i = 0; i < this.flickity.cells.length; i++) {
+ const x = (i + this.selectedIndex + 6) % this.flickity.cells.length
+ const e = this.flickity.cells[x].element
+ const img = e.firstElementChild
+ img.src = apiConnector.assetSrc(apiConnector.assets[i])
+ }
+ }
+
/* Flickity function for scrolling to ensure next and prev pics are always
* visible and to transition between states */
scroll(progress) {
@@ -89,7 +122,7 @@ class Slides {
for (let i = 0; i < imgs.length; i++) {
const img = imgs[i]
img.dataset.index = i
- img.addEventListener("load", this.imageLoaded)
+ img.addEventListener("load", e => { this.imageLoaded(e) })
if (img.complete)
this.positionImageStatic(img)
}
diff --git a/src/style.css b/src/style.css
index e84921e..f370f2c 100644
--- a/src/style.css
+++ b/src/style.css
@@ -1,11 +1,21 @@
+@import "tailwindcss" source(none);
+@source "../public/*.html";
+
:root {
--immich-dark-primary: rgb(172 203 250);
+ --immich-dark-secondary: rgb(33 33 33);
+ --immich-dark-secondary-border: rgb(33 33 33 / .1);
+ --selected-bg: rgb(172 203 250 / .1);
+ --selected-border: rgb(172 203 250 / .1);
+ --immich-dark-hover-bg: rgb(17 24 39);
+ --immich-dark-hover-border: rgb(31 41 55);
}
.font-bold { font-weight: 700 }
body {
background: black;
+ color-scheme: dark;
color: white;
height: 100vh;
max-height: 100vh;
@@ -13,18 +23,25 @@ body {
flex-direction: column;
margin: 0;
font-family: "Overpass", sans-serif;
+ overflow: hidden;
}
main, #slideshow {
height: 100%;
display: flex;
flex-direction: column;
+ overflow: hidden;
}
svg {
fill: white;
width: 100%;
height: 100%;
+
+ &.p24 {
+ width: 24px;
+ height: 24px;
+ }
}
/* slideshow */
@@ -35,10 +52,7 @@ svg {
.carousel-cell {
height: 100%;
width: 80vw;
-
margin: 24px;
-
-
}
.carousel-cell img {
@@ -86,26 +100,91 @@ svg {
/* albums */
#albums {
- width: 100%;
height: 100%;
overflow: scroll;
+ margin-inline: 1rem;
+}
+#album-search {
+ display: block;
+ padding: 1rem;
+ border-radius: 1rem;
+ border: 0;
+ margin: 1rem auto;
+ width: 100%;
+ max-width: 768px;
+ background-color: var(--immich-dark-secondary);
+ font-family: "Overpass", sans-serif;
+
+ &:focus { outline: 2px solid rgb(55, 65, 81) }
}
#albums-container {
display: grid;
- grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
- gap: 2.5rem;
- max-width: 1366px;
+ grid-template-columns: repeat(auto-fill, minmax(768px, 1fr));
+ width: max-content;
margin: auto;
padding: 2rem;
+ .album {
+ position: relative;
+ display: flex;
+ height: 10rem;
+ gap: 1.5em;
+ padding: 1rem;
+ border: 1px solid transparent;
+ border-bottom: 1px solid var(--selected-border);
+ border-top: 1px solid var(--selected-border);
+ /*border-bottom: 1px solid var(--immich-dark-hover-border);*/
+
+ .album-selector {
+ opacity: 0;
+ border-radius: 50%;
+ align-self: center
+ }
+
+ &.selected {
+ background: var(--selected-bg);
+ }
+
+ &:hover {
+ cursor: pointer;
+ background: var(--immich-dark-hover-bg);
+ border: 1px solid var(--immich-dark-hover-border);
+
+ .album-selector { opacity: .5 }
+ .album-thumb {
+ box-shadow: rgba(0, 0, 0, 0.1) 0px 10px 15px -3px, rgba(0, 0, 0, 0.1) 0px 4px 6px -4px;
+ }
+ .album-name { color: var(--immich-dark-primary) }
+ .album-open { opacity: 1 }
+ }
+
+
+ &.selected .album-selector {
+ opacity: 1;
+ fill: var(--immich-dark-primary);
+ background: black;
+ }
+ }
+
.album-thumb {
- width: 100%;
aspect-ratio: 1/1;
object-fit: cover;
border-radius: 1rem;
- margin-bottom: 1rem;
}
+ .album-desc-grid {
+ display: flex;
+ justify-content: space-between;
+ align-self: center;
+ font-size: 18px;
+ }
+
+ .album-open {
+ position: absolute;
+ bottom: 1rem;
+ right: 1rem;
+ opacity: 0;
+ }
}
@media (max-width: 512px) {