From e17b6aa1625bab71722e184f133f50aa89e1957f Mon Sep 17 00:00:00 2001 From: Sebastian Jambor Date: Tue, 29 Nov 2022 19:10:06 +0100 Subject: [PATCH] prototyping server sent events --- .../api/v1/activity_log_controller.rb | 44 +++++++++++++++++++ .../mastodon/features/activity_log/index.js | 19 +++++++- config/routes.rb | 2 + 3 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 app/controllers/api/v1/activity_log_controller.rb diff --git a/app/controllers/api/v1/activity_log_controller.rb b/app/controllers/api/v1/activity_log_controller.rb new file mode 100644 index 000000000..4acbb3206 --- /dev/null +++ b/app/controllers/api/v1/activity_log_controller.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +class Api::V1::ActivityLogController < Api::BaseController + include ActionController::Live + + # before_action -> { doorkeeper_authorize! :read, :'read:lists' }, only: [:index, :show] + # before_action -> { doorkeeper_authorize! :write, :'write:lists' }, except: [:index, :show] + + # before_action :require_user! + # before_action :set_list, except: [:index, :create] + # + # + # + class Foo + attr_accessor :test + end + + rescue_from ArgumentError do |e| + render json: { error: e.to_s }, status: 422 + end + + def index + render :text => "hello world" + end + + def show + response.headers['Content-Type'] = 'text/event-stream' + # hack to avoid computing Etag, which delays sending of data + response.headers['Last-Modified'] = Time.now.httpdate + + sse = SSE.new(response.stream) + + begin + 100.times { + f = Foo.new + f.test = "xxx" + sse.write f.to_json + sleep 1 + } + ensure + sse.close + end + end +end diff --git a/app/javascript/mastodon/features/activity_log/index.js b/app/javascript/mastodon/features/activity_log/index.js index b5f53c644..104a1d573 100644 --- a/app/javascript/mastodon/features/activity_log/index.js +++ b/app/javascript/mastodon/features/activity_log/index.js @@ -30,8 +30,25 @@ class Lists extends ImmutablePureComponent { multiColumn: PropTypes.bool, }; + state = { + logs: [], + }; + + componentDidMount() { + this.eventSource = new EventSource('/api/v1/activity_log'); + this.eventSource.onmessage = (event) => { + this.setState({ logs: [...this.state.logs, JSON.parse(event.data)] }); + }; + } + + componentWillUnmount() { + if (this.eventSource) { + this.eventSource.close(); + } + } + render () { - return
Hello world
; + return
{this.state.logs.map(x => (
{JSON.stringify(x)}
))}
; } } diff --git a/config/routes.rb b/config/routes.rb index 337c14c41..e65f0b94d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -542,6 +542,8 @@ Rails.application.routes.draw do resources :confirmations, only: [:create] end + resource :activity_log, only: [:show], controller: 'activity_log' + resource :instance, only: [:show] do resources :peers, only: [:index], controller: 'instances/peers' resources :rules, only: [:index], controller: 'instances/rules'