diff --git a/app/assets/javascripts/backbone/broadcasters/faye.js.coffee b/app/assets/javascripts/backbone/broadcasters/faye.js.coffee index 4fbe8271..3f16114a 100644 --- a/app/assets/javascripts/backbone/broadcasters/faye.js.coffee +++ b/app/assets/javascripts/backbone/broadcasters/faye.js.coffee @@ -23,16 +23,21 @@ class Kandan.Broadcasters.FayeBroadcaster [entityName, eventName] = data.event.split("#") @processEventsForUser(eventName, data) if entityName == "user" @processEventsForChannel(eventName, data) if entityName == "channel" + @processEventsForAttachments(eventName, data) if entityName == "attachments" + processEventsForAttachments: (eventName, data)-> + Kandan.Helpers.Channels.add_activity(data.entity, Kandan.Helpers.Activities.ACTIVE_STATE) + Kandan.Data.Attachments.runCallbacks("change", data) processEventsForUser: (eventName, data)-> - console.log "event:", eventName - $(document).data('active_users', data.extra.active_users) - Kandan.Data.ActiveUsers.runCallbacks("change", data) - + if eventName.match(/connect/) + $(document).data('active_users', data.extra.active_users) + Kandan.Data.ActiveUsers.runCallbacks("change", data) processEventsForChannel: (eventName, data)-> Kandan.Helpers.Channels.deleteChannelById(data.entity.id) if eventName == "delete" + + # TODO this has to be implemented Kandan.Helpers.Channels.renameChannelById(data.entity.id, data.entity.name) if data.eventName == "update" diff --git a/app/assets/javascripts/backbone/data/attachments.js.coffee b/app/assets/javascripts/backbone/data/attachments.js.coffee index 6f3e9db2..f3c8888d 100644 --- a/app/assets/javascripts/backbone/data/attachments.js.coffee +++ b/app/assets/javascripts/backbone/data/attachments.js.coffee @@ -1,2 +1,21 @@ class Kandan.Data.Attachments - # TODO use this for the file list plugin \ No newline at end of file + @callbacks: { "change": [] } + + @all: (callback)-> + attachments = new Kandan.Collections.Attachments([], { + channel_id: Kandan.Data.Channels.activeChannelId() + }) + attachments.fetch({ success: callback }) + + @registerCallback: (event, callback)-> + @callbacks[event].push(callback) + + @runCallbacks: (event, data)-> + @cache = data.extra.attachments + callback(data) for callback in @callbacks[event] + + + @unregisterCallback: (event, callback)-> + delete @callbacks[@callbacks.indexOf(callback)] + @callbacks.filter (element, index, array)-> + element!=undefined \ No newline at end of file diff --git a/app/assets/javascripts/backbone/data/channels.js.coffee b/app/assets/javascripts/backbone/data/channels.js.coffee index 30817609..16a8baa3 100644 --- a/app/assets/javascripts/backbone/data/channels.js.coffee +++ b/app/assets/javascripts/backbone/data/channels.js.coffee @@ -12,10 +12,10 @@ class Kandan.Data.Channels @runCallbacks: (event)-> callback() for callback in @callbacks[event] - @register_callback: (event, callback)-> + @registerCallback: (event, callback)-> @callbacks[event].push(callback) - @unregister_callback: (event, callback)-> + @unregisterCallback: (event, callback)-> delete @callbacks[@callbacks.indexOf(callback)] @callbacks.filter (element, index, array)-> element!=undefined \ No newline at end of file diff --git a/app/assets/javascripts/backbone/plugins/attachments.js.coffee b/app/assets/javascripts/backbone/plugins/attachments.js.coffee index d191f6da..9b006323 100644 --- a/app/assets/javascripts/backbone/plugins/attachments.js.coffee +++ b/app/assets/javascripts/backbone/plugins/attachments.js.coffee @@ -4,8 +4,11 @@ class Kandan.Plugins.Attachments @widget_icon_url: "/assets/media_icon.png" @plugin_namespace: "Kandan.Plugins.Attachments" + @dropzoneInit: false + @options: maxFileNameLength: 20 + defaultDropzoneText: "Drop file here to upload" @templates: no_files: _.template ''' @@ -21,7 +24,7 @@ class Kandan.Plugins.Attachments -
Drop files here to upload
+
<%= dropzoneText %>
''' @@ -44,65 +47,89 @@ class Kandan.Plugins.Attachments @fileIcon: (fileName)-> fileExtension = fileName.split(".").pop() return "/assets/img_icon.png" if fileExtension.match(/(png|jpeg|jpg|gif)/i) - return "/assets/video_icon.png" if fileExtension.match(/(mp3|wav)/i) - return "/assets/audio_icon.png" if fileExtension.match(/(mov|mpg|mpeg|mp4)/i) + return "/assets/audio_icon.png" if fileExtension.match(/(mp3|wav|m4a)/i) + return "/assets/video_icon.png" if fileExtension.match(/(mov|mpg|mpeg|mp4)/i) return "/assets/file_icon.png" @file_item_template: _.template ''' -
<%= fileName %>
+
+ + + <%= fileName %> + +
''' # TODO this part is very bad for APIs! shoudnt be exposing a backbone collection in a plugin. @render: ($widget_el)-> $upload_form = @templates.dropzone({ - channel_id: @channel_id(), - csrf_param: @csrf_param(), - csrf_token: @csrf_token() + channel_id: @channel_id(), + csrf_param: @csrf_param(), + csrf_token: @csrf_token(), + dropzoneText: @options.defaultDropzoneText }) $widget_el.next().html($upload_form) - @init_dropzone @channel_id() $widget_el.next(".action_block").html($upload_form) - attachments = new Kandan.Collections.Attachments([], {channel_id: @channel_id()}) - attachments.fetch({ - success: (collection)=> - - if collection.models.length > 0 - $file_list = $("
") - for model in collection.models - $file_list.append(@file_item_template({ - fileName: @truncateName(model.get('file_file_name')), - url: model.get('url') - iconUrl: @fileIcon(model.get('file_file_name')) - })) - else - $file_list = @templates.no_files() - $widget_el.html($file_list) - }) + populate = (collection)=> + if collection.models.length > 0 + $file_list = $("
") + for model in collection.models + $file_list.append(@file_item_template({ + fileName: @truncateName(model.get('file_file_name')), + url: model.get('url') + iconUrl: @fileIcon(model.get('file_file_name')) + })) + else + $file_list = @templates.no_files() + $widget_el.html($file_list) + Kandan.Data.Attachments.all(populate) - @init_dropzone: (channel_id)-> + + @initDropzone: -> $(".dropzone").filedrop({ fallback_id: "file" - url : "/channels/#{channel_id}/attachments.json", paramname : "file" + maxfilesize: 1000 + queuefiles : 1 + + url: -> + "/channels/#{ Kandan.Data.Channels.activeChannelId() }/attachments.json" - uploadStarted: => + uploadStarted: -> $(".dropzone").text("Uploading...") uploadFinished: (i, file, response, time)-> - $(".dropzone").text("Drop files here to upload") - Kandan.Widgets.render "Kandan.Plugins.Attachments" + console.log "Upload finished!" + + error: (err, file)-> + if err == "BrowserNotSupported" + $(".dropzone").text("Browser not supported") + else if err == "FileTooLarge" + $(".dropzone").text("File too large") + else + $(".dropzone").text("Sorry bud! couldn't upload") + + + progressUpdated: (i, file, progress)-> + $(".dropzone").text("#{progress}% Uploaded") + if progress == 100 + console.log "100% done" + $(".dropzone").text("#{progress}% Uploaded") + Kandan.Widgets.render "Kandan.Plugins.Attachments" dragOver: -> console.log "reached dropzone!" }) @init: ()-> + @initDropzone() Kandan.Widgets.register @plugin_namespace - Kandan.Data.Channels.register_callback "change", ()=> - Kandan.Widgets.render @plugin_namespace + Kandan.Data.Attachments.registerCallback "change", ()=> + Kandan.Widgets.render @plugin_namespace -# Kandan.Plugins.register "Kandan.Plugins.Attachments" + Kandan.Data.Channels.registerCallback "change", ()=> + Kandan.Widgets.render @plugin_namespace diff --git a/app/assets/javascripts/lib/jquery.filedrop.js b/app/assets/javascripts/lib/jquery.filedrop.js index 95202b76..c4083fb7 100644 --- a/app/assets/javascripts/lib/jquery.filedrop.js +++ b/app/assets/javascripts/lib/jquery.filedrop.js @@ -64,8 +64,16 @@ $.fn.filedrop = function(options) { var opts = $.extend({}, default_opts, options); - this.bind('drop', drop).bind('dragenter', dragEnter).bind('dragover', dragOver).bind('dragleave', dragLeave); - $(document).bind('drop', docDrop).bind('dragenter', docEnter).bind('dragover', docOver).bind('dragleave', docLeave); + this.live('drop', drop) + .live('dragenter', dragEnter) + .live('dragover', dragOver) + .live('dragleave', dragLeave); + + $(document) + .bind('drop', docDrop) + .bind('dragenter', docEnter) + .bind('dragover', docOver) + .bind('dragleave', docLeave); $('#' + opts.fallback_id).change(function(e) { opts.drop(e); @@ -283,7 +291,7 @@ upload.startData = 0; upload.addEventListener("progress", progress, false); - xhr.open("POST", opts.url, true); + xhr.open("POST", opts.url(), true); xhr.setRequestHeader('content-type', 'multipart/form-data; boundary=' + boundary); // Add headers diff --git a/app/models/activity_observer.rb b/app/models/activity_observer.rb index 4ce00018..139452cc 100644 --- a/app/models/activity_observer.rb +++ b/app/models/activity_observer.rb @@ -2,12 +2,33 @@ class ActivityObserver < ActiveRecord::Observer def after_save(activity) if activity.action == "message" || activity.action == "upload" - faye_channel = "/channels/#{activity.channel.to_param}" - broadcast_data = activity.attributes.merge({ - :user => activity.user.attributes, - :channel => activity.channel.attributes - }) + faye_channel, broadcast_data = self.send "#{activity.action}_broadcast_data", activity Kandan::Config.broadcaster.broadcast(faye_channel, broadcast_data) end end + + private + def message_broadcast_data(activity) + faye_channel = "/channels/#{activity.channel.to_param}" + broadcast_data = activity.attributes.merge({ + :user => activity.user.attributes, + :channel => activity.channel.attributes + }) + [faye_channel, broadcast_data] + end + + def upload_broadcast_data(activity) + faye_channel = "/app/activities" + broadcast_data = { + :event => "attachment#upload", + :entity => activity.attributes.merge({ + :user => activity.user.attributes, + :channel => activity.channel.attributes + }), + :extra => { + :attachments => activity.channel.attachments.as_json(:methods => :url) + } + } + [faye_channel, broadcast_data] + end end diff --git a/lib/active_users.rb b/lib/active_users.rb index 90d14b3e..d917cfc2 100644 --- a/lib/active_users.rb +++ b/lib/active_users.rb @@ -18,23 +18,23 @@ def add(client_id, user) end def remove_by_client_id(client_id) - user_id = find_by_client_id(client_id) + user_id = find_by_client_id client_id if user_id @@users[user_id][:client_ids].delete client_id if @@users[user_id][:client_ids].empty? - publish_message "disconnect", @@users[user_id][:user] - @@users.delete(user_id) + deleted_user_info = @@users.delete user_id + publish_message "disconnect", deleted_user_info[:user] end end end def remove_by_user_id(user_id) - @@users.delete(user_id) + @@users.delete user_id end def find_by_client_id(client_id) @@users.each do |user_id, detail| - return user_id if detail[:client_ids].include?(client_id) + return user_id if detail[:client_ids].include? client_id end false end