Skip to content

Commit 792f5f3

Browse files
committed
feat: add cue start offset and change go+ to goto
1 parent e159671 commit 792f5f3

1 file changed

Lines changed: 84 additions & 32 deletions

File tree

src/routes/+page.svelte

Lines changed: 84 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
let uploadArea: HTMLElement;
77
let sequenceNumber = 101;
88
let driveNumber = 2;
9+
let cueStartNumber = 1;
910
let prefix = "1";
1011
let exportMode: "cues-and-timecode" | "cues-only" = "cues-and-timecode";
1112
let isDragOver = false;
@@ -27,7 +28,7 @@
2728
}[];
2829
2930
type FullData = {
30-
uniqueSequences: ParsedData;
31+
uniqueCues: ParsedData;
3132
repeatedSequences: RepeatedSequenceData;
3233
filename: string;
3334
};
@@ -102,7 +103,7 @@
102103
}))
103104
.reverse();
104105
105-
const uniqueSequences = data.filter((item) => !item.color);
106+
const uniqueCues = data.filter((item) => !item.color);
106107
const repeatedSequenceList = data.filter((item) => item.color);
107108
108109
let sqCounter = sequenceNumber + 1;
@@ -124,11 +125,11 @@
124125
processingStatus = "Generating XML files...";
125126
await new Promise((resolve) => setTimeout(resolve, 100));
126127
127-
const xmlContent = generateMacroXML({ repeatedSequences, uniqueSequences, filename });
128+
const xmlContent = generateMacroXML({ repeatedSequences, uniqueCues, filename });
128129
downloadContentWithName(xmlContent, `${filename}_macro.xml`);
129130
130131
if (exportMode === "cues-and-timecode") {
131-
const timecodeContent = generateTimecodeXML({ repeatedSequences, uniqueSequences, filename });
132+
const timecodeContent = generateTimecodeXML({ repeatedSequences, uniqueCues, filename });
132133
downloadContentWithName(timecodeContent, `${filename}_timecode.xml`);
133134
}
134135
@@ -205,7 +206,7 @@
205206
.join(" ");
206207
}
207208
208-
function generateMacroXML({ repeatedSequences, uniqueSequences, filename }: FullData): string {
209+
function generateMacroXML({ repeatedSequences, uniqueCues, filename }: FullData): string {
209210
const obj = {
210211
...XML_HEADER,
211212
GMA3: {
@@ -216,11 +217,11 @@
216217
MacroLine: [
217218
// unique sequences
218219
{
219-
"@_Command": `Store Sequence ${sequenceNumber} Cue 1 thru ${uniqueSequences.length}`,
220+
"@_Command": `Store Sequence ${sequenceNumber} Cue ${cueStartNumber} thru ${uniqueCues.length + cueStartNumber - 1}`,
220221
"@_Wait": "0.10",
221222
},
222-
...uniqueSequences.map((item, index) => ({
223-
"@_Command": `Label Sequence ${sequenceNumber} Cue ${index + 1} "${item.name}"`,
223+
...uniqueCues.map((item, index) => ({
224+
"@_Command": `Label Sequence ${sequenceNumber} Cue ${index + cueStartNumber} "${item.name}"`,
224225
"@_Wait": "0.10",
225226
})),
226227
/// repeated sequences
@@ -261,20 +262,21 @@
261262
return builder.build(obj);
262263
}
263264
264-
function generateTimecodeXML({ uniqueSequences, repeatedSequences, filename }: FullData): string {
265+
function generateTimecodeXML({ uniqueCues, repeatedSequences, filename }: FullData): string {
265266
const obj = {
266267
...XML_HEADER,
267268
GMA3: {
268269
"@_DataVersion": "1.4.0.2",
270+
// unique sequences
269271
Timecode: {
270272
"@_Name": filename,
271273
"@_Guid": "00 00 00 00 3F 76 B7 04 32 0B 00 00 68 A1 4F AA",
272274
"@_Cursor": "00.00",
273-
"@_Duration": uniqueSequences.length > 0 ? (parseFloat(uniqueSequences[uniqueSequences.length - 1].start) + 1).toFixed(3) : "0.00",
275+
"@_Duration": uniqueCues.length > 0 ? (parseFloat(uniqueCues[uniqueCues.length - 1].start) + 1).toFixed(3) : "0.00",
274276
"@_LoopCount": "0",
275277
"@_TCSlot": "-1",
276278
"@_SwitchOff": "Keep Playbacks",
277-
"@_Goto": "as Go",
279+
// "@_Goto": "as Go",
278280
"@_Timedisplayformat": "<10d11h23m45>",
279281
"@_FrameReadout": "<Seconds>",
280282
TrackGroup: [
@@ -295,8 +297,8 @@
295297
"@_Play": "",
296298
"@_Rec": "",
297299
CmdSubTrack: {
298-
CmdEvent: uniqueSequences.map((item, index) => ({
299-
"@_Name": "Go+",
300+
CmdEvent: uniqueCues.map((item, index) => ({
301+
"@_Name": "Goto",
300302
"@_Time": item.start,
301303
RealtimeCmd: {
302304
"@_Type": "Key",
@@ -318,14 +320,15 @@
318320
"@_Object": `ShowData.DataPools.Default.Sequences.Sequence ${sequenceNumber}`,
319321
}
320322
: {}),
321-
"@_ExecToken": "Go+",
323+
"@_ExecToken": "Goto",
322324
"@_ValCueDestination": `ShowData.DataPools.Default.Sequences.Sequence ${sequenceNumber}.${item.name}`,
323325
},
324326
})),
325327
},
326328
},
327329
},
328330
},
331+
// repeated sequences
329332
{
330333
"@_Play": "",
331334
"@_Rec": "",
@@ -344,7 +347,7 @@
344347
"@_Rec": "",
345348
CmdSubTrack: {
346349
CmdEvent: item.timestamps.map((timestamp, index) => ({
347-
"@_Name": "Go+",
350+
"@_Name": "Goto",
348351
"@_Time": timestamp,
349352
RealtimeCmd: {
350353
"@_Type": "Key",
@@ -366,7 +369,7 @@
366369
"@_Object": `ShowData.DataPools.Default.Sequences.${item.name}`,
367370
}
368371
: {}),
369-
"@_ExecToken": "Go+",
372+
"@_ExecToken": "Goto",
370373
"@_ValCueDestination": `ShowData.DataPools.Default.Sequences.${item.name}.Cue 1`,
371374
},
372375
})),
@@ -466,6 +469,19 @@
466469
</div>
467470
</div>
468471

472+
<details class="advanced-mode-section section-card">
473+
<summary class="section-summary">
474+
<span class="label-text">Advanced</span>
475+
<span class="label-hint">Additional options</span>
476+
</summary>
477+
<div>
478+
<label for="drive-number" class="label">
479+
<span class="label-text">Cue Start Number</span>
480+
<span class="label-hint">Starting number for cues (1-9999)</span>
481+
</label>
482+
<input id="drive-number" type="number" min="1" max="9999" step="1" bind:value={cueStartNumber} class="input" />
483+
</div>
484+
</details>
469485
<div class="export-mode-section">
470486
<div class="label">
471487
<span class="label-text">Export Mode</span>
@@ -529,7 +545,7 @@
529545

530546
<footer class="footer">
531547
<p>Made with ❤️ and Svelte - View <a target="_blank" href="https://github.com/hrueger/reaper2ma">Source on GitHub</a></p>
532-
<p>&copy; 2025 Hannes Rüger</p>
548+
<p>&copy; 2025 - 2026 Hannes Rüger</p>
533549
</footer>
534550
</main>
535551

@@ -796,10 +812,60 @@
796812
flex-shrink: 0;
797813
}
798814
799-
.export-mode-section {
815+
.export-mode-section,
816+
.advanced-mode-section {
800817
margin-top: 1.5rem;
801818
}
802819
820+
.section-card {
821+
border: 1px solid var(--border-light);
822+
border-radius: 12px;
823+
padding: 1rem;
824+
background: color-mix(in srgb, var(--upload-bg) 82%, transparent);
825+
transition:
826+
border-color 0.2s ease,
827+
background 0.2s ease,
828+
box-shadow 0.2s ease;
829+
}
830+
831+
.section-card:hover {
832+
border-color: var(--border-hover);
833+
}
834+
835+
.section-summary {
836+
list-style: none;
837+
cursor: pointer;
838+
position: relative;
839+
padding-right: 2rem;
840+
}
841+
842+
.section-summary::-webkit-details-marker {
843+
display: none;
844+
}
845+
846+
.section-summary::after {
847+
content: "";
848+
position: absolute;
849+
right: 0.5rem;
850+
top: 50%;
851+
width: 0.55rem;
852+
height: 0.55rem;
853+
border-right: 2px solid var(--text-secondary);
854+
border-bottom: 2px solid var(--text-secondary);
855+
transform: translateY(-65%) rotate(45deg);
856+
transition: transform 0.2s ease;
857+
}
858+
859+
.advanced-mode-section[open] .section-summary::after {
860+
transform: translateY(-25%) rotate(225deg);
861+
}
862+
863+
.advanced-mode-section > div {
864+
margin-top: 0.75rem;
865+
padding-top: 0.75rem;
866+
border-top: 1px solid var(--border-light);
867+
}
868+
803869
.radio-group {
804870
display: grid;
805871
grid-template-columns: repeat(2, 1fr);
@@ -948,20 +1014,6 @@
9481014
flex-shrink: 0;
9491015
}
9501016
951-
.note {
952-
background: var(--note-bg);
953-
padding: 1rem;
954-
border-radius: 8px;
955-
border-left: 4px solid var(--note-border);
956-
margin: 0;
957-
font-size: 0.9rem;
958-
line-height: 1.5;
959-
color: var(--text-primary);
960-
transition:
961-
background 0.3s ease,
962-
border 0.3s ease;
963-
}
964-
9651017
.footer {
9661018
text-align: center;
9671019
color: rgba(255, 255, 255, 0.8);

0 commit comments

Comments
 (0)