Add hotlinking option to embed window

This commit is contained in:
2021-11-28 15:19:00 +01:00
parent 04bf28ea6f
commit 90519b0f81
10 changed files with 287 additions and 186 deletions

View File

@@ -6,8 +6,8 @@ export const adaround_load = writable(false)
export const adaround_loaded = writable(false) export const adaround_loaded = writable(false)
export const flyingsquare_load = writable(false) export const flyingsquare_load = writable(false)
export const flyingsquare_loaded = writable(false) export const flyingsquare_loaded = writable(false)
</script> </script>
<script> <script>
// This script makes sure that each head element is only loaded once. The _load // This script makes sure that each head element is only loaded once. The _load
// stores are for telling this script to load a head element, and the _loaded // stores are for telling this script to load a head element, and the _loaded

View File

@@ -20,29 +20,30 @@ let set_ad_type = (t) => {
} }
onMount(() => { onMount(() => {
if (window.location.pathname === "/u/demo") { let url_ads = new URL(window.location.href).searchParams.get("ads")
let url_ads = new URL(window.location.href).searchParams.get("ads") if (url_ads) {
if (url_ads !== "") { set_ad_type(url_ads)
set_ad_type(url_ads) return
return
}
} }
let now = new Date().getTime() let now = new Date().getTime()
switch (now % 5) { switch (now % 8) {
case 0: case 0:
set_ad_type("brave")
break
case 1: case 1:
set_ad_type("aads1")
break
case 2: case 2:
set_ad_type("ads.plus")
break
case 3: case 3:
set_ad_type("adaround") set_ad_type("aads")
break break
case 4: case 4:
set_ad_type("brave")
break
case 5:
set_ad_type("ads.plus")
break
case 6:
set_ad_type("adaround")
break
case 7:
set_ad_type("flyingsquare") set_ad_type("flyingsquare")
break break
} }
@@ -60,7 +61,7 @@ const resize = () => {
let scaleWidth = 1 let scaleWidth = 1
let scaleHeight = 1 let scaleHeight = 1
let minWindowHeight = 800 let minWindowHeight = 600
let bannerWidth = banner.offsetWidth let bannerWidth = banner.offsetWidth
let bannerHeight = banner.offsetHeight let bannerHeight = banner.offsetHeight
@@ -126,7 +127,7 @@ adsplus_loaded.subscribe(v => {
<i class="icon">shopping_cart</i> <i class="icon">shopping_cart</i>
</a> </a>
</div> </div>
{:else if ad_type === "aads1"} {:else if ad_type === "aads"}
<iframe bind:this={banner} class="banner" <iframe bind:this={banner} class="banner"
data-aa="73974" data-aa="73974"
src="//ad.a-ads.com/73974?size=728x90&background_color={window.style.layer2Color}&text_color={window.style.textColor}&title_color={window.style.highlightColor}&title_hover_color={window.style.highlightColor}&link_color={window.style.highlightColor}&link_hover_color={window.style.highlightColor}" src="//ad.a-ads.com/73974?size=728x90&background_color={window.style.layer2Color}&text_color={window.style.textColor}&title_color={window.style.highlightColor}&title_hover_color={window.style.highlightColor}&link_color={window.style.highlightColor}&link_hover_color={window.style.highlightColor}"

View File

@@ -7,28 +7,11 @@ let container
let ad_type = "" let ad_type = ""
let visible = false let visible = false
let set_ad_type = (t) => {
ad_type = t
if (ad_type === "ads.plus") {
adsplus_load.set(true)
} else if (ad_type === "adaround") {
adaround_load.set(true)
} else if (ad_type === "flyingsquare") {
flyingsquare_load.set(true)
}
console.log("skyscraper ad is " + t)
}
onMount(async () => { onMount(async () => {
if (window.location.pathname === "/u/demo") { let url_ads = new URL(window.location.href).searchParams.get("ads")
let url_ads = new URL(window.location.href).searchParams.get("ads") if (url_ads) {
if (url_ads !== "") { set_ad_type(url_ads)
set_ad_type(url_ads) return
open()
return
}
} }
if (document.body.clientWidth < 700) { if (document.body.clientWidth < 700) {
@@ -48,30 +31,37 @@ onMount(async () => {
return return
} }
switch (now % 4) { switch (now % 3) {
case 0: case 0:
set_ad_type("aads2")
break
case 1:
set_ad_type("ads.plus") set_ad_type("ads.plus")
break break
case 2: case 1:
set_ad_type("adaround") set_ad_type("adaround")
break break
case 3: case 2:
set_ad_type("flyingsquare") set_ad_type("flyingsquare")
break break
} }
open()
}) })
const open = async () => { let set_ad_type = async (t) => {
ad_type = t
if (ad_type === "ads.plus") {
adsplus_load.set(true)
} else if (ad_type === "adaround") {
adaround_load.set(true)
} else if (ad_type === "flyingsquare") {
flyingsquare_load.set(true)
}
visible = true visible = true
await tick() await tick()
dispatch("visibility", true) dispatch("visibility", true)
container.style.right = "0" container.style.right = "0"
console.log("skyscraper ad is " + t)
} }
const close = () => { const close = () => {
container.style.right = -container.offsetWidth + "px" container.style.right = -container.offsetWidth + "px"
dispatch("visibility", false) dispatch("visibility", false)
@@ -102,7 +92,7 @@ adsplus_loaded.subscribe(v => {
<i class="icon">close</i> Close ad <i class="icon">close</i> Close ad
</button> </button>
<div class="ad_space"> <div class="ad_space">
{#if ad_type === "aads2"} {#if ad_type === "aads"}
<iframe <iframe
data-aa="1811738" data-aa="1811738"
src="//ad.a-ads.com/1811738?size=160x600&background_color={window.style.layer2Color}&text_color={window.style.textColor}&title_color={window.style.highlightColor}&title_hover_color={window.style.highlightColor}&link_color={window.style.highlightColor}&link_hover_color={window.style.highlightColor}" src="//ad.a-ads.com/1811738?size=160x600&background_color={window.style.layer2Color}&text_color={window.style.textColor}&title_color={window.style.highlightColor}&title_hover_color={window.style.highlightColor}&link_color={window.style.highlightColor}&link_hover_color={window.style.highlightColor}"

View File

@@ -1,32 +1,78 @@
<script> <script>
import { copy_text, domain_url } from "../util/Util.svelte"; import { copy_text, domain_url } from "../util/Util.svelte";
import { file_type } from "./FileUtilities.svelte";
export let file = { export let file = {
id: "", id: "",
mime_type: "",
get_href: "",
download_href: "",
} }
export let list = { export let list = {
id: "", id: "",
} }
let tab = "iframe"
let embed_html = "" let embed_html = ""
let preview_area let preview_area
$: update_file(file.id, list.id) $: update_file(file.id, list.id)
let update_file = () => { let update_file = () => {
if (preview_area) {
preview_area.innerHTML = ""
}
if (tab === "iframe") {
embed_iframe()
} else if (tab === "hotlink") {
embed_hotlink()
}
}
let embed_iframe = () => {
tab = "iframe"
let url let url
if (list.id === "") { if (list.id === "") {
// Not a list, use file ID // Not a list, use file ID
url = domain_url()+"/u/"+file.id+"?embed" url = domain_url()+"/u/"+file.id+"?embed"
} else { } else {
url = domain_url()+"/l/"+list.id+"?embed" url = domain_url()+"/l/"+list.id+"?embed"+window.location.hash
} }
embed_html = `<iframe ` + embed_html = `<iframe ` +
`src="${url}" ` + `src="${url}" ` +
`style="border: none; width: 800px; max-width: 100%; height: 500px; border-radius: 16px;"` + `style="border: none; width: 800px; max-width: 100%; height: 600px; max-height: 100%; border-radius: 16px;"` +
`></iframe>` `></iframe>`
} }
let embed_hotlink = () => {
tab = "hotlink"
let t = file_type(file)
if (t === "video") {
embed_html = `<video controls playsinline autoplay style="max-width: 100%; max-height: 100%;">`+
`<source src="${domain_url()}${file.get_href}" type="${file.mime_type}" />`+
`</video>`
} else if (t === "audio") {
embed_html = `<audio controls autoplay style="width: 100%;">`+
`<source src="${domain_url()}${file.get_href}" type="${file.mime_type}" />`+
`</audio>`
} else if (t === "image") {
embed_html = `<img src="${domain_url()}${file.get_href}" alt="${html_escape(file.name)}" style="max-width: 100%; max-height: 100%;">`
} else {
embed_html = `<a href="${domain_url()}${file.download_href}">`+
`Download ${html_escape(file.name)} here`+
`</a>`
}
}
let html_escape = s => {
return s.replace(/&/g, "&amp;").
replace(/</g, "&lt;").
replace(/>/g, "&gt;").
replace(/"/g, "&quot;").
replace(/'/g, "&#039;");
}
let copy_status = "" // empty, success or error let copy_status = "" // empty, success or error
const copy = () => { const copy = () => {
@@ -43,33 +89,68 @@ const example = () => {
} }
</script> </script>
<div> <div class="container">
<p> <p>
You can embed pixeldrain's file viewer in your own web pages. We If you have a website you can embed pixeldrain files in your own
have created a special HTML code which renders a minimalistic webpages here.
version of the file viewer where the title bar is a bit thinner and
the toolbar is collapsed by default.
</p> </p>
<p> <p>
Unless it was uploaded using a pixeldrain Pro account the embedded The IFrame embed gives you a frame with a slightly more minimalistic
file will also show advertisements. file viewer in it. The embedded file viewer has a fullscreen button and
the toolbar is collapsed by default. If you do not have a pixeldrain Pro
account the frame will also have advertisements in it.
</p> </p>
<h3>Code</h3> <p>
<textarea bind:value={embed_html} style="width: 100%; height: 4em;" class="indent"></textarea> The hotlink embed option only works for single files uploaded with a Pro
<br/> account. You can use this to directly embed a video player, audio
<button on:click={copy} class="indent" class:button_highlight={copy_status === "success"} class:button_red={copy_status === "error"}> player, photo element or a download button in your site. Make sure you
<i class="icon">content_copy</i> have bandwidth sharing enabled on your
{#if copy_status === "success"} <a href="/user/subscription">subscription page</a> or the embed will not
Copied! work.
{:else if copy_status === "error"} </p>
Error! <div class="tab_bar">
{:else} <button on:click={embed_iframe} class:button_highlight={tab === "iframe"}>
Copy HTML <i class="icon">code</i>
IFrame
</button>
{#if file.id}
<button on:click={embed_hotlink} class:button_highlight={tab === "hotlink"}>
<i class="icon">code</i>
Hotlink
</button>
{/if} {/if}
</button> </div>
<button on:click={example}> <h3>Code</h3>
<i class="icon">visibility</i> Show example <p>
</button> Put this code in your website to embed the file.
</p>
<div class="center">
<textarea bind:value={embed_html} style="width: 95%; height: 4em;"></textarea>
<br/>
<button on:click={copy} class:button_highlight={copy_status === "success"} class:button_red={copy_status === "error"}>
<i class="icon">content_copy</i>
{#if copy_status === "success"}
Copied!
{:else if copy_status === "error"}
Error!
{:else}
Copy HTML
{/if}
</button>
<button on:click={example}>
<i class="icon">visibility</i> Show example
</button>
</div>
<h3>Example</h3> <h3>Example</h3>
<div bind:this={preview_area} style="text-align: center;"></div> <div bind:this={preview_area} style="text-align: center;"></div>
</div> </div>
<style>
.center {
text-align: center;
}
.container {
width: 100%;
overflow: hidden;
}
</style>

View File

@@ -9,8 +9,9 @@ import PDF from "./viewers/PDF.svelte";
import Text from "./viewers/Text.svelte"; import Text from "./viewers/Text.svelte";
import File from "./viewers/File.svelte"; import File from "./viewers/File.svelte";
import Abuse from "./viewers/Abuse.svelte"; import Abuse from "./viewers/Abuse.svelte";
import { file_type } from "./FileUtilities.svelte";
let file_type = "loading" let viewer_type = "loading"
export let file = { export let file = {
id: "", id: "",
name: "", name: "",
@@ -21,38 +22,14 @@ export let file = {
$: update_file(file.id) $: update_file(file.id)
const update_file = () => { const update_file = () => {
if (file.id === "") { if (file.id === "") {
file_type = "loading" viewer_type = "loading"
return
}else if (file.abuse_type !== "") {
viewer_type = "abuse"
return return
} }
if (file.abuse_type !== "") { viewer_type = file_type(file)
file_type = "abuse"
} else if (file.mime_type.startsWith("image")) {
file_type = "image"
} else if (
file.mime_type.startsWith("video") ||
file.mime_type === "application/matroska" ||
file.mime_type === "application/x-matroska"
) {
file_type = "video"
} else if (
file.mime_type.startsWith("audio") ||
file.mime_type === "application/ogg" ||
file.name.endsWith(".mp3")
) {
file_type = "audio"
} else if (
file.mime_type === "application/pdf" ||
file.mime_type === "application/x-pdf"
) {
file_type = "pdf"
} else if (
file.mime_type.startsWith("text")
) {
file_type = "text"
} else {
file_type = "file"
}
} }
let dispatch = createEventDispatcher() let dispatch = createEventDispatcher()
@@ -63,23 +40,23 @@ const prev = () => { dispatch("prev") }
</script> </script>
<div class="file_container"> <div class="file_container">
{#if file_type === "loading"} {#if viewer_type === "loading"}
<div class="center" style="width: 100px; height: 100px;"> <div class="center" style="width: 100px; height: 100px;">
<Spinner></Spinner> <Spinner></Spinner>
</div> </div>
{:else if file_type === "abuse"} {:else if viewer_type === "abuse"}
<Abuse file={file}></Abuse> <Abuse file={file}></Abuse>
{:else if file_type === "image"} {:else if viewer_type === "image"}
<Image file={file}></Image> <Image file={file}></Image>
{:else if file_type === "video"} {:else if viewer_type === "video"}
<Video file={file} on:download={download} on:prev={prev} on:next={next}></Video> <Video file={file} on:download={download} on:prev={prev} on:next={next}></Video>
{:else if file_type === "audio"} {:else if viewer_type === "audio"}
<Audio file={file} on:prev={prev} on:next={next}></Audio> <Audio file={file} on:prev={prev} on:next={next}></Audio>
{:else if file_type === "pdf"} {:else if viewer_type === "pdf"}
<PDF file={file}></PDF> <PDF file={file}></PDF>
{:else if file_type === "text"} {:else if viewer_type === "text"}
<Text file={file}></Text> <Text file={file}></Text>
{:else if file_type === "file"} {:else if viewer_type === "file"}
<File file={file} on:download={download}></File> <File file={file} on:download={download}></File>
{/if} {/if}
</div> </div>

View File

@@ -0,0 +1,64 @@
<script context="module">
export const file_struct = {
id: "",
name: "",
size: 0,
bandwidth_used: 0,
bandwidth_used_paid: 0,
downloads: 0,
views: 0,
mime_type: "",
availability: "",
abuse_type: "",
show_ads: false,
can_edit: false,
get_href: "",
info_href: "",
download_href: "",
icon_href: "",
}
export const list_struct = {
id: "",
title: "",
files: [],
download_href: "",
info_href: "",
can_edit: false,
}
export const file_set_href = file => {
file.get_href = window.api_endpoint+"/file/"+file.id
file.info_href = window.api_endpoint+"/file/"+file.id+"/info"
file.download_href = window.api_endpoint+"/file/"+file.id+"?download"
file.icon_href = window.api_endpoint+"/file/"+file.id+"/thumbnail"
file.timeseries_href = window.api_endpoint+"/file/"+file.id+"/timeseries"
}
export const file_type = file => {
if (file.mime_type.startsWith("image")) {
return "image"
} else if (
file.mime_type.startsWith("video") ||
file.mime_type === "application/matroska" ||
file.mime_type === "application/x-matroska"
) {
return "video"
} else if (
file.mime_type.startsWith("audio") ||
file.mime_type === "application/ogg" ||
file.name.endsWith(".mp3")
) {
return "audio"
} else if (
file.mime_type === "application/pdf" ||
file.mime_type === "application/x-pdf"
) {
return "pdf"
} else if (
file.mime_type.startsWith("text")
) {
return "text"
} else {
return "file"
}
}
</script>

View File

@@ -1,42 +1,7 @@
<script context="module">
export const file_struct = {
id: "",
name: "",
size: 0,
bandwidth_used: 0,
bandwidth_used_paid: 0,
downloads: 0,
views: 0,
mime_type: "",
availability: "",
abuse_type: "",
show_ads: false,
can_edit: false,
get_href: "",
info_href: "",
download_href: "",
icon_href: "",
}
export const list_struct = {
id: "",
title: "",
files: [],
download_href: "",
info_href: "",
can_edit: false,
}
export const file_set_href = f => {
f.get_href = window.api_endpoint+"/file/"+f.id
f.info_href = window.api_endpoint+"/file/"+f.id+"/info"
f.download_href = window.api_endpoint+"/file/"+f.id+"?download"
f.icon_href = window.api_endpoint+"/file/"+f.id+"/thumbnail"
f.timeseries_href = window.api_endpoint+"/file/"+f.id+"/timeseries"
}
</script>
<script> <script>
import { onMount, tick } from "svelte"; import { onMount, tick } from "svelte";
import { copy_text } from "../util/Util.svelte"; import { copy_text } from "../util/Util.svelte";
import { file_struct, list_struct, file_set_href } from "./FileUtilities.svelte";
import Modal from "../util/Modal.svelte"; import Modal from "../util/Modal.svelte";
import PixeldrainLogo from "../util/PixeldrainLogo.svelte"; import PixeldrainLogo from "../util/PixeldrainLogo.svelte";
import DetailsWindow from "./DetailsWindow.svelte"; import DetailsWindow from "./DetailsWindow.svelte";

View File

@@ -54,7 +54,7 @@ export const set_item = idx => {
let start = file_list_div.scrollLeft let start = file_list_div.scrollLeft
let end = ((idx * itemWidth) + (itemWidth / 2)) - (file_list_div.clientWidth / 2) let end = ((idx * itemWidth) + (itemWidth / 2)) - (file_list_div.clientWidth / 2)
let steps = 60 // One second let steps = 30 // One second
let stepSize = (end - start)/steps let stepSize = (end - start)/steps
let animateScroll = (pos, step) => { let animateScroll = (pos, step) => {
@@ -77,33 +77,53 @@ const select_item_event = idx => {
} }
</script> </script>
<div bind:this={file_list_div} class="list_navigator"> <div class="nav_container">
{#each files as file, index} <button class="nav_button" style="margin-right: 0;" on:click={prev}>
<div class="list_item file_button" <i class="icon">chevron_left</i>
class:file_button_selected={file.selected} </button>
on:click={() => { select_item_event(index) }}> <div bind:this={file_list_div} class="list_navigator">
<img src={file.icon_href+"?width=48&height=48"} alt={file.name} class="list_item_thumbnail" loading="lazy"/> {#each files as file, index}
{file.name} <div class="list_item file_button"
</div> class:file_button_selected={file.selected}
{/each} on:click={() => { select_item_event(index) }}>
<img src={file.icon_href+"?width=48&height=48"} alt={file.name} class="list_item_thumbnail" loading="lazy"/>
{file.name}
</div>
{/each}
</div>
<button class="nav_button" style="margin-left: 0;" on:click={next}>
<i class="icon">chevron_right</i>
</button>
</div> </div>
<style> <style>
.list_item { .nav_container{
height: 2.6em !important;
width: 220px !important;
}
.list_navigator {
flex-grow: 0; flex-grow: 0;
flex-shrink: 0; flex-shrink: 0;
display: flex;
position: relative; position: relative;
width: 100%; width: 100%;
border-top: 1px solid var(--layer_2_color_border); border-top: 1px solid var(--layer_2_color_border);
text-align: center; text-align: center;
line-height: 1em; line-height: 1em;
}
.nav_button{
flex-grow: 0;
flex-shrink: 0;
height: 2.6em;
margin-top: 8px;
}
.list_item {
height: 2.6em !important;
width: 220px !important;
}
.list_navigator {
flex-grow: 1;
flex-shrink: 1;
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
z-index: 50;
white-space: nowrap; white-space: nowrap;
} }
</style> </style>

View File

@@ -71,7 +71,7 @@ let submit = async e => {
} }
</script> </script>
<div> <div class="container">
<p> <p>
If you think this file violates pixeldrain's If you think this file violates pixeldrain's
<a href="/about#content-policy">content policy</a> you can <a href="/about#content-policy">content policy</a> you can
@@ -147,6 +147,11 @@ let submit = async e => {
</div> </div>
<style> <style>
.container {
width: 100%;
padding: 10px;
overflow: hidden;
}
label { label {
display: block; display: block;
border-bottom: 1px var(--layer_2_color_border) solid; border-bottom: 1px var(--layer_2_color_border) solid;

View File

@@ -82,29 +82,27 @@ onMount(load_tranfer_used)
{/if} {/if}
<div class="limit_width"> <div class="limit_width">
<h2>Manage subscription</h2> <h2>Manage subscription</h2>
<p> {#if window.user.subscription.type !== "patreon"}
Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro> <p>
</p> Current account balance: <Euro amount={window.user.balance_micro_eur}></Euro>
<p> </p>
When your prepaid subscription is active you will be charged daily <p>
based on usage. Hotlink bandwidth is charged per TB based on the When your prepaid subscription is active you will be charged daily
usage of the previous day. The amount charged for storage each day based on usage. Hotlink bandwidth is charged per TB based on the
is your storage usage at the end of the day multiplied by the usage of the previous day. The amount charged for storage each day
storage price (€4 / TB) and divided by the average number of days in is your storage usage at the end of the day multiplied by the
a month (30.4375). So if you have exactly 1 TB on your account you storage price (€4 / TB) and divided by the average number of days in
will be charged €0.131416838 per day. a month (30.4375). So if you have exactly 1 TB on your account you
</p> will be charged €0.131416838 per day.
<p> </p>
The prepaid subscription will stay active for as long as you have <p>
credit on your account. When you reach negative balance the The prepaid subscription will stay active for as long as you have
subscription will automatically end. You will need a positive credit on your account. When you reach negative balance the
balance to activate the subscription again. subscription will automatically end. You will need a positive
</p> balance to activate the subscription again.
</p>
<h3>Prepaid plans</h3> <h3>Prepaid plans</h3>
{#if window.user.subscription.type === "patreon"}
<p>Prepaid subscriptions are not available for Patreon supporters.</p>
{:else}
{#if result !== ""} {#if result !== ""}
<div class:highlight_green={result_success} class:highlight_red={!result_success}> <div class:highlight_green={result_success} class:highlight_red={!result_success}>
{result} {result}