vkhater-social_stream-events 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. data/.gitignore +10 -0
  2. data/Gemfile +5 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +26 -0
  5. data/app/assets/javascripts/0_init.js +4 -0
  6. data/app/assets/javascripts/events.js.coffee +66 -0
  7. data/app/assets/javascripts/social_stream-events.js +1 -0
  8. data/app/assets/stylesheets/events.css.scss +66 -0
  9. data/app/assets/stylesheets/social_stream-events.css +3 -0
  10. data/app/controllers/events_controller.rb +40 -0
  11. data/app/controllers/rooms_controller.rb +7 -0
  12. data/app/helpers/events_helper.rb +16 -0
  13. data/app/models/event.rb +53 -0
  14. data/app/models/room.rb +8 -0
  15. data/app/views/events/_calendar_month.erb +1 -0
  16. data/app/views/events/_event.html.erb +1 -0
  17. data/app/views/events/_new.html.erb +40 -0
  18. data/app/views/events/_sidebar_calendar.html.erb +34 -0
  19. data/app/views/events/create.js.erb +21 -0
  20. data/app/views/events/destroy.js.erb +1 -0
  21. data/app/views/events/index.html.erb +99 -0
  22. data/app/views/rooms/_form.html.erb +31 -0
  23. data/app/views/rooms/_index.html.erb +10 -0
  24. data/app/views/rooms/_settings.html.erb +23 -0
  25. data/app/views/rooms/create.js.erb +7 -0
  26. data/app/views/rooms/destroy.js.erb +1 -0
  27. data/config/locales/en.yml +35 -0
  28. data/config/locales/es.yml +35 -0
  29. data/config/routes.rb +3 -0
  30. data/db/migrate/20111101193523_create_events.rb +13 -0
  31. data/db/migrate/20111120104349_create_rooms.rb +26 -0
  32. data/db/migrate/20111204155637_add_scheduler.rb +33 -0
  33. data/db/migrate/20111218203314_change_scheduler.rb +11 -0
  34. data/lib/generators/social_stream/events/install_generator.rb +24 -0
  35. data/lib/social_stream-events.rb +27 -0
  36. data/lib/social_stream/events/ability.rb +13 -0
  37. data/lib/social_stream/events/engine.rb +29 -0
  38. data/lib/social_stream/events/models/actor.rb +13 -0
  39. data/lib/social_stream/events/version.rb +5 -0
  40. data/lib/social_stream/migrations/events.rb +8 -0
  41. data/lib/social_stream/toolbar_config/events.rb +22 -0
  42. data/lib/social_stream/views/settings/events.rb +18 -0
  43. data/lib/social_stream/views/sidebar/events.rb +15 -0
  44. data/social_stream-events.gemspec +24 -0
  45. data/vendor/assets/images/boxy-ne.png +0 -0
  46. data/vendor/assets/images/boxy-nw.png +0 -0
  47. data/vendor/assets/images/boxy-se.png +0 -0
  48. data/vendor/assets/images/boxy-sw.png +0 -0
  49. data/vendor/assets/javascripts/fullcalendar.js +5210 -0
  50. data/vendor/assets/javascripts/gcal.js +112 -0
  51. data/vendor/assets/javascripts/jquery.boxy.js +570 -0
  52. data/vendor/assets/javascripts/sprintf.js +183 -0
  53. data/vendor/assets/stylesheets/boxy.css +49 -0
  54. data/vendor/assets/stylesheets/fullcalendar.css +618 -0
  55. data/vendor/assets/stylesheets/fullcalendar.print.css +61 -0
  56. metadata +150 -0
@@ -0,0 +1,10 @@
1
+ pkg/*
2
+ .bundle
3
+ **.tmp_*
4
+ Gemfile.lock
5
+ .idea
6
+ nbproject
7
+ .loadpath
8
+ .project
9
+ .DS_Store
10
+ .yardoc/*
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'social_stream-base', :path => '../base'
4
+
5
+ gemspec
@@ -0,0 +1,3 @@
1
+ = Social Stream Events
2
+
3
+ This gem will change to support scheduled events
@@ -0,0 +1,26 @@
1
+ # encoding: UTF-8
2
+ require 'bundler/gem_tasks'
3
+
4
+ require 'rdoc/task'
5
+
6
+ require 'rspec/core'
7
+ require 'rspec/core/rake_task'
8
+
9
+ RSpec::Core::RakeTask.new(:spec)
10
+
11
+ task :default => :spec
12
+
13
+ Rake::RDocTask.new(:rdoc) do |rdoc|
14
+ rdoc.rdoc_dir = 'rdoc'
15
+ rdoc.title = 'Socialstream Events'
16
+ rdoc.options << '--line-numbers' << '--inline-source'
17
+ rdoc.rdoc_files.include('README.rdoc')
18
+ rdoc.rdoc_files.include('lib/**/*.rb')
19
+ end
20
+
21
+ # Modify this gem's tags
22
+ class Bundler::GemHelper
23
+ def version_tag
24
+ "events#{version}"
25
+ end
26
+ end
@@ -0,0 +1,4 @@
1
+ var SocialStream = SocialStream || {};
2
+ SocialStream.Events = SocialStream.Events || {};
3
+ SocialStream.Events.current = SocialStream.Events.current || {};
4
+
@@ -0,0 +1,66 @@
1
+ # Place all the behaviors and hooks related to the matching controller here.
2
+ # All this logic will automatically be available in application.js.
3
+ # You can use CoffeeScript in this file: http://jashkenas.github.com/coffee-script/
4
+ #
5
+ #= require fullcalendar
6
+ #= require jquery.boxy
7
+ #= require sprintf
8
+ #= require scheduler
9
+
10
+ SocialStream.Events.create = (start, end, allDay) ->
11
+ title = prompt('Event Title:');
12
+ if title
13
+ $.post(SocialStream.Events.current.eventsPath,
14
+ {
15
+ event: {
16
+ title: title,
17
+ start_at: start.toString(),
18
+ end_at: end.toString(),
19
+ all_day: allDay,
20
+ _contact_id: SocialStream.Events.current.contactId
21
+ }
22
+ },
23
+ undefined,
24
+ "script");
25
+
26
+ SocialStream.Events.tools = {}
27
+
28
+ SocialStream.Events.tools.currentRGB = () ->
29
+ [ parseInt(SocialStream.Events.current.eventColor[1..2], 16),
30
+ parseInt(SocialStream.Events.current.eventColor[3..4], 16),
31
+ parseInt(SocialStream.Events.current.eventColor[5..6], 16) ]
32
+
33
+ SocialStream.Events.tools.colorRange = () ->
34
+ min = 0
35
+
36
+ for color in SocialStream.Events.tools.currentRGB()
37
+ if color < min
38
+ min = color
39
+
40
+ parseInt 2 * (255 - min) / 3
41
+
42
+ SocialStream.Events.tools.increaseColor = (delta) ->
43
+ (if (color + delta) > 255 then 255 else (color + delta)) for color in SocialStream.Events.tools.currentRGB()
44
+
45
+
46
+ SocialStream.Events.tools.eventColorScale = (index) ->
47
+ range = SocialStream.Events.tools.colorRange()
48
+
49
+ delta = range * (index + 1) / (SocialStream.Events.current.roomIndex.length + 1)
50
+
51
+ delta = parseInt(delta)
52
+
53
+ newColor = SocialStream.Events.tools.increaseColor(delta)
54
+
55
+ sprintf "#%02x%02x%02x", newColor[0], newColor[1], newColor[2]
56
+
57
+
58
+ SocialStream.Events.tools.eventColor = (roomId) ->
59
+ currentColor = SocialStream.Events.current.eventColor
60
+
61
+ if not roomId? or not SocialStream.Events.current.roomIndex? or SocialStream.Events.current.roomIndex.length == 0
62
+ return currentColor
63
+
64
+ currentRoomIndex = SocialStream.Events.current.roomIndex.indexOf(roomId)
65
+
66
+ SocialStream.Events.tools.eventColorScale(currentRoomIndex)
@@ -0,0 +1 @@
1
+ //= require_tree .
@@ -0,0 +1,66 @@
1
+ // Place all the styles related to the events controller here.
2
+ // They will automatically be included in application.css.
3
+ // You can use Sass (SCSS) here: http://sass-lang.com/
4
+ //
5
+ //= require fullcalendar
6
+ //= require boxy
7
+
8
+ @import "colors";
9
+
10
+ #calendar {
11
+ margin-top: 20px;
12
+ }
13
+
14
+ #sidebar_calendar_date {
15
+ margin-left: 5px;
16
+ }
17
+
18
+ #sidebar_calendar {
19
+ width: 100%;
20
+ text-align: center;
21
+ padding-top: 5px;
22
+ border-top: thin solid $separation-color;
23
+ border-bottom: thin solid $separation-color;
24
+ }
25
+
26
+ #sidebar_calendar a {
27
+ color: black;
28
+ }
29
+
30
+ #sidebar_calendar td {
31
+ height: 25px;
32
+ }
33
+
34
+ #sidebar_calendar td.past {
35
+ opacity: 0.2;
36
+ }
37
+
38
+ #sidebar_calendar td.today {
39
+ border: 1px solid $sentence-color;
40
+ }
41
+
42
+ #sidebar_calendar td.next_month {
43
+ opacity: 0.8;
44
+ background-color: #F2F2F2;
45
+ }
46
+
47
+ .sidebar_calendar_month {
48
+ text-align: center;
49
+ padding: 5px;
50
+ }
51
+
52
+ .sidebar_calendar_month a {
53
+ color: $sentence-color;
54
+ }
55
+
56
+ .sidebar_calendar_month.not_current a {
57
+ color: $details-color;
58
+ }
59
+
60
+ #new_event div.form_row {
61
+ padding: 3px 0;
62
+ }
63
+
64
+ #scheduler-options {
65
+ padding: 2px 10px;
66
+ }
@@ -0,0 +1,3 @@
1
+ /*
2
+ *= require_tree .
3
+ */
@@ -0,0 +1,40 @@
1
+ class EventsController < ApplicationController
2
+ include SocialStream::Controllers::Objects
3
+
4
+ belongs_to_subjects :optional => true
5
+
6
+ before_filter :profile_subject!, :only => :index
7
+
8
+ def index
9
+ index! do |format|
10
+ format.json {
11
+ start_time = Time.at(params[:start].to_i)
12
+ end_time = Time.at(params[:end].to_i)
13
+ @activities =
14
+ collection.
15
+ joins(:activity_objects => :event).
16
+ merge(Event.between(start_time, end_time))
17
+
18
+ render :json =>
19
+ @activities.
20
+ map(&:direct_object).
21
+ map{ |e| e.to_json(:start => start_time, :end => end_time) }.flatten.to_json
22
+ }
23
+ end
24
+ end
25
+
26
+ def show
27
+ show! do |format|
28
+ format.html { redirect_to polymorphic_path([ @event.post_activity.receiver_subject, Event.new ], :at => @event.start_at.to_i) }
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def collection
35
+ @activities =
36
+ profile_subject.wall(:profile,
37
+ :for => current_subject,
38
+ :object_type => :Event)
39
+ end
40
+ end
@@ -0,0 +1,7 @@
1
+ class RoomsController < InheritedResources::Base
2
+ actions :create, :destroy
3
+
4
+ respond_to :js
5
+
6
+ load_and_authorize_resource
7
+ end
@@ -0,0 +1,16 @@
1
+ module EventsHelper
2
+ def event_class(day)
3
+ [].tap { |css|
4
+ css <<
5
+ if day < Date.today
6
+ "past"
7
+ elsif day == Date.today
8
+ "today"
9
+ elsif day.month != Date.today.month
10
+ "next_month"
11
+ end
12
+
13
+ #TODO: event ocurrence
14
+ }.join(" ")
15
+ end
16
+ end
@@ -0,0 +1,53 @@
1
+ class Event < ActiveRecord::Base
2
+ include SocialStream::Models::Object
3
+
4
+ scheduler
5
+
6
+ belongs_to :room
7
+
8
+ validates_presence_of :title
9
+
10
+ validate :room_belongs_to_receiver
11
+
12
+ def to_json(options = {})
13
+ if recurrence
14
+ st = options[:start].try(:to_date)
15
+ en = (options[:end] || end_at.end_of_month + 7.days).to_date
16
+
17
+ recurrence.events(:starts => st, :until => en).map do |d|
18
+
19
+ start_diff = d - start_at.to_date
20
+ end_diff = d - end_at.to_date
21
+
22
+ build_json start_at.advance(:days => start_diff),
23
+ end_at.advance(:days => end_diff)
24
+ end
25
+ else
26
+ build_json
27
+ end
28
+ end
29
+
30
+ protected
31
+
32
+ def build_json(start_time = start_at, end_time = end_at)
33
+ {
34
+ :id => id,
35
+ :title => title,
36
+ :start => start_time,
37
+ :end => end_time,
38
+ :allDay => all_day?,
39
+ :roomId => room_id
40
+ }
41
+
42
+ end
43
+
44
+ private
45
+
46
+ def room_belongs_to_receiver
47
+ return if room_id.blank?
48
+
49
+ unless _contact.receiver.room_ids.include?(room_id)
50
+ errors.add(:room_id, :invalid)
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,8 @@
1
+ class Room < ActiveRecord::Base
2
+ belongs_to :actor
3
+
4
+ has_many :events
5
+
6
+ validates_presence_of :actor_id, :name
7
+ validates_uniqueness_of :name, :scope => :actor_id
8
+ end
@@ -0,0 +1 @@
1
+ <div id="sidebar_calendar_month_<%= position %>" class="sidebar_calendar_month<%= " not_current" if date.month != Date.today.month %>"><%= link_to l(date, :format => "%B %Y"), polymorphic_path([profile_or_current_subject, Event.new], :date => date.to_time.to_i) %></div>
@@ -0,0 +1 @@
1
+ <%= raw t('event.wall_post', :title => link_to(h(event.title), event)) %>
@@ -0,0 +1,40 @@
1
+ <%= form_for @event || Event.new(:owner_id => profile_subject.actor_id, :interval => 1), :remote => true do |f| %>
2
+ <%= f.hidden_field :owner_id %>
3
+ <%= f.hidden_field :start_at %>
4
+ <%= f.hidden_field :end_at %>
5
+ <%= f.hidden_field :all_day %>
6
+
7
+ <% if f.object.errors.any? %>
8
+ <div id="error_explanation">
9
+ <h2><%= pluralize(f.object.errors.count, "error") %> evitaron que se guardara esta actividad:</h2>
10
+
11
+ <ul>
12
+ <% f.object.errors.full_messages.each do |msg| %>
13
+ <li><%= msg %></li>
14
+ <% end %>
15
+ </ul>
16
+ </div>
17
+ <% end %>
18
+
19
+ <div class="form_row">
20
+ <%= f.label :title %>
21
+ <%= f.text_field :title %>
22
+ </div>
23
+
24
+ <% if profile_subject.rooms.any? %>
25
+ <div class="form_row">
26
+ <%= f.label :room %>
27
+ <%= f.select :room_id, profile_subject.rooms.map{ |r| [r.name, r.id] }, { :include_blank => true } %>
28
+ </div>
29
+ <% end %>
30
+
31
+ <div class="form_row">
32
+ <%= render :partial => 'scheduler/form',
33
+ :locals => { :f => f }
34
+ %>
35
+ </div>
36
+
37
+ <div class="form_row space_center">
38
+ <%= f.submit %>
39
+ </div>
40
+ <% end %>
@@ -0,0 +1,34 @@
1
+ <div class="space_center"></div>
2
+
3
+ <div class="block">
4
+ <div class="content">
5
+
6
+ <%= render :partial => 'events/calendar_month',
7
+ :locals => {
8
+ :position => :top,
9
+ :date => Date.today.beginning_of_week
10
+ } %>
11
+
12
+ <table id="sidebar_calendar">
13
+ <% bow = Time.now.beginning_of_week %>
14
+
15
+ <% 28.times do |i| %>
16
+ <% day = bow + i.days %>
17
+
18
+ <%= raw cycle(*(Array.wrap("<tr>") + 6.times.map{""}) + Array.wrap(:name => "tr_start")) %>
19
+ <td class="<%= event_class(day.to_date) %>">
20
+ <%= link_to day.day, polymorphic_path([profile_or_current_subject, Event.new], :date => day.to_i, :view => "agendaDay") %>
21
+ </td>
22
+
23
+ <%= raw cycle(*(6.times.map{""} + Array.wrap('</tr>') + Array.wrap(:name => "tr_end"))) %>
24
+ <% end %>
25
+ </table>
26
+
27
+ <%= render :partial => 'events/calendar_month',
28
+ :locals => {
29
+ :position => :bottom,
30
+ :date => Date.today.beginning_of_week + 28
31
+ } %>
32
+
33
+ </div>
34
+ </div>
@@ -0,0 +1,21 @@
1
+ <% if @event.valid? %>
2
+ SocialStream.Events.current.newForm.unload();
3
+
4
+ var cal = SocialStream.Events.current.calendar;
5
+
6
+ jQuery.each(<%= raw Array.wrap(@event.to_json).to_json %>,
7
+ function(index, ev) {
8
+ ev.color = SocialStream.Events.tools.eventColor(<%= @event.room_id %>);
9
+
10
+ cal.fullCalendar('renderEvent', ev,
11
+ true // make the event "stick"
12
+ );
13
+ });
14
+
15
+ cal.fullCalendar('unselect');
16
+
17
+ <% else %>
18
+ SocialStream.Events.current.newForm.setContent("<%= escape_javascript render(:partial => 'new') %>");
19
+
20
+ Scheduler.form.init(SocialStream.Events.current.newForm.getContent().find('.scheduler_form'));
21
+ <% end %>
@@ -0,0 +1 @@
1
+ <%= render(:partial => 'objects/destroy') %>
@@ -0,0 +1,99 @@
1
+ <% content_for :headers do %>
2
+ <style type="text/css">
3
+ #sidebar {width: 0px;}
4
+ #center_body {width: 780px; max-width: 780px; border-right: 0px;}
5
+ </style>
6
+ <% end %>
7
+
8
+ <% content_for :title do %>
9
+ <%= profile_subject.name + ": " + t('event.title') %>
10
+ <% end %>
11
+
12
+ <%= location(
13
+ link_to(profile_subject.name, polymorphic_path(profile_subject)),
14
+ link_to(t('event.title'), polymorphic_path([profile_subject, Event.new]))
15
+ ) %>
16
+
17
+ <% toolbar :profile => profile_subject %>
18
+
19
+ <div id="calendar"></div>
20
+
21
+ <%= javascript_tag do %>
22
+ $(function(){
23
+
24
+ <% if profile_subject.respond_to? :rooms %>
25
+ SocialStream.Events.current.roomIndex = <%= raw profile_subject.rooms.map(&:id) %>;
26
+ <% end %>
27
+
28
+ SocialStream.Events.current.eventColor = '#58310E';
29
+
30
+ SocialStream.Events.current.calendar = $('#calendar').fullCalendar({
31
+ header: {
32
+ left: 'prev,next today',
33
+ center: 'title',
34
+ right: 'month,agendaWeek,agendaDay'
35
+ },
36
+ firstDay: 1,
37
+ eventColor: SocialStream.Events.current.eventColor,
38
+ <% if can? :create, new_post(profile_subject) %>
39
+ selectable: true,
40
+ selectHelper: true,
41
+ select: function(startDate, endDate, allDay, jsEvent){
42
+
43
+ SocialStream.Events.current.newForm = new Boxy(
44
+ "<%= escape_javascript render(:partial => 'events/new') %>",
45
+ {
46
+ title: "<%= t('event.new.title') %>",
47
+ closeable: true,
48
+ closeText: "<%= t('boxy.close_text') %>",
49
+ draggable: true
50
+ }
51
+ );
52
+
53
+
54
+ SocialStream.Events.current.newForm.moveTo(jsEvent.clientX, jsEvent.clientY);
55
+
56
+ var c = SocialStream.Events.current.newForm.getContent();
57
+
58
+ c.children('#event_start_at').val(startDate.toJSON());
59
+ c.children('#event_end_at').val(endDate.toJSON());
60
+ c.children('#event_all_day').val(allDay.toString());
61
+
62
+ // From rails-scheduler gem
63
+ Scheduler.form.init(c.find('.scheduler_form'), startDate);
64
+ },
65
+ <% end %>
66
+ // Implement event edition
67
+ // editable: true,
68
+ events: function(start, end, callback) {
69
+ $.ajax({
70
+ url: "<%= escape_javascript polymorphic_path([profile_subject, Event.new]) %>",
71
+ dataType: 'json',
72
+ data: {
73
+ // our hypothetical feed requires UNIX timestamps
74
+ start: Math.round(start.getTime() / 1000),
75
+ end: Math.round(end.getTime() / 1000)
76
+ },
77
+ success: function(events) {
78
+ callback(
79
+ $.map(events, function(event) {
80
+ event.color = SocialStream.Events.tools.eventColor(event.roomId);
81
+ return event;
82
+ }
83
+ )
84
+ );
85
+ }
86
+ });
87
+ }
88
+ });
89
+
90
+ <% if params[:date] %>
91
+ // TODO: optimize this to save one index call
92
+ SocialStream.Events.current.calendar.fullCalendar('gotoDate', new Date(<%= escape_javascript params[:date] %> * 1000));
93
+ <% end %>
94
+
95
+ <% if params[:view] %>
96
+ SocialStream.Events.current.calendar.fullCalendar('changeView', "<%= escape_javascript params[:view] %>");
97
+ <% end %>
98
+ });
99
+ <% end %>