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 flyingsquare_load = writable(false)
export const flyingsquare_loaded = writable(false)
</script>
<script>
// 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

View File

@@ -20,29 +20,30 @@ let set_ad_type = (t) => {
}
onMount(() => {
if (window.location.pathname === "/u/demo") {
let url_ads = new URL(window.location.href).searchParams.get("ads")
if (url_ads !== "") {
set_ad_type(url_ads)
return
}
let url_ads = new URL(window.location.href).searchParams.get("ads")
if (url_ads) {
set_ad_type(url_ads)
return
}
let now = new Date().getTime()
switch (now % 5) {
switch (now % 8) {
case 0:
set_ad_type("brave")
break
case 1:
set_ad_type("aads1")
break
case 2:
set_ad_type("ads.plus")
break
case 3:
set_ad_type("adaround")
set_ad_type("aads")
break
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")
break
}
@@ -60,7 +61,7 @@ const resize = () => {
let scaleWidth = 1
let scaleHeight = 1
let minWindowHeight = 800
let minWindowHeight = 600
let bannerWidth = banner.offsetWidth
let bannerHeight = banner.offsetHeight
@@ -126,7 +127,7 @@ adsplus_loaded.subscribe(v => {
<i class="icon">shopping_cart</i>
</a>
</div>
{:else if ad_type === "aads1"}
{:else if ad_type === "aads"}
<iframe bind:this={banner} class="banner"
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}"

View File

@@ -7,28 +7,11 @@ let container
let ad_type = ""
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 () => {
if (window.location.pathname === "/u/demo") {
let url_ads = new URL(window.location.href).searchParams.get("ads")
if (url_ads !== "") {
set_ad_type(url_ads)
open()
return
}
let url_ads = new URL(window.location.href).searchParams.get("ads")
if (url_ads) {
set_ad_type(url_ads)
return
}
if (document.body.clientWidth < 700) {
@@ -48,30 +31,37 @@ onMount(async () => {
return
}
switch (now % 4) {
switch (now % 3) {
case 0:
set_ad_type("aads2")
break
case 1:
set_ad_type("ads.plus")
break
case 2:
case 1:
set_ad_type("adaround")
break
case 3:
case 2:
set_ad_type("flyingsquare")
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
await tick()
dispatch("visibility", true)
container.style.right = "0"
console.log("skyscraper ad is " + t)
}
const close = () => {
container.style.right = -container.offsetWidth + "px"
dispatch("visibility", false)
@@ -102,7 +92,7 @@ adsplus_loaded.subscribe(v => {
<i class="icon">close</i> Close ad
</button>
<div class="ad_space">
{#if ad_type === "aads2"}
{#if ad_type === "aads"}
<iframe
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}"

View File

@@ -1,32 +1,78 @@
<script>
import { copy_text, domain_url } from "../util/Util.svelte";
import { file_type } from "./FileUtilities.svelte";
export let file = {
id: "",
mime_type: "",
get_href: "",
download_href: "",
}
export let list = {
id: "",
}
let tab = "iframe"
let embed_html = ""
let preview_area
$: update_file(file.id, list.id)
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
if (list.id === "") {
// Not a list, use file ID
url = domain_url()+"/u/"+file.id+"?embed"
} else {
url = domain_url()+"/l/"+list.id+"?embed"
url = domain_url()+"/l/"+list.id+"?embed"+window.location.hash
}
embed_html = `<iframe ` +
`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>`
}
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
const copy = () => {
@@ -43,33 +89,68 @@ const example = () => {
}
</script>
<div>
<div class="container">
<p>
You can embed pixeldrain's file viewer in your own web pages. We
have created a special HTML code which renders a minimalistic
version of the file viewer where the title bar is a bit thinner and
the toolbar is collapsed by default.
If you have a website you can embed pixeldrain files in your own
webpages here.
</p>
<p>
Unless it was uploaded using a pixeldrain Pro account the embedded
file will also show advertisements.
The IFrame embed gives you a frame with a slightly more minimalistic
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>
<h3>Code</h3>
<textarea bind:value={embed_html} style="width: 100%; height: 4em;" class="indent"></textarea>
<br/>
<button on:click={copy} class="indent" 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
<p>
The hotlink embed option only works for single files uploaded with a Pro
account. You can use this to directly embed a video player, audio
player, photo element or a download button in your site. Make sure you
have bandwidth sharing enabled on your
<a href="/user/subscription">subscription page</a> or the embed will not
work.
</p>
<div class="tab_bar">
<button on:click={embed_iframe} class:button_highlight={tab === "iframe"}>
<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}
</button>
<button on:click={example}>
<i class="icon">visibility</i> Show example
</button>
</div>
<h3>Code</h3>
<p>
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>
<div bind:this={preview_area} style="text-align: center;"></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 File from "./viewers/File.svelte";
import Abuse from "./viewers/Abuse.svelte";
import { file_type } from "./FileUtilities.svelte";
let file_type = "loading"
let viewer_type = "loading"
export let file = {
id: "",
name: "",
@@ -21,38 +22,14 @@ export let file = {
$: update_file(file.id)
const update_file = () => {
if (file.id === "") {
file_type = "loading"
viewer_type = "loading"
return
}else if (file.abuse_type !== "") {
viewer_type = "abuse"
return
}
if (file.abuse_type !== "") {
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"
}
viewer_type = file_type(file)
}
let dispatch = createEventDispatcher()
@@ -63,23 +40,23 @@ const prev = () => { dispatch("prev") }
</script>
<div class="file_container">
{#if file_type === "loading"}
{#if viewer_type === "loading"}
<div class="center" style="width: 100px; height: 100px;">
<Spinner></Spinner>
</div>
{:else if file_type === "abuse"}
{:else if viewer_type === "abuse"}
<Abuse file={file}></Abuse>
{:else if file_type === "image"}
{:else if viewer_type === "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>
{:else if file_type === "audio"}
{:else if viewer_type === "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>
{:else if file_type === "text"}
{:else if viewer_type === "text"}
<Text file={file}></Text>
{:else if file_type === "file"}
{:else if viewer_type === "file"}
<File file={file} on:download={download}></File>
{/if}
</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>
import { onMount, tick } from "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 PixeldrainLogo from "../util/PixeldrainLogo.svelte";
import DetailsWindow from "./DetailsWindow.svelte";

View File

@@ -54,7 +54,7 @@ export const set_item = idx => {
let start = file_list_div.scrollLeft
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 animateScroll = (pos, step) => {
@@ -77,33 +77,53 @@ const select_item_event = idx => {
}
</script>
<div bind:this={file_list_div} class="list_navigator">
{#each files as file, index}
<div class="list_item file_button"
class:file_button_selected={file.selected}
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 class="nav_container">
<button class="nav_button" style="margin-right: 0;" on:click={prev}>
<i class="icon">chevron_left</i>
</button>
<div bind:this={file_list_div} class="list_navigator">
{#each files as file, index}
<div class="list_item file_button"
class:file_button_selected={file.selected}
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>
<style>
.list_item {
height: 2.6em !important;
width: 220px !important;
}
.list_navigator {
.nav_container{
flex-grow: 0;
flex-shrink: 0;
display: flex;
position: relative;
width: 100%;
border-top: 1px solid var(--layer_2_color_border);
text-align: center;
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-y: hidden;
z-index: 50;
white-space: nowrap;
}
</style>

View File

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

View File

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