updated files preview ui
This commit is contained in:
@@ -1,10 +1,13 @@
|
||||
<script>
|
||||
import CommonHelper from "@/utils/CommonHelper";
|
||||
import OverlayPanel from "@/components/base/OverlayPanel.svelte";
|
||||
|
||||
let panel;
|
||||
let url = "";
|
||||
|
||||
export let type;
|
||||
$: filename = url.substring(url.lastIndexOf("/") + 1);
|
||||
|
||||
$: type = CommonHelper.getFileType(filename);
|
||||
|
||||
export function show(newUrl) {
|
||||
if (newUrl === "") {
|
||||
@@ -19,33 +22,33 @@
|
||||
export function hide() {
|
||||
return panel?.hide();
|
||||
}
|
||||
|
||||
$: filename = url.substring(url.lastIndexOf("/") + 1);
|
||||
</script>
|
||||
|
||||
<OverlayPanel bind:this={panel} class="preview {type}-preview" btnClose={false} popup on:show on:hide>
|
||||
<OverlayPanel bind:this={panel} class="preview preview-{type}" btnClose={false} popup on:show on:hide>
|
||||
<svelte:fragment slot="header">
|
||||
<button type="button" class="overlay-close" on:click|preventDefault={hide}>
|
||||
<i class="ri-close-line" />
|
||||
</button>
|
||||
</svelte:fragment>
|
||||
|
||||
{#if type === "image"}
|
||||
<img src={url} alt="Preview {url}" />
|
||||
{:else if type === "pdf"}
|
||||
<object title={filename} data={url} type="application/pdf"> PDF embed not loaded. </object>
|
||||
{#if panel?.isActive()}
|
||||
{#if type === "image"}
|
||||
<img src={url} alt="Preview {filename}" />
|
||||
{:else}
|
||||
<object title={filename} data={url}>Cannot preview the file.</object>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<svelte:fragment slot="footer">
|
||||
<a
|
||||
href={url}
|
||||
title="Download"
|
||||
title={filename}
|
||||
target="_blank"
|
||||
rel="noreferrer noopener"
|
||||
class="link-hint txt-ellipsis"
|
||||
class="link-hint txt-ellipsis inline-flex"
|
||||
>
|
||||
<i class="ri-file-download-line" />
|
||||
{filename}
|
||||
<i class="ri-external-link-line" />
|
||||
</a>
|
||||
<div class="flex-fill" />
|
||||
<button type="button" class="btn btn-secondary" on:click={hide}>Close</button>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
|
||||
<th
|
||||
tabindex="0"
|
||||
title={name}
|
||||
class="col-sort {classes}"
|
||||
class:col-sort-disabled={disable}
|
||||
class:sort-active={sort === "-" + name || sort === "+" + name}
|
||||
|
||||
@@ -66,3 +66,9 @@
|
||||
</span>
|
||||
{/if}
|
||||
</td>
|
||||
|
||||
<style>
|
||||
.filename {
|
||||
max-width: 200px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,16 +3,18 @@
|
||||
import CommonHelper from "@/utils/CommonHelper";
|
||||
import PreviewPopup from "@/components/base/PreviewPopup.svelte";
|
||||
|
||||
export let record;
|
||||
export let filename;
|
||||
export let size;
|
||||
export let record = null;
|
||||
export let filename = "";
|
||||
export let size = ""; // sm/lg/xl
|
||||
|
||||
let previewPopup;
|
||||
let thumbUrl = "";
|
||||
let originalUrl = ApiClient.getFileUrl(record, `${filename}`);
|
||||
let originalUrl = ApiClient.getFileUrl(record, filename);
|
||||
|
||||
$: type = CommonHelper.getFileType(filename);
|
||||
$: hasPreview = ["image", "pdf"].includes(type);
|
||||
|
||||
$: hasPreview = ["image", "audio", "video"].includes(type) || filename.endsWith(".pdf");
|
||||
|
||||
$: thumbUrl = originalUrl ? originalUrl + "?thumb=100x100" : "";
|
||||
|
||||
function onError() {
|
||||
@@ -21,23 +23,25 @@
|
||||
</script>
|
||||
|
||||
<a
|
||||
class="thumb thumb-{size} link-fade"
|
||||
class="thumb {size ? `thumb-${size}` : ''}"
|
||||
href={originalUrl}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
title={(hasPreview ? "Preview" : "Download") + " " + filename}
|
||||
on:click|stopPropagation={(e) => {
|
||||
if (!hasPreview) return;
|
||||
e.preventDefault();
|
||||
previewPopup?.show(originalUrl);
|
||||
if (hasPreview) {
|
||||
e.preventDefault();
|
||||
previewPopup?.show(originalUrl);
|
||||
}
|
||||
}}
|
||||
>
|
||||
{#if type === "image"}
|
||||
<img src={thumbUrl} alt={filename} title="Preview {filename}" on:error={onError} />
|
||||
{:else if type === "pdf"}
|
||||
<i class="ri-file-pdf-line" />
|
||||
{:else if type === "video" || type === "audio"}
|
||||
<i class="ri-video-line" />
|
||||
{:else}
|
||||
<i class="ri-file-3-line" />
|
||||
{/if}
|
||||
</a>
|
||||
|
||||
<PreviewPopup bind:this={previewPopup} {type} />
|
||||
<PreviewPopup bind:this={previewPopup} />
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
href={ApiClient.getFileUrl(record, filename)}
|
||||
class="filename link-hint"
|
||||
class:txt-strikethrough={deletedFileIndexes.includes(i)}
|
||||
use:tooltip={{ position: "right", text: "Download" }}
|
||||
title="Download"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
|
||||
+10
-3
@@ -485,7 +485,7 @@ a,
|
||||
}
|
||||
|
||||
.thumb {
|
||||
--thumbSize: 44px;
|
||||
--thumbSize: 40px;
|
||||
|
||||
flex-shrink: 0;
|
||||
position: relative;
|
||||
@@ -498,7 +498,7 @@ a,
|
||||
background: var(--baseAlt2Color);
|
||||
border-radius: var(--baseRadius);
|
||||
color: var(--txtPrimaryColor);
|
||||
font-size: 1.2rem;
|
||||
font-size: 1.16rem;
|
||||
@include shadowize();
|
||||
i {
|
||||
font-size: inherit;
|
||||
@@ -511,7 +511,7 @@ a,
|
||||
}
|
||||
&.thumb-sm {
|
||||
--thumbSize: 32px;
|
||||
font-size: 0.85rem;
|
||||
font-size: 0.92rem;
|
||||
}
|
||||
&.thumb-lg {
|
||||
--thumbSize: 60px;
|
||||
@@ -528,6 +528,13 @@ a,
|
||||
box-shadow: 0px 0px 0px 2px var(--primaryColor);
|
||||
}
|
||||
}
|
||||
a.thumb:not(.thumb-active) {
|
||||
transition: box-shadow var(--baseAnimationSpeed);
|
||||
&:hover,
|
||||
&:focus {
|
||||
@include shadowize(0px 2px 4px 1px var(--shadowColor));
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
display: flex;
|
||||
|
||||
@@ -238,28 +238,41 @@
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
&.image-preview {
|
||||
width: auto;
|
||||
min-width: 300px;
|
||||
min-height: 250px;
|
||||
max-width: 70%;
|
||||
max-height: 90%;
|
||||
|
||||
// preview elements
|
||||
img {
|
||||
max-width: 100%;
|
||||
border-top-left-radius: var(--baseRadius);
|
||||
border-top-right-radius: var(--baseRadius);
|
||||
}
|
||||
}
|
||||
&.pdf-preview {
|
||||
width: 70%;
|
||||
height: 90%;
|
||||
object {
|
||||
position:absolute;
|
||||
left:0;
|
||||
top:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
// preview variants
|
||||
&.preview-image {
|
||||
width: auto;
|
||||
min-width: 320px;
|
||||
min-height: 300px;
|
||||
max-width: 75%;
|
||||
max-height: 90%;
|
||||
}
|
||||
|
||||
&.preview-document,
|
||||
&.preview-video {
|
||||
width: 75%;
|
||||
height: 90%;
|
||||
}
|
||||
&.preview-audio {
|
||||
min-width: 320px;
|
||||
min-height: 300px;
|
||||
max-width: 90%;
|
||||
max-height: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,25 @@
|
||||
import { DateTime } from "luxon";
|
||||
|
||||
const imageExtensions = [
|
||||
".jpg", ".jpeg", ".png", ".svg",
|
||||
".gif", ".jfif", ".webp", ".avif",
|
||||
];
|
||||
|
||||
const videoExtensions = [
|
||||
".mp4", ".avi", ".mov", ".3gp", ".wmv",
|
||||
];
|
||||
|
||||
const audioExtensions = [
|
||||
".aa", ".aac", ".m4v", ".mp3",
|
||||
".ogg", ".oga", ".mogg", ".amr",
|
||||
];
|
||||
|
||||
const documentExtensions = [
|
||||
".pdf", ".doc", ".docx", ".xls",
|
||||
".xlsx", ".ppt", ".pptx", ".odp",
|
||||
".odt", ".ods", ".txt",
|
||||
];
|
||||
|
||||
export default class CommonHelper {
|
||||
/**
|
||||
* Checks whether value is plain object.
|
||||
@@ -654,34 +674,56 @@ export default class CommonHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
* Loosely check if a file is an image based on its filename extension.
|
||||
* Loosely check if a file has image extension.
|
||||
*
|
||||
* @param {String} filename
|
||||
* @return {Boolean}
|
||||
*/
|
||||
static hasImageExtension(filename) {
|
||||
return /\.jpg|\.jpeg|\.png|\.svg|\.gif|\.jfif|\.webp|\.avif$/.test(filename)
|
||||
return !!imageExtensions.find((ext) => filename.endsWith(ext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loosely check if a file is a pdf based on its filename extension.
|
||||
* Loosely check if a file has video extension.
|
||||
*
|
||||
* @param {String} filename
|
||||
* @return {Boolean}
|
||||
*/
|
||||
static hasPdfExtension(filename) {
|
||||
return /\.pdf$/.test(filename);
|
||||
static hasVideoExtension(filename) {
|
||||
return !!videoExtensions.find((ext) => filename.endsWith(ext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns file type
|
||||
* Loosely check if a file has audio extension.
|
||||
*
|
||||
* @param {String} filename
|
||||
* @return {Boolean}
|
||||
*/
|
||||
static hasAudioExtension(filename) {
|
||||
return !!audioExtensions.find((ext) => filename.endsWith(ext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loosely check if a file has document extension.
|
||||
*
|
||||
* @param {String} filename
|
||||
* @return {Boolean}
|
||||
*/
|
||||
static hasDocumentExtension(filename) {
|
||||
return !!documentExtensions.find((ext) => filename.endsWith(ext));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the file type based on its filename.
|
||||
*
|
||||
* @param {String} filename
|
||||
* @return {String}
|
||||
*/
|
||||
static getFileType(filename) {
|
||||
if (this.hasImageExtension(filename)) return "image";
|
||||
if (this.hasPdfExtension(filename)) return "pdf";
|
||||
if (CommonHelper.hasImageExtension(filename)) return "image";
|
||||
if (CommonHelper.hasDocumentExtension(filename)) return "document";
|
||||
if (CommonHelper.hasVideoExtension(filename)) return "video";
|
||||
if (CommonHelper.hasAudioExtension(filename)) return "audio";
|
||||
return "file";
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user