Skip to content

Commit 64d8f69

Browse files
committed
Add exports popup
1 parent 7246e22 commit 64d8f69

5 files changed

Lines changed: 115 additions & 33 deletions

File tree

score-display/loaders/wd_data.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,7 @@ export class WdDataLoader {
7070
}
7171

7272
async exportAs(format) {
73-
console.error("WdDataLoader can't generate an export.");
74-
return
73+
throw "WdDataLoader can't generate an export.";
7574
}
7675

7776
async destroy() {}

score-display/loaders/webmscore.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export class WebMscoreLoader {
154154
if (format == "ogg")
155155
return score.saveAudio("ogg");
156156

157-
console.error(`Unknown download format ${format}`);
157+
throw `Unknown download format ${format}`;
158158
}
159159

160160
async destroy() {

score-display/score-display.css

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,4 +193,72 @@
193193

194194
.slcwd-button:hover+.slcwd-playback-tooltip {
195195
display: unset;
196+
}
197+
198+
.slcwd-exports {
199+
position: absolute;
200+
top: 50%;
201+
left: 50%;
202+
transform: translate(-50%, -50%);
203+
z-index: 3;
204+
205+
display: grid;
206+
grid-template-columns: 1fr 1fr;
207+
gap: 8px;
208+
min-width: 400px;
209+
padding: 12px;
210+
padding-top: 40px;
211+
border: 1px solid #ccc;
212+
background: #fff;
213+
box-shadow: rgba(17, 17, 26, 0.12) 0px 8px 24px;
214+
215+
border-radius: 10px;
216+
}
217+
218+
.slcwd-exports-close {
219+
position: absolute;
220+
right: 8px;
221+
top: 8px;
222+
width: 24px;
223+
height: 24px;
224+
border: none;
225+
background: transparent;
226+
cursor: pointer;
227+
}
228+
229+
.slcwd-exports-close:hover {
230+
color: red;
231+
}
232+
233+
.slcwd-exports > div {
234+
display: flex;
235+
}
236+
237+
.slcwd-exports .slcwd-button {
238+
width: 100%;
239+
text-align: left;
240+
padding: 8px 10px;
241+
border-radius: 5px;
242+
white-space: nowrap;
243+
}
244+
245+
.slcwd-export-error {
246+
color: red;
247+
}
248+
249+
.slcwd-spinner {
250+
animation-name: slcwd-spin;
251+
animation-duration: 3s;
252+
animation-iteration-count: infinite;
253+
animation-timing-function: linear;
254+
color: #0B67FF;
255+
}
256+
257+
@keyframes slcwd-spin {
258+
from {
259+
transform:rotate(0deg);
260+
}
261+
to {
262+
transform:rotate(360deg);
263+
}
196264
}

score-display/score-display.global.js

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,27 @@ loadStylesheet("https://maxst.icons8.com/vue-static/landings/line-awesome/line-a
4848
downloads: Object
4949
},
5050
setup(props, ctx) {
51-
console.log(props);
52-
5351
function close() {
5452
ctx.emit('close')
5553
}
5654

5755
function download(element) {
58-
ctx.emit('download', element)
56+
if (element.isLoading || element.errored) return;
57+
58+
element.isLoading = true;
59+
ctx.emit('download', element, () => {element.isLoading = false}, () => {element.errored = true})
5960
}
6061

6162
return { close, download }
6263
},
6364
template: /*html*/`
6465
<div class="slcwd-exports" ref="ref">
65-
<button @click="close">x</button>
66+
<button class="slcwd-exports-close" @click="close"><i class="las la-times"></i></button>
6667
<div v-for="el of downloads">
6768
<button class="slcwd-button" @click="() => download(el)">
69+
<i v-if="el.errored" class="las la-exclamation-circle slcwd-export-error"></i>
70+
<i v-else-if="el.isLoading" class="las la-circle-notch slcwd-spinner"></i>
71+
<i v-else class="las la-file-download"></i>
6872
{{ el.name }}
6973
</button>
7074
</div>
@@ -292,8 +296,8 @@ loadStylesheet("https://maxst.icons8.com/vue-static/landings/line-awesome/line-a
292296
ctx.emit('select', ret)
293297
}
294298

295-
function download(element) {
296-
ctx.emit('download', element);
299+
function download(element, callback, errcallback) {
300+
ctx.emit('download', element, callback, errcallback);
297301
}
298302

299303
function closeExportPopup () {
@@ -345,7 +349,7 @@ loadStylesheet("https://maxst.icons8.com/vue-static/landings/line-awesome/line-a
345349
</button>
346350
<button
347351
v-if="downloads.length == 1"
348-
@click="() => download(downloads[0])"
352+
@click="() => download(downloads[0], () => {}, () => {})"
349353
class="slcwd-button"
350354
>
351355
<i class="las la-file-download"></i> <span class="label">{{ downloads[0].name }}</span>
@@ -357,13 +361,13 @@ loadStylesheet("https://maxst.icons8.com/vue-static/landings/line-awesome/line-a
357361
>
358362
<i class="las la-file-download"></i> <span class="label">Download</span>
359363
</button>
360-
<ExportPopup
361-
v-if="showExportPopup"
362-
:downloads=downloads
363-
@close="closeExportPopup"
364-
@download="download"
365-
/>
366364
</div>
365+
<ExportPopup
366+
v-show="showExportPopup"
367+
:downloads=downloads
368+
@close="closeExportPopup"
369+
@download="download"
370+
/>
367371
`
368372
}
369373

@@ -786,26 +790,31 @@ loadStylesheet("https://maxst.icons8.com/vue-static/landings/line-awesome/line-a
786790
}
787791
)
788792

789-
async function download(element) {
790-
let dataLoc = element.href;
791-
let filename = null; // If null, will get it from URL
792-
if (dataLoc.startsWith("mscz/export:")) {
793-
if (!WebMscoreSupported.includes(props.type)) {// We have no mscz source file
794-
console.error("Could not save file, score is not loaded from websmcore", element);
795-
return;
796-
}
797-
if (loader.value == null) {
798-
console.error("Loader not available.");
799-
return;
793+
async function download(element, callback, errcallback) {
794+
try {
795+
let dataLoc = element.href;
796+
let filename = null;
797+
if (dataLoc.startsWith("mscz/export:")) {
798+
if (!WebMscoreSupported.includes(props.type)) // We have no mscz source file
799+
throw "Could not save file, score is not loaded from websmcore";
800+
if (loader.value == null)
801+
throw "Loader not available.";
802+
803+
const exportFormat = dataLoc.split(":")[1];
804+
const data = await loader.value.exportAs(exportFormat);
805+
filename = `${scoreMeta.value.title}.${exportFormat}`;
806+
dataLoc = new Blob([data]);
807+
} else {
808+
filename = element.href.substr(element.href.lastIndexOf("/")+1);
800809
}
810+
811+
saveAs(dataLoc, filename);
812+
callback();
801813

802-
const exportFormat = dataLoc.split(":")[1];
803-
const data = await loader.value.exportAs(exportFormat);
804-
filename = `${scoreMeta.value.title}.${exportFormat}`;
805-
dataLoc = new Blob([data]);
814+
} catch (error) {
815+
console.error(`While exporting for "${element.name}" : ${error}`);
816+
errcallback();
806817
}
807-
808-
saveAs(dataLoc, filename);
809818
}
810819

811820

viewer.html

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@
3636
document.getElementById("score-container").innerHTML += `
3737
<score-display id="score-display" src="data:.${extension};base64,${base64score}" type="${extension}">
3838
<score-track type="mscz/synth:all">Tutti</score-track>
39+
40+
<score-download href="mscz/export:mscz">Download mscz</score-download>
41+
<score-download href="mscz/export:pdf">Download pdf</score-download>
42+
<score-download href="mscz/export:mxl">Download mxl</score-download>
43+
<score-download href="mscz/export:musicxml">Download MusicXML</score-download>
44+
<score-download href="mscz/export:ogg">Download audio (ogg)</score-download>
3945
</score-display>
4046
`;
4147

0 commit comments

Comments
 (0)