From 5239c83e710d4995125cd751727ff0cb0ad47743 Mon Sep 17 00:00:00 2001 From: Felix Niklas Date: Mon, 7 Jan 2019 17:06:10 +0100 Subject: [PATCH] Admin Chat Preview: fix for widescreen & add animation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out that the chat preview was broken on big screens. The website screenshot didn’t span the whole width and the chat was getting cut off. Fixes: - preserve 16:10 browser aspect ratio - rename zoom to 1:1 - hide 1:1 mode on big screens that don’t need it - scale the website screenshot to the full width - scale the website screenshot in 1:1 mode with the chat - make color picker work with changes - use dynamic height in the form preview --- .../app/controllers/_channel/chat.coffee | 60 +++++------- .../app/views/channel/chat.jst.eco | 98 ++++++++++--------- .../app/views/channel/form.jst.eco | 14 +-- app/assets/stylesheets/zammad.scss | 70 +++++++++++-- 4 files changed, 143 insertions(+), 99 deletions(-) diff --git a/app/assets/javascripts/app/controllers/_channel/chat.coffee b/app/assets/javascripts/app/controllers/_channel/chat.coffee index fb1def070..8bd48d2fd 100644 --- a/app/assets/javascripts/app/controllers/_channel/chat.coffee +++ b/app/assets/javascripts/app/controllers/_channel/chat.coffee @@ -5,7 +5,7 @@ class App.ChannelChat extends App.ControllerSubContent 'change .js-params': 'updateParams' 'input .js-params': 'updateParams' 'submit .js-demo-head': 'onUrlSubmit' - 'click .js-selectBrowserWidth': 'selectBrowserWidth' + 'click .js-selectBrowserSize': 'selectBrowserSize' 'click .js-swatch': 'usePaletteColor' 'click .js-toggle-chat': 'toggleChat' 'change .js-chatSetting input': 'toggleChatSetting' @@ -104,8 +104,7 @@ class App.ChannelChat extends App.ControllerSubContent ] isOpen: true - browserWidth: 1280 - browserWidthMax: 1280 + browserSize: 'desktop' previewUrl: '' previewScale: 1 @@ -167,45 +166,33 @@ class App.ChannelChat extends App.ControllerSubContent $(window).off 'resize.chat-designer' @website.off('click.eyedropper') - selectBrowserWidth: (event) => - tab = $(event.target).closest('[data-value]') + selectBrowserSize: (event) => + tab = $(event.target).closest('[data-size]') # select tab tab.addClass('is-selected').siblings().removeClass('is-selected') - @browserWidth = tab.attr('data-value') + @browserSize = tab.attr('data-size') @updatePreview() updatePreview: (animate = true) => - width = parseInt @browserWidth, 10 - # reset zoom @chat .removeClass('is-fullscreen') .toggleClass('no-transition', !animate) .css 'transform', "translateY(#{ @getChatOffset() }px)" - @browser.css('width', '') - @website.css - transform: '' - width: '' - height: '' + @browser.attr('data-size', @browserSize) @previewScale = 1 - return if @browserWidth is 'fit' - - if width < @el.width() && width == 375 - @chat.addClass('is-fullscreen').css 'transform', "translateY(#{ @getChatOffset(true) }px)" - @browser.css('width', "#{ width }px") - else - if @el.width() > width && width == @browserWidthMax - @previewScale = 1 - else - @previewScale = @el.width()/width - - @chat.css 'transform', "translateY(#{ @getChatOffset() * @previewScale }px) scale(#{ @previewScale })" - @website.css - transform: "scale(#{ @previewScale })" - width: @el.width() / @previewScale - height: @browserBody.height() / @previewScale + switch @browserSize + when 'mobile' + @chat.addClass('is-fullscreen').css 'transform', "translateY(#{ @getChatOffset(true) }px)" + when '1:1' + @previewScale = Math.max(1, 1280/@el.width()) + @website.css 'transform', "scale(#{ @previewScale })" + when 'desktop' + scale = Math.min(1, @el.width()/1280) # don't use it for the previewScale (used for the color picker) + @website.css 'transform', '' + @chat.css 'transform', "translateY(#{ @getChatOffset() * scale }px) scale(#{ scale })" getChatOffset: (fullscreen) -> return 0 if @isOpen @@ -296,8 +283,11 @@ class App.ChannelChat extends App.ControllerSubContent @eyedropper.addClass('is-active') onColorPicked: (event) => - x = event.pageX - @website.offset().left - y = event.pageY - @website.offset().top + website_x = @website.position().left + website_y = @website.position().top + + relative_x = event.pageX - @browserBody.offset().left + relative_y = event.pageY - @browserBody.offset().top image = new Image() image.src = @_screenshotSource @@ -305,11 +295,11 @@ class App.ChannelChat extends App.ControllerSubContent canvas = document.createElement('canvas') ctx = canvas.getContext('2d') - canvas.width = image.width - canvas.height = image.height + canvas.width = @browserBody.width() + canvas.height = @browserBody.height() - ctx.drawImage(image, 0, 0, @previewScale * canvas.width, @previewScale * canvas.height) - pixels = ctx.getImageData(x, y, 1, 1).data + ctx.drawImage(image, website_x, website_y, @website.width() * @previewScale, @website.width() * @previewScale) + pixels = ctx.getImageData(relative_x, relative_y, 1, 1).data @colorField.val("rgb(#{pixels.slice(0,3).join(',')})").trigger('change') diff --git a/app/assets/javascripts/app/views/channel/chat.jst.eco b/app/assets/javascripts/app/views/channel/chat.jst.eco index 310183074..a70f86726 100644 --- a/app/assets/javascripts/app/views/channel/chat.jst.eco +++ b/app/assets/javascripts/app/views/channel/chat.jst.eco @@ -19,62 +19,64 @@
-
-
iPhone 6
-
1:1
-
MacBook
+
+
Mobile
+
1:1
+
Desktop
-
-
-
- -
-
- -
-
-
- -
- -
-
-
-
- <%- @T('Online') %> - - - - +
+
+
+
+ +
+
+ +
+
+
+ +
+ +
+
+
+
+ <%- @T('Online') %> + + + + +
+
+ + + <%- @T('John Smith') %> + +
+
+ + Chat with us! +
-
- - - <%- @T('John Smith') %> - -
-
- - Chat with us! +
+
<%- @T('today') %> 14:45
+
+ <%- @T('Hello! I need help with your product.') %> +
+
+ <%- @T('Hi! Which one of our products?') %> +
+
+ + +
-
-
<%- @T('today') %> 14:45
-
- <%- @T('Hello! I need help with your product.') %> -
-
- <%- @T('Hi! Which one of our products?') %> -
-
-
- - -
diff --git a/app/assets/javascripts/app/views/channel/form.jst.eco b/app/assets/javascripts/app/views/channel/form.jst.eco index 40101bd29..392f65c00 100644 --- a/app/assets/javascripts/app/views/channel/form.jst.eco +++ b/app/assets/javascripts/app/views/channel/form.jst.eco @@ -117,12 +117,14 @@ -
-
-
-
<%- @T('Feedback') %>
-
- +
+
+
+
+
<%- @T('Feedback') %>
+
+ +
diff --git a/app/assets/stylesheets/zammad.scss b/app/assets/stylesheets/zammad.scss index 24f6b52be..8f149ebc7 100644 --- a/app/assets/stylesheets/zammad.scss +++ b/app/assets/stylesheets/zammad.scss @@ -10040,32 +10040,82 @@ output { .browser { margin: 0 0 20px; - border: 1px solid hsl(0,0%,90%); - border-radius: 5px; position: relative; - transition: 500ms; - width: 100%; + + &[data-size] { + padding-bottom: 65%; // 16:10 aspect ratio; + + .browser-ratio { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + transition: 500ms; + display: flex; + flex-direction: column; + } + + .browser-body { + padding: 0; + } + } + + &[data-size="mobile"] .browser-ratio { + width: 375px; + } + + &-ratio { + border: 1px solid hsl(0,0%,90%); + border-radius: 5px; + } +} + +@media screen and (min-width: #{1280 + $sidebarWidth + $navigationWidth}) { + // hide 1:1 button when it gets inrelevant + [data-size="1:1"] { + display: none; + } + + .browser[data-size="mobile"] .browser-ratio { + width: 500px; + } } .browser-body { + flex: 1; position: relative; overflow: hidden; - height: 450px; - width: 100%; + padding: 20px; + + &-inner { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + } .browser-website { position: relative; height: 100%; - transform-origin: left top; + transform-origin: right bottom; + transition: 500ms; overflow: hidden; &.is-picking { cursor: image_url("/assets/images/eyedropper.gif") 0 15, auto; } - } - img { - vertical-align: bottom; + &-background { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + object-fit: cover; + object-position: left top; + } } }