2021-10-26 22:15:01 +02:00
|
|
|
<script>
|
2021-11-23 23:45:42 +01:00
|
|
|
import { createEventDispatcher } from "svelte";
|
2021-10-26 22:15:01 +02:00
|
|
|
|
|
|
|
let dispatch = createEventDispatcher()
|
|
|
|
|
|
|
|
export let files = []
|
2021-12-13 16:33:23 +01:00
|
|
|
export let shuffle = false
|
2021-10-26 22:15:01 +02:00
|
|
|
let file_list_div
|
|
|
|
let selected_file_index = 0
|
|
|
|
|
|
|
|
export const next = () => {
|
|
|
|
if (shuffle) {
|
|
|
|
rand_item()
|
2021-12-28 13:56:24 +01:00
|
|
|
} else {
|
|
|
|
dispatch("set_file", selected_file_index+1)
|
2021-10-26 22:15:01 +02:00
|
|
|
}
|
2021-11-23 23:45:42 +01:00
|
|
|
}
|
|
|
|
export const prev = () => {
|
2021-12-28 13:56:24 +01:00
|
|
|
dispatch("set_file", selected_file_index-1)
|
2021-10-26 22:15:01 +02:00
|
|
|
}
|
2022-03-30 19:35:26 +02:00
|
|
|
export const toggle_gallery = () => {
|
|
|
|
dispatch("toggle_gallery")
|
|
|
|
}
|
2021-10-26 22:15:01 +02:00
|
|
|
|
|
|
|
let history = []
|
|
|
|
export const rand_item = () => {
|
|
|
|
// Avoid viewing the same file multiple times
|
|
|
|
let rand
|
|
|
|
do {
|
2021-12-13 16:33:23 +01:00
|
|
|
rand = Math.floor(Math.random() * files.length)
|
2021-10-26 22:15:01 +02:00
|
|
|
console.log("rand is " + rand)
|
|
|
|
} while(history.indexOf(rand) > -1)
|
|
|
|
|
2021-12-28 13:56:24 +01:00
|
|
|
dispatch("set_file", rand)
|
2021-12-13 16:33:23 +01:00
|
|
|
}
|
2021-10-26 22:15:01 +02:00
|
|
|
|
|
|
|
export const set_item = idx => {
|
|
|
|
// Remove the class from the previous selected file
|
|
|
|
selected_file_index = idx
|
2021-11-23 23:45:42 +01:00
|
|
|
files.forEach((f, i) => {
|
|
|
|
f.selected = selected_file_index === i
|
|
|
|
})
|
|
|
|
files = files
|
2021-10-26 22:15:01 +02:00
|
|
|
|
|
|
|
// Add item to history
|
|
|
|
if(history.length >= (files.length - 6)){
|
|
|
|
history.shift()
|
|
|
|
}
|
|
|
|
history.push(idx)
|
|
|
|
|
|
|
|
// Smoothly scroll the navigator to the correct element
|
|
|
|
let selected_file = file_list_div.children[idx]
|
|
|
|
let cst = window.getComputedStyle(selected_file)
|
|
|
|
let itemWidth = selected_file.offsetWidth + parseInt(cst.marginLeft) + parseInt(cst.marginRight)
|
|
|
|
|
|
|
|
let start = file_list_div.scrollLeft
|
|
|
|
let end = ((idx * itemWidth) + (itemWidth / 2)) - (file_list_div.clientWidth / 2)
|
2021-11-28 15:19:00 +01:00
|
|
|
let steps = 30 // One second
|
2021-10-26 22:15:01 +02:00
|
|
|
let stepSize = (end - start)/steps
|
|
|
|
|
|
|
|
let animateScroll = (pos, step) => {
|
|
|
|
file_list_div.scrollLeft = pos
|
|
|
|
|
|
|
|
if (step < steps) {
|
|
|
|
requestAnimationFrame(() => {
|
|
|
|
animateScroll(pos+stepSize, step+1)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
animateScroll(start, 0)
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
2021-11-28 15:19:00 +01:00
|
|
|
<div class="nav_container">
|
2022-03-30 19:35:26 +02:00
|
|
|
<button class="nav_button" on:click={toggle_gallery} title="Opens a gallery view of the album">
|
|
|
|
<i class="icon">photo_library</i><br/>
|
|
|
|
Gallery
|
2021-11-28 15:19:00 +01:00
|
|
|
</button>
|
|
|
|
<div bind:this={file_list_div} class="list_navigator">
|
2021-12-28 13:56:24 +01:00
|
|
|
{#each files as file, index (file)}
|
|
|
|
<a
|
|
|
|
href="#item={index}"
|
2021-12-28 17:04:00 +01:00
|
|
|
title="Open {file.name}"
|
2022-06-21 14:00:03 +02:00
|
|
|
class="file_button"
|
2022-05-13 17:43:10 +02:00
|
|
|
class:file_selected={file.selected}>
|
2022-06-21 14:00:03 +02:00
|
|
|
<img src={file.icon_href+"?width=64&height=64"} alt={file.name} class="list_item_thumbnail" loading="lazy"/>
|
2021-11-28 15:19:00 +01:00
|
|
|
{file.name}
|
2021-12-28 13:56:24 +01:00
|
|
|
</a>
|
2021-11-28 15:19:00 +01:00
|
|
|
{/each}
|
|
|
|
</div>
|
2021-10-26 22:15:01 +02:00
|
|
|
</div>
|
|
|
|
|
|
|
|
<style>
|
2021-11-28 15:19:00 +01:00
|
|
|
.nav_container{
|
2021-10-26 22:15:01 +02:00
|
|
|
flex-grow: 0;
|
|
|
|
flex-shrink: 0;
|
2021-11-28 15:19:00 +01:00
|
|
|
display: flex;
|
2021-10-26 22:15:01 +02:00
|
|
|
position: relative;
|
|
|
|
width: 100%;
|
2022-06-21 14:00:03 +02:00
|
|
|
border-top: 2px solid var(--separator);
|
2021-10-26 22:15:01 +02:00
|
|
|
text-align: center;
|
|
|
|
line-height: 1em;
|
2021-11-28 15:19:00 +01:00
|
|
|
|
|
|
|
}
|
|
|
|
.nav_button{
|
|
|
|
flex-grow: 0;
|
|
|
|
flex-shrink: 0;
|
2022-06-21 14:00:03 +02:00
|
|
|
margin: 6px;
|
2021-11-28 15:19:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
.list_navigator {
|
|
|
|
flex-grow: 1;
|
|
|
|
flex-shrink: 1;
|
2021-10-26 22:15:01 +02:00
|
|
|
overflow-x: auto;
|
|
|
|
overflow-y: hidden;
|
|
|
|
white-space: nowrap;
|
|
|
|
}
|
2022-05-13 17:43:10 +02:00
|
|
|
|
2022-06-21 14:00:03 +02:00
|
|
|
.file_button {
|
|
|
|
position: relative;
|
|
|
|
height: 50px;
|
|
|
|
width: 220px;
|
|
|
|
margin: 6px;
|
|
|
|
padding: 0;
|
|
|
|
overflow: hidden;
|
|
|
|
border-radius: 6px;
|
|
|
|
background: var(--input_background);
|
|
|
|
color: var(--body_text_color);
|
|
|
|
word-break: break-all;
|
|
|
|
text-align: left;
|
|
|
|
line-height: 1.2em;
|
|
|
|
display: inline-block;
|
|
|
|
transition: background 0.2s;
|
|
|
|
white-space: normal;
|
|
|
|
text-decoration: none;
|
|
|
|
vertical-align: top;
|
|
|
|
cursor: pointer;
|
|
|
|
border-width: 2px;
|
|
|
|
border-style: solid;
|
|
|
|
border-color: var(--input_background);
|
|
|
|
}
|
|
|
|
|
|
|
|
.file_button:hover {
|
|
|
|
text-decoration: none;
|
|
|
|
background: var(--input_hover_background);
|
|
|
|
}
|
|
|
|
|
|
|
|
.file_button>img {
|
|
|
|
height: 100%;
|
|
|
|
margin-right: 5px;
|
|
|
|
float: left;
|
|
|
|
display: block;
|
|
|
|
}
|
2022-05-13 17:43:10 +02:00
|
|
|
.file_selected {
|
|
|
|
text-decoration: none;
|
2022-06-21 14:00:03 +02:00
|
|
|
border-color: var(--highlight_color);
|
2022-05-13 17:43:10 +02:00
|
|
|
}
|
2021-10-26 22:15:01 +02:00
|
|
|
</style>
|