Files
fnx_web/res/include/script/file_viewer/Viewer.js

257 lines
7.4 KiB
JavaScript
Raw Normal View History

2020-01-28 12:51:21 +01:00
function Viewer(type, viewToken, data) {
2020-01-27 16:56:16 +01:00
// Set defaults
2020-02-04 19:37:46 +01:00
this.toolbar = null
this.listNavigator = null
this.detailsWindow = null
this.divFilepreview = null
this.title = "" // Contains either the file name or list title
this.listId = ""
this.viewToken = ""
this.isList = false
this.isFile = false
this.initialized = false
this.viewToken = viewToken
this.toolbar = new Toolbar(this)
this.detailsWindow = new DetailsWindow(this)
this.divFilepreview = document.getElementById("filepreview")
2020-01-27 16:56:16 +01:00
// On small screens the toolbar takes too much space, so it collapses
// automatically
2020-01-28 12:51:21 +01:00
if (this.divFilepreview.clientWidth > 600 && !this.toolbar.visible) {
2020-02-04 19:37:46 +01:00
this.toolbar.toggle()
2020-01-27 16:56:16 +01:00
}
2020-01-20 19:55:51 +01:00
2020-01-27 16:56:16 +01:00
// The close button only works if the window has an opener. So we hide
// the button if it does not
if (window.opener === null && window.history.length !== 1) {
document.getElementById("button_close_file_viewer").remove()
}
2020-01-20 19:55:51 +01:00
2020-01-27 16:56:16 +01:00
if (type === "file") {
2020-02-04 19:37:46 +01:00
this.isFile = true
this.title = data.name
this.setFile(fileFromAPIResp(data))
2020-01-27 16:56:16 +01:00
} else if (type === "list") {
2020-02-04 19:37:46 +01:00
this.isList = true
this.listId = data.id
this.title = data.title
let files = []
for (let i in data.files) {
files.push(fileFromAPIResp(data.files[i]))
}
this.listNavigator = new ListNavigator(this, files)
} else if (type === "skylink") {
this.isFile = true
this.title = data.name
document.getElementById("btn_details").remove()
document.getElementById("stat_views_label").remove()
document.getElementById("stat_views").remove()
document.getElementById("stat_downloads_label").remove()
document.getElementById("stat_downloads").remove()
let file = fileFromSkyNet(data)
console.log(file)
this.setFile(file)
2020-01-27 16:56:16 +01:00
}
2020-02-04 19:37:46 +01:00
this.renderSponsors()
window.addEventListener("resize", e => { this.renderSponsors(e) })
2020-01-20 19:55:51 +01:00
2020-01-27 16:56:16 +01:00
// Register keyboard shortcuts
2020-02-04 19:37:46 +01:00
document.addEventListener("keydown", e => { this.keyboardEvent(e) })
2020-01-20 19:55:51 +01:00
2020-02-04 19:37:46 +01:00
this.initialized = true
2020-01-27 16:56:16 +01:00
}
2020-01-20 19:55:51 +01:00
2020-01-28 12:51:21 +01:00
Viewer.prototype.setFile = function(file) {
if (this.isList) {
2020-02-04 19:37:46 +01:00
document.getElementById("file_viewer_headerbar_title").style.lineHeight = "1em"
document.getElementById("file_viewer_list_title").innerText = this.title
document.getElementById("file_viewer_file_title").innerText = file.name
document.title = this.title + " ~ " + file.name + " ~ pixeldrain"
2020-01-27 16:56:16 +01:00
} else {
2020-02-04 19:37:46 +01:00
document.getElementById("file_viewer_file_title").innerText = file.name
document.title = file.name + " ~ pixeldrain"
2020-01-20 19:55:51 +01:00
}
2020-01-27 16:56:16 +01:00
// Update the file details
2020-02-04 19:37:46 +01:00
this.detailsWindow.setDetails(file)
this.toolbar.setFile(file)
2020-01-27 16:56:16 +01:00
// Register a new view. We don't care what this returns becasue we can't
// do anything about it anyway
2020-02-04 19:37:46 +01:00
if (file.view_href !== "") {
fetch(file.view_href, {
method: "POST",
headers: {"Content-Type": "application/x-www-form-urlencoded"},
body: "token="+this.viewToken
}
)
}
2020-01-20 19:55:51 +01:00
2020-01-27 16:56:16 +01:00
// Clear the canvas
2020-02-04 19:37:46 +01:00
this.divFilepreview.innerHTML = ""
2020-01-27 16:56:16 +01:00
let nextItem = () => {
2020-01-28 12:51:21 +01:00
if (this.listNavigator !== null) {
2020-02-04 19:37:46 +01:00
this.listNavigator.nextItem()
2020-01-20 19:55:51 +01:00
}
2020-02-04 19:37:46 +01:00
}
2020-01-27 16:56:16 +01:00
if (
file.mime_type.startsWith("image")
) {
2020-02-04 19:37:46 +01:00
new ImageViewer(this, file).render(this.divFilepreview)
2020-01-27 16:56:16 +01:00
} else if (
file.mime_type.startsWith("video") ||
file.mime_type === "application/matroska" ||
file.mime_type === "application/x-matroska"
) {
2020-02-04 19:37:46 +01:00
new VideoViewer(this, file, nextItem).render(this.divFilepreview)
2020-01-27 16:56:16 +01:00
} else if (
file.mime_type.startsWith("audio") ||
file.mime_type === "application/ogg" ||
file.name.endsWith(".mp3")
) {
2020-02-04 19:37:46 +01:00
new AudioViewer(this, file, nextItem).render(this.divFilepreview)
2020-01-27 16:56:16 +01:00
} else if (
file.mime_type === "application/pdf" ||
file.mime_type === "application/x-pdf"
) {
2020-02-04 19:37:46 +01:00
new PDFViewer(this, file).render(this.divFilepreview)
2020-01-27 16:56:16 +01:00
} else if (
file.mime_type.startsWith("text") ||
file.id === "demo"
) {
2020-02-04 19:37:46 +01:00
new TextViewer(this, file).render(this.divFilepreview)
2020-01-27 16:56:16 +01:00
} else {
2020-02-04 19:37:46 +01:00
new FileViewer(this, file).render(this.divFilepreview)
2020-01-20 19:55:51 +01:00
}
2020-01-27 16:56:16 +01:00
}
2020-01-20 19:55:51 +01:00
2020-01-27 16:56:16 +01:00
Viewer.prototype.renderSponsors = function() {
2020-02-04 19:37:46 +01:00
let scale = 1
let scaleWidth = 1
let scaleHeight = 1
let minWidth = 728
let minHeight = 800
2020-01-20 19:55:51 +01:00
2020-01-27 16:56:16 +01:00
if (window.innerWidth < minWidth) {
2020-02-04 19:37:46 +01:00
scaleWidth = window.innerWidth/minWidth
2020-01-27 16:56:16 +01:00
}
if (window.innerHeight < minHeight) {
2020-02-04 19:37:46 +01:00
scaleHeight = window.innerHeight/minHeight
2020-01-27 16:56:16 +01:00
}
2020-02-04 19:37:46 +01:00
scale = scaleWidth < scaleHeight ? scaleWidth : scaleHeight
2020-01-27 16:56:16 +01:00
// Because of the scale transformation the automatic margins don't work
// anymore. So we have to maunally calculate the margin. Where we take the
// width of the viewport - the width of the ad to calculate the amount of
// pixels around the ad. We multiply the ad size by the scale we calcualted
// to account for the smaller size.
let offset = (window.innerWidth - (minWidth*scale)) / 2
if (offset < 0) {
offset = 0
}
2020-02-04 19:37:46 +01:00
document.querySelector(".sponsors > iframe").style.marginLeft = offset+"px"
2020-01-27 16:56:16 +01:00
if (scale == 1) {
2020-02-04 19:37:46 +01:00
document.querySelector(".sponsors > iframe").style.transform = "none"
document.querySelector(".sponsors").style.height = "90px"
2020-01-27 16:56:16 +01:00
} else {
2020-02-04 19:37:46 +01:00
document.querySelector(".sponsors > iframe").style.transform = "scale("+scale+")"
document.querySelector(".sponsors").style.height = (scale*90)+"px"
2020-01-27 16:56:16 +01:00
}
}
2020-01-20 19:55:51 +01:00
2020-01-28 12:51:21 +01:00
Viewer.prototype.keyboardEvent = function(evt) {
2020-01-27 16:56:16 +01:00
if (evt.ctrlKey || evt.altKey) {
return // prevent custom shortcuts from interfering with system shortcuts
2020-01-20 19:55:51 +01:00
}
2020-01-27 16:56:16 +01:00
switch (evt.keyCode) {
case 65: // A or left arrow key go to previous file
case 37:
2020-01-28 12:51:21 +01:00
if (this.listNavigator != null) {
2020-02-04 19:37:46 +01:00
this.listNavigator.previousItem()
2020-01-20 19:55:51 +01:00
}
2020-02-04 19:37:46 +01:00
break
2020-01-27 16:56:16 +01:00
case 68: // D or right arrow key go to next file
case 39:
2020-01-28 12:51:21 +01:00
if (this.listNavigator != null) {
2020-02-04 19:37:46 +01:00
this.listNavigator.nextItem()
2020-01-27 16:56:16 +01:00
}
2020-02-04 19:37:46 +01:00
break
2020-01-27 16:56:16 +01:00
case 83:
if (evt.shiftKey) {
2020-02-04 19:37:46 +01:00
this.listNavigator.downloadList() // SHIFT + S downloads all files in list
2020-01-27 16:56:16 +01:00
} else {
2020-02-04 19:37:46 +01:00
this.toolbar.download() // S to download the current file
2020-01-20 19:55:51 +01:00
}
2020-02-04 19:37:46 +01:00
break
2020-01-27 16:56:16 +01:00
case 82: // R to toggle list shuffle
2020-01-28 12:51:21 +01:00
if (this.listNavigator != null) {
2020-02-04 19:37:46 +01:00
this.listNavigator.toggleShuffle()
2020-01-27 16:56:16 +01:00
}
2020-02-04 19:37:46 +01:00
break
2020-01-27 16:56:16 +01:00
case 67: // C to copy to clipboard
2020-02-04 19:37:46 +01:00
this.toolbar.copyUrl()
break
2020-01-27 16:56:16 +01:00
case 73: // I to open the details window
2020-02-04 19:37:46 +01:00
this.detailsWindow.toggle()
break
2020-01-27 16:56:16 +01:00
case 81: // Q to close the window
2020-02-04 19:37:46 +01:00
window.close()
break
2020-01-20 19:55:51 +01:00
}
2020-01-27 16:56:16 +01:00
}
2020-01-20 19:55:51 +01:00
// Against XSS attacks
function escapeHTML(str) {
return String(str)
.replace(/&/g, '&amp;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/"/g, '&quot;');
}
2020-02-04 19:37:46 +01:00
function fileFromAPIResp(resp) {
let file = {
id: resp.id,
name: resp.name,
mime_type: resp.mime_type,
size: resp.size,
date_created: new Date(resp.date_upload),
date_last_view: new Date(resp.date_last_view),
views: resp.views,
bandwidth_used: resp.bandwidth_used,
description: "",
icon_href: apiEndpoint+"/file/"+resp.id+"/thumbnail",
get_href: apiEndpoint+"/file/"+resp.id,
download_href: apiEndpoint+"/file/"+resp.id+"?download",
availability_href: apiEndpoint+"/file/"+resp.id+"/availability",
view_href: apiEndpoint+"/file/"+resp.id+"/view",
timeseries_href: apiEndpoint+"/file/"+resp.id+"/timeseries",
link: domainURL()+"/u/"+resp.id,
}
if (resp.description !== undefined) {
file.description = resp.description
}
return file
}
function fileFromSkyNet(resp) {
let file = fileFromAPIResp(resp)
file.icon_href = "/res/img/mime/empty.png"
file.get_href = "https://siasky.net/"+resp.id
file.download_href = "https://siasky.net/"+resp.id
file.availability_href = ""
file.view_href = ""
file.timeseries_href = ""
file.link = domainURL()+"/s/"+resp.id
return file
}