Convert the whole filesystem UI to Typescript
This commit is contained in:
105
svelte/src/lib/VideoPosition.ts
Normal file
105
svelte/src/lib/VideoPosition.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
|
||||
type VideoPositions = {
|
||||
[key: string]: VideoPosition
|
||||
}
|
||||
|
||||
export type VideoPosition = {
|
||||
time: number
|
||||
pos: number
|
||||
dur: number
|
||||
}
|
||||
|
||||
const storage_key = "video_positions"
|
||||
const expiry_time = 28 * 24 * 60 * 60 * 1000
|
||||
|
||||
let position_cache: VideoPositions | null = null
|
||||
export const get_video_positions = () => {
|
||||
if (position_cache !== null) {
|
||||
return position_cache
|
||||
}
|
||||
|
||||
let video_positions = JSON.parse(window.localStorage.getItem(storage_key)) as VideoPositions
|
||||
if (video_positions === null) {
|
||||
return {} as VideoPositions
|
||||
}
|
||||
return video_positions
|
||||
}
|
||||
|
||||
export const save_video_position = (id: string, position: number, duration: number) => {
|
||||
if (duration < 300) {
|
||||
return // Don't bother saving videos less than 5 minutes long
|
||||
}
|
||||
|
||||
const video_positions = get_video_positions()
|
||||
|
||||
// Add our new entry
|
||||
video_positions[id] = {
|
||||
time: (new Date).getTime(),
|
||||
pos: position,
|
||||
dur: duration,
|
||||
}
|
||||
|
||||
// Remove old entries
|
||||
const expiry_thresh = (new Date).getTime() - expiry_time
|
||||
for (const key in video_positions) {
|
||||
if (video_positions[key].time < expiry_thresh) {
|
||||
delete video_positions[key]
|
||||
console.debug("Delete old video position", key)
|
||||
}
|
||||
}
|
||||
|
||||
// Save updated object
|
||||
window.localStorage.setItem(storage_key, JSON.stringify(video_positions))
|
||||
|
||||
// Update the cache
|
||||
position_cache = video_positions
|
||||
}
|
||||
|
||||
export const get_video_position = (id: string) => {
|
||||
const video_positions = get_video_positions()
|
||||
if (video_positions[id] === undefined) {
|
||||
return null
|
||||
}
|
||||
return video_positions[id]
|
||||
}
|
||||
|
||||
export const video_position = (node: HTMLVideoElement, get_id: () => string) => {
|
||||
let last_time = 0
|
||||
|
||||
const loadeddata = (e: Event) => {
|
||||
last_time = 0
|
||||
|
||||
const vp = get_video_position(get_id())
|
||||
if (vp === null || vp.pos === 0 || vp.dur === 0) {
|
||||
return
|
||||
} else if (vp.pos / vp.dur > 0.95) {
|
||||
// If the video is more than 95% complete we don't do anything
|
||||
console.debug("Video is at end, not setting time")
|
||||
return
|
||||
}
|
||||
|
||||
(e.target as HTMLVideoElement).currentTime = vp.pos
|
||||
last_time = vp.pos
|
||||
}
|
||||
|
||||
const timeupdate = (e: Event) => {
|
||||
const vid = (e.target as HTMLVideoElement)
|
||||
|
||||
// If the current timestamp is more than ten seconds off the last
|
||||
// timestamp we saved, then we save the new timestamp
|
||||
if (Math.abs(vid.currentTime - last_time) > 10) {
|
||||
save_video_position(get_id(), vid.currentTime, vid.duration)
|
||||
last_time = vid.currentTime
|
||||
}
|
||||
}
|
||||
|
||||
node.addEventListener("loadeddata", loadeddata)
|
||||
node.addEventListener("timeupdate", timeupdate)
|
||||
|
||||
return {
|
||||
destroy() {
|
||||
node.removeEventListener("loadeddata", loadeddata)
|
||||
node.removeEventListener("timeupdate", timeupdate)
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user