Class: Collavre::CommentsPresenceChannel

Inherits:
ApplicationCable::Channel
  • Object
show all
Defined in:
app/channels/collavre/comments_presence_channel.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.broadcast_agent_status(creative_id, status:, agent_id:, agent_name:, task_id: nil, content: nil, source_creative_id: nil) ⇒ Object

Broadcast agent status (thinking/streaming/idle) to presence channel. This allows the frontend typing indicator to show AI agent activity. source_creative_id: the actual creative where agent is working (for filtering on frontend)



41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'app/channels/collavre/comments_presence_channel.rb', line 41

def self.broadcast_agent_status(creative_id, status:, agent_id:, agent_name:, task_id: nil, content: nil, source_creative_id: nil)
  payload = {
    agent_status: {
      id: agent_id,
      name: agent_name,
      status: status,
      task_id: task_id,
      creative_id: source_creative_id || creative_id
    }
  }
  payload[:agent_status][:content] = content if content.present?
  ActionCable.server.broadcast("comments_presence:#{creative_id}", payload)
end

.broadcast_running_agents(creative_id) ⇒ Object

Broadcast status for any currently running AI agent tasks for a creative. Called when a user subscribes to ensure they see ongoing agent activity.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'app/channels/collavre/comments_presence_channel.rb', line 22

def self.broadcast_running_agents(creative_id)
  Task.where(status: %w[running pending]).find_each do |task|
    task_creative_id = task.trigger_event_payload&.dig("creative", "id")
    next unless task_creative_id == creative_id

    broadcast_agent_status(
      creative_id,
      status: "thinking",
      agent_id: task.agent_id,
      agent_name: task.agent.display_name,
      task_id: task.id,
      source_creative_id: task_creative_id
    )
  end
end

.broadcast_shares_changed(creative_id, shared_user_id:, permission: nil, action: "updated", has_access: nil, can_comment: nil, has_access_changed: nil, can_comment_changed: nil) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'app/channels/collavre/comments_presence_channel.rb', line 3

def self.broadcast_shares_changed(creative_id, shared_user_id:, permission: nil, action: "updated", has_access: nil, can_comment: nil, has_access_changed: nil, can_comment_changed: nil)
  ActionCable.server.broadcast(
    "comments_presence:#{creative_id}",
    {
      shares_changed: {
        user_id: shared_user_id,
        permission: permission,
        action: action,
        has_access: has_access,
        can_comment: can_comment,
        has_access_changed: has_access_changed,
        can_comment_changed: can_comment_changed
      }
    }
  )
end

Instance Method Details

#stopped_typingObject



89
90
91
92
93
# File 'app/channels/collavre/comments_presence_channel.rb', line 89

def stopped_typing
  return unless @creative_id && current_user

  ActionCable.server.broadcast(stream_name, { stop_typing: { id: current_user.id } })
end

#subscribedObject



55
56
57
58
59
60
61
62
63
64
65
66
# File 'app/channels/collavre/comments_presence_channel.rb', line 55

def subscribed
  Rails.logger.info "User #{current_user&.email} subscribed to comments presence for creative #{params[:creative_id]}"
  return unless params[:creative_id].present? && current_user

  @creative_id = Creative.find(params[:creative_id].to_i).effective_origin.id
  creative = Creative.find(@creative_id)
  stream_from stream_name
  CommentPresenceStore.add(@creative_id, current_user.id)
  Comment.broadcast_badge(creative, current_user)
  broadcast_presence
  CommentsPresenceChannel.broadcast_running_agents(@creative_id)
end

#typingObject



80
81
82
83
84
85
86
87
# File 'app/channels/collavre/comments_presence_channel.rb', line 80

def typing
  return unless @creative_id && current_user

  ActionCable.server.broadcast(
    stream_name,
    { typing: { id: current_user.id, name: current_user.display_name } }
  )
end

#unsubscribedObject



68
69
70
71
72
73
74
75
76
77
78
# File 'app/channels/collavre/comments_presence_channel.rb', line 68

def unsubscribed
  if @creative_id && current_user
    CommentPresenceStore.remove(@creative_id, current_user.id)
    creative = Creative.find(@creative_id)
    pointer = CommentReadPointer.find_or_initialize_by(user: current_user, creative: creative)
    pointer.last_read_comment_id = creative.comments.maximum(:id)
    pointer.save!
    Comment.broadcast_badge(creative, current_user)
    broadcast_presence
  end
end