Compare commits
5 Commits
66310adb22
...
18cbe256de
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18cbe256de | ||
|
|
2b2324ee8a | ||
|
|
6c6fccdfb4 | ||
|
|
ef5188aa6d | ||
|
|
c4fdc8efa4 |
@@ -14,9 +14,18 @@
|
||||
warnings but can still upload. Covers `.ppt`, `.doc` (block) and other legacy exts (warn-only).
|
||||
(2026-04-19)
|
||||
|
||||
- [x] **[Files] Hide draft/flagged files from list** — `hide_draft` prop in `launcher_file_cont.svelte`
|
||||
now hides files with `file_purpose == 'outline'`, `'draft'`, or `'admin'` when the launcher's
|
||||
hide-draft toggle is enabled. (2026-04-19)
|
||||
- [x] **[Files] Hide internal-purpose files from Launcher by default** — renamed `hide_draft` prop
|
||||
to `show_internal_purpose_files` in `launcher_file_cont.svelte`; logic flipped so `false` (the
|
||||
default) hides files with `file_purpose == 'outline'`, `'draft'`, or `'admin'`. Store key renamed
|
||||
from `hide_content__draft_files` (inverted, misleading) to `show_content__internal_files: false`
|
||||
(show-on-opt-in, consistent with all other `show_content__*` flags). Updated across all 8 Launcher
|
||||
templates that pass this prop. (2026-04-19, revised 2026-04-20)
|
||||
|
||||
- [x] **[Launcher] Remove duplicate session API call on session select** — `menu_session_list.svelte`
|
||||
was calling `load_ae_obj_id__event_session` directly AND then `goto()` triggered `+page.ts` which
|
||||
also called it — two concurrent calls per session click. Removed the direct call entirely;
|
||||
`+page.ts` is now the sole owner of session data loading. `goto()` promise assigned to
|
||||
`ae_promises.slct__event_session_id` to drive the existing `{#await}` spinner. (2026-04-20)
|
||||
|
||||
- [ ] **[Electron/Launcher] Deploy + test Aether Native Electron app on Mac laptops** — build,
|
||||
deploy, and verify on onsite Mac laptops. Additional testing of cache/launch flow still needed
|
||||
|
||||
@@ -26,13 +26,12 @@ export interface LauncherLocState {
|
||||
hide__ws_form: boolean;
|
||||
hide__ws_messages: boolean;
|
||||
hide__ws_commands: boolean;
|
||||
hide_content__draft_files: boolean;
|
||||
show_content__disabled_files: boolean;
|
||||
show_content__hidden_files: boolean;
|
||||
show_content__hidden_presentations: boolean;
|
||||
show_content__hidden_presenters: boolean;
|
||||
show_content__hidden_sessions: boolean;
|
||||
show_content__draft_files: boolean;
|
||||
show_content__internal_files: boolean;
|
||||
show_content__session_code: boolean;
|
||||
show_content__presentation_code: boolean;
|
||||
show_content__presenter_code: boolean;
|
||||
@@ -134,14 +133,12 @@ export const launcher_loc_defaults: LauncherLocState = {
|
||||
hide__ws_messages: true,
|
||||
hide__ws_commands: true,
|
||||
|
||||
hide_content__draft_files: true,
|
||||
|
||||
show_content__disabled_files: false,
|
||||
show_content__hidden_files: false,
|
||||
show_content__hidden_presentations: false,
|
||||
show_content__hidden_presenters: false,
|
||||
show_content__hidden_sessions: false,
|
||||
show_content__draft_files: false,
|
||||
show_content__internal_files: false,
|
||||
|
||||
// These should be renamed to match the pres_mgmt section. Use "hide" instead of "show".
|
||||
show_content__session_code: true,
|
||||
|
||||
@@ -16,7 +16,7 @@ let { children }: Props = $props();
|
||||
|
||||
// WHY: When running inside Electron (is_native), app_mode must be 'native' for
|
||||
// the file launch path to work correctly. On a fresh install the persisted store
|
||||
// has no value set, so we auto-initialise it here. This preserves the three-mode
|
||||
// has no value set, so we auto-initialize it here. This preserves the three-mode
|
||||
// design (default / onsite / native) — browser sessions are unaffected because
|
||||
// is_native is only ever true inside the Electron shell.
|
||||
$effect(() => {
|
||||
|
||||
@@ -298,11 +298,10 @@ let lq__event_session_obj_li = $derived.by(() => {
|
||||
if (!id) return [];
|
||||
if (log_lvl > 1)
|
||||
console.log(`LQ - Event Session list location_id: ${id}`);
|
||||
// Note: .reverse() before .sortBy() is a no-op — sortBy always re-sorts.
|
||||
return await db_events.session
|
||||
.where('event_location_id')
|
||||
.equals(id)
|
||||
.sortBy('name');
|
||||
.sortBy('start_datetime');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ interface Props {
|
||||
hide_created_on?: boolean;
|
||||
hide_os?: boolean;
|
||||
hide_size?: boolean;
|
||||
hide_draft?: boolean;
|
||||
show_internal_purpose_files?: boolean;
|
||||
show_bak_download?: boolean;
|
||||
btn_size?: string;
|
||||
btn_text_align?: string;
|
||||
@@ -34,7 +34,7 @@ let {
|
||||
hide_created_on = $bindable(false),
|
||||
hide_os = $bindable(false),
|
||||
hide_size = $bindable(false),
|
||||
hide_draft = $bindable(false),
|
||||
show_internal_purpose_files = $bindable(false),
|
||||
show_bak_download = false,
|
||||
btn_size = $bindable('btn-sm'),
|
||||
btn_text_align = $bindable('text-left'),
|
||||
@@ -235,7 +235,7 @@ function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
<div
|
||||
class:justify-between={!hide_meta}
|
||||
class:justify-center={hide_meta}
|
||||
class:hidden={hide_draft &&
|
||||
class:hidden={!show_internal_purpose_files &&
|
||||
(event_file_obj.file_purpose == 'outline' ||
|
||||
event_file_obj.file_purpose == 'draft' ||
|
||||
event_file_obj.file_purpose == 'admin')}
|
||||
@@ -386,16 +386,28 @@ function prevent_default<T extends Event>(fn: (event: T) => void) {
|
||||
});
|
||||
}}
|
||||
class="btn btn-sm group transition-all"
|
||||
class:preset-tonal-success={event_file_obj?.open_in_os == 'win'}
|
||||
class:preset-tonal-warning={event_file_obj?.open_in_os == 'mac'}
|
||||
disabled={!$ae_loc.trusted_access}>
|
||||
{#if event_file_obj?.open_in_os == 'win'}<Monitor
|
||||
class:preset-tonal-warning={event_file_obj?.open_in_os == 'win'}
|
||||
class:preset-tonal-success={event_file_obj?.open_in_os == 'mac'}
|
||||
disabled={!$ae_loc.trusted_access}
|
||||
title={`Open in OS: ${
|
||||
event_file_obj?.open_in_os
|
||||
? event_file_obj.open_in_os.toUpperCase()
|
||||
: 'None'
|
||||
}`}
|
||||
>
|
||||
{#if event_file_obj?.open_in_os == 'win'}
|
||||
<!-- <Monitor
|
||||
size="1em"
|
||||
class="m-1" />
|
||||
{:else if event_file_obj?.open_in_os == 'mac'}<Laptop
|
||||
class="m-1" /> -->
|
||||
Win
|
||||
{:else if event_file_obj?.open_in_os == 'mac'}
|
||||
<!-- <Laptop
|
||||
size="1em"
|
||||
class="m-1" />
|
||||
{:else}<FolderOpen size="1em" class="m-1" />{/if}
|
||||
class="m-1" /> -->
|
||||
Mac
|
||||
{:else}
|
||||
<FolderOpen size="1em" class="m-1" />
|
||||
{/if}
|
||||
</button>
|
||||
|
||||
<span
|
||||
|
||||
@@ -171,6 +171,7 @@ let ae_promises: key_val = $state({
|
||||
hide_created_on={true}
|
||||
hide_os={true}
|
||||
hide_size={true}
|
||||
show_internal_purpose_files={$events_loc.launcher.show_content__internal_files}
|
||||
show_bak_download={$ae_loc.trusted_access &&
|
||||
$ae_loc.edit_mode}
|
||||
btn_size={'btn-sm'}
|
||||
@@ -213,6 +214,7 @@ let ae_promises: key_val = $state({
|
||||
hide_created_on={true}
|
||||
hide_os={true}
|
||||
hide_size={true}
|
||||
show_internal_purpose_files={$events_loc.launcher.show_content__internal_files}
|
||||
show_bak_download={$ae_loc.trusted_access &&
|
||||
$ae_loc.edit_mode}
|
||||
btn_size={'btn-sm'}
|
||||
|
||||
@@ -67,8 +67,8 @@ let lq__event_file_obj_li = $derived(
|
||||
{event_file_obj}
|
||||
hide_created_on={false}
|
||||
hide_meta={session_type == 'poster'}
|
||||
bind:hide_draft={
|
||||
$events_loc.launcher.hide_content__draft_files
|
||||
bind:show_internal_purpose_files={
|
||||
$events_loc.launcher.show_content__internal_files
|
||||
}
|
||||
show_bak_download={$ae_loc.trusted_access}
|
||||
session_type={session_type || 'oral'}
|
||||
|
||||
@@ -96,8 +96,8 @@ let lq__event_file_obj_li = $derived(
|
||||
event_file_id={event_file_obj.event_file_id}
|
||||
{event_file_obj}
|
||||
hide_created_on={false}
|
||||
bind:hide_draft={
|
||||
$events_loc.launcher.hide_content__draft_files
|
||||
bind:show_internal_purpose_files={
|
||||
$events_loc.launcher.show_content__internal_files
|
||||
}
|
||||
show_bak_download={$ae_loc.trusted_access}
|
||||
session_type={session_type || 'oral'}
|
||||
|
||||
@@ -91,6 +91,7 @@ let lq__event_file_obj_li = $derived(
|
||||
{event_file_obj}
|
||||
hide_created_on={false}
|
||||
hide_meta={true}
|
||||
show_internal_purpose_files={$events_loc.launcher.show_content__internal_files}
|
||||
show_bak_download={$ae_loc.trusted_access}
|
||||
session_type="poster"
|
||||
open_method="modal"
|
||||
|
||||
@@ -306,6 +306,8 @@ let ae_promises: key_val = $state({});
|
||||
event_file_id={event_file_obj.event_file_id}
|
||||
{event_file_obj}
|
||||
hide_created_on={true}
|
||||
show_internal_purpose_files={$events_loc.launcher
|
||||
.show_content__internal_files}
|
||||
show_bak_download={$ae_loc.trusted_access &&
|
||||
$ae_loc.edit_mode}
|
||||
session_type={type_code || 'oral'}
|
||||
|
||||
@@ -149,6 +149,8 @@ let poster_count = $derived($lq__event_presentation_obj_li?.length ?? 0);
|
||||
event_file_id={event_file_obj.event_file_id}
|
||||
{event_file_obj}
|
||||
hide_created_on={true}
|
||||
show_internal_purpose_files={$events_loc.launcher
|
||||
.show_content__internal_files}
|
||||
show_bak_download={$ae_loc.trusted_access &&
|
||||
$ae_loc.edit_mode}
|
||||
session_type="poster"
|
||||
|
||||
@@ -40,10 +40,10 @@ let { log_lvl = $bindable(0) }: Props = $props();
|
||||
onclick={() => {
|
||||
if ($events_loc.launcher.show_content__hidden_files) {
|
||||
$events_loc.launcher.show_content__hidden_files = false;
|
||||
$events_loc.launcher.hide_content__draft_files = true;
|
||||
$events_loc.launcher.show_content__internal_files = false;
|
||||
} else {
|
||||
$events_loc.launcher.show_content__hidden_files = true;
|
||||
$events_loc.launcher.hide_content__draft_files = false;
|
||||
$events_loc.launcher.show_content__internal_files = true;
|
||||
}
|
||||
}}
|
||||
class="
|
||||
|
||||
@@ -79,7 +79,6 @@ import {
|
||||
ae_snip,
|
||||
ae_loc,
|
||||
ae_sess,
|
||||
ae_api,
|
||||
ae_trig,
|
||||
slct,
|
||||
slct_trigger
|
||||
@@ -90,7 +89,6 @@ import {
|
||||
events_slct,
|
||||
events_trigger
|
||||
} from '$lib/stores/ae_events_stores';
|
||||
import { events_func } from '$lib/ae_events/ae_events_functions';
|
||||
import {
|
||||
CalendarCheck,
|
||||
CalendarDays,
|
||||
@@ -115,7 +113,7 @@ let ae_promises: key_val = $state({
|
||||
// focus on a row for over a second before it fires — still fast for intentional use.
|
||||
// NOTE: hover-timer only triggers a data PRE-LOAD (preview). The session does not
|
||||
// actually switch until the operator clicks. See onclick handler below.
|
||||
let hover_timer_wait = 1200;
|
||||
let hover_timer_wait = 1400;
|
||||
let hover_timer: any = $state(null);
|
||||
|
||||
// Navigation Shield Pattern (Refactored 2026-02-11)
|
||||
@@ -142,26 +140,26 @@ $effect(() => {
|
||||
slct__event_session_id = event_session_id;
|
||||
}
|
||||
|
||||
// 3. Background Data Fetch
|
||||
handle_load_ae_obj_id__event_session(event_session_id);
|
||||
|
||||
// 4. Remote Control Sync
|
||||
// 3. Remote Control Sync
|
||||
if ($events_loc.launcher.controller == 'local_push') {
|
||||
$events_sess.launcher.controller_cmd = `ae_load:event_session=${event_session_id}`;
|
||||
$events_sess.launcher.controller_trigger_send = true;
|
||||
}
|
||||
|
||||
// 5. URL Navigation
|
||||
// 4. URL Navigation — the single load fires from +page.ts when the URL updates.
|
||||
// Assigning the goto promise to ae_promises drives the #await spinner in the template.
|
||||
loading__session_id_status = 'loading';
|
||||
let new_url_obj = new URL(page.url);
|
||||
new_url_obj.searchParams.set('session_id', event_session_id);
|
||||
|
||||
if (log_lvl) console.log(`[UI Trace] Initiating SvelteKit goto...`);
|
||||
|
||||
goto(new_url_obj.toString(), {
|
||||
ae_promises.slct__event_session_id = goto(new_url_obj.toString(), {
|
||||
replaceState: false,
|
||||
noScroll: true,
|
||||
keepFocus: true
|
||||
}).then(() => {
|
||||
loading__session_id_status = false;
|
||||
if (log_lvl)
|
||||
console.log(
|
||||
`🏁 [Trace] Navigation Roundtrip: ${(performance.now() - start).toFixed(2)}ms`
|
||||
@@ -170,45 +168,6 @@ $effect(() => {
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function handle_load_ae_obj_id__event_session(event_session_id: any) {
|
||||
const start = performance.now();
|
||||
if (log_lvl) {
|
||||
console.log(
|
||||
`[UI Trace] handle_load_ae_obj_id__event_session: Calling library for id=${event_session_id}`
|
||||
);
|
||||
}
|
||||
|
||||
loading__session_id_status = 'loading';
|
||||
|
||||
ae_promises.slct__event_session_id = events_func
|
||||
.load_ae_obj_id__event_session({
|
||||
api_cfg: $ae_api,
|
||||
event_session_id: event_session_id,
|
||||
inc_file_li: true,
|
||||
inc_all_file_li: true,
|
||||
inc_presentation_li: true,
|
||||
inc_presenter_li: true,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then(async (load_results) => {
|
||||
if (log_lvl)
|
||||
console.log(
|
||||
`[UI Trace] handle_load_ae_obj_id: Library returned results in ${(performance.now() - start).toFixed(2)}ms.`
|
||||
);
|
||||
|
||||
if (load_results) {
|
||||
$events_slct.event_session_obj = load_results;
|
||||
$events_slct.event_file_obj_li =
|
||||
load_results.event_file_li ?? [];
|
||||
$events_slct.event_presentation_obj_li =
|
||||
load_results.event_presentation_li ?? [];
|
||||
}
|
||||
})
|
||||
.finally(() => {
|
||||
loading__session_id_status = false;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
@@ -252,7 +211,11 @@ function handle_load_ae_obj_id__event_session(event_session_id: any) {
|
||||
max-w-full p-0
|
||||
"
|
||||
class:session-active={slct__event_session_id ===
|
||||
event_session_obj?.id}>
|
||||
event_session_obj?.id}
|
||||
class:hidden={!$events_loc.launcher
|
||||
.show_content__hidden_sessions &&
|
||||
(event_session_obj?.hide ||
|
||||
event_session_obj?.hide_event_launcher)}>
|
||||
<button
|
||||
type="button"
|
||||
onmouseenter={() => {
|
||||
@@ -280,34 +243,26 @@ function handle_load_ae_obj_id__event_session(event_session_id: any) {
|
||||
$events_slct.event_file_obj = null;
|
||||
}}
|
||||
class="
|
||||
session-btn
|
||||
btn btn-sm
|
||||
focus-visible:ring-primary-400 m-0 flex
|
||||
session-btn
|
||||
btn btn-sm
|
||||
focus-visible:ring-primary-400 m-0 flex
|
||||
|
||||
w-full
|
||||
max-w-full flex-row
|
||||
items-center
|
||||
justify-start
|
||||
rounded-md px-1.5
|
||||
w-full
|
||||
max-w-full flex-row
|
||||
items-center
|
||||
justify-start
|
||||
rounded-md px-1.5
|
||||
|
||||
py-1
|
||||
text-left text-sm transition-colors duration-200
|
||||
focus-visible:ring-2 focus-visible:ring-offset-1
|
||||
"
|
||||
class:preset-filled-primary={slct__event_session_id ===
|
||||
event_session_obj?.id}
|
||||
class:preset-tonal-secondary={slct__event_session_id !=
|
||||
event_session_obj?.id}
|
||||
class:border-secondary-500={slct__event_session_id !=
|
||||
event_session_obj?.id}
|
||||
class:font-bold={slct__event_session_id ===
|
||||
event_session_obj?.id}
|
||||
class:hidden={!$events_loc.launcher
|
||||
.show_content__hidden_sessions &&
|
||||
(event_session_obj?.hide ||
|
||||
event_session_obj?.hide_event_launcher)}
|
||||
class:opacity-40={event_session_obj?.hide ||
|
||||
event_session_obj?.hide_event_launcher}
|
||||
py-1
|
||||
text-left text-sm transition-colors duration-200
|
||||
focus-visible:ring-2 focus-visible:ring-offset-1
|
||||
"
|
||||
class:font-bold={slct__event_session_id === event_session_obj?.id}
|
||||
class:preset-tonal-primary={slct__event_session_id === event_session_obj?.id}
|
||||
class:preset-outlined-primary-200-800={slct__event_session_id === event_session_obj?.id}
|
||||
class:preset-tonal-secondary={slct__event_session_id != event_session_obj?.id}
|
||||
class:preset-outlined-secondary-200-800={slct__event_session_id != event_session_obj?.id}
|
||||
class:opacity-40={event_session_obj?.hide || event_session_obj?.hide_event_launcher}
|
||||
title={`Session: ${event_session_obj?.name}\nID: ${event_session_obj?.id} | ${ae_util.iso_datetime_formatter(event_session_obj?.start_datetime, $events_loc.launcher.time_format)}`}>
|
||||
<!-- Session row layout: [date column | session name]
|
||||
Date column is fixed-width (shrink-0) so name column always
|
||||
|
||||
@@ -153,11 +153,16 @@ async function handle_input_upload_files({
|
||||
api_cfg: $ae_api,
|
||||
endpoint: '/v3/action/hosted_file/upload',
|
||||
form_data: form_data,
|
||||
timeout: 1200000, // 20 minutes — large presentation files can be very slow to upload
|
||||
task_id: task_id,
|
||||
log_lvl: log_lvl
|
||||
})
|
||||
.then(async function (result) {
|
||||
// WARNING: endpoint returns a list, we sequentially handle one at a time.
|
||||
if (!result || !result[0]) {
|
||||
console.error('Upload failed or timed out — no result returned.');
|
||||
return false;
|
||||
}
|
||||
const hosted_file_obj = result[0];
|
||||
const hosted_file_id = hosted_file_obj.hosted_file_id;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user