diff --git a/customize.dist/messages.js b/customize.dist/messages.js index abf96dbc0..6803d59fb 100755 --- a/customize.dist/messages.js +++ b/customize.dist/messages.js @@ -164,6 +164,11 @@ define(req, function(AppConfig, Default, Language) { Messages.fm_link_invalid = "Please provide a valid URL"; // XXX Messages.skipLink = "Skip to main content"; // XXX + //NOTE: these keys are also added to the Kanban mobile UI PR #1727 + Messages.moveItemUp = 'Move item up'; // XXX + Messages.moveItemDown = 'Move item down'; // XXX + Messages.toggleArrows = 'Switch to arrow view'; // XXX + Messages.toggleDrag = 'Switch to drag view'; // XXX return Messages; }); diff --git a/www/form/app-form.less b/www/form/app-form.less index 2042999ce..42f2c1bd7 100644 --- a/www/form/app-form.less +++ b/www/form/app-form.less @@ -133,6 +133,19 @@ } } + .cp-form-iseditor { + .cp-form-block header { + display: flex !important; + } + } + .cp-form-creator-results { + .cp-form-block-type { + float: right; + margin-top: -10px; + margin-right: -10px; + } + } + &.cp-form-readonly { .cp-form-creator-inline-add { display: none; @@ -203,6 +216,32 @@ //flex-wrap: wrap; overflow: auto; + .cp-drag-container { + display: flex; + flex-direction: row; + + button.cp-form-view-drag { + margin: 0; + padding: 1px 4px; + width: 30px; + height: 30px; + border: none; + border-radius: @variables_radius 0px 0px @variables_radius; + background-color: @cp_form-bg1; + color: @cryptpad_text_col; + &:focus-visible { + outline: @variables_focus_style; + } + &.cp-toggle-active { + color: @cp_form-bg1; + background-color: @cryptpad_text_col; + } + } + #cp-toggle-drag-on { + border-radius: 0px @variables_radius @variables_radius 0px !important; + } + } + @media screen and (max-width: 1000px) { flex-wrap: wrap; justify-content: flex-start; @@ -295,7 +334,6 @@ div.cp-form-creator-content { position: relative; .cp-form-block-type { - margin-top: -35px; &.editable { cursor: pointer; } @@ -369,6 +407,29 @@ display: flex; flex-flow: column; flex: 1 1 1000px; + &.cp-no-drag { + .cp-form-block { + .cp-form-block-arrows { + padding-left: 5px; + border-radius: 0px @variables_radius 0px 0px; + display: flex; + column-gap: 10px; + .cp-form-arrow { + display: block; + background-color: transparent; + border: none; + color: @cryptpad_text_col; + &:focus-visible { + border-radius: @variables_radius; + outline: @variables_focus_style; + } + } + } + .cp-form-block-drag-handle { + display: none !important; + } + } + } .cp-form-creator-add-inline { display: flex; @@ -560,6 +621,14 @@ margin-bottom: 20px; } + header { + display: none; + justify-content: space-between; + margin-top: -10px; + margin-left: -10px; + margin-right: -10px; + } + .cp-form-disabled { .cp-form-poll-choice, .cp-form-type-sort { cursor: not-allowed !important; @@ -575,18 +644,22 @@ .cp-form-block-drag-handle { display: flex; flex-flow: column; - height: 25px; - align-items: center; + width: 50px; + justify-content: center; + padding-left: 10px; + font-size: 20px; color: @cp_sidebar-hint; i { cursor: grab; &:first-child { height: 3px; - margin-top: -10px; - margin-bottom: 1px; + margin-bottom: 2px; } } } + .cp-form-block-arrows { + display: none; + } &.sortable-ghost { visibility: hidden; } &.sortable-drag { opacity: 0.9 !important; } @@ -963,10 +1036,10 @@ } } .cp-form-block-type { - float: right; + //float: right; padding: 5px; - margin-top: -10px; - margin-right: -10px; + //margin-top: -10px; + //margin-right: -10px; border-radius: 0px @variables_radius 0px 0px; i { margin-right: 5px; } background: fade(@cryptpad_text_col, 10%); diff --git a/www/form/inner.js b/www/form/inner.js index fd2daabc4..6585a4f96 100644 --- a/www/form/inner.js +++ b/www/form/inner.js @@ -3765,8 +3765,8 @@ define([ } }); $body.addClass('cp-form-palette-'+color); - - $container.attr('class', 'cp-form-creator-content'+(APP.isEditor? ' cp-form-iseditor': '')); + var containerDragClass = ('ontouchstart' in window || APP.drag === false) ? ' cp-no-drag' : ''; + $container.attr('class', 'cp-form-creator-content'+(APP.isEditor? ' cp-form-iseditor': '')+ containerDragClass); if (APP.isClosed && content.answers.privateKey && !APP.isEditor && !APP.hasAnswered) { var sframeChan = framework._.sfCommon.getSframeChannel(); @@ -3894,7 +3894,7 @@ define([ var updateAddInline = APP.updateAddInline = function () { $container.find('.cp-form-creator-add-inline').remove(); // Add before existing question - $container.find('.cp-form-block:not(.nodrag)').each(function (i, el) { + $container.find('.cp-form-block:not(.cp-form-submit-message)').each(function (i, el) { var $el = $(el); var uid = $el.attr('data-id'); $el.before(getFormCreator(uid)); @@ -4009,13 +4009,47 @@ define([ var changeType; + let shiftButtons; if (editable) { - // Drag handle - dragHandle = h('span.cp-form-block-drag-handle', [ - h('i.fa.fa-ellipsis-h'), - h('i.fa.fa-ellipsis-h'), + // Arrows + var upButton = h('button.cp-form-arrow', { + 'data-notippy':1, + 'title': Messages.moveItemUp, + 'aria-label': Messages.moveItemUp + }, [h('i.fa.fa-arrow-up', {'aria-hidden': true})]); + var downButton = h('button.cp-form-arrow', { + 'data-notippy':1, + 'title': Messages.moveItemDown, + 'aria-label': Messages.moveItemDown + }, [h('i.fa.fa-arrow-down', {'aria-hidden': true})]); + var shiftBlock = function(direction) { + var blockIndex = content.order.indexOf(uid); + if (direction === 'up' && blockIndex > 0) { + content.order.splice(blockIndex-1, 0, content.order.splice(blockIndex, 1)[0]); + updateForm(framework, content, true); + framework.localChange(); + } else if (direction === 'down' && blockIndex < content.order.length-1) { + content.order.splice(blockIndex+1, 0, content.order.splice(blockIndex, 1)[0]); + updateForm(framework, content, true); + framework.localChange(); + } + }; + $(upButton).click(function () { + shiftBlock('up'); + }); + $(downButton).click(function () { + shiftBlock('down'); + }); + shiftButtons = h('div.cp-form-block-arrows', [ + upButton, + downButton ]); + + // Drag handle + var dragEllipses = [h('i.fa.fa-ellipsis-h'), h('i.fa.fa-ellipsis-h')]; + dragHandle = h('span.cp-form-block-drag-handle', dragEllipses); + // Question var inputQ = h('input', { value: block.q || Messages.form_default @@ -4251,13 +4285,18 @@ define([ } } } + var editableCls = editable ? ".editable" : ""; - elements.push(h('div.cp-form-block'+editableCls, { + var draggable = APP.drag ? '' : '.nodrag'; + elements.push(h('div.cp-form-block'+editableCls+draggable, { 'data-id':uid, 'data-type':type }, [ - APP.isEditor ? dragHandle : undefined, - changeType, + h('header', [ + APP.isEditor ? dragHandle : undefined, + shiftButtons, + changeType + ]), isStatic ? undefined : q, h('div.cp-form-block-content', [ APP.isEditor && !isStatic ? requiredDiv : undefined, @@ -4524,6 +4563,8 @@ define([ } } }); + APP.mainSortable.options.disabled = 'ontouchstart' in window ? true : false; + return; } @@ -5090,9 +5131,37 @@ define([ editableStr ]); + var toggleOffclass = 'ontouchstart' in window ? 'cp-toggle-active' : undefined; + var toggleOnclass = 'ontouchstart' in window ? undefined : 'cp-toggle-active'; + var toggleDragOff = h(`button#cp-toggle-drag-off.cp-form-view-drag.${toggleOffclass}.fa.fa-arrows`, {'title': Messages.toggleArrows, 'tabindex': 0}); + var toggleDragOn = h(`button#cp-toggle-drag-on.cp-form-view-drag.${toggleOnclass}.fa.fa-hand-o-up`, {'title': Messages.toggleDrag, 'tabindex': 0}); + const updateDrag = state => { + return function () { + var $container = $('.cp-form-creator-content'); + $(toggleDragOn).toggleClass('cp-toggle-active', state); + $(toggleDragOff).toggleClass('cp-toggle-active', !state); + APP.mainSortable.options.disabled = !state; + APP.drag = state; + if (state) { + $container.removeClass('cp-no-drag'); + } else { + $container.addClass('cp-no-drag'); + } + }; + }; + + $(toggleDragOn).click(updateDrag(true)); + $(toggleDragOff).click(updateDrag(false)); + + var drag = h('div.cp-drag-container', [ + toggleDragOff, + toggleDragOn + ]); + return [ preview, previewSettings, + drag, colorTheme ]; }; @@ -5208,7 +5277,7 @@ define([ fillerContainer = h('div.cp-form-filler-container'); } - var contentContainer = h('div.cp-form-creator-content' + (APP.isEditor ? '.cp-form-iseditor' : '')); + var contentContainer = h('div.cp-form-creator-content' + (APP.isEditor ? '.cp-form-iseditor' : '') + ('ontouchstart' in window ? '.cp-no-drag' : '')); var resultsContainer = h('div.cp-form-creator-results'); var answeredContainer = h('div.cp-form-creator-answered', { style: 'display: none;' @@ -5478,7 +5547,7 @@ define([ var editButtons = h('div.cp-form-edit-buttons-container', [ preview, edit, del ]); var editDiv, previewDiv; - var div = h('div.cp-form-block.editable.nodrag', [ + var div = h('div.cp-form-block.editable.nodrag.cp-form-submit-message', [ h('div.cp-form-block-content', [ p, editDiv = h('div.cp-form-response-modal', t),