diff --git a/app/assets/javascripts/app/controllers/_channel/chat.coffee b/app/assets/javascripts/app/controllers/_channel/chat.coffee index 15c5d13c0..357cf6c55 100644 --- a/app/assets/javascripts/app/controllers/_channel/chat.coffee +++ b/app/assets/javascripts/app/controllers/_channel/chat.coffee @@ -3,16 +3,15 @@ class App.ChannelChat extends App.Controller 'change .js-params': 'updateParams' 'input .js-params': 'updateParams' 'submit .js-demo-head': 'onUrlSubmit' - 'blur .js-testurl-input': 'changeDemoWebsite' 'click .js-selectBrowserWidth': 'selectBrowserWidth' 'click .js-swatch': 'usePaletteColor' 'click .js-toggle-chat': 'toggleChat' 'click .js-chatSetting': 'toggleChatSetting' + 'click .js-eyedropper': 'pickColor' elements: '.js-browser': 'browser' '.js-browserBody': 'browserBody' - '.js-iframe': 'iframe' '.js-screenshot': 'screenshot' '.js-website': 'website' '.js-chat': 'chat' @@ -25,6 +24,7 @@ class App.ChannelChat extends App.Controller '.js-palette': 'palette' '.js-color': 'colorField' '.js-chatSetting input': 'chatSetting' + '.js-eyedropper': 'eyedropper' apiOptions: [ { @@ -105,6 +105,7 @@ class App.ChannelChat extends App.Controller isOpen: true browserWidth: 1280 previewUrl: '' + previewScale: 1 constructor: -> super @@ -155,6 +156,7 @@ class App.ChannelChat extends App.Controller release: -> $(window).off 'resize.chat-designer' + @website.off('click.eyedropper') selectBrowserWidth: (event) => tab = $(event.target).closest('[data-value]') @@ -177,6 +179,7 @@ class App.ChannelChat extends App.Controller transform: '' width: '' height: '' + @previewScale = 1 return if @browserWidth is 'fit' @@ -184,12 +187,12 @@ class App.ChannelChat extends App.Controller @chat.addClass('is-fullscreen').css 'transform', "translateY(#{ @getChatOffset(true) }px)" @browser.css('width', "#{ width }px") else - percentage = @el.width()/width - @chat.css 'transform', "translateY(#{ @getChatOffset() * percentage }px) scale(#{ percentage })" + @previewScale = @el.width()/width + @chat.css 'transform', "translateY(#{ @getChatOffset() * @previewScale }px) scale(#{ @previewScale })" @website.css - transform: "scale(#{ percentage })" - width: @el.width() / percentage - height: @browserBody.height() / percentage + transform: "scale(#{ @previewScale })" + width: @el.width() / @previewScale + height: @browserBody.height() / @previewScale getChatOffset: (fullscreen) -> return 0 if @isOpen @@ -217,8 +220,6 @@ class App.ChannelChat extends App.Controller @palette.empty() @screenshot.attr('src', '') - @website.attr('data-mode', 'iframe') - @iframe.attr('src', @url) $.ajax url: 'https://images.zammad.com/api/v1/webpage/combined' @@ -229,12 +230,9 @@ class App.ChannelChat extends App.Controller dataType: 'json' renderDemoWebsite: (data) => - imageSource = data['data_url'] + @_screenshotSource = data['data_url'] - if imageSource - @screenshot.attr 'src', imageSource - @iframe.attr('src', '') - @website.attr('data-mode', 'screenshot') + @screenshot.attr 'src', @_screenshotSource @renderPalette data['palette'] @@ -268,6 +266,40 @@ class App.ChannelChat extends App.Controller @colorField.val code @updateParams() + pickColor: -> + return if !@_screenshotSource + + if @_pickingColor + @_pickingColor = false + @website + .off('click.eyedropper') + .removeClass('is-picking') + @eyedropper.removeClass('is-active') + else + @_pickingColor = true + @website + .on('click.eyedropper', @onColorPicked) + .addClass('is-picking') + @eyedropper.addClass('is-active') + + onColorPicked: (event) => + x = event.pageX - @website.offset().left + y = event.pageY - @website.offset().top + + image = new Image() + image.src = @_screenshotSource + + canvas = document.createElement('canvas') + ctx = canvas.getContext('2d') + + canvas.width = image.width + canvas.height = image.height + + ctx.drawImage(image, 0, 0, @previewScale * canvas.width, @previewScale * canvas.height) + pixels = ctx.getImageData(x, y, 1, 1).data + + @colorField.val("rgb(#{pixels.slice(0,3).join(',')})").trigger('change') + toggleChat: => @chat.toggleClass('is-open') @isOpen = @chat.hasClass('is-open') diff --git a/app/assets/javascripts/app/views/channel/chat.jst.eco b/app/assets/javascripts/app/views/channel/chat.jst.eco index 1327442de..558fa6668 100644 --- a/app/assets/javascripts/app/views/channel/chat.jst.eco +++ b/app/assets/javascripts/app/views/channel/chat.jst.eco @@ -38,7 +38,6 @@
-
@@ -97,8 +96,13 @@
-
- +
+ +
+
+ <%- @Icon('eyedropper') %> +
+
<%- @T('Can be in any CSS color format.') %>
diff --git a/app/assets/javascripts/app/views/layout_ref/inputs.jst.eco b/app/assets/javascripts/app/views/layout_ref/inputs.jst.eco index 1baef73fe..28479211d 100644 --- a/app/assets/javascripts/app/views/layout_ref/inputs.jst.eco +++ b/app/assets/javascripts/app/views/layout_ref/inputs.jst.eco @@ -2,6 +2,21 @@

Inputs

+

Color

+
+
+ +
+
+ +
+
+ <%- @Icon('eyedropper') %> +
+
+
+
+

Time

A time of the day

diff --git a/app/assets/javascripts/app/views/layout_ref/merge_customer.jst.eco b/app/assets/javascripts/app/views/layout_ref/merge_customer.jst.eco index f99a405ce..41c03490d 100644 --- a/app/assets/javascripts/app/views/layout_ref/merge_customer.jst.eco +++ b/app/assets/javascripts/app/views/layout_ref/merge_customer.jst.eco @@ -103,13 +103,13 @@
-
+
nicole.braun@zammad.org
-
+
nicole.mueller@zammad.org
diff --git a/app/assets/javascripts/app/views/layout_ref/primary_email.jst.eco b/app/assets/javascripts/app/views/layout_ref/primary_email.jst.eco index 43b8faed7..8e40c7db8 100644 --- a/app/assets/javascripts/app/views/layout_ref/primary_email.jst.eco +++ b/app/assets/javascripts/app/views/layout_ref/primary_email.jst.eco @@ -38,11 +38,13 @@ +
-
+
-
- - +
+
+ + +
@@ -53,11 +55,13 @@ ×
-
+
-
- - +
+
+ + +
diff --git a/app/assets/stylesheets/svg-dimensions.css b/app/assets/stylesheets/svg-dimensions.css index 7fb77979d..481d629f3 100644 --- a/app/assets/stylesheets/svg-dimensions.css +++ b/app/assets/stylesheets/svg-dimensions.css @@ -17,6 +17,7 @@ .icon-dropdown-list { width: 19px; height: 14px; } .icon-email-button { width: 29px; height: 22px; } .icon-email { width: 17px; height: 17px; } +.icon-eyedropper { width: 17px; height: 17px; } .icon-facebook-button { width: 29px; height: 22px; } .icon-facebook { width: 17px; height: 17px; } .icon-full-logo { width: 175px; height: 50px; } diff --git a/app/assets/stylesheets/zammad.scss b/app/assets/stylesheets/zammad.scss index b0ae7495e..6c3d1c375 100644 --- a/app/assets/stylesheets/zammad.scss +++ b/app/assets/stylesheets/zammad.scss @@ -1506,190 +1506,198 @@ input.time.time--12 { width: 7.5ch; } - .tokenfield.focus { - border-color: hsl(200,71%,59%); - box-shadow: 0 0 0 3px hsl(201,62%,90%); - } +.tokenfield.focus { + border-color: hsl(200,71%,59%); + box-shadow: 0 0 0 3px hsl(201,62%,90%); +} - .richtext.form-control { - padding-bottom: 28px; - } +.richtext.form-control { + padding-bottom: 28px; +} - .richtext.form-control [contenteditable] { - height: auto; - min-height: 82px; - background: none; - } +.richtext.form-control [contenteditable] { + height: auto; + min-height: 82px; + background: none; +} - .richtext.form-control .attachments.attachments--list:not(:empty) { - border-top: 1px solid rgba(0,0,0,.04); - white-space: normal; - margin: 0 -12px -28px; - padding: 25px 20px 21px 72px; - position: relative; - line-height: 1; - } +.richtext.form-control .attachments.attachments--list:not(:empty) { + border-top: 1px solid rgba(0,0,0,.04); + white-space: normal; + margin: 0 -12px -28px; + padding: 25px 20px 21px 72px; + position: relative; + line-height: 1; +} - textarea.form-control { - height: 118px; - } +textarea.form-control { + height: 118px; +} - select.form-control:not([multiple]) { - padding-left: 10px; - padding-right: 34px; - word-wrap: normal; - } +select.form-control:not([multiple]) { + padding-left: 10px; + padding-right: 34px; + word-wrap: normal; +} - .form-control.is-hidden { - display: none; - } +.form-control.is-hidden { + display: none; +} - .form-control[disabled], .form-control.is-disabled { - cursor: not-allowed; - background-color: #fff; - color: #d5d5d5; - opacity: 1; - } +.form-control[disabled], .form-control.is-disabled { + cursor: not-allowed; + background-color: #fff; + color: #d5d5d5; + opacity: 1; +} - .form-control.form-control--borderless { - border: none; - padding: 0; - line-height: inherit; - height: auto; - - &:focus { - box-shadow: none; - } - } - - .form-control + .icon-arrow-down, - .dropdown-arrow { - position: absolute; - right: 12px; - top: 50%; - margin-top: -3px; - fill: black; - opacity: 0.39; - width: 13px; - height: 7px; - @extend .u-unclickable; - } - - /* - - Firefox only hack - ----------------- - - Firefox below version 35 doesn't allow us to - hide the dropdown arrow but we want to replace - it with our own icon. So we have to hide our own - icon in Firefox versions under 35. - - The class is set via Javascript - - */ - - html.ff-lt-35 .form-control + .icon-arrow-down, - html.ff-lt-35 .dropdown-arrow { - display: none; - } - - select::-ms-expand { - display: none; - } - - .has-error .form-control, - .has-error .form-control:focus, - .has-error .form-control.focus { +.form-control.form-control--borderless { + border: none; + padding: 0; + line-height: inherit; + height: auto; + + &:focus { box-shadow: none; - border-color: red !important; + } +} + +.form-control + .icon-arrow-down, +.dropdown-arrow { + position: absolute; + right: 12px; + top: 50%; + margin-top: -3px; + fill: black; + opacity: 0.39; + width: 13px; + height: 7px; + @extend .u-unclickable; +} + +/* + + Firefox only hack + ----------------- + + Firefox below version 35 doesn't allow us to + hide the dropdown arrow but we want to replace + it with our own icon. So we have to hide our own + icon in Firefox versions under 35. + + The class is set via Javascript + +*/ + +html.ff-lt-35 .form-control + .icon-arrow-down, +html.ff-lt-35 .dropdown-arrow { + display: none; +} + +select::-ms-expand { + display: none; +} + +.has-error .form-control, +.has-error .form-control:focus, +.has-error .form-control.focus { + box-shadow: none; + border-color: red !important; +} + +input.has-error { + box-shadow: none; + border-color: red !important; +} + +.help-inline:not(:empty) { + color: red; + padding: 2px; + font-size: 13px; +} + +/* use on input[type=radio] */ +.primary-email-switch { + display: none; + + & + label { + font-size: 11px; + color: #DBDBDB; + cursor: pointer; + margin: 0; } - input.has-error { - box-shadow: none; - border-color: red !important; + &:checked + label { + color: $highlight-color; } +} - .help-inline:not(:empty) { - color: red; - padding: 2px; - font-size: 13px; - } +.primary-email-switch-label { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} - /* use on input[type=radio] */ - .primary-email-switch { - display: none; +.primary-email-switch + label { + align-self: stretch; + padding: 0 5px; + display: flex; + align-items: center; +} - & + label { - font-size: 11px; - color: #DBDBDB; - cursor: pointer; - margin: 0; - } - - &:checked + label { - color: $highlight-color; - } - } - - .primary-email-switch-holder { - position: relative; - display: flex; +.controls--button { + display: flex; + + input, + .form-control { + flex: 1; + border-right: none; + border-top-right-radius: 0; + border-bottom-right-radius: 0; - .primary-email-switch-label { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - } - - .primary-email-switch + label { - align-self: stretch; - padding: 0 5px; - display: flex; - align-items: center; - } - } - - .controls--emailSwitch { - display: flex; - - .form-control { - flex: 1; - border-right: none; - border-top-right-radius: 0; - border-bottom-right-radius: 0; + &:focus + .controls-button { + .controls-button-inner { + border-color: hsl(200,71%,59%); + } - &:focus + .primary-email-switch-holder { - label { - border-color: hsl(200,71%,59%); - } - - /* + /* - fake the form-control outline + fake the form-control outline - */ - &:before { - content: ""; - position: absolute; - left: 0; - top: -3px; - right: -3px; - bottom: -3px; - background: hsl(201,62%,90%); - border-radius: 0 7px 7px 0; - } + */ + &:before { + content: ""; + position: absolute; + left: 0; + top: -3px; + right: -3px; + bottom: -3px; + background: hsl(201,62%,90%); + border-radius: 0 7px 7px 0; } } - - .primary-email-switch-holder label { - padding: 0 9px; - background: white; - position: relative; - border: 1px solid hsl(0, 0%, 90%); - border-radius: 0 3px 3px 0; - } } +} + +.controls-button { + position: relative; + display: flex; + + &.is-active .icon { + fill: $highlight-color; + } +} + +.controls-button-inner { + display: flex; + justify-content: center; + align-items: center; + padding: 0 10px; + background: white; + position: relative; + border: 1px solid hsl(0, 0%, 90%); + border-radius: 0 3px 3px 0; +} .searchfield { position: relative; @@ -7642,24 +7650,11 @@ output { height: 100%; transform-origin: left top; overflow: hidden; - - &[data-mode=screenshot] iframe, - &[data-mode=iframe] img { - display: none; + + &.is-picking { + cursor: image_url("/assets/images/eyedropper.gif") 0 15, auto; } } - - iframe { - position: absolute; - border: none; - left: 0; - top: 0; - width: 100%; - height: 100%; - background: white; - border-radius: 0 0 5px 5px; - pointer-events: none; - } img { vertical-align: bottom; diff --git a/contrib/icon-sprite.sketch b/contrib/icon-sprite.sketch index 5d68abe9b..158fd7916 100644 Binary files a/contrib/icon-sprite.sketch and b/contrib/icon-sprite.sketch differ diff --git a/public/assets/images/eyedropper.gif b/public/assets/images/eyedropper.gif new file mode 100644 index 000000000..b644a53f9 Binary files /dev/null and b/public/assets/images/eyedropper.gif differ diff --git a/public/assets/images/icons.svg b/public/assets/images/icons.svg index e181a3ad4..a1aa7d504 100644 --- a/public/assets/images/icons.svg +++ b/public/assets/images/icons.svg @@ -1 +1 @@ -arrow-downarrow-leftarrow-rightarrow-upchatcheckbox-checkedcheckboxcheckmarkclipboardclockcloudcogcrowndashboarddiagonal-crossdownloaddropdown-listemail-buttonemailfacebook-buttonfacebookgoogle-buttongrouphelpimportantin-processline-left-arrowline-right-arrowlinkedin-buttonlistloadinglock-openlocklogotypelong-arrow-rightmagnifiermarkermessageminus-smallminusmood-badmood-goodmood-okmood-super-badmood-supergoodmutenoteone-ticketorganizationoutbound-callsoverviewspackagepaperclippenpersonphoneplus-smallplusradio-checkedradioreceived-callsreloadreopeningreply-allreplyreportsignoutsmall-dotsplitstatus-modified-outer-circlestatusstopwatchswitchViewtask-stateteamtemplatestoolstotal-ticketstrashtwitter-buttontwitterunmuteuserzoom-inzoom-out \ No newline at end of file +arrow-downarrow-leftarrow-rightarrow-upchatcheckbox-checkedcheckboxcheckmarkclipboardclockcloudcogcrowndashboarddiagonal-crossdownloaddropdown-listemail-buttonemaileyedropperfacebook-buttonfacebookgoogle-buttongrouphelpimportantin-processline-left-arrowline-right-arrowlinkedin-buttonlistloadinglock-openlocklogotypelong-arrow-rightmagnifiermarkermessageminus-smallminusmood-badmood-goodmood-okmood-super-badmood-supergoodmutenoteone-ticketorganizationoutbound-callsoverviewspackagepaperclippenpersonphoneplus-smallplusradio-checkedradioreceived-callsreloadreopeningreply-allreplyreportsignoutsmall-dotsplitstatus-modified-outer-circlestatusstopwatchswitchViewtask-stateteamtemplatestoolstotal-ticketstrashtwitter-buttontwitterunmuteuserzoom-inzoom-out \ No newline at end of file diff --git a/public/assets/images/icons/eyedropper.svg b/public/assets/images/icons/eyedropper.svg new file mode 100644 index 000000000..0a996fdbc --- /dev/null +++ b/public/assets/images/icons/eyedropper.svg @@ -0,0 +1,12 @@ + + + + eyedropper + Created with Sketch. + + + + + + + \ No newline at end of file