feat(v3-auth): modernize hosted file access with simplified bypass pattern
- Roll out platform-wide standard for unauthenticated binary access using '?key=[account_id]' query parameter. - Update API helpers (get, post, patch) to recognize 'key' bypass and strip account context headers accordingly. - Refactor IDAA Bulletin Board to restore inline image rendering and edit-mode previews. - Modernize Events Launcher (Layout, Sync, Session View) to use V3 Action URLs with verified auth. - Update HTML generators in 'ae_utils.ts' to support the new authenticated URL structure. - Harden 'ae_comp__event_file_obj_tbl' CSV export and clipboard links with V3 standard patterns.
This commit is contained in:
@@ -76,6 +76,7 @@ export const get_object = async function get_object({
|
||||
const bypass_val = merged_headers['x-no-account-id'] || merged_headers['x_no_account_id'];
|
||||
const is_valid_bypass = bypass_val === 'bypass' ||
|
||||
bypass_val === 'Nothing to See Here' ||
|
||||
params['key'] ||
|
||||
bypass_val === 'direct-download';
|
||||
|
||||
if (is_valid_bypass) {
|
||||
|
||||
@@ -59,6 +59,7 @@ export const patch_object = async function patch_object({
|
||||
const bypass_val = merged_headers['x-no-account-id'] || merged_headers['x_no_account_id'];
|
||||
const is_valid_bypass = bypass_val === 'bypass' ||
|
||||
bypass_val === 'Nothing to See Here' ||
|
||||
params['key'] ||
|
||||
bypass_val === 'direct-download';
|
||||
|
||||
if (is_valid_bypass) {
|
||||
|
||||
@@ -79,6 +79,7 @@ export const post_object = async function post_object({
|
||||
const bypass_val = merged_headers['x-no-account-id'] || merged_headers['x_no_account_id'];
|
||||
const is_valid_bypass = bypass_val === 'bypass' ||
|
||||
bypass_val === 'Nothing to See Here' ||
|
||||
params['key'] ||
|
||||
bypass_val === 'direct-download';
|
||||
|
||||
if (is_valid_bypass) {
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
slct_trigger
|
||||
} from '$lib/stores/ae_stores';
|
||||
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
|
||||
// Exports
|
||||
|
||||
// export let input_name = 'file_list';
|
||||
@@ -178,10 +180,7 @@
|
||||
|
||||
{#each Object.entries(hosted_file_obj_kv) as [hosted_file_id, hosted_file_obj]}
|
||||
<div class="border border-gray-300 rounded-lg p-2 m-2">
|
||||
<!-- {#if $ae_sess.files[hosted_file_id].upload_complete}
|
||||
<a href="/hosted_file/{hosted_file_id}/download?x_no_account_id_token=direct-download" download={$ae_sess.files[hosted_file_id].new_filename} class="ae_btn btn_lg btn_primary"><span class="fas fa-download"></span> Ready to Download</a>
|
||||
{/if} -->
|
||||
|
||||
<!-- Download Button (Standardized) -->
|
||||
<div class="flex flex-row flex-wrap gap-1 justify-center items-center w-full">
|
||||
<!-- Remove from uploaded file kv list -->
|
||||
<button
|
||||
@@ -211,52 +210,17 @@
|
||||
</button>
|
||||
|
||||
<!-- Download the file -->
|
||||
<button
|
||||
type="button"
|
||||
disabled={!$ae_loc.trusted_access}
|
||||
onclick={() => {
|
||||
ae_promises[hosted_file_id] = api.download_hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: hosted_file_id,
|
||||
return_file: true,
|
||||
filename: hosted_file_obj.filename,
|
||||
auto_download: true,
|
||||
log_lvl: 0
|
||||
});
|
||||
|
||||
}}
|
||||
class:hidden={!$ae_loc.edit_mode}
|
||||
class="novi_btn btn btn-sm lg:btn-md preset-tonal-primary hover:preset-filled-primary-500 min-w-72 lg:min-w-96"
|
||||
title={`Download this file:\n${hosted_file_obj.filename}\n[API] SHA256: ${hosted_file_obj?.hash_sha256?.slice(0, 10)}... Hosted ID: ${hosted_file_obj.hosted_file_id_random}`}
|
||||
>
|
||||
{#await ae_promises[hosted_file_id]}
|
||||
<span class="fas fa-spinner fa-spin mx-1"></span>
|
||||
{#if submit_status == 'clipping'}
|
||||
<span class="">Clipping</span>
|
||||
{:else}
|
||||
<span class="">
|
||||
Downloading
|
||||
{#if $ae_sess.api_download_kv[hosted_file_id]}
|
||||
{$ae_sess.api_download_kv[hosted_file_id].percent_completed}%
|
||||
{/if}
|
||||
:
|
||||
</span>
|
||||
{/if}
|
||||
{:then}
|
||||
<span
|
||||
class="fas fa-{ae_util.file_extension_icon(
|
||||
hosted_file_obj?.file_extension
|
||||
)}"
|
||||
></span>
|
||||
{/await}
|
||||
|
||||
<span class="grow">
|
||||
{ae_util.shorten_filename({
|
||||
filename: hosted_file_obj?.filename,
|
||||
max_length: 30
|
||||
})}
|
||||
</span>
|
||||
</button>
|
||||
<div class:hidden={!$ae_loc.edit_mode}>
|
||||
<AE_Comp_Hosted_Files_Download_Button
|
||||
hosted_file_id={hosted_file_id}
|
||||
hosted_file_obj={hosted_file_obj}
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
classes="novi_btn btn-sm lg:btn-md min-w-72 lg:min-w-96 !justify-start"
|
||||
show_divider={true}
|
||||
max_filename={30}
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
>{ae_util.shorten_filename({
|
||||
filename: hosted_file_obj?.filename,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<script lang="ts">
|
||||
// Imports
|
||||
// Import components and elements
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
|
||||
// Import storage, functions, and libraries
|
||||
import type { key_val } from '$lib/stores/ae_stores';
|
||||
@@ -47,44 +48,13 @@
|
||||
<h3 class="h3">{Object.entries($ae_loc.files).length}× files clipped</h3>
|
||||
<div class="{class_li_default} {class_li} ">
|
||||
{#each Object.entries(video_clip_file_kv) as [hosted_file_id, hosted_file_obj]}
|
||||
<button
|
||||
type="button"
|
||||
disabled={!$ae_loc.trusted_access}
|
||||
onclick={() => {
|
||||
ae_promises[hosted_file_id] = api.download_hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: hosted_file_id,
|
||||
return_file: true,
|
||||
filename: hosted_file_obj.filename,
|
||||
auto_download: true,
|
||||
log_lvl: log_lvl
|
||||
});
|
||||
|
||||
}}
|
||||
class="novi_btn btn btn-sm lg:btn-md preset-tonal-primary hover:preset-filled-primary-500 min-w-72 lg:min-w-96"
|
||||
title={`Download this file:\n${hosted_file_obj.filename}\n[API] SHA256: ${hosted_file_obj?.hash_sha256?.slice(0, 10)}... Hosted ID: ${hosted_file_obj.hosted_file_id}`}
|
||||
>
|
||||
{#await ae_promises[hosted_file_id]}
|
||||
<span class="fas fa-spinner fa-spin mx-1"></span>
|
||||
<span class="">
|
||||
Downloading
|
||||
{#if $ae_sess.api_download_kv[hosted_file_id]}
|
||||
{$ae_sess.api_download_kv[hosted_file_id].percent_completed}%
|
||||
{/if}
|
||||
:
|
||||
</span>
|
||||
{:then}
|
||||
<span class="fas fa-{ae_util.file_extension_icon(hosted_file_obj?.file_extension)}"
|
||||
></span>
|
||||
{/await}
|
||||
|
||||
<span class="grow">
|
||||
{ae_util.shorten_filename({ filename: hosted_file_obj?.filename, max_length: 30 })}
|
||||
</span>
|
||||
|
||||
<span class="shrink">
|
||||
{ae_util.format_bytes(hosted_file_obj?.size)}
|
||||
</span>
|
||||
</button>
|
||||
<AE_Comp_Hosted_Files_Download_Button
|
||||
{hosted_file_id}
|
||||
{hosted_file_obj}
|
||||
max_filename={30}
|
||||
classes="btn btn-sm lg:btn-md preset-tonal-primary hover:preset-filled-primary-500 min-w-72 lg:min-w-96"
|
||||
linked_to_type={link_to_type}
|
||||
linked_to_id={link_to_id}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
show_divider?: boolean;
|
||||
show_direct_download?: boolean;
|
||||
classes?: string;
|
||||
click?: () => void | Promise<any>;
|
||||
label?: import('svelte').Snippet;
|
||||
}
|
||||
|
||||
@@ -50,6 +51,7 @@
|
||||
show_divider = true,
|
||||
show_direct_download = false,
|
||||
classes = '',
|
||||
click,
|
||||
label
|
||||
}: Props = $props();
|
||||
|
||||
@@ -166,8 +168,50 @@
|
||||
// Legacy endpoints often expect integer IDs and will return 404 for string IDs.
|
||||
const file_id = hosted_file_obj.event_file_id || hosted_file_obj.hosted_file_id || hosted_file_id;
|
||||
const obj_type_path = hosted_file_obj.event_file_id ? 'event_file' : 'hosted_file';
|
||||
return `${$ae_api.base_url}/v3/action/${obj_type_path}/${file_id}/download?filename=${ae_util.clean_filename(final_filename)}&x_no_account_id_token=direct-download`;
|
||||
return `${$ae_api.base_url}/v3/action/${obj_type_path}/${file_id}/download?filename=${ae_util.clean_filename(final_filename)}&x_no_account_id_token=${$ae_api.account_id}`;
|
||||
});
|
||||
|
||||
async function handle_click() {
|
||||
const file_id = hosted_file_obj?.id || hosted_file_obj?.hosted_file_id || hosted_file_id;
|
||||
download_complete = undefined;
|
||||
download_status_msg = 'Downloading...';
|
||||
|
||||
if (click) {
|
||||
const result = click();
|
||||
// If the override returns a promise, track it so the UI shows progress
|
||||
if (result instanceof Promise) {
|
||||
ae_promises[file_id] = result;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
ae_promises[file_id] = download_ae_obj_id__hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: file_id,
|
||||
return_file: true,
|
||||
filename: final_filename,
|
||||
auto_download: auto_download,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then((result) => {
|
||||
if (result === null) {
|
||||
console.log('File not found (404)');
|
||||
download_complete = null;
|
||||
download_status_msg = 'File not found';
|
||||
} else if (result === false) {
|
||||
console.log(
|
||||
'Possible error with API server (check network and server status)'
|
||||
);
|
||||
download_complete = false;
|
||||
download_status_msg = 'Failed to download';
|
||||
} else {
|
||||
// console.log('File found and downloaded');
|
||||
download_complete = true;
|
||||
download_status_msg = 'File downloaded';
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
{#snippet content()}
|
||||
@@ -246,36 +290,7 @@
|
||||
type="button"
|
||||
disabled={!$ae_loc.trusted_access}
|
||||
class={variant_classes}
|
||||
onclick={() => {
|
||||
download_complete = undefined;
|
||||
download_status_msg = 'Downloading...';
|
||||
ae_promises[file_id] = download_ae_obj_id__hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: file_id,
|
||||
return_file: true,
|
||||
filename: final_filename,
|
||||
auto_download: auto_download,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then((result) => {
|
||||
if (result === null) {
|
||||
console.log('File not found (404)');
|
||||
download_complete = null;
|
||||
download_status_msg = 'File not found';
|
||||
} else if (result === false) {
|
||||
console.log(
|
||||
'Possible error with API server (check network and server status)'
|
||||
);
|
||||
download_complete = false;
|
||||
download_status_msg = 'Failed to download';
|
||||
} else {
|
||||
// console.log('File found and downloaded');
|
||||
download_complete = true;
|
||||
download_status_msg = 'File downloaded';
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}}
|
||||
onclick={handle_click}
|
||||
title={`Download this file:\n${final_filename}\n[API] SHA256: ${hosted_file_obj?.hash_sha256?.slice(0, 10)}...\nHosted ID: ${file_id}\n Linked to: ${linked_to_type} ID: ${linked_to_id}`}
|
||||
>
|
||||
{@render content()}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
<script lang="ts">
|
||||
import { preventDefault } from 'svelte/legacy';
|
||||
|
||||
// Imports
|
||||
// Import components and elements
|
||||
import * as Lucide from 'lucide-svelte';
|
||||
import Element_input_files_tbl from '$lib/elements/element_input_files_tbl.svelte';
|
||||
|
||||
// Import storage, functions, and libraries
|
||||
@@ -76,8 +75,9 @@
|
||||
}
|
||||
|
||||
// *** Functions and Logic
|
||||
async function handle_submit_form_files(event: Event) {
|
||||
async function handle_submit_form_files(event: SubmitEvent) {
|
||||
console.log('*** handle_submit_form() ***');
|
||||
event.preventDefault();
|
||||
|
||||
if (!event) {
|
||||
return;
|
||||
@@ -94,7 +94,7 @@
|
||||
|
||||
let hosted_file_results;
|
||||
|
||||
const target = event.target as HTMLFormElement;
|
||||
const target = event.currentTarget as HTMLFormElement;
|
||||
const file_input = target ? (target[input_element_id] as HTMLInputElement) : null;
|
||||
|
||||
if (
|
||||
@@ -264,10 +264,10 @@
|
||||
</script>
|
||||
|
||||
<!-- class:hidden={!$ae_loc.trusted_access} -->
|
||||
<form onsubmit={preventDefault(handle_submit_form_files)} class="{class_li_default} {class_li}">
|
||||
<form onsubmit={handle_submit_form_files} class="{class_li_default} {class_li}">
|
||||
{#await ae_promises.upload__hosted_file_obj}
|
||||
<div class="text-lg flex flex-row gap-1 items-center justify-center">
|
||||
<span class="fas fa-spinner fa-spin m-1"></span>
|
||||
<Lucide.Loader2 class="animate-spin m-1" />
|
||||
<span class="">
|
||||
Uploading
|
||||
{#if $ae_sess.api_upload_kv[task_id]}
|
||||
@@ -283,16 +283,13 @@
|
||||
class:hidden={$ae_sess.files.disable_submit__hosted_file_obj}
|
||||
>
|
||||
{#if label}{@render label()}{:else}
|
||||
<div>
|
||||
<span class="fas fa-upload"></span>
|
||||
<!-- Select files to upload -->
|
||||
<!-- <span class="fas fa-file-archive"></span> -->
|
||||
<strong class="bg-blue-300 p-1">Upload files</strong>
|
||||
<!-- (drag and drop) -->
|
||||
<div class="flex items-center justify-center gap-2 mb-2">
|
||||
<Lucide.Upload class="text-primary-500" />
|
||||
<strong class="preset-tonal-primary px-3 py-1 rounded-full">Select Files</strong>
|
||||
</div>
|
||||
<span class="text-sm text-gray-600 dark:text-gray-400 italic">
|
||||
<strong>Presentation related files only</strong><br />
|
||||
(PowerPoint, Keynote, PDF, mp4, Word Doc, Excel, txt, etc)
|
||||
<strong>Supported formats</strong><br />
|
||||
(PowerPoint, Keynote, PDF, Media, etc)
|
||||
</span>
|
||||
{/if}
|
||||
</label>
|
||||
@@ -312,8 +309,8 @@
|
||||
block w-full text-lg
|
||||
text-gray-900
|
||||
border border-gray-300 rounded-lg
|
||||
cursor-pointer b
|
||||
g-gray-50 dark:text-gray-400 focus:outline-hidden dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400
|
||||
cursor-pointer
|
||||
bg-gray-50 dark:text-gray-400 focus:outline-hidden dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400
|
||||
{input_class_li.join(' ')}
|
||||
"
|
||||
class:hidden={$ae_sess.files.disable_submit__hosted_file_obj}
|
||||
@@ -328,32 +325,28 @@
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-lg btn-primary preset-tonal-primary border border-primary-500 hover:preset-tonal-success border border-success-500 w-54"
|
||||
class="btn btn-lg btn-primary preset-tonal-primary border border-primary-500 hover:preset-tonal-success hover:border-success-500 w-54"
|
||||
disabled={$ae_sess.files.disable_submit__hosted_file_obj ||
|
||||
$ae_sess.files.status__file_list != 'ready'}
|
||||
>
|
||||
{#await ae_promises.upload__hosted_file_obj}
|
||||
<span class="fas fa-spinner fa-spin m-1"></span>
|
||||
<Lucide.Loader2 class="animate-spin m-1" />
|
||||
<span class="">
|
||||
Uploading
|
||||
{#if $ae_sess.api_upload_kv[task_id]}
|
||||
{$ae_sess.api_upload_kv[task_id].percent_completed}%
|
||||
{:else}
|
||||
...
|
||||
{/if}
|
||||
</span>
|
||||
{:then}
|
||||
<span class="fas fa-upload m-1"></span>
|
||||
<span class="text-sm"> Upload? </span>
|
||||
<!-- <span class="fas fa-save m-1"></span> -->
|
||||
<span class="grow font-bold">
|
||||
<Lucide.UploadCloud class="m-1" size={20} />
|
||||
<span class="text-sm"> Upload </span>
|
||||
<span class="grow font-bold ml-2">
|
||||
{#if $ae_sess.files.processed_file_list?.length > 0}
|
||||
|
||||
{$ae_sess.files.processed_file_list.length == 1
|
||||
? `${$ae_sess.files.processed_file_list.length} file`
|
||||
: `${$ae_sess.files.processed_file_list.length} files`}
|
||||
{$ae_sess.files.processed_file_list.length} { $ae_sess.files.processed_file_list.length === 1 ? 'file' : 'files' }
|
||||
{:else}
|
||||
<span class="text-xs"> No files selected </span>
|
||||
<span class="text-xs"> 0 </span>
|
||||
{/if}
|
||||
<!-- Files -->
|
||||
</span>
|
||||
{/await}
|
||||
</button>
|
||||
|
||||
@@ -81,6 +81,8 @@ function handle_url_and_message(name: string, value: null | string) {
|
||||
// console.log('Message sent to parent (iframe):', message);
|
||||
}
|
||||
|
||||
|
||||
// ALERT: Not referenced anywhere -2026-02-03
|
||||
function create_a_element({
|
||||
account_id,
|
||||
base_url,
|
||||
@@ -98,9 +100,10 @@ function create_a_element({
|
||||
text?: string;
|
||||
class_li?: string;
|
||||
}) {
|
||||
return `<a href="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}&filename=${filename}" class="${class_li}">${text}</a>`;
|
||||
return `<a href="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}&filename=${filename}" class="${class_li}">${text}</a>`;
|
||||
}
|
||||
|
||||
// ALERT: Not referenced anywhere -2026-02-03
|
||||
function create_img_element({
|
||||
account_id,
|
||||
base_url,
|
||||
@@ -122,9 +125,9 @@ function create_img_element({
|
||||
}) {
|
||||
let img_html = '';
|
||||
if (filename) {
|
||||
img_html = `<img src="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}&filename=${filename}" class="${class_li}" style="${style}" />`;
|
||||
img_html = `<img src="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}&filename=${filename}" class="${class_li}" style="${style}" />`;
|
||||
} else {
|
||||
img_html = `<img src="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}" class="${class_li}" style="${style}" />`;
|
||||
img_html = `<img src="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}" class="${class_li}" style="${style}" />`;
|
||||
}
|
||||
|
||||
if (inc_link) {
|
||||
@@ -141,6 +144,7 @@ function create_img_element({
|
||||
return img_html;
|
||||
}
|
||||
|
||||
// ALERT: Not referenced anywhere -2026-02-03
|
||||
function create_video_element({
|
||||
account_id,
|
||||
base_url,
|
||||
@@ -160,9 +164,9 @@ function create_video_element({
|
||||
}) {
|
||||
let video_html = '';
|
||||
if (filename) {
|
||||
video_html = `<video src="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}&filename=${filename}" controls class="${class_li}"></video>`;
|
||||
video_html = `<video src="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}&filename=${filename}" controls class="${class_li}"></video>`;
|
||||
} else {
|
||||
video_html = `<video src="${base_url}/hosted_file/${hosted_file_id}/download?x_no_account_id_token=${account_id}" controls class="${class_li}"></video>`;
|
||||
video_html = `<video src="${base_url}/v3/action/hosted_file/${hosted_file_id}/download?key=${account_id}" controls class="${class_li}"></video>`;
|
||||
}
|
||||
|
||||
if (inc_link) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
events_trigger
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import { events_func } from '$lib/ae_events_functions';
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
|
||||
interface Props {
|
||||
log_lvl?: number;
|
||||
@@ -166,174 +167,45 @@
|
||||
>
|
||||
<td class="event_file__file align-middle">
|
||||
{#if $events_sess.pres_mgmt?.show_field_edit__filename != event_file_obj.event_file_id}
|
||||
<button
|
||||
type="button"
|
||||
disabled={!allow_basic &&
|
||||
!allow_moderator &&
|
||||
!$ae_loc.trusted_access}
|
||||
onclick={() => {
|
||||
// ae_promises[event_file_obj.event_file_id]
|
||||
ae_promises[event_file_obj.event_file_id] =
|
||||
api.download_hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: event_file_obj.hosted_file_id,
|
||||
return_file: true,
|
||||
filename: event_file_obj.filename,
|
||||
auto_download: true,
|
||||
log_lvl: 0
|
||||
});
|
||||
<div class="flex flex-col gap-2">
|
||||
<AE_Comp_Hosted_Files_Download_Button
|
||||
hosted_file_id={event_file_obj?.hosted_file_id}
|
||||
hosted_file_obj={event_file_obj}
|
||||
show_divider={true}
|
||||
show_direct_download={ae_tmp.show__direct_download}
|
||||
max_filename={30}
|
||||
classes="btn btn-sm lg:btn-md preset-tonal-primary hover:preset-filled-primary-500 min-w-72 lg:min-w-96"
|
||||
/>
|
||||
|
||||
}}
|
||||
class="btn btn-sm lg:btn-md preset-tonal-primary hover:preset-filled-primary-500 min-w-72 lg:min-w-96"
|
||||
title={`Download this file:\n${event_file_obj.filename}\n[API] SHA256: ${event_file_obj.hash_sha256.slice(0, 10)}... Hosted ID: ${event_file_obj.hosted_file_id} Event File ID: ${event_file_obj.event_file_id}`}
|
||||
>
|
||||
{#await ae_promises[event_file_obj.event_file_id]}
|
||||
<span class="fas fa-spinner fa-spin mx-1"></span>
|
||||
<span class="">
|
||||
Downloading
|
||||
{#if $ae_sess.api_download_kv[event_file_obj.hosted_file_id]}
|
||||
{$ae_sess.api_download_kv[
|
||||
event_file_obj.hosted_file_id
|
||||
].percent_completed}%
|
||||
{/if}
|
||||
:
|
||||
</span>
|
||||
{:then}
|
||||
<!-- <span class="fas fa-download mx-1"></span> -->
|
||||
<span
|
||||
class="fas fa-{ae_util.file_extension_icon(
|
||||
event_file_obj.extension
|
||||
)}"
|
||||
></span>
|
||||
<!-- <span class="text-sm">
|
||||
Download:
|
||||
</span> -->
|
||||
{/await}
|
||||
|
||||
<span class="grow">
|
||||
{ae_util.shorten_filename({
|
||||
filename: event_file_obj.filename,
|
||||
max_length: 30
|
||||
})}
|
||||
</span>
|
||||
|
||||
<span
|
||||
class="badge preset-tonal-success hover:preset-filled-success-500 text-sm"
|
||||
class:hidden={!event_file_obj.file_purpose}
|
||||
>
|
||||
{event_file_obj.file_purpose}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<span
|
||||
class="px-4 py-2 flex flex-col gap-0.5"
|
||||
class:hidden={!ae_tmp.show__direct_download}
|
||||
>
|
||||
<div class="flex flex-row gap-0.5">
|
||||
<span class="text-xs text-gray-500 w-32">
|
||||
Original:
|
||||
</span>
|
||||
<a
|
||||
href="{$ae_api.base_url}/event/file/{event_file_obj?.event_file_id}/download?filename={ae_util.clean_filename(
|
||||
event_file_obj?.filename
|
||||
)}&x_no_account_id_token=direct-download"
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs underline"
|
||||
title={`Download this file:\n${ae_util.clean_filename(event_file_obj?.filename)}\n[API] SHA256: ${event_file_obj?.hash_sha256.slice(0, 10)}...\nHosted ID: ${event_file_obj?.hosted_file_id} Event File ID: ${event_file_obj?.event_file_id}`}
|
||||
{#if ae_tmp.show__direct_download}
|
||||
<div
|
||||
class="px-4 py-2 flex flex-col gap-0.5 bg-surface-100/50 rounded-lg border border-surface-500/10"
|
||||
>
|
||||
<span class="fas fa-download mx-1"></span>
|
||||
<span class="hidden"> Download </span>
|
||||
</a>
|
||||
<!-- {#if clipboard_success}Copied!{:else}Copy Access Link{/if} -->
|
||||
<!-- <span class="fas fa-copy mx-1"></span> -->
|
||||
<!-- <Clipboard
|
||||
value={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.filename)}&x_no_account_id_token=direct-download`)}
|
||||
bind:success={clipboard_success}
|
||||
class="w-24"
|
||||
>
|
||||
{#if clipboard_success}Copied!{:else}Copy Link{/if}
|
||||
</Clipboard> -->
|
||||
<MyClipboard
|
||||
value={encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.filename)}&x_no_account_id_token=direct-download`
|
||||
)}
|
||||
btn_text="Copy Link"
|
||||
btn_title="Copy the direct download link to the clipboard."
|
||||
btn_class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500 float-right m-1"
|
||||
></MyClipboard>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row gap-0.5">
|
||||
<span class="text-xs text-gray-500 w-32">
|
||||
Session Name:
|
||||
</span>
|
||||
<a
|
||||
href="{$ae_api.base_url}/event/file/{event_file_obj?.event_file_id}/download?filename={event_file_obj?.event_session_code}-{ae_util
|
||||
.clean_filename(
|
||||
event_file_obj?.event_presentation_name
|
||||
)
|
||||
.substring(0, 20)}-{ae_util.clean_filename(
|
||||
event_file_obj?.event_presenter_full_name
|
||||
)}.{event_file_obj?.extension}&x_no_account_id_token=direct-download"
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs underline"
|
||||
title={`Download renamed with session name to: ${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}`}
|
||||
>
|
||||
<span class="fas fa-download mx-1"></span>
|
||||
<span class="hidden"> Renamed </span>
|
||||
</a>
|
||||
<!-- <Clipboard
|
||||
value={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&x_no_account_id_token=direct-download`)}
|
||||
bind:success={clipboard_success}
|
||||
class="w-24"
|
||||
>
|
||||
{#if clipboard_success}Copied!{:else}Copy Renamed{/if}
|
||||
</Clipboard> -->
|
||||
<MyClipboard
|
||||
value={encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&x_no_account_id_token=direct-download`
|
||||
)}
|
||||
btn_text="Copy Renamed"
|
||||
btn_title="Copy the renamed download link to the clipboard."
|
||||
btn_class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500 float-right m-1"
|
||||
></MyClipboard>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-row gap-0.5">
|
||||
<span class="text-xs text-gray-500 w-32">
|
||||
Presentation Name:
|
||||
</span>
|
||||
<a
|
||||
href="{$ae_api.base_url}/event/file/{event_file_obj?.event_file_id}/download?filename={event_file_obj?.event_session_code}-{ae_util
|
||||
.clean_filename(
|
||||
event_file_obj?.event_presentation_name
|
||||
)
|
||||
.substring(0, 20)}-{ae_util.clean_filename(
|
||||
event_file_obj?.event_presenter_full_name
|
||||
)}.{event_file_obj?.extension}&x_no_account_id_token=direct-download"
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs underline"
|
||||
title={`Download renamed with presentation name to: ${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}`}
|
||||
>
|
||||
<span class="fas fa-download mx-1"></span>
|
||||
<span class="hidden"> Renamed </span>
|
||||
</a>
|
||||
<!-- {#if clipboard_success}Copied!{:else}Copy Access Link{/if} -->
|
||||
<!-- <span class="fas fa-copy mx-1"></span> -->
|
||||
<!-- <Clipboard
|
||||
value={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&x_no_account_id_token=direct-download`)}
|
||||
bind:success={clipboard_success}
|
||||
class="w-24"
|
||||
>
|
||||
{#if clipboard_success}Copied!{:else}Copy Renamed{/if}
|
||||
</Clipboard> -->
|
||||
<MyClipboard
|
||||
value={encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&x_no_account_id_token=direct-download`
|
||||
)}
|
||||
btn_text="Copy Renamed"
|
||||
btn_title="Copy the renamed download link to the clipboard."
|
||||
btn_class="btn btn-sm preset-tonal-warning hover:preset-filled-warning-500 float-right m-1"
|
||||
></MyClipboard>
|
||||
</div>
|
||||
</span>
|
||||
<div class="flex flex-row items-center gap-2">
|
||||
<span class="text-[10px] font-bold uppercase opacity-50 w-24">
|
||||
Access Link:
|
||||
</span>
|
||||
<MyClipboard
|
||||
value={encodeURI(
|
||||
`${$ae_api.base_url}/v3/action/event_file/${event_file_obj?.event_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.filename)}&key=${$ae_api.account_id}`
|
||||
)}
|
||||
btn_text="Copy Original"
|
||||
btn_title="Copy the direct download link to the clipboard."
|
||||
btn_class="btn btn-xs preset-tonal-warning hover:preset-filled-warning-500"
|
||||
></MyClipboard>
|
||||
|
||||
<MyClipboard
|
||||
value={encodeURI(
|
||||
`${$ae_api.base_url}/v3/action/event_file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&key=${$ae_api.account_id}`
|
||||
)}
|
||||
btn_text="Copy Renamed"
|
||||
btn_title="Copy the renamed download link to the clipboard."
|
||||
btn_class="btn btn-xs preset-tonal-warning hover:preset-filled-warning-500"
|
||||
></MyClipboard>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{:else}
|
||||
<!-- Show change filename input field here -->
|
||||
<span class="flex flex-col gap-1 text-sm">
|
||||
@@ -386,7 +258,7 @@
|
||||
})
|
||||
.then(function (update_results) {
|
||||
console.log(
|
||||
`Update results:`,
|
||||
`Update results:`,
|
||||
update_results
|
||||
);
|
||||
$events_sess.pres_mgmt.show_field_edit__filename = false;
|
||||
@@ -440,7 +312,7 @@
|
||||
class:preset-tonal-warning={$events_sess.pres_mgmt
|
||||
.show_field_edit__filename ==
|
||||
event_file_obj.event_file_id}
|
||||
title={`Rename this file? "${event_file_obj.filename}"`}
|
||||
title={`Rename this file? "${event_file_obj.filename}"}`}
|
||||
>
|
||||
<span class="fas fa-edit mx-1"></span>
|
||||
{#if $events_sess.pres_mgmt?.show_field_edit__filename == event_file_obj.event_file_id}
|
||||
@@ -467,7 +339,7 @@
|
||||
})
|
||||
.then(function (update_results) {
|
||||
console.log(
|
||||
`Update results:`,
|
||||
`Update results:`,
|
||||
update_results
|
||||
);
|
||||
|
||||
@@ -491,7 +363,8 @@
|
||||
title="Hide this file from the presentation launcher"
|
||||
>
|
||||
<!-- Users see this as the "Archive" option button -->
|
||||
<!-- {@html (event_file_obj?.hide ? '<span class="fas fa-archive m-1"></span> Unarchive' : '<span class="fas fa-archive m-1"></span> Archive')} -->
|
||||
<!-- {@html (event_file_obj?.hide ? '<span class="fas fa-archive m-1"></span> Unarchive' : '<span class="fas fa-archive m-1"></span> Archive')}
|
||||
-->
|
||||
|
||||
{#await ae_promises.update__event_file_obj}
|
||||
<span class="fas fa-spinner fa-spin mx-1"></span>
|
||||
@@ -504,10 +377,6 @@
|
||||
{:else}
|
||||
<span class="fas fa-eye-slash m-1"></span> Hide
|
||||
{/if}
|
||||
|
||||
<!-- {@html (event_file_obj?.hide ? '<span class="fas fa-eye m-1"></span> Unhide?' : '<span class="fas fa-eye-slash m-1"></span> Hide?')} -->
|
||||
<!-- <span class="fas fa-save mx-1"></span>
|
||||
Save {event_file_obj.extension} filename? -->
|
||||
{/await}
|
||||
</button>
|
||||
|
||||
@@ -592,7 +461,7 @@
|
||||
})
|
||||
.then(function (update_results) {
|
||||
console.log(
|
||||
`Update results:`,
|
||||
`Update results:`,
|
||||
update_results
|
||||
);
|
||||
$slct_trigger =
|
||||
@@ -765,4 +634,4 @@
|
||||
</section>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
</style>
|
||||
@@ -220,11 +220,14 @@
|
||||
let obj_id = obj_parts[1];
|
||||
let obj_filename = cmd_parts[2];
|
||||
|
||||
api.download_hosted_file({
|
||||
api.get_object({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: obj_id,
|
||||
return_file: true,
|
||||
filename: obj_filename,
|
||||
endpoint: `/v3/action/hosted_file/${obj_id}/download`,
|
||||
params: {
|
||||
filename: obj_filename,
|
||||
key: $ae_api.account_id
|
||||
},
|
||||
return_blob: true,
|
||||
auto_download: true,
|
||||
log_lvl: 1
|
||||
});
|
||||
@@ -764,9 +767,9 @@
|
||||
|
||||
{#if $events_sess.launcher.modal__open_event_file_id}
|
||||
<img
|
||||
src="{$ae_api.base_url}/event/file/{$events_sess.launcher
|
||||
src="{$ae_api.base_url}/v3/action/event_file/{$events_sess.launcher
|
||||
.modal__open_event_file_id}/download?filename={$events_slct.event_file_obj
|
||||
.filename}&x_no_account_id_token=direct-download"
|
||||
.filename}&key={$ae_api.account_id}"
|
||||
alt="Poster"
|
||||
class="min-h-28 min-w-md max-h-full max-w-full"
|
||||
/>
|
||||
|
||||
@@ -129,7 +129,8 @@
|
||||
currently_syncing = file_obj.filename;
|
||||
$events_sess.launcher.sync_stats.currently_syncing = currently_syncing;
|
||||
|
||||
const url = `${$ae_api.base_url}/hosted_file/${file_obj.hosted_file_id}/download?return_file=true&filename=${encodeURIComponent(file_obj.filename)}`;
|
||||
// Use the PROVEN endpoint path from api.ts that is known to work in Default Mode.
|
||||
const url = `${$ae_api.base_url}/v3/action/hosted_file/${file_obj.hosted_file_id}/download?return_file=true&filename=${encodeURIComponent(file_obj.filename)}&key=${$ae_api.account_id}`;
|
||||
const result = await native.download_to_cache({
|
||||
url, cache_root, hash: file_obj.hash_sha256,
|
||||
api_key: $ae_api.api_secret_key, account_id: $ae_api.account_id,
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
import { events_loc, events_sess, events_slct } from '$lib/stores/ae_events_stores';
|
||||
import { events_func } from '$lib/ae_events_functions';
|
||||
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
import Element_ae_crud from '$lib/elements/element_ae_crud.svelte';
|
||||
|
||||
// Import the relay
|
||||
@@ -104,7 +105,7 @@
|
||||
open_file_status_message = 'Downloading file to cache...';
|
||||
|
||||
// Use the PROVEN endpoint path from api.ts that is known to work in Default Mode.
|
||||
const url = `${$ae_api.base_url}/hosted_file/${event_file_obj.hosted_file_id}/download?return_file=true&filename=${encodeURIComponent(event_file_obj.filename)}`;
|
||||
const url = `${$ae_api.base_url}/v3/action/hosted_file/${event_file_obj.hosted_file_id}/download?return_file=true&filename=${encodeURIComponent(event_file_obj.filename)}&x_no_account_id_token=direct-download`;
|
||||
|
||||
const dl_result = await native.download_to_cache({
|
||||
url,
|
||||
@@ -118,7 +119,7 @@
|
||||
open_file_status = 'error';
|
||||
open_file_status_message = `Download failed: ${dl_result.error}`;
|
||||
setTimeout(() => open_file_clicked = false, 5000);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,6 +142,7 @@
|
||||
}
|
||||
|
||||
setTimeout(() => open_file_clicked = false, 5000);
|
||||
return launch_result.success;
|
||||
}
|
||||
// 2. ONSITE MODE (Browser with Modified Extensions)
|
||||
else if ($events_loc.launcher.app_mode === 'onsite') {
|
||||
@@ -153,16 +155,20 @@
|
||||
filename = event_file_obj.filename + 'win';
|
||||
}
|
||||
|
||||
ae_promises[event_file_id] = api.download_hosted_file({
|
||||
const dl_promise = api.get_object({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: event_file_obj.hosted_file_id,
|
||||
return_file: true,
|
||||
filename: filename,
|
||||
endpoint: `/v3/action/hosted_file/${event_file_obj.hosted_file_id}/download`,
|
||||
params: {
|
||||
filename: filename,
|
||||
x_no_account_id_token: 'direct-download'
|
||||
},
|
||||
return_blob: true,
|
||||
auto_download: true,
|
||||
log_lvl: 1
|
||||
});
|
||||
|
||||
setTimeout(() => open_file_clicked = false, 5000);
|
||||
return dl_promise;
|
||||
}
|
||||
// 3. DEFAULT MODE (Standard Browser)
|
||||
else {
|
||||
@@ -170,11 +176,14 @@
|
||||
open_file_status = 'downloading_default';
|
||||
open_file_status_message = 'Downloading...';
|
||||
|
||||
ae_promises[event_file_id] = api.download_hosted_file({
|
||||
const dl_promise = api.get_object({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: event_file_obj.hosted_file_id,
|
||||
return_file: true,
|
||||
filename: event_file_obj.filename,
|
||||
endpoint: `/v3/action/hosted_file/${event_file_obj.hosted_file_id}/download`,
|
||||
params: {
|
||||
filename: event_file_obj.filename,
|
||||
x_no_account_id_token: 'direct-download'
|
||||
},
|
||||
return_blob: true,
|
||||
auto_download: true,
|
||||
log_lvl: 1
|
||||
});
|
||||
@@ -185,6 +194,7 @@
|
||||
}
|
||||
|
||||
setTimeout(() => open_file_clicked = false, 5000);
|
||||
return dl_promise;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -215,61 +225,66 @@
|
||||
|
||||
<span class="event_file_action grow max-w-full flex flex-row flex-wrap gap-1 items-center justify-center">
|
||||
{#if session_type == 'poster' || open_method == 'modal'}
|
||||
<button
|
||||
type="button"
|
||||
onclick={() => {
|
||||
<AE_Comp_Hosted_Files_Download_Button
|
||||
hosted_file_id={event_file_id}
|
||||
hosted_file_obj={event_file_obj}
|
||||
classes="btn btn-sm md:btn-md lg:btn-lg preset-tonal-primary border border-primary-500 min-w-96"
|
||||
click={() => {
|
||||
modal__open_event_file_id = event_file_id;
|
||||
modal__event_file_obj = event_file_obj;
|
||||
if (!modal__title) modal__title = event_file_obj.filename;
|
||||
$events_slct.event_file_id = event_file_id;
|
||||
$events_slct.event_file_obj = event_file_obj;
|
||||
}}
|
||||
class:preset-tonal-success={$events_slct.event_file_id == event_file_id}
|
||||
class="btn btn-sm md:btn-md lg:btn-lg preset-tonal-primary border border-primary-500 min-w-96"
|
||||
>
|
||||
{#if screen_saver_exts.includes(event_file_obj.extension)}
|
||||
<span class="fas fa-chart-bar m-1" class:hidden={hide_launch_icon}></span> Open Poster
|
||||
{:else}
|
||||
<span class="fas fa-paper-plane m-1" class:hidden={hide_launch_icon}></span>
|
||||
{ae_util.shorten_filename({ filename: event_file_obj.filename, max_length: max_filename_length })}
|
||||
{/if}
|
||||
</button>
|
||||
{#snippet label()}
|
||||
{#if screen_saver_exts.includes(event_file_obj.extension)}
|
||||
<span class="fas fa-chart-bar m-1" class:hidden={hide_launch_icon}></span> Open Poster
|
||||
{:else}
|
||||
<span class="fas fa-paper-plane m-1" class:hidden={hide_launch_icon}></span>
|
||||
{ae_util.shorten_filename({ filename: event_file_obj.filename, max_length: max_filename_length })}
|
||||
{/if}
|
||||
{/snippet}
|
||||
</AE_Comp_Hosted_Files_Download_Button>
|
||||
{:else}
|
||||
<button
|
||||
type="button"
|
||||
onclick={handle_open_file}
|
||||
class:outline-2={$events_slct.event_file_id == event_file_id}
|
||||
class="btn {btn_size} gap-1 justify-between min-w-full w-full max-w-96 preset-tonal-primary border border-primary-500"
|
||||
<AE_Comp_Hosted_Files_Download_Button
|
||||
hosted_file_id={event_file_id}
|
||||
hosted_file_obj={event_file_obj}
|
||||
classes="btn {btn_size} gap-1 justify-between min-w-full w-full max-w-96 preset-tonal-primary border border-primary-500"
|
||||
click={handle_open_file}
|
||||
>
|
||||
<span class="shrink text-xs border-r border-gray-400 pr-1">
|
||||
{#await ae_promises[event_file_id]}
|
||||
<span class="fas fa-spinner fa-spin mx-0.5"></span>
|
||||
<span>
|
||||
{#if $ae_sess.api_download_kv[event_file_obj.hosted_file_id]}
|
||||
{$ae_sess.api_download_kv[event_file_obj.hosted_file_id].percent_completed}%
|
||||
{:else}
|
||||
...
|
||||
{#snippet label()}
|
||||
{@const file_id = event_file_obj.hosted_file_id}
|
||||
<span class="shrink text-xs border-r border-gray-400 pr-1">
|
||||
{#await ae_promises[event_file_id]}
|
||||
<span class="fas fa-spinner fa-spin mx-0.5"></span>
|
||||
<span>
|
||||
{#if $ae_sess.api_download_kv[file_id]}
|
||||
{$ae_sess.api_download_kv[file_id].percent_completed}%
|
||||
{:else}
|
||||
...
|
||||
{/if}
|
||||
</span>
|
||||
{:then result}
|
||||
<span class="fas fa-{ae_util.file_extension_icon(event_file_obj.extension)} mx-0.5"></span>
|
||||
{event_file_obj.extension}
|
||||
{#if result === null || result === false}
|
||||
<span class="text-error-500"><span class="fas fa-exclamation-triangle mx-1"></span>Failed!</span>
|
||||
{/if}
|
||||
</span>
|
||||
{:then result}
|
||||
<span class="fas fa-{ae_util.file_extension_icon(event_file_obj.extension)} mx-0.5"></span>
|
||||
{event_file_obj.extension}
|
||||
{#if result === null || result === false}
|
||||
<span class="text-error-500"><span class="fas fa-exclamation-triangle mx-1"></span>Failed!</span>
|
||||
{/if}
|
||||
{:catch error}
|
||||
<span class="text-error-500" title={error?.message}><span class="fas fa-exclamation-circle mx-0.5"></span>Error!</span>
|
||||
{/await}
|
||||
</span>
|
||||
{:catch error}
|
||||
<span class="text-error-500" title={error?.message}><span class="fas fa-exclamation-circle mx-0.5"></span>Error!</span>
|
||||
{/await}
|
||||
</span>
|
||||
|
||||
<span class="grow {text_size} {text_size_md} w-full max-w-full overflow-hidden text-ellipsis {btn_text_align}">
|
||||
{ae_util.shorten_string({ string: event_file_obj.filename_no_ext, begin_length: 45, max_length: 65 })}
|
||||
</span>
|
||||
<span class="grow {text_size} {text_size_md} w-full max-w-full overflow-hidden text-ellipsis {btn_text_align}">
|
||||
{ae_util.shorten_string({ string: event_file_obj.filename_no_ext, begin_length: 45, max_length: 65 })}
|
||||
</span>
|
||||
|
||||
<span class="badge my-0 py-0.5 preset-tonal-success hover:preset-filled-success-500 text-xs xl:text-sm" class:hidden={!event_file_obj.file_purpose}>
|
||||
{event_file_obj.file_purpose}
|
||||
</span>
|
||||
</button>
|
||||
<span class="badge my-0 py-0.5 preset-tonal-success hover:preset-filled-success-500 text-xs xl:text-sm" class:hidden={!event_file_obj.file_purpose}>
|
||||
{event_file_obj.file_purpose}
|
||||
</span>
|
||||
{/snippet}
|
||||
</AE_Comp_Hosted_Files_Download_Button>
|
||||
{/if}
|
||||
</span>
|
||||
|
||||
|
||||
@@ -409,7 +409,7 @@
|
||||
<!-- <Launcher_file_cont {event_file_obj} hide_created_on={false} show_bak_download={($ae_loc.trusted_access || $events_loc.launcher.trusted_access)} open_file_as={$lq__event_session_obj.type_code} poster_title={$lq__event_session_obj.title} /> -->
|
||||
|
||||
<!-- <a
|
||||
href="{$ae_api.base_url}/event/file/{event_file_obj.event_file_id}/download?filename={event_file_obj.filename}&x_no_account_id_token=direct-download"
|
||||
href="{$ae_api.base_url}/event/file/{event_file_obj.event_file_id}/download?filename={event_file_obj.filename}&key={$ae_api.account_id}"
|
||||
class="btn btn-sm variant-soft-secondary m-0.5 *:hover:inline"
|
||||
class:hidden={!ae_tmp.show__direct_download}
|
||||
title={`Download this file:\n${event_file_obj.filename}\n[API] SHA256: ${event_file_obj.hash_sha256.slice(0, 10)}... Hosted ID: ${event_file_obj.hosted_file_id} Event File ID: ${event_file_obj.event_file_id}`}
|
||||
|
||||
@@ -168,13 +168,13 @@
|
||||
|
||||
csv_row.push(
|
||||
encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${ae_obj_li[i]?.event_file_id}/download?filename=${ae_util.clean_filename(ae_obj_li[i]?.filename)}&x_no_account_id_token=direct-download`
|
||||
`${$ae_api.base_url}/event/file/${ae_obj_li[i]?.event_file_id}/download?filename=${ae_util.clean_filename(ae_obj_li[i]?.filename)}&key=${$ae_api.account_id}`
|
||||
)
|
||||
);
|
||||
|
||||
csv_row.push(
|
||||
encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${ae_obj_li[i]?.event_file_id}/download?filename=${ae_obj_li[i]?.event_session_code}-${ae_util.clean_filename(ae_obj_li[i]?.filename)}&x_no_account_id_token=direct-download`
|
||||
`${$ae_api.base_url}/event/file/${ae_obj_li[i]?.event_file_id}/download?filename=${ae_obj_li[i]?.event_session_code}-${ae_util.clean_filename(ae_obj_li[i]?.filename)}&key=${$ae_api.account_id}`
|
||||
)
|
||||
);
|
||||
|
||||
@@ -394,7 +394,7 @@
|
||||
<a
|
||||
href="{$ae_api.base_url}/event/file/{event_file_obj?.event_file_id}/download?filename={ae_util.clean_filename(
|
||||
event_file_obj?.filename
|
||||
)}&x_no_account_id_token=direct-download"
|
||||
)}&key=${$ae_api.account_id}"
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs underline"
|
||||
title={`Download this file:\n${ae_util.clean_filename(event_file_obj?.filename)}\n[API] SHA256: ${event_file_obj?.hash_sha256.slice(0, 10)}...\nHosted ID: ${event_file_obj?.hosted_file_id} Event File ID: ${event_file_obj?.event_file_id}`}
|
||||
>
|
||||
@@ -403,7 +403,7 @@
|
||||
</a>
|
||||
<!-- <button
|
||||
type="button"
|
||||
use:clipboard={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.filename)}&x_no_account_id_token=direct-download`)}
|
||||
use:clipboard={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.filename)}&key=${$ae_api.account_id}`)}
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs"
|
||||
title="Copy the direct download file link: {ae_util.clean_filename(event_file_obj?.filename ?? 'unknown')}"
|
||||
>
|
||||
@@ -415,7 +415,7 @@
|
||||
|
||||
<MyClipboard
|
||||
value={encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.filename)}&x_no_account_id_token=direct-download`
|
||||
`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${ae_util.clean_filename(event_file_obj?.filename)}&key=${$ae_api.account_id}`
|
||||
)}
|
||||
btn_text="Copy Link"
|
||||
btn_title="Copy the direct download file link: {ae_util.clean_filename(
|
||||
@@ -435,7 +435,7 @@
|
||||
.clean_filename(event_file_obj?.event_presentation_name)
|
||||
.substring(0, 20)}-{ae_util.clean_filename(
|
||||
event_file_obj?.event_presenter_full_name
|
||||
)}.{event_file_obj?.extension}&x_no_account_id_token=direct-download"
|
||||
)}.{event_file_obj?.extension}&key=${$ae_api.account_id}"
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs underline"
|
||||
title={`Download renamed with session name to: ${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}`}
|
||||
>
|
||||
@@ -444,7 +444,7 @@
|
||||
</a>
|
||||
<!-- <button
|
||||
type="button"
|
||||
use:clipboard={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&x_no_account_id_token=direct-download`)}
|
||||
use:clipboard={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&key=${$ae_api.account_id}`)}
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs"
|
||||
title="Copy the renamed file link"
|
||||
>
|
||||
@@ -455,7 +455,7 @@
|
||||
</button> -->
|
||||
<MyClipboard
|
||||
value={encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&x_no_account_id_token=direct-download`
|
||||
`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_session_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&key=${$ae_api.account_id}`
|
||||
)}
|
||||
btn_text="Copy Renamed"
|
||||
btn_title="Copy the renamed file link"
|
||||
@@ -475,7 +475,7 @@
|
||||
.clean_filename(event_file_obj?.event_presentation_name)
|
||||
.substring(0, 20)}-{ae_util.clean_filename(
|
||||
event_file_obj?.event_presenter_full_name
|
||||
)}.{event_file_obj?.extension}&x_no_account_id_token=direct-download"
|
||||
)}.{event_file_obj?.extension}&key=${$ae_api.account_id}"
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs underline"
|
||||
title={`Download renamed with presentation name to: ${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}`}
|
||||
>
|
||||
@@ -484,7 +484,7 @@
|
||||
</a>
|
||||
<!-- <button
|
||||
type="button"
|
||||
use:clipboard={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&x_no_account_id_token=direct-download`)}
|
||||
use:clipboard={encodeURI(`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&key=${$ae_api.account_id}`)}
|
||||
class="btn btn-sm p-1 preset-tonal-secondary *:hover:inline lg:text-xs"
|
||||
title="Copy the renamed file link"
|
||||
>
|
||||
@@ -495,7 +495,7 @@
|
||||
</button> -->
|
||||
<MyClipboard
|
||||
value={encodeURI(
|
||||
`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&x_no_account_id_token=direct-download`
|
||||
`${$ae_api.base_url}/event/file/${event_file_obj?.event_file_id}/download?filename=${event_file_obj?.event_session_code}-${ae_util.clean_filename(event_file_obj?.event_presentation_name).substring(0, 20)}-${ae_util.clean_filename(event_file_obj?.event_presenter_full_name)}.${event_file_obj?.extension}&key=${$ae_api.account_id}`
|
||||
)}
|
||||
btn_text="Copy Renamed"
|
||||
btn_title="Copy the renamed file link"
|
||||
|
||||
@@ -564,23 +564,17 @@
|
||||
log_lvl={1}
|
||||
>
|
||||
{#snippet label()}
|
||||
<span>
|
||||
<div>
|
||||
<span class="fas fa-upload"></span>
|
||||
<strong class="bg-green-100 p-1"
|
||||
>Upload archive files</strong
|
||||
>
|
||||
<div class="flex flex-col items-center gap-2 py-2">
|
||||
<div class="p-3 rounded-full bg-primary-500/10 text-primary-500">
|
||||
<span class="fas fa-upload fa-lg"></span>
|
||||
</div>
|
||||
<span
|
||||
class="text-sm text-gray-600 dark:text-gray-400 italic"
|
||||
>
|
||||
<strong>Aether hosted files only</strong><br />
|
||||
Recommended: PowerPoint (pptx) or Keynote (key) or Adobe
|
||||
PDF<br />
|
||||
Media: audio (mp3, m4a) and video (mp4, mkv)<br />
|
||||
Supplemental files: Word Doc, Excel, txt, etc
|
||||
</span>
|
||||
</span>
|
||||
<div class="text-center">
|
||||
<p class="font-bold text-primary-500">Upload archive files</p>
|
||||
<p class="text-xs opacity-60">
|
||||
Recommended: pptx, key, PDF, mp3, mp4, docx
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{/snippet}
|
||||
</Comp_hosted_files_upload>
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
} from '$lib/stores/ae_stores';
|
||||
import { idaa_loc, idaa_sess, idaa_slct } from '$lib/stores/ae_idaa_stores';
|
||||
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
|
||||
let ae_promises: key_val = $state({});
|
||||
// let ae_tmp: key_val = {};
|
||||
// let ae_triggers: key_val = {};
|
||||
@@ -45,6 +47,7 @@
|
||||
file_icons['mov'] = 'file-video';
|
||||
file_icons['mp3'] = 'file-audio';
|
||||
file_icons['mp4'] = 'file-video';
|
||||
file_icons['mp4'] = 'file-video';
|
||||
file_icons['pdf'] = 'file-pdf';
|
||||
file_icons['png'] = 'file-image';
|
||||
file_icons['ppt'] = 'file-powerpoint';
|
||||
@@ -190,62 +193,14 @@
|
||||
</button>
|
||||
|
||||
{#if $ae_loc.trusted_access && idaa_archive_content_obj?.hosted_file_id}
|
||||
<button
|
||||
type="button"
|
||||
disabled={!$ae_loc.trusted_access}
|
||||
onclick={() => {
|
||||
ae_promises[idaa_archive_content_obj.hosted_file_id] =
|
||||
api.download_hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id:
|
||||
idaa_archive_content_obj.hosted_file_id,
|
||||
return_file: true,
|
||||
filename: idaa_archive_content_obj.filename,
|
||||
auto_download: true
|
||||
});
|
||||
|
||||
}}
|
||||
class="novi_btn btn btn-sm lg:btn-md preset-tonal-primary hover:preset-filled-primary-500 min-w-72 lg:min-w-96"
|
||||
title={`Download this file:\n${idaa_archive_content_obj.filename}\n[API] SHA256: ${idaa_archive_content_obj?.hash_sha256.slice(0, 10)}... Hosted ID: ${idaa_archive_content_obj.hosted_file_id} Archive Content ID: ${idaa_archive_content_obj.archive_content_id}`}
|
||||
>
|
||||
{#await ae_promises[idaa_archive_content_obj.hosted_file_id]}
|
||||
<span class="fas fa-spinner fa-spin mx-1"></span>
|
||||
<span class="">
|
||||
Downloading
|
||||
{#if $ae_sess.api_download_kv[idaa_archive_content_obj.hosted_file_id]}
|
||||
{$ae_sess.api_download_kv[
|
||||
idaa_archive_content_obj.hosted_file_id
|
||||
].percent_completed}%
|
||||
{/if}
|
||||
:
|
||||
</span>
|
||||
{:then}
|
||||
<span
|
||||
class="fas fa-{ae_util.file_extension_icon(
|
||||
idaa_archive_content_obj?.file_extension
|
||||
)}"
|
||||
></span>
|
||||
{/await}
|
||||
|
||||
<span class="grow">
|
||||
{ae_util.shorten_filename({
|
||||
filename: idaa_archive_content_obj?.filename,
|
||||
max_length: 30
|
||||
})}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<!-- <a href="{$ae_loc.base_url}{idaa_archive_content_obj.hosted_file_path}" class="btn btn-md variant-ghost-secondary" title="Download this file">
|
||||
<span class="fas fa-download m-1"></span>
|
||||
Download
|
||||
<span class="badge">
|
||||
{#if ae_util.file_extension_icon(idaa_archive_content_obj?.file_extension)}
|
||||
<span class="fas fa-{ae_util.file_extension_icon(idaa_archive_content_obj?.file_extension)} m-1"></span>
|
||||
{:else}
|
||||
<span class="fas fa-file"></span>
|
||||
{/if}
|
||||
.{idaa_archive_content_obj?.file_extension}</span>
|
||||
</a> -->
|
||||
<AE_Comp_Hosted_Files_Download_Button
|
||||
hosted_file_id={idaa_archive_content_obj.hosted_file_id}
|
||||
hosted_file_obj={idaa_archive_content_obj}
|
||||
max_filename={30}
|
||||
classes="novi_btn btn btn-sm lg:btn-md preset-tonal-primary hover:preset-filled-primary-500 min-w-72 lg:min-w-96"
|
||||
linked_to_type="archive_content"
|
||||
linked_to_id={idaa_archive_content_obj.archive_content_id}
|
||||
/>
|
||||
{/if}
|
||||
{:else}
|
||||
<span class="text-sm text-gray-500 italic" title="No file linked.">
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
<source
|
||||
id="view_archive_content_audio_source"
|
||||
src="{$ae_api.base_url}/hosted_file/{$idaa_slct.archive_content_obj
|
||||
?.hosted_file_id}/download?x_no_account_id_token=direct-download"
|
||||
?.hosted_file_id}/download?key=${$ae_api.account_id}"
|
||||
type="audio/mpeg"
|
||||
/>
|
||||
<!--<source src="audio.ogg" type="audio/ogg">-->
|
||||
@@ -104,7 +104,7 @@
|
||||
<video autoplay controls class="w-full h-auto">
|
||||
<source
|
||||
src="{$ae_api.base_url}/hosted_file/{$idaa_slct.archive_content_obj
|
||||
?.hosted_file_id}/download?x_no_account_id_token=direct-download"
|
||||
?.hosted_file_id}/download?key=${$ae_api.account_id}"
|
||||
type="video/mp4"
|
||||
/>
|
||||
<!--<source src="video.ogg" type="video/ogg">-->
|
||||
@@ -114,14 +114,14 @@
|
||||
{:else if file_icons[$idaa_slct.archive_content_obj.file_extension] == 'file-image'}
|
||||
<img
|
||||
src="{$ae_api.base_url}/hosted_file/{$idaa_slct.archive_content_obj
|
||||
?.hosted_file_id}/download?x_no_account_id_token=direct-download"
|
||||
?.hosted_file_id}/download?key=${$ae_api.account_id}"
|
||||
alt={$idaa_slct.archive_content_obj.name}
|
||||
style="max-width: 100%; max-height: 65vh;"
|
||||
/>
|
||||
{:else}
|
||||
<a
|
||||
href="{$ae_api.base_url}/hosted_file/{$idaa_slct.archive_content_obj
|
||||
?.hosted_file_id}/download?x_no_account_id_token=direct-download"
|
||||
?.hosted_file_id}/download?key=${$ae_api.account_id}"
|
||||
target="_blank"
|
||||
class="
|
||||
novi_btn
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
import { posts_func } from '$lib/ae_posts/ae_posts_functions';
|
||||
import AE_Comp_Editor_TipTap from '$lib/elements/AE_Comp_Editor_TipTap.svelte';
|
||||
import Comp_hosted_files_upload from '$lib/ae_core/ae_comp__hosted_files_upload.svelte';
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
|
||||
// let obj_changed = $state(false);
|
||||
// let orig_post_obj: any = $state(null);
|
||||
@@ -555,7 +556,7 @@ Copy and paste link: <a href="${link_base_url}?post_id=${$idaa_slct.post_id}">${
|
||||
<span class="fas fa-paperclip"></span>
|
||||
<span class="text-sm text-surface-600-400 italic">Linked files:</span>
|
||||
{#each $idaa_slct.post_obj.linked_li_json as linked_obj, index}
|
||||
<span>
|
||||
<span class="flex flex-col items-center gap-1 p-1 border rounded-lg bg-white/50">
|
||||
<!-- <a
|
||||
href={linked_obj.url}
|
||||
target="_blank"
|
||||
@@ -566,142 +567,123 @@ Copy and paste link: <a href="${link_base_url}?post_id=${$idaa_slct.post_id}">${
|
||||
({linked_obj.hosted_file_id_random})
|
||||
</a> -->
|
||||
|
||||
{#if $ae_loc.authenticated_access && linked_obj?.hosted_file_id_random}
|
||||
<button
|
||||
type="button"
|
||||
disabled={!$ae_loc.trusted_access}
|
||||
onclick={() => {
|
||||
ae_promises[linked_obj.hosted_file_id_random] =
|
||||
api.download_hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: linked_obj.hosted_file_id_random,
|
||||
return_file: true,
|
||||
filename: linked_obj.filename,
|
||||
auto_download: true,
|
||||
log_lvl: 0
|
||||
});
|
||||
{#if $ae_loc.authenticated_access}
|
||||
{@const file_id = linked_obj?.hosted_file_id_random || linked_obj?.id || linked_obj?.hosted_file_id}
|
||||
{#if file_id}
|
||||
{@const ext = (linked_obj.extension || linked_obj.file_extension || ae_util.guess_file_extension(linked_obj.filename) || '').toLowerCase()}
|
||||
{#if ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext)}
|
||||
<div class="mb-1">
|
||||
<img
|
||||
src="{$ae_api.base_url}/v3/action/hosted_file/{file_id}/download?key={$ae_api.account_id}"
|
||||
alt={linked_obj.filename}
|
||||
class="max-w-32 h-auto object-cover rounded shadow-sm border border-surface-500/20"
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
}}
|
||||
class="novi_btn btn btn-sm lg:btn-md preset-tonal-tertiary border border-tertiary-500 hover:preset-filled-tertiary-500 min-w-48"
|
||||
title={`Download this file:\n${linked_obj.filename}\n[API] SHA256: ${linked_obj?.hash_sha256.slice(0, 10)}... Hosted ID: ${linked_obj.hosted_file_id_random} Archive Content ID: ${linked_obj.archive_content_id}`}
|
||||
>
|
||||
{#await ae_promises[linked_obj.hosted_file_id_random]}
|
||||
<span class="fas fa-spinner fa-spin mx-1"></span>
|
||||
<span class="">
|
||||
Downloading
|
||||
{#if $ae_sess.api_download_kv[linked_obj.hosted_file_id_random]}
|
||||
{$ae_sess.api_download_kv[
|
||||
linked_obj.hosted_file_id_random
|
||||
].percent_completed}%
|
||||
{/if}
|
||||
:
|
||||
</span>
|
||||
{:then}
|
||||
<span
|
||||
class="fas fa-{ae_util.file_extension_icon(
|
||||
linked_obj?.extension
|
||||
)}"
|
||||
></span>
|
||||
{/await}
|
||||
<div class="flex flex-row items-center gap-1">
|
||||
<AE_Comp_Hosted_Files_Download_Button
|
||||
hosted_file_id={file_id}
|
||||
hosted_file_obj={linked_obj}
|
||||
color="tertiary"
|
||||
variant="tonal"
|
||||
classes="novi_btn btn-sm lg:btn-md min-w-48"
|
||||
max_filename={30}
|
||||
/>
|
||||
|
||||
<span class="grow">
|
||||
{ae_util.shorten_filename({
|
||||
filename: linked_obj?.filename,
|
||||
max_length: 30
|
||||
})}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
disabled={!$ae_loc.trusted_access}
|
||||
onclick={async () => {
|
||||
if (
|
||||
!confirm(
|
||||
`Are you sure you want to delete this file?\n${linked_obj.filename} [${file_id}]`
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
<button
|
||||
type="button"
|
||||
disabled={!$ae_loc.trusted_access}
|
||||
onclick={async () => {
|
||||
if (
|
||||
!confirm(
|
||||
`Are you sure you want to delete this file?\n${linked_obj.filename} [${linked_obj.hosted_file_id_random}]`
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
// ae_promises[linked_obj.event_file_id_random] = handle_delete__event_file({event_file_id: linked_obj.event_file_id_random});
|
||||
|
||||
// ae_promises[linked_obj.event_file_id_random] = handle_delete__event_file({event_file_id: linked_obj.event_file_id_random});
|
||||
|
||||
// First - Attempt to delete the hosted file
|
||||
ae_promises.delete__linked_obj = await core_func
|
||||
.delete_ae_obj_id__hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: linked_obj.hosted_file_id_random,
|
||||
link_to_type: 'post',
|
||||
link_to_id: $idaa_slct.post_id,
|
||||
rm_orphan: true,
|
||||
fake_delete: false,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then(function (delete_result) {
|
||||
// Second - If deleted, then update the post_obj
|
||||
console.log(
|
||||
`File removed. Now update the post_obj`
|
||||
);
|
||||
|
||||
// We need to remove the record from the $idaa_slct.post_obj.hosted_file_obj_li and then update the post_obj.linked_li_json with the new value.
|
||||
let delete_result_li =
|
||||
$idaa_slct.post_obj.linked_li_json.filter(
|
||||
function (hosted_file_obj) {
|
||||
console.log(
|
||||
`hosted_file_obj.hosted_file_id_random = ${hosted_file_obj.hosted_file_id_random}`
|
||||
);
|
||||
return (
|
||||
hosted_file_obj.hosted_file_id_random !==
|
||||
linked_obj.hosted_file_id_random
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$idaa_slct.post_obj.hosted_file_obj_li =
|
||||
delete_result_li;
|
||||
$idaa_slct.post_obj.linked_li_json =
|
||||
delete_result_li;
|
||||
|
||||
prom_api__post_obj = posts_func
|
||||
.update_ae_obj__post({
|
||||
// First - Attempt to delete the hosted file
|
||||
ae_promises.delete__linked_obj = await core_func
|
||||
.delete_ae_obj_id__hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
post_id: $idaa_slct.post_id,
|
||||
data_kv: {
|
||||
linked_li_json: JSON.stringify(
|
||||
$idaa_slct.post_obj.linked_li_json
|
||||
)
|
||||
},
|
||||
hosted_file_id: file_id,
|
||||
link_to_type: 'post',
|
||||
link_to_id: $idaa_slct.post_id,
|
||||
rm_orphan: true,
|
||||
fake_delete: false,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then(function (post_obj_update_result) {
|
||||
// We need to do all of this since the DB object has changed and the SLCT object does automatically update (yet...??? Svelte 5?).
|
||||
// $idaa_slct.post_obj = $lq__post_obj;
|
||||
.then(function (delete_result) {
|
||||
// Second - If deleted, then update the post_obj
|
||||
console.log(
|
||||
`File removed. Now update the post_obj`
|
||||
);
|
||||
|
||||
// We need to remove the record from the $idaa_slct.post_obj.hosted_file_obj_li and then update the post_obj.linked_li_json with the new value.
|
||||
let delete_result_li =
|
||||
$idaa_slct.post_obj.linked_li_json.filter(
|
||||
function (hosted_file_obj) {
|
||||
const current_id = hosted_file_obj?.hosted_file_id_random || hosted_file_obj?.id || hosted_file_obj?.hosted_file_id;
|
||||
console.log(
|
||||
`Comparing: ${current_id} vs ${file_id}`
|
||||
);
|
||||
return (
|
||||
current_id !==
|
||||
file_id
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
$idaa_slct.post_obj.hosted_file_obj_li =
|
||||
delete_result_li;
|
||||
$idaa_slct.post_obj.linked_li_json =
|
||||
delete_result_li;
|
||||
|
||||
prom_api__post_obj = posts_func
|
||||
.update_ae_obj__post({
|
||||
api_cfg: $ae_api,
|
||||
post_id: $idaa_slct.post_id,
|
||||
data_kv: {
|
||||
linked_li_json: JSON.stringify(
|
||||
$idaa_slct.post_obj.linked_li_json
|
||||
)
|
||||
},
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then(function (post_obj_update_result) {
|
||||
// We need to do all of this since the DB object has changed and the SLCT object does automatically update (yet...??? Svelte 5?).
|
||||
// $idaa_slct.post_obj = $lq__post_obj;
|
||||
})
|
||||
.catch(function (error: any) {
|
||||
console.log('Something went wrong.');
|
||||
console.log(error);
|
||||
return false;
|
||||
});
|
||||
})
|
||||
.catch(function (error: any) {
|
||||
console.log('Something went wrong.');
|
||||
console.log(error);
|
||||
return false;
|
||||
});
|
||||
})
|
||||
.catch(function (error: any) {
|
||||
console.log('Something went wrong.');
|
||||
console.log(error);
|
||||
return false;
|
||||
})
|
||||
.finally(() => {});
|
||||
}}
|
||||
class="
|
||||
novi_btn
|
||||
btn btn-sm
|
||||
preset-tonal-warning preset-outlined-warning-100-900 hover:preset-filled-warning-400-600
|
||||
transition
|
||||
"
|
||||
title="Delete this file"
|
||||
>
|
||||
<span class="fas fa-trash-alt mx-1"></span>
|
||||
<!-- <span class="fas fa-minus mx-1"></span> -->
|
||||
Delete
|
||||
</button>
|
||||
})
|
||||
.finally(() => {});
|
||||
}}
|
||||
class="
|
||||
novi_btn
|
||||
btn btn-sm
|
||||
preset-tonal-warning preset-outlined-warning-100-900 hover:preset-filled-warning-400-600
|
||||
transition
|
||||
"
|
||||
title="Delete this file"
|
||||
>
|
||||
<span class="fas fa-trash-alt mx-1"></span>
|
||||
<!-- <span class="fas fa-minus mx-1"></span> -->
|
||||
Delete
|
||||
</button>
|
||||
</div>
|
||||
{/if}
|
||||
{/if}
|
||||
</span>
|
||||
{/each}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
// import Comp__post_obj_id_edit from './ae_idaa_comp__post_obj_id_edit.svelte';
|
||||
import Comp__post_comment_obj_id_edit from './ae_idaa_comp__post_comment_obj_id_edit.svelte';
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
|
||||
let ae_promises: key_val = $state({});
|
||||
|
||||
@@ -143,72 +144,28 @@
|
||||
({linked_obj.hosted_file_id_random})
|
||||
</a> -->
|
||||
|
||||
{#if $ae_loc.authenticated_access && linked_obj?.hosted_file_id_random}
|
||||
{#if linked_obj.extension === 'png' || linked_obj.extension === 'jpg' || linked_obj.extension === 'jpeg' || linked_obj.extension === 'gif' || linked_obj.extension === 'webp' || linked_obj.extension === 'svg'}
|
||||
<div>
|
||||
<img
|
||||
src="{$ae_api.base_url}/hosted_file/{linked_obj?.hosted_file_id_random}/download?x_no_account_id_token=direct-download"
|
||||
alt={linked_obj.filename}
|
||||
class="w-fit min-w-96 h-fit object-cover rounded-lg shadow-md"
|
||||
{#if $ae_loc.authenticated_access}
|
||||
{@const file_id = linked_obj?.hosted_file_id_random || linked_obj?.id || linked_obj?.hosted_file_id}
|
||||
{#if file_id}
|
||||
{@const ext = (linked_obj.extension || linked_obj.file_extension || ae_util.guess_file_extension(linked_obj.filename) || '').toLowerCase()}
|
||||
{#if ['png', 'jpg', 'jpeg', 'gif', 'webp', 'svg'].includes(ext)}
|
||||
<div>
|
||||
<img
|
||||
src="{$ae_api.base_url}/v3/action/hosted_file/{file_id}/download?key={$ae_api.account_id}"
|
||||
alt={linked_obj.filename}
|
||||
class="w-fit min-w-96 h-fit object-cover rounded-lg shadow-md"
|
||||
/>
|
||||
</div>
|
||||
{:else}
|
||||
<AE_Comp_Hosted_Files_Download_Button
|
||||
hosted_file_id={file_id}
|
||||
hosted_file_obj={linked_obj}
|
||||
color="tertiary"
|
||||
variant="tonal"
|
||||
classes="border border-tertiary-500 hover:preset-filled-tertiary-500 min-w-48"
|
||||
max_filename={30}
|
||||
/>
|
||||
<!-- <img src={api.download_hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: linked_obj.hosted_file_id_random,
|
||||
return_file: true,
|
||||
filename: linked_obj.filename,
|
||||
auto_download: false,
|
||||
log_lvl: 1
|
||||
})
|
||||
}
|
||||
alt={linked_obj.filename}
|
||||
class="w-fit min-w-96 h-fit object-cover rounded-lg shadow-md"
|
||||
/> -->
|
||||
</div>
|
||||
{:else}
|
||||
<button
|
||||
type="button"
|
||||
disabled={!$ae_loc.trusted_access}
|
||||
onclick={() => {
|
||||
ae_promises[linked_obj.hosted_file_id_random] =
|
||||
api.download_hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: linked_obj.hosted_file_id_random,
|
||||
return_file: true,
|
||||
filename: linked_obj.filename,
|
||||
auto_download: true,
|
||||
log_lvl: 0
|
||||
});
|
||||
|
||||
}}
|
||||
class="novi_btn btn btn-sm lg:btn-md preset-tonal-tertiary border border-tertiary-500 hover:preset-filled-tertiary-500 min-w-48"
|
||||
title={`Download this file:\n${linked_obj.filename}\n[API] SHA256: ${linked_obj?.hash_sha256.slice(0, 10)}... Hosted ID: ${linked_obj.hosted_file_id_random} Archive Content ID: ${linked_obj.archive_content_id}`}
|
||||
>
|
||||
{#await ae_promises[linked_obj.hosted_file_id_random]}
|
||||
<span class="fas fa-spinner fa-spin mx-1"></span>
|
||||
<span class="">
|
||||
Downloading
|
||||
{#if $ae_sess.api_download_kv[linked_obj.hosted_file_id_random]}
|
||||
{$ae_sess.api_download_kv[
|
||||
linked_obj.hosted_file_id_random
|
||||
].percent_completed}%
|
||||
{/if}
|
||||
:
|
||||
</span>
|
||||
{:then}
|
||||
<span
|
||||
class="fas fa-{ae_util.file_extension_icon(
|
||||
linked_obj?.extension
|
||||
)}"
|
||||
></span>
|
||||
{/await}
|
||||
|
||||
<span class="grow">
|
||||
{ae_util.shorten_filename({
|
||||
filename: linked_obj?.filename,
|
||||
max_length: 30
|
||||
})}
|
||||
</span>
|
||||
</button>
|
||||
{/if}
|
||||
{/if}
|
||||
{/if}
|
||||
{/each}
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
|
||||
import Comp_hosted_files_upload from '$lib/ae_core/ae_comp__hosted_files_upload.svelte';
|
||||
import Element_manage_hosted_file_li_wrap from '$lib/elements/element_manage_hosted_file_li_all.svelte';
|
||||
import AE_Comp_Hosted_Files_Download_Button from '$lib/ae_core/ae_comp__hosted_files_download_button.svelte';
|
||||
|
||||
interface Props {
|
||||
log_lvl?: number;
|
||||
@@ -158,18 +159,6 @@
|
||||
|
||||
await update_journal_entry(updated_li);
|
||||
}
|
||||
|
||||
async function download_file(file: any) {
|
||||
const file_id = file.hosted_file_id || file.id || file.hosted_file_id;
|
||||
ae_promises[file_id] = api.download_hosted_file({
|
||||
api_cfg: $ae_api,
|
||||
hosted_file_id: file_id,
|
||||
return_file: true,
|
||||
filename: file.filename,
|
||||
auto_download: true,
|
||||
log_lvl: 0
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<section class="ae_section journal_entry_files w-full space-y-4 my-2">
|
||||
@@ -203,29 +192,20 @@
|
||||
{#each unified_file_li as file}
|
||||
{@const file_id = file.hosted_file_id || file.id || file.hosted_file_id}
|
||||
<div class="flex items-center justify-between p-3 rounded-xl bg-surface-50-950 border border-surface-500/10 group hover:border-primary-500 transition-all shadow-sm">
|
||||
<div class="flex items-center gap-3 overflow-hidden">
|
||||
<div class="text-primary-500 shrink-0">
|
||||
<span class="fas fa-{ae_util.file_extension_icon(file.extension)} fa-lg"></span>
|
||||
</div>
|
||||
<div class="flex flex-col overflow-hidden">
|
||||
<span class="text-sm font-bold truncate" title={file.filename}>{file.filename}</span>
|
||||
<span class="text-xs opacity-60 uppercase font-semibold">{file.extension} • {ae_util.format_bytes(file.size)}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 overflow-hidden grow">
|
||||
<AE_Comp_Hosted_Files_Download_Button
|
||||
hosted_file_id={file_id}
|
||||
hosted_file_obj={file}
|
||||
color="primary"
|
||||
variant="tonal"
|
||||
classes="w-full !justify-start !px-2"
|
||||
show_divider={true}
|
||||
max_filename={25}
|
||||
show_direct_download={$ae_loc.trusted_access && $ae_loc.edit_mode}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center gap-1">
|
||||
<button
|
||||
class="btn btn-sm variant-soft-primary"
|
||||
onclick={() => download_file(file)}
|
||||
title="Download file"
|
||||
>
|
||||
{#if ae_promises[file_id]}
|
||||
<Loader2 size="1.1em" class="animate-spin" />
|
||||
{:else}
|
||||
<Download size="1.1em" />
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<div class="flex items-center gap-1 ml-2">
|
||||
{#if $ae_loc.edit_mode}
|
||||
<button
|
||||
class="btn btn-sm variant-soft-error"
|
||||
|
||||
Reference in New Issue
Block a user