format :html do
watch_perms = lambda { |r| Account.logged_in? && !r.card.new_card? }
view :watch, :tags=>:unknown_ok, :denial=>:blank, :perms=>watch_perms do |args|
wrap :watch, args do
if card.watching_type?
watching_type_cards
else
link_args = if card.watching?
["following", :off, "stop sending emails about changes to #{card.cardname}", { :hover_content=> 'unfollow' } ]
else
["follow", :on, "send emails about changes to #{card.cardname}" ]
end
watch_link *link_args
end
end
end
def watching_type_cards
%{
(following)
} #yuck
end
def watch_link text, toggle, title, extra={}
link_to "#{text}", path(:action=>:watch, :toggle=>toggle),
{:class=>"watch-toggle watch-toggle-#{toggle} slotter", :title=>title, :remote=>true, :method=>'post'}.merge(extra)
end
end
event :record_followers, :before=>:store, :on=>:delete do
# find before, because in case of deleted cards all the data is gone!
@trunk_watcher_watched_pairs = trunk_watcher_watched_pairs
@watcher_watched_pairs = watcher_watched_pairs
end
event :notify_followers, :after=>:extend do
begin
return false if Card.record_timestamps==false || ENV['WAGN_MIGRATION']
# userstamps and timestamps are turned off in cases like updating read_rules that are automated and
# generally not of enough interest to warrant notification
action = "#{@action}d"
@trunk_watcher_watched_pairs ||= trunk_watcher_watched_pairs
@watcher_watched_pairs ||= watcher_watched_pairs
@watcher_watched_pairs.reject {|p| @trunk_watcher_watched_pairs.map(&:first).include? p.first }.each do |watcher, watched|
watcher and mail = Mailer.change_notice( watcher, self, action, watched.to_s, nested_notifications ) and mail.deliver
end
if @supercard
@supercard.nested_notifications ||= []
@supercard.nested_notifications << [ name, action ]
else
@trunk_watcher_watched_pairs.each do |watcher, watched|
next if watcher.nil?
Mailer.change_notice( watcher, self.left, 'updated', watched.to_s, [[name, action]], self ).send_if :deliver
end
end
rescue Exception=>e #this error handling should apply to all extend callback exceptions
Airbrake.notify e if Airbrake.configuration.api_key
Rails.logger.info "\nController exception: #{e.message}"
Rails.logger.debug "BT: #{e.backtrace*"\n"}"
end
end
attr_accessor :nested_notifications
def trunk_watcher_watched_pairs
# do the watchers lookup before the includer test since it's faster.
if cardname.junction?
#warn "trunk_watcher_pairs #{cardname}, #{cardname.trunk_name.inspect}, #{includers.inspect}"
tcard = Card[tname=cardname.trunk_name]
tcard and pairs = tcard.watcher_watched_pairs
#warn "trunk_watcher_pairs TC:#{tcard.inspect}, #{tname}, P:#{pairs.inspect}, k:#{tname.key} member: pr:#{!pairs.nil?}, and I:#{includers.map(&:key).member?(tname.key)}"
return pairs if !pairs.nil? and includers.map(&:key).member?(tname.key)
#warn "twatch empty ..."
end
[]
end
def watching_type?; watcher_pairs(false, :type).member? Account.current_id end
def watching?; watcher_pairs(false). member? Account.current_id end
def watchers
watcher_watched_pairs false
end
def watcher_watched_pairs pairs=true
watcher_pairs pairs, :name, whash = {}
watcher_pairs pairs, :type, whash
end
def watcher_pairs pairs=true, kind=:name, hash={}
#warn "wp #{inspect} P:#{pairs}, k:#{kind}, uid:#{Account.current_id} #{hash.inspect}, OI:#{hash.object_id}"
wname, rc = (kind == :type) ?
[ self.type_name, self.type_card.fetch(:trait=>:watchers) ] :
[ self.cardname, fetch(:trait=>:watchers) ]
!rc.nil? and hash = rc.item_cards.inject( hash ) { |h, watcher| h[watcher.id] ||= wname; h }
if hash.any?
#warn "wp #{pairs}, #{kind}, #{hash.inspect}"
if pairs
hash.each.reject {|i,wname| i == Account.current_id }.map {|i,wname| [ i, wname ] }
else
hash.keys
end
else []
end
#warn "wp r:#{r}"; r
end