|
12 | 12 | <meta property="og:description" content="WoofJS is a Scratch-inspired Javascript library for making games.">
|
13 | 13 |
|
14 | 14 | <script src="//load.sumome.com/" data-sumo-site-id="44245233c319d8fe9fb7ce8c7ed64db9381aa56477888a10319261f655cfffe2" async="async"></script>
|
15 |
| - |
16 | 15 |
|
| 16 | + <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"> |
17 | 17 |
|
18 | 18 |
|
19 | 19 |
|
|
251 | 251 | <button style="display: none" :style="{display: 'inline-block'}" style="margin-right: 5px; background-color:#4390BF !important; ; border:none; color:white; " class="btn btn-medium" :class="styles" onclick="save()">{{ status == "SAVED" ? 'Saved' : 'Save' }}</button>
|
252 | 252 | </span>
|
253 | 253 | </div>
|
254 |
| - |
| 254 | + |
| 255 | + <div class="modal fade" id="saveModal" tabindex="-1" role="dialog" aria-labelledby="saveModalLabel"> |
| 256 | + <div class="modal-dialog" role="document"> |
| 257 | + <div class="modal-content"> |
| 258 | + <div class="modal-header"> |
| 259 | + <h4 class="modal-title" id="saveModalLabel">Choose a name for your project</h4> |
| 260 | + </div> |
| 261 | + <div class="modal-body"> |
| 262 | + <div id="projectNameGroup" class="form-group" :class="{'has-info': projectNameInputValue == '', 'has-error': projectNameRequest == 'NAME TAKEN', 'has-success': projectNameInputValue != '' && projectNameRequest != 'NAME TAKEN', animated: projectNameRequest == 'NAME TAKEN' || projectNameLastKeyIllegal, shake: projectNameRequest == 'NAME TAKEN' || projectNameLastKeyIllegal}"> |
| 263 | + <input type="text" class="form-control" id="projectName" placeholder="my-project" :value="projectNameInputValue" @input="validate($event)" @keyDown.enter="saveName(projectNameInputValue)"> |
| 264 | + <span id="nameTaken" :style="{opacity: projectNameRequest == 'NAME TAKEN' ? '1' : '0'}" class="text-danger">That project name has already been taken. Try another one.</span> |
| 265 | + </div> |
| 266 | + <span id="illegalCharacter" class="text-danger" :class="{animated: projectNameLastKeyIllegal, shake: projectNameLastKeyIllegal}" style="display: inline-block" :style="{opacity: projectNameLastKeyIllegal ? '1' : '0'}">You cannot include {{ projectNameLastKeyIllegal }} in project names.</span> |
| 267 | + </div> |
| 268 | + <div class="modal-footer"> |
| 269 | + <button type="button" class="btn btn-default" data-dismiss="modal">Close</button> |
| 270 | + <button type="button" id="saveChanges" class="btn btn-primary" :class="{disabled: projectNameRequest != 'NOT LOADING' || projectNameInputValue == ''}" @click="saveName()">{{ projectNameRequest == "LOADING" ? "Loading..." : "Save" }}</button> |
| 271 | + </div> |
| 272 | + </div> |
| 273 | + </div> |
| 274 | + </div> |
| 275 | + |
255 | 276 | <div id="container">
|
256 | 277 |
|
257 | 278 | <div id="previewbar" v-show="previewbar" @click="previewbar= !previewbar" :style="{display: 'flex'}">
|
|
322 | 343 | return window.location.hash.substring(1, window.location.hash.length).split("/")[0];
|
323 | 344 | }
|
324 | 345 | var getIDWithRevision = function() {
|
325 |
| - // returns the name of a project, not inlcuding the current revision |
| 346 | + // returns the name of a project, inlcuding the current revision |
326 | 347 | return window.location.hash.substring(1, window.location.hash.length);
|
327 | 348 | }
|
328 | 349 | var getCurrentRevisionCode = function(revisions) {
|
|
366 | 387 | mouseX: 0,
|
367 | 388 | mouseY: 0,
|
368 | 389 | seenError: true,
|
| 390 | + |
| 391 | + projectNameRequest: "NOT LOADING", // or "LOADING" or "NAME TAKEN" |
| 392 | + projectNameInputValue: "", |
| 393 | + projectNameLastKeyIllegal: false, |
369 | 394 | },
|
370 | 395 | computed: {
|
371 | 396 | styles : function() { return {
|
|
401 | 426 | var beautiful = js_beautify(editor.getValue(), {space_after_anon_function: true, indent_size: 2, indent_with_tabs: false })
|
402 | 427 | editor.setValue(beautiful)
|
403 | 428 | },
|
| 429 | + validate: function($event) { |
| 430 | + var newName = $event.target.value |
| 431 | + |
| 432 | + this.projectNameRequest = 'NOT LOADING' // reset state so that you can hit save after you change the name after you get a NAME TAKEN error |
| 433 | + |
| 434 | + this.projectNameLastKeyIllegal = false // take off the animation |
| 435 | + setTimeout(function() { |
| 436 | + var lastKeyPressIllegal = newName.length > 0 && newName[newName.length - 1].match(/\.|#|\$|\/|\[|\]/) |
| 437 | + if (lastKeyPressIllegal) { |
| 438 | + this.projectNameLastKeyIllegal = lastKeyPressIllegal[0] |
| 439 | + } else { |
| 440 | + this.projectNameLastKeyIllegal = false |
| 441 | + } |
| 442 | + }.bind(this), 10) |
| 443 | + |
| 444 | + |
| 445 | + this.projectNameInputValue = newName.replace(" ", "-") |
| 446 | + this.projectNameInputValue = this.projectNameInputValue.replace(/\.|#|\$|\/|\[|\]/g, "") |
| 447 | + }, |
| 448 | + saveName : function() { |
| 449 | + if (app.projectNameRequest == "NOT LOADING"){ |
| 450 | + app.projectNameRequest = "LOADING" |
| 451 | + var name = app.projectNameInputValue |
| 452 | + if (name) { |
| 453 | + saveProject(name); |
| 454 | + } |
| 455 | + } |
| 456 | + }, |
404 | 457 | },
|
405 | 458 | watch: {
|
406 | 459 | error: function(newError) {
|
|
523 | 576 | window.location.reload()
|
524 | 577 | }
|
525 | 578 | })
|
526 |
| - |
527 |
| - var save = function(){ |
528 |
| - if (app.status == "SAVED") { return } |
529 |
| - |
530 |
| - if (editor.getValue().startsWith("// Loading...")){ |
531 |
| - return // don't allow students to save projects that haven't loaded |
532 |
| - } |
533 |
| - |
534 |
| - var name |
535 |
| - if (myCode) { |
536 |
| - name = getID() |
537 |
| - } else { |
538 |
| - name = window.prompt('Choose a name for your project. You cannot include ".", "#", "$", "[", "]", or spaces in the name of your project.', "my-project") || ''; |
539 |
| - } |
540 |
| - if (name.includes('.') || name.includes('/') || name.includes('$') || name.includes("#") || name.includes("[") || name.includes("]") || name.includes(" ")){ |
541 |
| - alert('You cannot include ".", "#", "$", "[", "]", or spaces in the name of your project. Try to save again.') |
542 |
| - } else if (name) { |
543 |
| - firebase.database().ref('/code/' + name).limitToLast(1).once('value').then(function(snapshot) { |
544 |
| - if (snapshot.val()){ |
545 |
| - if (firebase.auth().currentUser && snapshot.val()[Object.keys(snapshot.val())[0]].uid == firebase.auth().currentUser.uid) { |
546 |
| - // if the project exists and you own it, push the new code as a revision |
547 |
| - firebase.database().ref().child("/code/" + name).push({ |
548 |
| - code: editor.getValue(), |
549 |
| - time: firebase.database.ServerValue.TIMESTAMP, |
550 |
| - uid: firebase.auth().currentUser && firebase.auth().currentUser.uid |
551 |
| - }).then(function(){ |
552 |
| - window.location.hash = name |
553 |
| - makeClean() |
554 |
| - }).catch(function(error){ |
555 |
| - alert("Unable to save project: " + error) |
556 |
| - }); |
557 |
| - } else { |
558 |
| - alert("That project name has already been taken. Try another one.") |
559 |
| - } |
560 |
| - } else { |
561 |
| - // else create a new project and push this code as the first revision |
562 |
| - firebase.database().ref().child("/code/" + name + "/--uid").set(firebase.auth().currentUser && firebase.auth().currentUser.uid) |
| 579 | + |
| 580 | + var saveProject = function(name){ |
| 581 | + firebase.database().ref('/code/' + name).limitToLast(1).once('value').then(function(snapshot) { |
| 582 | + if (snapshot.val()){ |
| 583 | + if (firebase.auth().currentUser && snapshot.val()[Object.keys(snapshot.val())[0]].uid == firebase.auth().currentUser.uid) { |
| 584 | + // if the project exists and you own it, push the new code as a revision |
| 585 | + $('#saveModal').modal('hide'); |
| 586 | + app.projectNameRequest = "NOT LOADING" |
563 | 587 | firebase.database().ref().child("/code/" + name).push({
|
564 | 588 | code: editor.getValue(),
|
565 | 589 | time: firebase.database.ServerValue.TIMESTAMP,
|
566 | 590 | uid: firebase.auth().currentUser && firebase.auth().currentUser.uid
|
567 | 591 | }).then(function(){
|
568 | 592 | window.location.hash = name
|
569 |
| - myCode = firebase.auth().currentUser |
570 | 593 | makeClean()
|
571 | 594 | }).catch(function(error){
|
572 | 595 | alert("Unable to save project: " + error)
|
573 | 596 | });
|
| 597 | + } else { |
| 598 | + app.projectNameRequest = "NAME TAKEN" |
574 | 599 | }
|
575 |
| - }); |
| 600 | + } else { |
| 601 | + $('#saveModal').modal('hide'); |
| 602 | + app.projectNameRequest = "NOT LOADING" |
| 603 | + firebase.database().ref().child("/code/" + name + "/--uid").set(firebase.auth().currentUser && firebase.auth().currentUser.uid) |
| 604 | + firebase.database().ref().child("/code/" + name).push({ |
| 605 | + code: editor.getValue(), |
| 606 | + time: firebase.database.ServerValue.TIMESTAMP, |
| 607 | + uid: firebase.auth().currentUser && firebase.auth().currentUser.uid |
| 608 | + }).then(function(){ |
| 609 | + window.location.hash = name |
| 610 | + myCode = firebase.auth().currentUser |
| 611 | + makeClean() |
| 612 | + }).catch(function(error){ |
| 613 | + alert("Unable to save project: " + error) |
| 614 | + }); |
| 615 | + } |
| 616 | + }); |
| 617 | + } |
| 618 | + |
| 619 | + var save = function(){ |
| 620 | + if (app.status == "SAVED") { return } |
| 621 | + |
| 622 | + if (editor.getValue().startsWith("// Loading...")){ |
| 623 | + return // don't allow students to save projects that haven't loaded |
576 | 624 | }
|
577 |
| - }; |
| 625 | + |
| 626 | + if (myCode && getID()) { |
| 627 | + saveProject(getID()) |
| 628 | + } else { |
| 629 | + if (getID()) { |
| 630 | + app.projectNameInputValue = autoIncrimentedName() |
| 631 | + } |
| 632 | + $('#saveModal').modal('show') |
| 633 | + } |
| 634 | + } |
| 635 | + |
| 636 | + $('.modal').on('shown.bs.modal', function () { |
| 637 | + $('#projectName').focus() // focus on the project name input box when the modal loads |
| 638 | + }) |
| 639 | + |
| 640 | + var autoIncrimentedName = function() { |
| 641 | + var projName = getID(); |
| 642 | + var versionNumber = parseInt(projName[projName.length-1]) |
| 643 | + if (!isNaN(versionNumber) && projName[projName.length-2] == "-"){ |
| 644 | + versionNumber += 1; |
| 645 | + return projName.substring(0, projName.length-1) + versionNumber.toString(); |
| 646 | + } else { |
| 647 | + return projName + "-1"; |
| 648 | + } |
| 649 | + } |
578 | 650 |
|
579 | 651 | // keyboard shortcuts
|
580 | 652 | var mac = CodeMirror.keyMap["default"] == CodeMirror.keyMap.macDefault;
|
|
790 | 862 | c.parentNode.insertBefore(n,c);
|
791 | 863 | }();
|
792 | 864 | </script>
|
793 |
| - |
794 | 865 | </body>
|
795 | 866 | </html>
|
0 commit comments