-
Notifications
You must be signed in to change notification settings - Fork 2
/
+page.svelte
138 lines (120 loc) · 3.94 KB
/
+page.svelte
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<script lang="ts">
// Svelte and UI Imports
import '../app.postcss';
import {
AppShell,
Drawer,
Modal,
ProgressBar,
storePopup,
initializeStores,
getModalStore,
type ModalSettings
} from '@skeletonlabs/skeleton';
import { computePosition, autoUpdate, flip, shift, offset, arrow } from '@floating-ui/dom';
import { onMount } from 'svelte';
// Svelte Component Imports
import AdvancedOptions from './AdvancedOptions.svelte';
import Footer from './Footer.svelte';
import Header from './Header.svelte';
import LinksAndDownloads from './LinksAndDownloads.svelte';
import MassLibraryUploader from './MassLibraryUploader.svelte';
import MsDataUploader from './MsDataUploader.svelte';
// Worker and JS Imports
import PGFinder from '$lib/pgfinder.ts?worker';
import { defaultPyio } from '$lib/constants';
import fileDownload from 'js-file-download';
import ErrorModal from './ErrorModal.svelte';
// Initialize Stores for Drawers and Modals
initializeStores();
// Get the Error Modal Store
const modalStore = getModalStore();
// Floating UI for Popups
storePopup.set({ computePosition, autoUpdate, flip, shift, offset, arrow });
// Pre-Declare Variables
let pyio: Pyio = { ...defaultPyio };
let loading = true;
let processing = false;
let ready = false;
let advancedMode = false;
let pgfinderVersion: string;
let allowedModifications: Array<string>;
let massLibraries: MassLibraryIndex;
// Start PGFinder
let pgfinder: Worker | undefined;
onMount(() => {
pgfinder = new PGFinder();
pgfinder.onmessage = ({ data: { type, content } }) => {
if (type === 'Ready') {
pgfinderVersion = content.pgfinderVersion;
allowedModifications = content.allowedModifications;
massLibraries = content.massLibraries;
loading = false;
} else if (type === 'Result') {
fileDownload(content.blob, content.filename);
processing = false;
} else if (type === 'Error') {
const modal: ModalSettings = {
type: 'component',
component: {
ref: ErrorModal,
props: {
message: content.message
}
}
};
modalStore.trigger(modal);
processing = false;
}
};
});
// Reactively compute if PGFinder is ready
$: ready = !loading && !processing && pyio.msData !== undefined && pyio.massLibrary !== undefined;
// Send data to PGFinder for processing
function runAnalysis() {
pgfinder?.postMessage(pyio);
processing = true;
}
// Reactively adapt the UI when entering advanced mode
let uiWidth: string;
$: uiWidth = advancedMode ? 'md:w-[40rem]' : '';
// It's nice to animate the width when opening and closing advanced mode, but
// it seems like animating the opening leads to some jittery animations, so
// this is just enables the animation on close. If browsers ever put
// transitions in their own threads, then maybe this will look nice...
$: animateWidth = !advancedMode ? 'transition-all' : '';
</script>
<Modal regionBackdrop="bg-surface-backdrop-token overflow-y-hidden" />
<Drawer>
<LinksAndDownloads />
</Drawer>
<AppShell>
<svelte:fragment slot="header">
<Header {pgfinderVersion} />
</svelte:fragment>
<div class="h-full flex flex-col justify-center items-center">
<div class="card m-2 w-[20rem] {uiWidth} max-w-[90%] {animateWidth}">
<section class="flex flex-col space-y-4 justify-center p-4">
<MsDataUploader bind:value={pyio.msData} />
<MassLibraryUploader bind:value={pyio.massLibrary} {massLibraries} />
<AdvancedOptions
bind:enabledModifications={pyio.enabledModifications}
bind:ppmTolerance={pyio.ppmTolerance}
bind:cleanupWindow={pyio.cleanupWindow}
bind:consolidationPpm={pyio.consolidationPpm}
bind:advancedMode
{allowedModifications}
/>
<button type="button" class="btn variant-filled" on:click={runAnalysis} disabled={!ready}>
Run Analysis
</button>
{#if processing}
<ProgressBar />
{/if}
</section>
</div>
</div>
<svelte:fragment slot="footer">
<Footer />
</svelte:fragment>
</AppShell>