From c00e4088d7bce788dbbaf5e373275449ed394cec Mon Sep 17 00:00:00 2001 From: Guangcong Luo Date: Wed, 16 Dec 2015 00:46:47 -0500 Subject: [PATCH] Teambuilder: Support dragging teams onto folders This was ridiculous, or, in other words, par for the course when you're dealing with HTML5 drag-and-drop. Folders are now clickable divs instead of buttons. This turned out not to be necessary as it was a different issue that was causing drag-and-drop to fail, but I'd already changed everything over when I discovered the real bug. Oh well, some things are slightly nicer this way. --- js/client-teambuilder.js | 85 ++++++++++++++++++++++++++++++++++------ style/client.css | 48 ++++++++++++++--------- 2 files changed, 103 insertions(+), 30 deletions(-) diff --git a/js/client-teambuilder.js b/js/client-teambuilder.js index 19c6151c6..ac78eab3f 100644 --- a/js/client-teambuilder.js +++ b/js/client-teambuilder.js @@ -53,11 +53,15 @@ // drag/drop 'click .team': 'edit', + 'click .selectFolder': 'selectFolder', 'mouseover .team': 'mouseOverTeam', 'mouseout .team': 'mouseOutTeam', 'dragstart .team': 'dragStartTeam', 'dragend .team': 'dragEndTeam', 'dragenter .team': 'dragEnterTeam', + 'dragenter .folder .selectFolder': 'dragEnterFolder', + 'dragleave .folder .selectFolder': 'dragLeaveFolder', + 'dragexit .folder .selectFolder': 'dragExitFolder', // clipboard 'click .teambuilder-clipboard-data .result': 'clipboardResultSelect', @@ -164,7 +168,7 @@ updateFolderList: function () { var buf = '
'; - buf += '
'; + buf += '
' : '">') + '
(all)
' + (!this.curFormat ? '
' : ''); var folderTable = {}; var folders = []; if (Storage.teams) for (var i = -1; i < Storage.teams.length; i++) { @@ -218,11 +222,13 @@ format = 'gen' + newGen + formatName; } if (format === 'gen6') formatName = '(uncategorized)'; - buf += '
'; + // folders are
s rather than
'; + buf += '
(New format folder)
'; buf += '
'; @@ -284,6 +290,8 @@ formatText = '[' + team.format + '] '; } + // teams are
s rather than '; @@ -308,6 +316,16 @@ if (resetScroll) $pane.scrollTop(0); }, selectFolder: function (format) { + if (format && format.currentTarget) { + var e = format; + format = $(e.currentTarget).data('value'); + e.preventDefault(); + if (format === '+') { + this.format('', e.currentTarget); + e.stopImmediatePropagation(); + return; + } + } this.curFormat = (format === 'all' ? '' : format); this.updateFolderList(); this.updateTeamList(true); @@ -494,8 +512,9 @@ } var newLoc = Math.floor(app.draggingLoc); if (app.draggingLoc < originalLoc) newLoc += 1; + var team = Storage.teams[originalLoc]; + var edited = false; if (newLoc !== originalLoc) { - var team = Storage.teams[originalLoc]; Storage.teams.splice(originalLoc, 1); Storage.teams.splice(newLoc, 0, team); for (var room in app.rooms) { @@ -510,15 +529,27 @@ obj.curTeamIndex--; } } - Storage.saveTeams(); - app.user.trigger('saveteams'); + edited = true; } // possibly half-works-around a hover issue in this.$('.teamlist').css('pointer-events', 'none'); $(teamEl).parent().removeClass('dragging'); - this.updateTeamList(); + if (app.draggingFolder) { + var format = app.draggingFolder.dataset.value; + app.draggingFolder = null; + team.format = format; + this.selectFolder(format); + edited = true; + } else { + this.updateTeamList(); + } + + if (edited) { + Storage.saveTeams(); + app.user.trigger('saveteams'); + } // We're going to try to animate the team settling into its new position @@ -547,7 +578,8 @@ // everything is sane. var $newTeamEl = this.$('.team[data-value=' + newLoc + ']'); - $newTeamEl.css('transform', 'translate(' + this.finalOffset[0] + 'px, ' + this.finalOffset[1] + 'px)'); + var finalPos = $newTeamEl.offset(); + $newTeamEl.css('transform', 'translate(' + (this.finalOffset[0] - finalPos.left) + 'px, ' + (this.finalOffset[1] - finalPos.top) + 'px)'); setTimeout(function () { $newTeamEl.css('transition', 'transform 0.15s'); // it's 2015 and Safari doesn't support unprefixed transition!!! @@ -558,6 +590,8 @@ }, dragEnterTeam: function (e) { if (!app.dragging) return; + var $draggingLi = $(app.dragging).parent(); + this.dragLeaveFolder(); if (e.currentTarget === app.dragging) { e.preventDefault(); return; @@ -565,14 +599,41 @@ var hoverLoc = parseInt(e.currentTarget.dataset.value, 10); if (app.draggingLoc > hoverLoc) { // dragging up - $(e.currentTarget).parent().before($(app.dragging).parent()); + $(e.currentTarget).parent().before($draggingLi); app.draggingLoc = parseInt(e.currentTarget.dataset.value, 10) - 0.5; } else { // dragging down - $(e.currentTarget).parent().after($(app.dragging).parent()); + $(e.currentTarget).parent().after($draggingLi); app.draggingLoc = parseInt(e.currentTarget.dataset.value, 10) + 0.5; } }, + dragEnterFolder: function (e) { + if (!app.dragging) return; + this.dragLeaveFolder(); + if (e.currentTarget === app.draggingFolder) { + return; + } + var format = e.currentTarget.dataset.value; + if (format === '+' || format === 'all' || format === this.curFormat) { + return; + } + if (parseInt(app.dragging.dataset.value, 10) >= Storage.teams.length) { + // dragging a team file, already has a known format + return; + } + app.draggingFolder = e.currentTarget; + $(app.draggingFolder).addClass('active'); + // amusing note: using .detach() instead of .hide() will make `dragend` not fire + $(app.dragging).parent().hide(); + }, + dragLeaveFolder: function (e) { + // sometimes there's a race condition and dragEnter happens before dragLeave + if (e && e.currentTarget !== app.draggingFolder) return; + if (!app.dragging || !app.draggingFolder) return; + $(app.draggingFolder).removeClass('active'); + app.draggingFolder = null; + $(app.dragging).parent().show(); + }, defaultDragEnterTeam: function (e) { var dataTransfer = e.originalEvent.dataTransfer; if (!dataTransfer) return; @@ -580,6 +641,7 @@ if (dataTransfer.types.contains && !dataTransfer.types.contains('Files')) return; if (dataTransfer.files[0] && dataTransfer.files[0].name.slice(-4) !== '.txt') return; // We're dragging a file! It might be a team! + this.selectFolder('all'); this.$('.teamlist').append('
  • '); app.dragging = this.$('.dragging .team')[0]; app.draggingLoc = Storage.teams.length; @@ -628,8 +690,7 @@ }; reader.readAsText(file); } - var finalPos = $(app.dragging).offset(); - this.finalOffset = [e.originalEvent.pageX - app.draggingOffsetX - finalPos.left, e.originalEvent.pageY - app.draggingOffsetY - finalPos.top]; + this.finalOffset = [e.originalEvent.pageX - app.draggingOffsetX, e.originalEvent.pageY - app.draggingOffsetY]; }, /********************************************************* diff --git a/style/client.css b/style/client.css index 119dba4d9..a7a381dbd 100644 --- a/style/client.css +++ b/style/client.css @@ -1993,7 +1993,7 @@ a.ilink.yours { .folderlist { height: 100%; - width: 100%; + width: 154px; display: table; margin: 0; padding: 0; @@ -2045,33 +2045,40 @@ a.ilink.yours { background: #d7e3ec; border-right: 1px solid #888888; } -.folderpane button { +.folder .selectFolder { display: block; - position: relative; padding: 0 0 0 7px; border: 0; border-right: 1px solid #888888; background: #d7e3ec; color: black; - width: 100%; - height: 30px; + width: auto; + padding-top: 7px; + height: 23px; font-size: 9pt; font-family: Verdana, sans-serif; white-space: nowrap; overflow: hidden; text-align: left; cursor: pointer; + user-select: none; + -webkit-user-select: none; } -.folderpane button:hover { +.folder .selectFolder:hover { background: #c7d3dc; } -.folderpane button:active, -.folderpane button.active { +.folder .selectFolder:active { background: #b7c3cc; } -.folderpane button:disabled, -.folderpane button:disabled:hover, -.folderpane button:disabled:active { +.folder .selectFolder.active { + background: #27333c; + color: white; +} +.folder.cur .selectFolder, +.folder.cur .selectFolder:hover, +.folder.cur .selectFolder:active { + padding-top: 6px; + height: 22px; cursor: default; background: transparent; color: black; @@ -2084,8 +2091,9 @@ a.ilink.yours { border-bottom-left-radius: 3px; } -.folder.cur:before, -.folder.cur:after { +/* believe me, there was no other way to do this */ +.folderhack1, +.folderhack2 { position: absolute; display: block; left: 0; @@ -2094,12 +2102,16 @@ a.ilink.yours { background: #d7e3ec; content: ''; } -.folder.cur:before { +.folderhack1 { top: 0; } -.folder.cur:after { +.folderhack2 { bottom: 0; } +.folderhack3 { + position: relative; + height: 30px; +} .teampane .button, .teamwrapper .button { @@ -2137,9 +2149,9 @@ a.ilink.yours { } .teamlist .dragging .team { visibility: visible; - background: #DDDDDD; - border-color: #DDDDDD; - color: #DDDDDD; + background: #b7c3cc; + border-color: #b7c3cc; + color: #b7c3cc; box-shadow: none; } .teamlist .dragging .team small {