refactor(launcher): canonicalize default profiles
This commit is contained in:
@@ -37,7 +37,7 @@ platform is flexible enough to handle the full range.
|
||||
|
||||
### Object Hierarchy
|
||||
|
||||
```
|
||||
```text
|
||||
Event
|
||||
├── Event File (walk-in/out, hold slides for the whole event)
|
||||
├── Location (physical room — assigned to Sessions, not the other way around)
|
||||
@@ -314,11 +314,30 @@ The Electron app zero-configs itself:
|
||||
**Configurable launch behavior:** The file-open behavior is driven by a Launch Profile, not
|
||||
just a command string. Profiles are stored per file extension in
|
||||
`event_device.data_json.launch_profiles` (device-level config) or
|
||||
`event.launcher.launch_profiles` (event-level fallback). A profile can choose the app,
|
||||
display mode, open command, and post-open automation. The resolved native template uses
|
||||
`{{path}}` as the file path placeholder; AppleScript or `shell:` prefixed commands are both
|
||||
supported. No Electron rebuild is required to change how files open — edit config in Aether
|
||||
and it applies immediately. See `PROJECT__AE_Events_Launcher_Native_integration.md` Section 8.
|
||||
`event.launcher.launch_profiles` (event-level fallback). The built-in Svelte defaults are the
|
||||
final fallback and are documented below. A profile can choose the app, display mode, open
|
||||
command, and post-open automation. The resolved native template uses `{{path}}` as the file
|
||||
path placeholder; AppleScript or `shell:` prefixed commands are both supported. No Electron
|
||||
rebuild is required to change how files open — edit config in Aether and it applies
|
||||
immediately. See `PROJECT__AE_Events_Launcher_Native_integration.md` Section 8.
|
||||
|
||||
### Built-In Default Launch Profiles
|
||||
|
||||
These are the initial built-in defaults shipped with the Launcher. They are the Svelte-side
|
||||
fallbacks used when neither device config nor event config defines a profile for the file
|
||||
extension. Each canonical profile can have multiple extension aliases.
|
||||
|
||||
| Profile name | Extension aliases | Default app | Display mode | Notes |
|
||||
|---|---|---|---|---|
|
||||
| `powerpoint_mac_extend` | `pptx`, `ppt` | Microsoft PowerPoint for macOS | `extend` | Open in the presentation app and extend to an external display if one is present. |
|
||||
| `keynote_mac_extend` | `key` | Keynote | `extend` | Keynote slideshow on the external display if available. |
|
||||
| `libreoffice_mac_extend` | `odp` | LibreOffice for macOS | `extend` | LibreOffice Impress for OpenDocument presentations. |
|
||||
| `acrobat_mac_mirror` | `pdf` | Adobe Acrobat for macOS | `mirror` | PDF handout / deck view uses mirrored display. |
|
||||
| `vlc_mirror` | `mp4`, `mkv`, `mp3`, `m4v`, `m4a`, `webm`, `wav`, `aac`, `flac`, `mov`, `mpeg`, `avi`, `flv`, `ogg`, `ogv`, `wmv` | VLC for macOS | `mirror` | Media playback is mirrored so the room sees the same output as the operator. |
|
||||
| `powerpoint_win_extend` | `pptxwin`, `pptwin` | PowerPoint for Windows (Parallels) | `extend` | Windows PowerPoint profile for Parallels-based rooms. |
|
||||
| `libreoffice_win_extend` | `odpwin` | LibreOffice for Windows | `extend` | Windows LibreOffice profile for Parallels-based rooms. |
|
||||
| `acrobat_win_mirror` | `pdfwin` | Adobe Acrobat for Windows (Parallels) | `mirror` | Windows PDF profile for mirrored display rooms. |
|
||||
| `url_web` | `url` | Browser / Event File web presentation | `extend` | Web-based presentations are handled as Event File URLs rather than cached local files. |
|
||||
|
||||
Versioning is handled automatically: when a presenter uploads an updated file, the new
|
||||
hash is cached separately and the old one remains intact.
|
||||
|
||||
@@ -41,7 +41,8 @@ The integration is built on a decoupled three-layer communication model to ensur
|
||||
- **Role:** Provides a clean, typed API for Svelte components.
|
||||
- **Responsibilities:**
|
||||
- Mapping `camelCase` UI triggers to `snake_case` IPC calls.
|
||||
- Resolving a Launch Profile to a single `native_template` string before crossing IPC.
|
||||
- Resolving an extension alias to a canonical Launch Profile, then to a single
|
||||
`native_template` string before crossing IPC.
|
||||
|
||||
The reason for this split is simple: Launch Profiles are policy, while Native Templates are
|
||||
executable strings. Keeping that distinction explicit prevents the bridge from mixing config
|
||||
@@ -199,6 +200,11 @@ resolved a template yet, it should stop before IPC and surface a missing-profile
|
||||
This keeps all fallback logic in Svelte, where it can be edited without rebuilding Electron.
|
||||
The native layer should not invent or guess a default launch path.
|
||||
|
||||
The built-in defaults are organized as canonical profile names plus extension aliases. That
|
||||
lets multiple file types share one profile without repeating the same app/script details.
|
||||
URL-based presentations remain a special pseudo-extension handled separately from the cache
|
||||
open flow.
|
||||
|
||||
### Native Template Formats
|
||||
|
||||
| Format | Example |
|
||||
|
||||
@@ -22,11 +22,15 @@ guessing defaults.
|
||||
- [x] `get_launch_profile()` in `launcher_file_cont.svelte` reads from device config then event config; resolves to a `native_template` string and passes it to `launch_from_cache`
|
||||
|
||||
**Svelte-side migration — remaining before May 26:**
|
||||
- [ ] **[Launcher] Built-in Svelte default profiles** — move the "known good" pptx/key/pdf
|
||||
- [ ] **[Launcher] Built-in Svelte default profiles** — move the built-in presentation/media
|
||||
policy objects into a Svelte constants file (e.g. `ae_launcher__default_launch_profiles.ts`).
|
||||
Priority: `get_launch_profile()` already checks device config and event config; add a 3rd
|
||||
fallback to these Svelte defaults before returning `null`. Keep the fallback in Svelte, not
|
||||
in Electron.
|
||||
Use canonical profile names plus extension aliases so the media family does not repeat the
|
||||
same VLC config for every file type. Cover the core macOS set (`pptx`, `ppt`, `key`, `odp`,
|
||||
`pdf`), the media set (`mp4`, `mkv`, `mp3`, and related media types), the Windows /
|
||||
Parallels variants (`pptxwin`, `pptwin`, `odpwin`, `pdfwin`), and the URL/web-based
|
||||
presentation path. Priority: `get_launch_profile()` already checks device config and event
|
||||
config; add a 3rd fallback to these Svelte defaults before returning `null`. Keep the
|
||||
fallback in Svelte, not in Electron.
|
||||
- [ ] **[Launcher] Composable open flow** — refactor `handle_open_file()` to use
|
||||
`copy_from_cache_to_temp` + `run_osascript` / `run_cmd` directly instead of the all-in-one
|
||||
`launch_from_cache`. Finer error handling at each step (verify copy succeeded before
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
* 1. event_file.cfg_json.display_override — per-file, display_mode only
|
||||
* 2. event_device.data_json.launch_profiles[ext] — full profile, per device (API)
|
||||
* 3. $events_loc.launcher.launch_profiles[ext] — local persistent override
|
||||
* 4. DEFAULT_LAUNCH_PROFILES[ext] — these built-ins
|
||||
* 4. DEFAULT_LAUNCH_PROFILES[ext] — extension aliases to canonical built-ins
|
||||
* 5. DEFAULT_LAUNCH_PROFILES['default'] — catch-all
|
||||
*
|
||||
* Keys are lowercase file extensions without the dot: "pptx", "key", "pdf", etc.
|
||||
@@ -18,9 +18,12 @@
|
||||
* - Plain string → run as AppleScript via run_osascript() (macOS only)
|
||||
* - "shell:..." prefix → run as shell command via run_cmd()
|
||||
*
|
||||
* Reserved for future use (not yet read anywhere):
|
||||
* Reserved for future use:
|
||||
* - speed_factor: number — delay multiplier for slower machines (1.0 = normal)
|
||||
* - url: string — for URL-type presentations (e.g. Google Slides)
|
||||
*
|
||||
* Special pseudo-extension:
|
||||
* - url — web-based presentations. Handled by the launcher URL branch rather
|
||||
* than a cache-to-temp open flow.
|
||||
*/
|
||||
|
||||
export interface LaunchProfile {
|
||||
@@ -46,18 +49,29 @@ export interface LaunchProfile {
|
||||
// url?: string;
|
||||
}
|
||||
|
||||
export const DEFAULT_LAUNCH_PROFILES: Record<string, LaunchProfile> = {
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// macOS presentation formats
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
pptx: {
|
||||
app: 'Microsoft PowerPoint',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "Microsoft PowerPoint" "{{path}}"',
|
||||
function make_vlc_mirror_profile(): LaunchProfile {
|
||||
return {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "Microsoft PowerPoint"
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
};
|
||||
}
|
||||
|
||||
const POWERPOINT_MAC_EXTEND_PROFILE: LaunchProfile = {
|
||||
app: 'Microsoft PowerPoint',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "Microsoft PowerPoint" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "Microsoft PowerPoint"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
@@ -65,40 +79,25 @@ tell application "System Events"
|
||||
keystroke return using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
};
|
||||
|
||||
ppt: {
|
||||
app: 'Microsoft PowerPoint',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "Microsoft PowerPoint" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "Microsoft PowerPoint"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "Microsoft PowerPoint"
|
||||
keystroke return using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
key: {
|
||||
app: 'Keynote',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "Keynote" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "Keynote"
|
||||
const KEYNOTE_MAC_EXTEND_PROFILE: LaunchProfile = {
|
||||
app: 'Keynote',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "Keynote" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "Keynote"
|
||||
activate
|
||||
start (front document)
|
||||
end tell`
|
||||
},
|
||||
};
|
||||
|
||||
odp: {
|
||||
app: 'LibreOffice',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "LibreOffice" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "LibreOffice"
|
||||
const LIBREOFFICE_MAC_EXTEND_PROFILE: LaunchProfile = {
|
||||
app: 'LibreOffice',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "LibreOffice" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "LibreOffice"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
@@ -106,14 +105,14 @@ tell application "System Events"
|
||||
key code 96
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
};
|
||||
|
||||
pdf: {
|
||||
app: 'Adobe Acrobat Reader DC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "Adobe Acrobat Reader DC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "Adobe Acrobat Reader DC"
|
||||
const ACROBAT_MAC_MIRROR_PROFILE: LaunchProfile = {
|
||||
app: 'Adobe Acrobat Reader DC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "Adobe Acrobat Reader DC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "Adobe Acrobat Reader DC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
@@ -121,198 +120,29 @@ tell application "System Events"
|
||||
keystroke "l" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
};
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Media (VLC) — mirror display
|
||||
// -------------------------------------------------------------------------
|
||||
const VLC_MIRROR_PROFILE: LaunchProfile = make_vlc_mirror_profile();
|
||||
|
||||
mp4: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
mkv: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
mov: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
mpeg: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
avi: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
flv: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
ogg: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
ogv: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
mp3: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
wmv: {
|
||||
app: 'VLC',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "VLC" "{{path}}"',
|
||||
post_delay_ms: 2000,
|
||||
post_script: `tell application "VLC"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
tell process "VLC"
|
||||
keystroke "f" using command down
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Windows / Parallels variants — longer post_delay_ms (Parallels needs more time)
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
pptxwin: {
|
||||
app: 'Microsoft Office PowerPoint (Windows)',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "Microsoft Office PowerPoint" "{{path}}"',
|
||||
post_delay_ms: 3000,
|
||||
post_script: `tell application "Microsoft Office PowerPoint"
|
||||
const POWERPOINT_WIN_EXTEND_PROFILE: LaunchProfile = {
|
||||
app: 'Microsoft Office PowerPoint (Windows)',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "Microsoft Office PowerPoint" "{{path}}"',
|
||||
post_delay_ms: 3000,
|
||||
post_script: `tell application "Microsoft Office PowerPoint"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
key code 96
|
||||
end tell`
|
||||
},
|
||||
};
|
||||
|
||||
pptwin: {
|
||||
app: 'Microsoft Office PowerPoint (Windows)',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "Microsoft Office PowerPoint" "{{path}}"',
|
||||
post_delay_ms: 3000,
|
||||
post_script: `tell application "Microsoft Office PowerPoint"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
key code 96
|
||||
end tell`
|
||||
},
|
||||
|
||||
odpwin: {
|
||||
app: 'LibreOffice (Windows)',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "LibreOffice" "{{path}}"',
|
||||
post_delay_ms: 3000,
|
||||
post_script: `tell application "LibreOffice"
|
||||
const LIBREOFFICE_WIN_EXTEND_PROFILE: LaunchProfile = {
|
||||
app: 'LibreOffice (Windows)',
|
||||
display_mode: 'extend',
|
||||
open_cmd: 'open -a "LibreOffice" "{{path}}"',
|
||||
post_delay_ms: 3000,
|
||||
post_script: `tell application "LibreOffice"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
@@ -320,46 +150,110 @@ tell application "System Events"
|
||||
key code 96
|
||||
end tell
|
||||
end tell`
|
||||
},
|
||||
};
|
||||
|
||||
pdfwin: {
|
||||
app: 'Acrobat Reader (Windows)',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "Acrobat Reader Windows" "{{path}}"',
|
||||
post_delay_ms: 3000,
|
||||
post_script: `tell application "Acrobat Reader Windows"
|
||||
const ACROBAT_WIN_MIRROR_PROFILE: LaunchProfile = {
|
||||
app: 'Acrobat Reader (Windows)',
|
||||
display_mode: 'mirror',
|
||||
open_cmd: 'open -a "Acrobat Reader Windows" "{{path}}"',
|
||||
post_delay_ms: 3000,
|
||||
post_script: `tell application "Acrobat Reader Windows"
|
||||
activate
|
||||
end tell
|
||||
tell application "System Events"
|
||||
key code 108 using control down
|
||||
end tell`
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// Catch-all — OS default handler, no display change
|
||||
// Works on macOS (open) and Linux (xdg-open via open_local_file_v2)
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
default: {
|
||||
app: 'OS Default',
|
||||
display_mode: 'none'
|
||||
// No open_cmd — execution falls through to open_local_file_v2(path)
|
||||
// No post_script
|
||||
},
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// URL-type files: event_file.filename IS the URL (https://...)
|
||||
// Opened via native.open_external({ url, app: 'chrome' }) — no local file involved.
|
||||
// display_mode 'extend' is the default for URL presentations (e.g. Google Slides).
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
url: {
|
||||
app: 'Chrome',
|
||||
display_mode: 'mirror'
|
||||
// No open_cmd or post_script — URL branch in handle_open_file() handles this
|
||||
}
|
||||
};
|
||||
|
||||
const URL_WEB_PROFILE: LaunchProfile = {
|
||||
app: 'Chrome',
|
||||
display_mode: 'extend',
|
||||
// No open_cmd or post_script — URL branch in handle_open_file() handles this
|
||||
};
|
||||
|
||||
const DEFAULT_OS_PROFILE: LaunchProfile = {
|
||||
app: 'OS Default',
|
||||
display_mode: 'none',
|
||||
// No open_cmd — execution falls through to open_local_file_v2(path)
|
||||
// No post_script
|
||||
};
|
||||
|
||||
type DefaultLaunchProfileDefinition = {
|
||||
name: string;
|
||||
aliases: string[];
|
||||
profile: LaunchProfile;
|
||||
};
|
||||
|
||||
export const DEFAULT_LAUNCH_PROFILE_DEFS: DefaultLaunchProfileDefinition[] = [
|
||||
{
|
||||
name: 'powerpoint_mac_extend',
|
||||
aliases: ['pptx', 'ppt'],
|
||||
profile: POWERPOINT_MAC_EXTEND_PROFILE
|
||||
},
|
||||
{
|
||||
name: 'keynote_mac_extend',
|
||||
aliases: ['key'],
|
||||
profile: KEYNOTE_MAC_EXTEND_PROFILE
|
||||
},
|
||||
{
|
||||
name: 'libreoffice_mac_extend',
|
||||
aliases: ['odp'],
|
||||
profile: LIBREOFFICE_MAC_EXTEND_PROFILE
|
||||
},
|
||||
{
|
||||
name: 'acrobat_mac_mirror',
|
||||
aliases: ['pdf'],
|
||||
profile: ACROBAT_MAC_MIRROR_PROFILE
|
||||
},
|
||||
{
|
||||
name: 'vlc_mirror',
|
||||
aliases: ['mp4', 'mkv', 'mov', 'mpeg', 'avi', 'flv', 'ogg', 'ogv', 'mp3', 'm4v', 'm4a', 'webm', 'wmv', 'wav', 'aac', 'flac'],
|
||||
profile: VLC_MIRROR_PROFILE
|
||||
},
|
||||
{
|
||||
name: 'powerpoint_win_extend',
|
||||
aliases: ['pptxwin', 'pptwin'],
|
||||
profile: POWERPOINT_WIN_EXTEND_PROFILE
|
||||
},
|
||||
{
|
||||
name: 'libreoffice_win_extend',
|
||||
aliases: ['odpwin'],
|
||||
profile: LIBREOFFICE_WIN_EXTEND_PROFILE
|
||||
},
|
||||
{
|
||||
name: 'acrobat_win_mirror',
|
||||
aliases: ['pdfwin'],
|
||||
profile: ACROBAT_WIN_MIRROR_PROFILE
|
||||
},
|
||||
{
|
||||
name: 'url_web',
|
||||
aliases: ['url'],
|
||||
profile: URL_WEB_PROFILE
|
||||
},
|
||||
{
|
||||
name: 'os_default',
|
||||
aliases: ['default'],
|
||||
profile: DEFAULT_OS_PROFILE
|
||||
}
|
||||
];
|
||||
|
||||
export const DEFAULT_LAUNCH_PROFILE_LIBRARY: Record<string, LaunchProfile> = Object.fromEntries(
|
||||
DEFAULT_LAUNCH_PROFILE_DEFS.map(({ name, profile }) => [name, profile])
|
||||
);
|
||||
|
||||
export const DEFAULT_LAUNCH_PROFILE_ALIASES: Record<string, string> = Object.fromEntries(
|
||||
DEFAULT_LAUNCH_PROFILE_DEFS.flatMap(({ name, aliases }) =>
|
||||
aliases.map((alias) => [alias, name])
|
||||
)
|
||||
);
|
||||
|
||||
export const DEFAULT_LAUNCH_PROFILES: Record<string, LaunchProfile> = Object.fromEntries(
|
||||
DEFAULT_LAUNCH_PROFILE_DEFS.flatMap(({ name, aliases, profile }) => [
|
||||
[name, { ...profile }],
|
||||
...aliases.map((alias) => [alias, { ...profile }])
|
||||
])
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns a shallow copy of the built-in profile for the given extension,
|
||||
* with a display_override applied if provided.
|
||||
@@ -373,15 +267,16 @@ export function resolve_launch_profile(
|
||||
local_profiles?: Record<string, LaunchProfile> | null
|
||||
): LaunchProfile {
|
||||
const ext = (extension || '').toLowerCase().replace(/^\./, '');
|
||||
const default_profile_name = DEFAULT_LAUNCH_PROFILE_ALIASES[ext] ?? ext;
|
||||
|
||||
// Priority: device config → local config → built-ins → default
|
||||
// Priority: device config → local config → canonical built-ins → default
|
||||
const source =
|
||||
device_profiles?.[ext] ??
|
||||
device_profiles?.['default'] ??
|
||||
local_profiles?.[ext] ??
|
||||
local_profiles?.['default'] ??
|
||||
DEFAULT_LAUNCH_PROFILES[ext] ??
|
||||
DEFAULT_LAUNCH_PROFILES['default'];
|
||||
DEFAULT_LAUNCH_PROFILES[default_profile_name] ??
|
||||
DEFAULT_LAUNCH_PROFILE_LIBRARY.os_default;
|
||||
|
||||
const profile = { ...source };
|
||||
|
||||
|
||||
@@ -65,7 +65,7 @@ export async function launch_from_cache({
|
||||
temp_root,
|
||||
filename,
|
||||
hash_prefix_length = 2,
|
||||
script_template = null
|
||||
native_template = null
|
||||
}: {
|
||||
cache_root: string;
|
||||
hash: string;
|
||||
@@ -73,17 +73,17 @@ export async function launch_from_cache({
|
||||
filename: string;
|
||||
hash_prefix_length?: number;
|
||||
/**
|
||||
* Optional data-driven launch script. If provided, Electron runs this instead of
|
||||
* its hardcoded extension-based logic — no app rebuild needed for script changes.
|
||||
* Resolved native launch template. If provided, Electron executes this string
|
||||
* after the file is copied to temp.
|
||||
*
|
||||
* Two formats:
|
||||
* - AppleScript: multi-line string with {{path}} placeholder (macOS only)
|
||||
* - Shell command: prefix with "shell:" → e.g. "shell:open \"{{path}}\""
|
||||
*
|
||||
* Configure via event_device.data_json.launch_profiles or $events_loc.launcher.launch_profiles.
|
||||
* If null, Electron falls through to its built-in hardcoded defaults.
|
||||
* If null, Electron should treat that as a missing profile error.
|
||||
*/
|
||||
script_template?: string | null;
|
||||
native_template?: string | null;
|
||||
}) {
|
||||
if (!native)
|
||||
return { success: false, error: 'Native bridge not available' };
|
||||
@@ -93,7 +93,7 @@ export async function launch_from_cache({
|
||||
temp_root,
|
||||
filename,
|
||||
hash_prefix_length,
|
||||
script_template
|
||||
native_template
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user