From a71776ba1b67f151b4a27b69379ccb1de626a118 Mon Sep 17 00:00:00 2001 From: Martin Edenhofer Date: Fri, 2 Oct 2015 15:30:18 +0200 Subject: [PATCH] Improved performance of tab highlighting. --- .../app/controllers/ticket_zoom.coffee | 68 +++++++++---------- .../ticket_zoom/article_new.coffee | 2 +- .../ticket_zoom/article_view.coffee | 23 ++++--- .../controllers/ticket_zoom/higlighter.coffee | 38 ++++++++--- 4 files changed, 78 insertions(+), 53 deletions(-) diff --git a/app/assets/javascripts/app/controllers/ticket_zoom.coffee b/app/assets/javascripts/app/controllers/ticket_zoom.coffee index 09be514a9..1235459ff 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom.coffee @@ -14,7 +14,7 @@ class App.TicketZoom extends App.Controller # check authentication if !@authenticate() - App.TaskManager.remove( @task_key ) + App.TaskManager.remove(@task_key) return @navupdate '#' @@ -32,14 +32,14 @@ class App.TicketZoom extends App.Controller @overview_id = false @key = 'ticket::' + @ticket_id - cache = App.Store.get( @key ) + cache = App.Store.get(@key) if cache @load(cache) update = => - @fetch( @ticket_id, false ) + @fetch(@ticket_id, false) # check if ticket has beed updated every 30 min - @interval( update, 1800000, 'pull_check' ) + @interval(update, 1800000, 'pull_check') # fetch new data if triggered @bind( @@ -47,14 +47,14 @@ class App.TicketZoom extends App.Controller (data) => # check if current ticket has changed - if data.id.toString() is @ticket_id.toString() + return if data.id.toString() isnt @ticket_id.toString() - # check if we already have the request queued - #@log 'notice', 'TRY', @ticket_id, new Date(data.updated_at), new Date(@ticketUpdatedAtLastCall) - update = => - @fetch( @ticket_id, false ) - if !@ticketUpdatedAtLastCall || ( new Date(data.updated_at).toString() isnt new Date(@ticketUpdatedAtLastCall).toString() ) - @delay( update, 1200, 'ticket-zoom-' + @ticket_id ) + # check if we already have the request queued + #@log 'notice', 'TRY', @ticket_id, new Date(data.updated_at), new Date(@ticketUpdatedAtLastCall) + update = => + @fetch( @ticket_id, false ) + if !@ticketUpdatedAtLastCall || ( new Date(data.updated_at).toString() isnt new Date(@ticketUpdatedAtLastCall).toString() ) + @delay( update, 1200, 'ticket-zoom-' + @ticket_id ) ) # rerender view, e. g. on langauge change @@ -85,7 +85,7 @@ class App.TicketZoom extends App.Controller # set icon and title based on ticket if @ticket - @ticket = App.Ticket.fullLocal( @ticket.id ) + @ticket = App.Ticket.fullLocal(@ticket.id) meta.head = @ticket.title meta.title = '#' + @ticket.number + ' - ' + @ticket.title meta.class = "task-state-#{ @ticket.getState() }" @@ -102,7 +102,7 @@ class App.TicketZoom extends App.Controller @navupdate '#' # set all notifications to seen - App.OnlineNotification.seen( 'Ticket', @ticket_id ) + App.OnlineNotification.seen('Ticket', @ticket_id) # if controller is executed twice, go to latest article if @activeState @@ -116,7 +116,7 @@ class App.TicketZoom extends App.Controller if !@shown # trigger shown to article - App.Event.trigger('ui::ticket::shown', { ticket_id: @ticket_id } ) + App.Event.trigger('ui::ticket::shown', { ticket_id: @ticket_id }) # observe content header position @positionPageHeaderStart() @@ -134,8 +134,8 @@ class App.TicketZoom extends App.Controller return false if !@ticket formCurrent = @formParam( @el.find('.edit') ) ticket = App.Ticket.find(@ticket_id).attributes() - modelDiff = App.Utils.formDiff( formCurrent, ticket ) - return false if !modelDiff || _.isEmpty( modelDiff ) + modelDiff = App.Utils.formDiff(formCurrent, ticket) + return false if !modelDiff || _.isEmpty(modelDiff) return true release: => @@ -143,14 +143,13 @@ class App.TicketZoom extends App.Controller @positionPageHeaderStop() fetch: (ticket_id, force) -> - return if !@Session.get() # get data @ajax( - id: 'ticket_zoom_' + ticket_id + id: "ticket_zoom_#{ticket_id}" type: 'GET' - url: @apiPath + '/ticket_full/' + ticket_id + url: "#{@apiPath}/ticket_full/#{ticket_id}" processData: true success: (data, status, xhr) => @@ -163,21 +162,22 @@ class App.TicketZoom extends App.Controller # notify if ticket changed not by my self if newTicketRaw.updated_by_id isnt @Session.get('id') - App.TaskManager.notify( @task_key ) + App.TaskManager.notify(@task_key) # remember current data @ticketUpdatedAtLastCall = newTicketRaw.updated_at @load(data, force) - App.Store.write( @key, data ) + App.Store.write(@key, data) if !@doNotLog @doNotLog = 1 - @recentView( 'Ticket', ticket_id ) + @recentView('Ticket', ticket_id) # scroll to end of page if force @scrollToBottom() + @positionPageHeaderUpdate() error: (xhr) => statusText = xhr.statusText @@ -235,10 +235,10 @@ class App.TicketZoom extends App.Controller @form_meta = data.form_meta # load assets - App.Collection.loadAssets( data.assets ) + App.Collection.loadAssets(data.assets) # get data - @ticket = App.Ticket.fullLocal( @ticket_id ) + @ticket = App.Ticket.fullLocal(@ticket_id) @ticket.article = undefined # render page @@ -334,9 +334,9 @@ class App.TicketZoom extends App.Controller # rerender whole sidebar if customer or organization has changed if @ticketLastAttributes.customer_id isnt @ticket.customer_id || @ticketLastAttributes.organization_id isnt @ticket.organization_id new App.WidgetAvatar( - el: @$('.ticketZoom-header .js-avatar') - user_id: @ticket.customer_id - size: 50 + el: @$('.ticketZoom-header .js-avatar') + user_id: @ticket.customer_id + size: 50 ) new App.TicketZoomSidebar( el: @el.find('.tabsSidebar') @@ -374,7 +374,7 @@ class App.TicketZoom extends App.Controller @positionPageHeaderStart() # trigger shown if init shown render - App.Event.trigger('ui::ticket::shown', { ticket_id: @ticket_id } ) + App.Event.trigger('ui::ticket::shown', { ticket_id: @ticket_id }) scrollToBottom: => @main.scrollTop( @main.prop('scrollHeight') ) @@ -593,9 +593,9 @@ class App.TicketZoom extends App.Controller # reset form after save @reset() - App.TaskManager.mute( @task_key ) + App.TaskManager.mute(@task_key) - @fetch( ticket.id, true ) + @fetch(ticket.id, true) ) bookmark: (e) -> @@ -609,7 +609,7 @@ class App.TicketZoom extends App.Controller @taskReset() # reset edit ticket / reset new article - App.Event.trigger('ui::ticket::taskReset', { ticket_id: @ticket.id } ) + App.Event.trigger('ui::ticket::taskReset', { ticket_id: @ticket.id }) # hide reset button @$('.js-reset').addClass('hide') @@ -630,18 +630,18 @@ class App.TicketZoom extends App.Controller taskUpdate: (area, data) => @localTaskData[area] = data - App.TaskManager.update( @task_key, { 'state': @localTaskData }) + App.TaskManager.update(@task_key, { 'state': @localTaskData }) taskUpdateAll: (data) => @localTaskData = data - App.TaskManager.update( @task_key, { 'state': @localTaskData }) + App.TaskManager.update(@task_key, { 'state': @localTaskData }) # reset task state taskReset: => @localTaskData = ticket: {} article: {} - App.TaskManager.update( @task_key, { 'state': @localTaskData }) + App.TaskManager.update(@task_key, { 'state': @localTaskData }) class TicketZoomRouter extends App.ControllerPermanent constructor: (params) -> diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/article_new.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/article_new.coffee index 180ac3b58..612b05927 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom/article_new.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom/article_new.coffee @@ -162,7 +162,7 @@ class App.TicketZoomArticleNew extends App.Controller @$('[data-name="body"]').ce({ mode: 'richtext' multiline: true - maxlength: 5000 + maxlength: 40000 }) html5Upload.initialize( diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/article_view.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/article_view.coffee index 2825457da..c7bc4e4e2 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom/article_view.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom/article_view.coffee @@ -48,12 +48,8 @@ class ArticleViewItem extends App.Controller # set highlighter @setHighlighter() - if !@shown - - # set see more - @setSeeMore() - - @shown = true + # set see more + @setSeeMore() ) # subscribe to changes @@ -64,7 +60,11 @@ class ArticleViewItem extends App.Controller setHighlighter: => return if !@el.is(':visible') - @highligher.loadHighlights(@ticket_article_id) + # use delay do no ui blocking + #@highligher.loadHighlights(@ticket_article_id) + d = => + @highligher.loadHighlights(@ticket_article_id) + @delay(d, 800) hasChanged: (article) => @@ -127,6 +127,7 @@ class ArticleViewItem extends App.Controller ) # set see more + @shown = false @setSeeMore() # set highlighter @@ -134,6 +135,10 @@ class ArticleViewItem extends App.Controller # set see more options setSeeMore: => + return if !@el.is(':visible') + return if @shown + @shown = true + maxHeight = 560 bubbleContent = @textBubbleContent bubbleOvervlowContainer = @textBubbleOverflowContainer @@ -183,10 +188,10 @@ class ArticleViewItem extends App.Controller # allow double click select # by adding a delay to the toggle - if @lastClick and +new Date - @lastClick < 150 + if @lastClick and +new Date - @lastClick < 100 clearTimeout(@toggleMetaTimeout) else - @toggleMetaTimeout = setTimeout(@toggle_meta, 150, e) + @toggleMetaTimeout = setTimeout(@toggle_meta, 100, e) @lastClick = +new Date toggle_meta: (e) => diff --git a/app/assets/javascripts/app/controllers/ticket_zoom/higlighter.coffee b/app/assets/javascripts/app/controllers/ticket_zoom/higlighter.coffee index 2bab9bf95..5800eddb5 100644 --- a/app/assets/javascripts/app/controllers/ticket_zoom/higlighter.coffee +++ b/app/assets/javascripts/app/controllers/ticket_zoom/higlighter.coffee @@ -38,6 +38,8 @@ class App.TicketZoomHighlighter extends App.Controller return if !@isRole('Agent') + @currentHighlights = {} + rangy.init() @highlighter = rangy.createHighlighter(document, 'TextRange') @@ -86,6 +88,8 @@ class App.TicketZoomHighlighter extends App.Controller articles = @el.closest('.content').find('.textBubble-content') articles.off('mouseup', @onMouseUp) articles.on('mouseup', @onMouseUp) #future: touchend + articles.off('mousedown', @onMouseDown) + articles.on('mousedown', @onMouseDown) #future: touchend # for testing purposes the highlights get stored in localStorage loadHighlights: (ticket_article_id) -> @@ -95,7 +99,9 @@ class App.TicketZoomHighlighter extends App.Controller return if !article.preferences.highlight return if _.isEmpty(article.preferences.highlight) return if article.preferences.highlight is 'type:TextRange' - @highlighter.deserialize(article.preferences['highlight']) + return if @currentHighlights[ticket_article_id] is article.preferences.highlight + @currentHighlights[ticket_article_id] = article.preferences.highlight + @highlighter.deserialize(article.preferences.highlight) # the serialization creates one string for the entiery ticket # containing the offsets and the highlight classes @@ -136,6 +142,8 @@ class App.TicketZoomHighlighter extends App.Controller articles.attr('data-highlightcolor', @colors[@activeColorIndex].name) toggleHighlight: (e) => + @mouseDownInside = false + @mouseUpInside = false if @isActive $(e.currentTarget).removeClass('active') @@ -168,19 +176,31 @@ class App.TicketZoomHighlighter extends App.Controller # check if selection exists - highlight it or remove highlight @toggleHighlightAtSelection(@content, @article_id) - onMouseUp: (e) => - @updateSelectedArticle(e) + onMouseDown: (e) => + if @updateSelectedArticle(e) + @mouseDownInside = true + else + @mouseDownInside = false - console.log('onMouseUp', @isActive, @content, @article_id) - if @isActive - @toggleHighlightAtSelection(@content, @article_id) # @articles.selector + onMouseUp: (e) => + if @updateSelectedArticle(e) + @mouseUpInside = true + else + @mouseUpInside = false + + return if !@mouseDownInside + return if !@mouseUpInside + return if !@isActive + @toggleHighlightAtSelection(@content, @article_id) updateSelectedArticle: (e) => @content = $(e.currentTarget).closest('.textBubble-content') @article_id = @content.data('id') - if !@article_id - @content = $(e.currentTarget) - @article_id = @content.data('id') + return true if @article_id + @content = $(e.currentTarget) + @article_id = @content.data('id') + return true if @article_id + false # # toggle Highlight