diff --git a/app/assets/images/sprite.svg b/app/assets/images/sprite.svg index 1af804920..cfafff8b1 100644 --- a/app/assets/images/sprite.svg +++ b/app/assets/images/sprite.svg @@ -1,5 +1,5 @@ - + 1 Created with Sketch (http://www.bohemiancoding.com/sketch) @@ -190,8 +190,8 @@ - - - + + + \ No newline at end of file diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee index e1d209320..d25b6a427 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.js.coffee @@ -319,6 +319,7 @@ class Sidebar extends App.Controller class Edit extends App.Controller elements: 'textarea' : 'textarea' + '.js-edit-control' : 'editControls' events: 'click .submit': 'update' @@ -326,7 +327,7 @@ class Edit extends App.Controller 'click .visibility-toggle': 'toggle_visibility' 'click .pop-selectable': 'select_type' 'click .pop-selected': 'show_selectable_types' - 'focus textarea': 'show_controls' + 'focus textarea': 'open_textarea' 'input textarea': 'detect_empty_textarea' 'click .recipient-picker': 'show_recipients' 'click .recipient-list': 'stopPropagation' @@ -335,6 +336,11 @@ class Edit extends App.Controller constructor: -> super + + @textareaHeight = + open: 148 + closed: 38 + @render() stopPropagation: (e) -> @@ -559,17 +565,44 @@ class Edit extends App.Controller else @remove_textarea_catcher() - show_controls: => + open_textarea: => if !@textareaCatcher and !@textarea.val() @el.addClass('mode--edit') + # scroll to bottom - @el.scrollParent().scrollTop(99999) + @textarea.velocity "scroll", + container: @textarea.scrollParent() + offset: @textareaHeight.open - @textareaHeight.closed + duration: 300 + easing: 'easeOutQuad' + + @textarea.velocity + properties: + height: "#{ @textareaHeight.open }px" + options: + speed: 300 + easing: 'easeOutQuad' + queue: false + + @editControls.velocity + properties: + translateY: [ + (i) -> (i+1) * 38, + 'easeOutQuad', + 0 + ] + opacity: [ 1, [ 0.34, 1.61, 0.7, 1 ], 0] + scale: [ 1, 'easeOutQuad', 0 ] + options: + speed: 300 + stagger: (i) -> i*100 + @add_textarea_catcher() add_textarea_catcher: -> @textareaCatcher = new App.clickCatcher holder: @el.offsetParent() - callback: @hide_controls + callback: @close_textarea zIndexScale: 4 remove_textarea_catcher: -> @@ -577,11 +610,32 @@ class Edit extends App.Controller @textareaCatcher.remove() @textareaCatcher = null - hide_controls: => + close_textarea: => @remove_textarea_catcher() if !@textarea.val() @el.removeClass('mode--edit') + @textarea.velocity + properties: + height: "#{ @textareaHeight.closed }px" + options: + speed: 300 + easing: 'easeOutQuad' + + @editControls.velocity + properties: + translateY: [ + 0, + 'easeOutQuad', + (i) -> (i+1) * 38 + ] + scale: [ 0, [ 0.34, 1.61, 0.7, 1 ], 1 ] + opacity: [ 0, 'easeOutQuad', 1 ] + options: + speed: 300 + stagger: 300 + backwards: true + autosaveStop: => @clearInterval( 'autosave' ) diff --git a/app/assets/javascripts/app/lib/core/jquery.velocity.min.js b/app/assets/javascripts/app/lib/animations/jquery.velocity.min.js similarity index 100% rename from app/assets/javascripts/app/lib/core/jquery.velocity.min.js rename to app/assets/javascripts/app/lib/animations/jquery.velocity.min.js diff --git a/app/assets/javascripts/app/lib/animations/velocity.ui.js b/app/assets/javascripts/app/lib/animations/velocity.ui.js new file mode 100644 index 000000000..2f4aee8ef --- /dev/null +++ b/app/assets/javascripts/app/lib/animations/velocity.ui.js @@ -0,0 +1,672 @@ +/********************** + Velocity UI Pack +**********************/ + +/* VelocityJS.org UI Pack (4.1.4). (C) 2014 Julian Shapiro. MIT @license: en.wikipedia.org/wiki/MIT_License. Portions copyright Daniel Eden, Christian Pucci. */ + +;(function (factory) { + /* CommonJS module. */ + if (typeof module === "object" && typeof module.exports === "object") { + module.exports = factory(); + /* AMD module. */ + } else if (typeof define === "function" && define.amd) { + define([ "velocity" ], factory); + /* Browser globals. */ + } else { + factory(); + } +}(function() { +return function (global, window, document, undefined) { + + /************** + Checks + **************/ + + if (!global.Velocity || !global.Velocity.Utilities) { + window.console && console.log("Velocity UI Pack: Velocity must be loaded first. Aborting."); + return; + } else if (!global.Velocity.version || (global.Velocity.version.major <= 0 && global.Velocity.version.minor <= 11 && global.Velocity.version.patch < 8)) { + var abortError = "Velocity UI Pack: You need to update Velocity (jquery.velocity.js) to a newer version. Visit http://github.com/julianshapiro/velocity."; + + alert(abortError); + throw new Error(abortError); + } + + /****************** + Register UI + ******************/ + + global.Velocity.RegisterUI = function (effectName, properties) { + /* Animate the expansion/contraction of the elements' parent's height for In/Out effects. */ + function animateParentHeight (elements, direction, totalDuration, stagger) { + var totalHeightDelta = 0, + parentNode; + + /* Sum the total height (including padding and margin) of all targeted elements. */ + global.Velocity.Utilities.each(elements.nodeType ? [ elements ] : elements, function(i, element) { + if (stagger) { + /* Increase the totalDuration by the successive delay amounts produced by the stagger option. */ + totalDuration += i * stagger; + } + + parentNode = element.parentNode; + + global.Velocity.Utilities.each([ "height", "paddingTop", "paddingBottom", "marginTop", "marginBottom"], function(i, property) { + totalHeightDelta += parseFloat(global.Velocity.CSS.getPropertyValue(element, property)); + }); + }); + + /* Animate the parent element's height adjustment (with a varying duration multiplier for aesthetic benefits). */ + global.Velocity.animate( + parentNode, + { height: (direction === "In" ? "+" : "-") + "=" + totalHeightDelta }, + { queue: false, easing: "ease-in-out", duration: totalDuration * (direction === "In" ? 0.6 : 1) } + ); + } + + /* Register a custom sequence for each effect. */ + global.Velocity.Sequences[effectName] = function (element, sequenceOptions, elementsIndex, elementsSize, elements, promiseData) { + var finalElement = (elementsIndex === elementsSize - 1); + + /* Iterate through each effect's call array. */ + for (var callIndex = 0; callIndex < properties.calls.length; callIndex++) { + var call = properties.calls[callIndex], + propertyMap = call[0], + sequenceDuration = (sequenceOptions.duration || properties.defaultDuration || 1000), + durationPercentage = call[1], + callOptions = call[2] || {}, + opts = {}; + + /* Assign the whitelisted per-call options. */ + opts.duration = sequenceDuration * (durationPercentage || 1); + opts.queue = sequenceOptions.queue || ""; + opts.easing = callOptions.easing || "ease"; + opts.delay = callOptions.delay || 0; + opts._cacheValues = callOptions._cacheValues || true; + + /* Special processing for the first effect call. */ + if (callIndex === 0) { + /* If a delay was passed into the sequence, combine it with the first call's delay. */ + opts.delay += (sequenceOptions.delay || 0); + + if (elementsIndex === 0) { + opts.begin = function() { + /* Only trigger a begin callback on the first effect call with the first element in the set. */ + sequenceOptions.begin && sequenceOptions.begin.call(elements, elements); + + /* Only trigger animateParentHeight() if we're using an In/Out transition. */ + var direction = effectName.match(/(In|Out)$/); + if (sequenceOptions.animateParentHeight && direction) { + animateParentHeight(elements, direction[0], sequenceDuration + opts.delay, sequenceOptions.stagger); + } + } + } + + /* If the user isn't overriding the display option, default to "auto" for "In"-suffixed transitions. */ + if (sequenceOptions.display !== null) { + if (sequenceOptions.display !== undefined && sequenceOptions.display !== "none") { + opts.display = sequenceOptions.display; + } else if (/In$/.test(effectName)) { + /* Inline elements cannot be subjected to transforms, so we switch them to inline-block. */ + var defaultDisplay = global.Velocity.CSS.Values.getDisplayType(element); + opts.display = (defaultDisplay === "inline") ? "inline-block" : defaultDisplay; + } + } + + if (sequenceOptions.visibility && sequenceOptions.visibility !== "hidden") { + opts.visibility = sequenceOptions.visibility; + } + } + + /* Special processing for the last effect call. */ + if (callIndex === properties.calls.length - 1) { + /* Append promise resolving onto the user's sequence callback. */ + function injectFinalCallbacks () { + if ((sequenceOptions.display === undefined || sequenceOptions.display === "none") && /Out$/.test(effectName)) { + global.Velocity.Utilities.each(elements.nodeType ? [ elements ] : elements, function(i, element) { + global.Velocity.CSS.setPropertyValue(element, "display", "none"); + }); + } + + sequenceOptions.complete && sequenceOptions.complete.call(elements, elements); + + if (promiseData) { + promiseData.resolver(elements || element); + } + } + + opts.complete = function() { + if (properties.reset) { + for (var resetProperty in properties.reset) { + var resetValue = properties.reset[resetProperty]; + + /* Format each non-array value in the reset property map to [ value, value ] so that changes apply + immediately and DOM querying is avoided (via forcefeeding). */ + if (typeof resetValue === "string" || typeof resetValue === "number") { + properties.reset[resetProperty] = [ properties.reset[resetProperty], properties.reset[resetProperty] ]; + } + } + + /* So that the reset values are applied instantly upon the next rAF tick, use a zero duration and parallel queueing. */ + var resetOptions = { duration: 0, queue: false }; + + /* Since the reset option uses up the complete callback, we trigger the user's complete callback at the end of ours. */ + if (finalElement) { + resetOptions.complete = injectFinalCallbacks; + } + + global.Velocity.animate(element, properties.reset, resetOptions); + /* Only trigger the user's complete callback on the last effect call with the last element in the set. */ + } else if (finalElement) { + injectFinalCallbacks(); + } + }; + + if (sequenceOptions.visibility === "hidden") { + opts.visibility = sequenceOptions.visibility; + } + } + + global.Velocity.animate(element, propertyMap, opts); + } + }; + + /* Return the Velocity object so that RegisterUI calls can be chained. */ + return global.Velocity; + }; + + /********************* + Packaged Effects + *********************/ + + /* Externalize the packagedEffects data so that they can optionally be modified and re-registered. */ + /* Support: <=IE8: Callouts will have no effect, and transitions will simply fade in/out. IE9/Android 2.3: Most effects are fully supported, the rest fade in/out. All other browsers: full support. */ + global.Velocity.RegisterUI.packagedEffects = + { + /* Animate.css */ + "callout.bounce": { + defaultDuration: 550, + calls: [ + [ { translateY: -30 }, 0.25 ], + [ { translateY: 0 }, 0.125 ], + [ { translateY: -15 }, 0.125 ], + [ { translateY: 0 }, 0.25 ] + ] + }, + /* Animate.css */ + "callout.shake": { + defaultDuration: 800, + calls: [ + [ { translateX: -11 }, 0.125 ], + [ { translateX: 11 }, 0.125 ], + [ { translateX: -11 }, 0.125 ], + [ { translateX: 11 }, 0.125 ], + [ { translateX: -11 }, 0.125 ], + [ { translateX: 11 }, 0.125 ], + [ { translateX: -11 }, 0.125 ], + [ { translateX: 0 }, 0.125 ] + ] + }, + /* Animate.css */ + "callout.flash": { + defaultDuration: 1100, + calls: [ + [ { opacity: [ 0, "easeInOutQuad", 1 ] }, 0.25 ], + [ { opacity: [ 1, "easeInOutQuad" ] }, 0.25 ], + [ { opacity: [ 0, "easeInOutQuad" ] }, 0.25 ], + [ { opacity: [ 1, "easeInOutQuad" ] }, 0.25 ] + ] + }, + /* Animate.css */ + "callout.pulse": { + defaultDuration: 825, + calls: [ + [ { scaleX: 1.1, scaleY: 1.1 }, 0.50 ], + [ { scaleX: 1, scaleY: 1 }, 0.50 ] + ] + }, + /* Animate.css */ + "callout.swing": { + defaultDuration: 950, + calls: [ + [ { rotateZ: 15 }, 0.20 ], + [ { rotateZ: -10 }, 0.20 ], + [ { rotateZ: 5 }, 0.20 ], + [ { rotateZ: -5 }, 0.20 ], + [ { rotateZ: 0 }, 0.20 ] + ] + }, + /* Animate.css */ + "callout.tada": { + defaultDuration: 1000, + calls: [ + [ { scaleX: 0.9, scaleY: 0.9, rotateZ: -3 }, 0.10 ], + [ { scaleX: 1.1, scaleY: 1.1, rotateZ: 3 }, 0.10 ], + [ { scaleX: 1.1, scaleY: 1.1, rotateZ: -3 }, 0.10 ], + [ "reverse", 0.125 ], + [ "reverse", 0.125 ], + [ "reverse", 0.125 ], + [ "reverse", 0.125 ], + [ "reverse", 0.125 ], + [ { scaleX: 1, scaleY: 1, rotateZ: 0 }, 0.20 ] + ] + }, + "transition.fadeIn": { + defaultDuration: 500, + calls: [ + [ { opacity: [ 1, 0 ] } ] + ] + }, + "transition.fadeOut": { + defaultDuration: 500, + calls: [ + [ { opacity: [ 0, 1 ] } ] + ] + }, + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.flipXIn": { + defaultDuration: 700, + calls: [ + [ { opacity: [ 1, 0 ], transformPerspective: [ 800, 800 ], rotateY: [ 0, -55 ] } ] + ], + reset: { transformPerspective: 0 } + }, + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.flipXOut": { + defaultDuration: 700, + calls: [ + [ { opacity: [ 0, 1 ], transformPerspective: [ 800, 800 ], rotateY: 55 } ] + ], + reset: { transformPerspective: 0, rotateY: 0 } + }, + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.flipYIn": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 1, 0 ], transformPerspective: [ 800, 800 ], rotateX: [ 0, -45 ] } ] + ], + reset: { transformPerspective: 0 } + }, + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.flipYOut": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 0, 1 ], transformPerspective: [ 800, 800 ], rotateX: 25 } ] + ], + reset: { transformPerspective: 0, rotateX: 0 } + }, + /* Animate.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.flipBounceXIn": { + defaultDuration: 900, + calls: [ + [ { opacity: [ 0.725, 0 ], transformPerspective: [ 400, 400 ], rotateY: [ -10, 90 ] }, 0.50 ], + [ { opacity: 0.80, rotateY: 10 }, 0.25 ], + [ { opacity: 1, rotateY: 0 }, 0.25 ] + ], + reset: { transformPerspective: 0 } + }, + /* Animate.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.flipBounceXOut": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 0.9, 1 ], transformPerspective: [ 400, 400 ], rotateY: -10 }, 0.50 ], + [ { opacity: 0, rotateY: 90 }, 0.50 ] + ], + reset: { transformPerspective: 0, rotateY: 0 } + }, + /* Animate.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.flipBounceYIn": { + defaultDuration: 850, + calls: [ + [ { opacity: [ 0.725, 0 ], transformPerspective: [ 400, 400 ], rotateX: [ -10, 90 ] }, 0.50 ], + [ { opacity: 0.80, rotateX: 10 }, 0.25 ], + [ { opacity: 1, rotateX: 0 }, 0.25 ] + ], + reset: { transformPerspective: 0 } + }, + /* Animate.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.flipBounceYOut": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 0.9, 1 ], transformPerspective: [ 400, 400 ], rotateX: -15 }, 0.50 ], + [ { opacity: 0, rotateX: 90 }, 0.50 ] + ], + reset: { transformPerspective: 0, rotateX: 0 } + }, + /* Magic.css */ + "transition.swoopIn": { + defaultDuration: 850, + calls: [ + [ { opacity: [ 1, 0 ], transformOriginX: [ "100%", "50%" ], transformOriginY: [ "100%", "100%" ], scaleX: [ 1, 0 ], scaleY: [ 1, 0 ], translateX: [ 0, -700 ], translateZ: 0 } ] + ], + reset: { transformOriginX: "50%", transformOriginY: "50%" } + }, + /* Magic.css */ + "transition.swoopOut": { + defaultDuration: 850, + calls: [ + [ { opacity: [ 0, 1 ], transformOriginX: [ "50%", "100%" ], transformOriginY: [ "100%", "100%" ], scaleX: 0, scaleY: 0, translateX: -700, translateZ: 0 } ] + ], + reset: { transformOriginX: "50%", transformOriginY: "50%", scaleX: 1, scaleY: 1, translateX: 0 } + }, + /* Magic.css */ + /* Support: Loses rotation in IE9/Android 2.3. (Fades and scales only.) */ + "transition.whirlIn": { + defaultDuration: 900, + calls: [ + [ { opacity: [ 1, 0 ], transformOriginX: [ "50%", "50%" ], transformOriginY: [ "50%", "50%" ], scaleX: [ 1, 0 ], scaleY: [ 1, 0 ], rotateY: [ 0, 160 ] } ] + ] + }, + /* Magic.css */ + /* Support: Loses rotation in IE9/Android 2.3. (Fades and scales only.) */ + "transition.whirlOut": { + defaultDuration: 900, + calls: [ + [ { opacity: [ 0, 1 ], transformOriginX: [ "50%", "50%" ], transformOriginY: [ "50%", "50%" ], scaleX: 0, scaleY: 0, rotateY: 160 } ] + ], + reset: { scaleX: 1, scaleY: 1, rotateY: 0 } + }, + "transition.shrinkIn": { + defaultDuration: 700, + calls: [ + [ { opacity: [ 1, 0 ], transformOriginX: [ "50%", "50%" ], transformOriginY: [ "50%", "50%" ], scaleX: [ 1, 1.5 ], scaleY: [ 1, 1.5 ], translateZ: 0 } ] + ] + }, + "transition.shrinkOut": { + defaultDuration: 650, + calls: [ + [ { opacity: [ 0, 1 ], transformOriginX: [ "50%", "50%" ], transformOriginY: [ "50%", "50%" ], scaleX: 1.3, scaleY: 1.3, translateZ: 0 } ] + ], + reset: { scaleX: 1, scaleY: 1 } + }, + "transition.expandIn": { + defaultDuration: 700, + calls: [ + [ { opacity: [ 1, 0 ], transformOriginX: [ "50%", "50%" ], transformOriginY: [ "50%", "50%" ], scaleX: [ 1, 0.625 ], scaleY: [ 1, 0.625 ], translateZ: 0 } ] + ] + }, + "transition.expandOut": { + defaultDuration: 700, + calls: [ + [ { opacity: [ 0, 1 ], transformOriginX: [ "50%", "50%" ], transformOriginY: [ "50%", "50%" ], scaleX: 0.5, scaleY: 0.5, translateZ: 0 } ] + ], + reset: { scaleX: 1, scaleY: 1 } + }, + /* Animate.css */ + "transition.bounceIn": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 1, 0 ], scaleX: [ 1.05, 0.3 ], scaleY: [ 1.05, 0.3 ] }, 0.40 ], + [ { scaleX: 0.9, scaleY: 0.9, translateZ: 0 }, 0.20 ], + [ { scaleX: 1, scaleY: 1 }, 0.50 ] + ] + }, + /* Animate.css */ + "transition.bounceOut": { + defaultDuration: 800, + calls: [ + [ { scaleX: 0.95, scaleY: 0.95 }, 0.40 ], + [ { scaleX: 1.1, scaleY: 1.1, translateZ: 0 }, 0.40 ], + [ { opacity: [ 0, 1 ], scaleX: 0.3, scaleY: 0.3 }, 0.20 ] + ], + reset: { scaleX: 1, scaleY: 1 } + }, + /* Animate.css */ + "transition.bounceUpIn": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 1, 0 ], translateY: [ -30, 1000 ] }, 0.60, { easing: "easeOutCirc" } ], + [ { translateY: 10 }, 0.20 ], + [ { translateY: 0 }, 0.20 ] + ] + }, + /* Animate.css */ + "transition.bounceUpOut": { + defaultDuration: 1000, + calls: [ + [ { translateY: 20 }, 0.20 ], + [ { opacity: [ 0, "easeInCirc", 1 ], translateY: -1000 }, 0.80 ] + ], + reset: { translateY: 0 } + }, + /* Animate.css */ + "transition.bounceDownIn": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 1, 0 ], translateY: [ 30, -1000 ] }, 0.60, { easing: "easeOutCirc" } ], + [ { translateY: -10 }, 0.20 ], + [ { translateY: 0 }, 0.20 ] + ] + }, + /* Animate.css */ + "transition.bounceDownOut": { + defaultDuration: 1000, + calls: [ + [ { translateY: -20 }, 0.20 ], + [ { opacity: [ 0, "easeInCirc", 1 ], translateY: 1000 }, 0.80 ] + ], + reset: { translateY: 0 } + }, + /* Animate.css */ + "transition.bounceLeftIn": { + defaultDuration: 750, + calls: [ + [ { opacity: [ 1, 0 ], translateX: [ 30, -1250 ] }, 0.60, { easing: "easeOutCirc" } ], + [ { translateX: -10 }, 0.20 ], + [ { translateX: 0 }, 0.20 ] + ] + }, + /* Animate.css */ + "transition.bounceLeftOut": { + defaultDuration: 750, + calls: [ + [ { translateX: 30 }, 0.20 ], + [ { opacity: [ 0, "easeInCirc", 1 ], translateX: -1250 }, 0.80 ] + ], + reset: { translateX: 0 } + }, + /* Animate.css */ + "transition.bounceRightIn": { + defaultDuration: 750, + calls: [ + [ { opacity: [ 1, 0 ], translateX: [ -30, 1250 ] }, 0.60, { easing: "easeOutCirc" } ], + [ { translateX: 10 }, 0.20 ], + [ { translateX: 0 }, 0.20 ] + ] + }, + /* Animate.css */ + "transition.bounceRightOut": { + defaultDuration: 750, + calls: [ + [ { translateX: -30 }, 0.20 ], + [ { opacity: [ 0, "easeInCirc", 1 ], translateX: 1250 }, 0.80 ] + ], + reset: { translateX: 0 } + }, + "transition.slideUpIn": { + defaultDuration: 900, + calls: [ + [ { opacity: [ 1, 0 ], translateY: [ 0, 20 ], translateZ: 0 } ] + ] + }, + "transition.slideUpOut": { + defaultDuration: 900, + calls: [ + [ { opacity: [ 0, 1 ], translateY: -20, translateZ: 0 } ] + ], + reset: { translateY: 0 } + }, + "transition.slideDownIn": { + defaultDuration: 900, + calls: [ + [ { opacity: [ 1, 0 ], translateY: [ 0, -20 ], translateZ: 0 } ] + ] + }, + "transition.slideDownOut": { + defaultDuration: 900, + calls: [ + [ { opacity: [ 0, 1 ], translateY: 20, translateZ: 0 } ] + ], + reset: { translateY: 0 } + }, + "transition.slideLeftIn": { + defaultDuration: 1000, + calls: [ + [ { opacity: [ 1, 0 ], translateX: [ 0, -20 ], translateZ: 0 } ] + ] + }, + "transition.slideLeftOut": { + defaultDuration: 1050, + calls: [ + [ { opacity: [ 0, 1 ], translateX: -20, translateZ: 0 } ] + ], + reset: { translateX: 0 } + }, + "transition.slideRightIn": { + defaultDuration: 1000, + calls: [ + [ { opacity: [ 1, 0 ], translateX: [ 0, 20 ], translateZ: 0 } ] + ] + }, + "transition.slideRightOut": { + defaultDuration: 1050, + calls: [ + [ { opacity: [ 0, 1 ], translateX: 20, translateZ: 0 } ] + ], + reset: { translateX: 0 } + }, + "transition.slideUpBigIn": { + defaultDuration: 850, + calls: [ + [ { opacity: [ 1, 0 ], translateY: [ 0, 75 ], translateZ: 0 } ] + ] + }, + "transition.slideUpBigOut": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 0, 1 ], translateY: -75, translateZ: 0 } ] + ], + reset: { translateY: 0 } + }, + "transition.slideDownBigIn": { + defaultDuration: 850, + calls: [ + [ { opacity: [ 1, 0 ], translateY: [ 0, -75 ], translateZ: 0 } ] + ] + }, + "transition.slideDownBigOut": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 0, 1 ], translateY: 75, translateZ: 0 } ] + ], + reset: { translateY: 0 } + }, + "transition.slideLeftBigIn": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 1, 0 ], translateX: [ 0, -75 ], translateZ: 0 } ] + ] + }, + "transition.slideLeftBigOut": { + defaultDuration: 750, + calls: [ + [ { opacity: [ 0, 1 ], translateX: -75, translateZ: 0 } ] + ], + reset: { translateX: 0 } + }, + "transition.slideRightBigIn": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 1, 0 ], translateX: [ 0, 75 ], translateZ: 0 } ] + ] + }, + "transition.slideRightBigOut": { + defaultDuration: 750, + calls: [ + [ { opacity: [ 0, 1 ], translateX: 75, translateZ: 0 } ] + ], + reset: { translateX: 0 } + }, + /* Magic.css */ + "transition.perspectiveUpIn": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 1, 0 ], transformPerspective: [ 800, 800 ], transformOriginX: [ 0, 0 ], transformOriginY: [ "100%", "100%" ], rotateX: [ 0, -180 ] } ] + ], + reset: { transformPerspective: 0, transformOriginX: "50%", transformOriginY: "50%" } + }, + /* Magic.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.perspectiveUpOut": { + defaultDuration: 850, + calls: [ + [ { opacity: [ 0, 1 ], transformPerspective: [ 800, 800 ], transformOriginX: [ 0, 0 ], transformOriginY: [ "100%", "100%" ], rotateX: -180 } ] + ], + reset: { transformPerspective: 0, transformOriginX: "50%", transformOriginY: "50%", rotateX: 0 } + }, + /* Magic.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.perspectiveDownIn": { + defaultDuration: 800, + calls: [ + [ { opacity: [ 1, 0 ], transformPerspective: [ 800, 800 ], transformOriginX: [ 0, 0 ], transformOriginY: [ 0, 0 ], rotateX: [ 0, 180 ] } ] + ], + reset: { transformPerspective: 0, transformOriginX: "50%", transformOriginY: "50%" } + }, + /* Magic.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.perspectiveDownOut": { + defaultDuration: 850, + calls: [ + [ { opacity: [ 0, 1 ], transformPerspective: [ 800, 800 ], transformOriginX: [ 0, 0 ], transformOriginY: [ 0, 0 ], rotateX: 180 } ] + ], + reset: { transformPerspective: 0, transformOriginX: "50%", transformOriginY: "50%", rotateX: 0 } + }, + /* Magic.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.perspectiveLeftIn": { + defaultDuration: 950, + calls: [ + [ { opacity: [ 1, 0 ], transformPerspective: [ 2000, 2000 ], transformOriginX: [ 0, 0 ], transformOriginY: [ 0, 0 ], rotateY: [ 0, -180 ] } ] + ], + reset: { transformPerspective: 0, transformOriginX: "50%", transformOriginY: "50%" } + }, + /* Magic.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.perspectiveLeftOut": { + defaultDuration: 950, + calls: [ + [ { opacity: [ 0, 1 ], transformPerspective: [ 2000, 2000 ], transformOriginX: [ 0, 0 ], transformOriginY: [ 0, 0 ], rotateY: -180 } ] + ], + reset: { transformPerspective: 0, transformOriginX: "50%", transformOriginY: "50%", rotateY: 0 } + }, + /* Magic.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.perspectiveRightIn": { + defaultDuration: 950, + calls: [ + [ { opacity: [ 1, 0 ], transformPerspective: [ 2000, 2000 ], transformOriginX: [ "100%", "100%" ], transformOriginY: [ 0, 0 ], rotateY: [ 0, 180 ] } ] + ], + reset: { transformPerspective: 0, transformOriginX: "50%", transformOriginY: "50%" } + }, + /* Magic.css */ + /* Support: Loses rotation in IE9/Android 2.3 (fades only). */ + "transition.perspectiveRightOut": { + defaultDuration: 950, + calls: [ + [ { opacity: [ 0, 1 ], transformPerspective: [ 2000, 2000 ], transformOriginX: [ "100%", "100%" ], transformOriginY: [ 0, 0 ], rotateY: 180 } ] + ], + reset: { transformPerspective: 0, transformOriginX: "50%", transformOriginY: "50%", rotateY: 0 } + } + }; + + /* Register the packaged effects. */ + for (var effectName in global.Velocity.RegisterUI.packagedEffects) { + global.Velocity.RegisterUI(effectName, global.Velocity.RegisterUI.packagedEffects[effectName]); + } +}((window.jQuery || window.Zepto || window), window, document); +})); \ No newline at end of file diff --git a/app/assets/javascripts/app/views/ticket_zoom/edit.jst.eco b/app/assets/javascripts/app/views/ticket_zoom/edit.jst.eco index cc8148bf5..0f9bdbd1f 100644 --- a/app/assets/javascripts/app/views/ticket_zoom/edit.jst.eco +++ b/app/assets/javascripts/app/views/ticket_zoom/edit.jst.eco @@ -1,79 +1,75 @@
-
+
-
-
-
-
-
-
-
-
- -
-
- -
-
- -
-
-
-
+
+
+
+
+
+
+
+ +
+
+ +
+
+ +
+
+
-
-
-
-
-
3
-
-
-
-
- <%- @T('Recipients') %> -
<%- @T('type') %>
-
-
-
-
Hans Peter Baxxter
-
-
To
-
Cc
-
-
-
-
-
Julia Maier
-
-
To
-
Cc
-
-
-
-
-
Remo Batlogg
-
-
To
-
Cc
-
-
-
- - -
-
+
+
+
+
+
3
-
-
-
"> -
+
+
+
+ <%- @T('Recipients') %> +
<%- @T('type') %>
-
"> -
+
+
+
Hans Peter Baxxter
+
+
To
+
Cc
+
+
+
+
Julia Maier
+
+
To
+
Cc
+
+
+
+
+
Remo Batlogg
+
+
To
+
Cc
+
+
+
+ + +
+
+
+
+
"> +
+
+
"> +
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index c56536fc7..028975953 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -8,7 +8,9 @@ //= require ./app/lib/core/jquery-1.11.0.js //= require ./app/lib/core/jquery-ui-1.8.23.custom.min.js //= require ./app/lib/core/underscore-1.6.0.js -//= require ./app/lib/core/jquery.velocity.min.js + +//= require ./app/lib/animations/jquery.velocity.min.js +//= require ./app/lib/animations/velocity.ui.js //not_used= require_tree ./app/lib/spine //= require ./app/lib/spine/spine.coffee diff --git a/app/assets/stylesheets/zzz.css.erb b/app/assets/stylesheets/zzz.css.erb index f0aaa9871..5af8d4624 100644 --- a/app/assets/stylesheets/zzz.css.erb +++ b/app/assets/stylesheets/zzz.css.erb @@ -1460,21 +1460,21 @@ ol.tabs li { } .public.visibility.icon { - width: 14px; - height: 19px; + width: 11px; + height: 15px; background-position: 0 -356px; } .internal.visibility.icon { - width: 14px; - height: 19px; - background-position: -14px -356px; + width: 11px; + height: 15px; + background-position: -11px -356px; } .recipients.icon { - width: 17px; - height: 17px; - background-position: -28px -358px; + width: 15px; + height: 12px; + background-position: -22px -359px; } @@ -2798,12 +2798,16 @@ footer { margin-bottom: 3px; } - .ticket-edit .edit-controls { - display: none; + .ticket-edit .js-edit-control { + width: 38px; + height: 36px; + position: absolute; + top: 0; + transform: scale(0); } - .ticket-edit.mode--edit .edit-controls { - display: block; + .ticket-edit .js-edit-control:not(:last-child) { + border-bottom: 1px solid #e6e6e6; } .ticket-edit .pop-selectable .icon { @@ -2820,32 +2824,31 @@ footer { float: right; } - .ticket-edit hr { - border-color: #e6e6e6; + .visibility-toggle > * { + height: 36px; width: 38px; - margin: 0; + position: absolute; } - .visibility-toggle { - height: 38px; - width: 38px; + .visibility-toggle .icon { + display: block; } - .visibility-toggle, + .visibility-toggle .icon, .recipient-picker { opacity: 0.2; } .ticket-edit.is-public .internal-visibility { - display: none; + visibility: hidden; } - .ticket-edit.is-internal .visibility-toggle { + .ticket-edit.is-internal .visibility-toggle .icon { opacity: 1; } .ticket-edit.is-internal .public-visibility { - display: none; + visibility: hidden; } .ticket-edit .recipient-picker { @@ -2859,12 +2862,12 @@ footer { } .recipient-picker .icon { - margin-top: -3px; + margin-top: -2px; } .recipient-count { - margin-top: 5px; margin-left: 3px; + margin-top: 1px; line-height: 1; } @@ -2979,12 +2982,8 @@ footer { outline: none; } - .ticket-edit.mode--edit textarea { - height: 155px; - } - .ticket-edit.mode--edit .bubble-placeholder { - display: none; + opacity: 0; } .ticket-edit .bubble-arrow:after {