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)



48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'app/channels/collavre/comments_presence_channel.rb', line 48

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_channel_chips_changed(creative_id, topic_id:) ⇒ Object



3
4
5
6
7
8
# File 'app/channels/collavre/comments_presence_channel.rb', line 3

def self.broadcast_channel_chips_changed(creative_id, topic_id:)
  ActionCable.server.broadcast(
    "comments_presence:#{creative_id}",
    { channel_chips: { topic_id: topic_id } }
  )
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.



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'app/channels/collavre/comments_presence_channel.rb', line 29

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



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'app/channels/collavre/comments_presence_channel.rb', line 10

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



96
97
98
99
100
# File 'app/channels/collavre/comments_presence_channel.rb', line 96

def stopped_typing
  return unless @creative_id && current_user

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

#subscribedObject



62
63
64
65
66
67
68
69
70
71
72
73
# File 'app/channels/collavre/comments_presence_channel.rb', line 62

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



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

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



75
76
77
78
79
80
81
82
83
84
85
# File 'app/channels/collavre/comments_presence_channel.rb', line 75

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