diff --git a/app/controllers/api/v1/annual_reports_controller.rb b/app/controllers/api/v1/annual_reports_controller.rb index 724c7658d7..71a97e1d9a 100644 --- a/app/controllers/api/v1/annual_reports_controller.rb +++ b/app/controllers/api/v1/annual_reports_controller.rb @@ -57,27 +57,18 @@ class Api::V1::AnnualReportsController < Api::BaseController render_empty end - def refresh_key - "wrapstodon:#{current_account.id}:#{year}" - end - private def report_state - return 'available' if GeneratedAnnualReport.exists?(account_id: current_account.id, year: year) - - async_refresh = AsyncRefresh.new(refresh_key) - - if async_refresh.running? + AnnualReport.new(current_account, year).state do |async_refresh| add_async_refresh_header(async_refresh, retry_seconds: 2) - 'generating' - elsif AnnualReport.current_campaign == year && AnnualReport.new(current_account, year).eligible? - 'eligible' - else - 'ineligible' end end + def refresh_key + "wrapstodon:#{current_account.id}:#{year}" + end + def year params[:id]&.to_i end diff --git a/app/javascript/mastodon/initial_state.ts b/app/javascript/mastodon/initial_state.ts index 3bfd48a76b..358c307c30 100644 --- a/app/javascript/mastodon/initial_state.ts +++ b/app/javascript/mastodon/initial_state.ts @@ -2,6 +2,11 @@ import type { ApiAccountJSON } from './api_types/accounts'; type InitialStateLanguage = [code: string, name: string, localName: string]; +interface InitialWrapstodonState { + year: number; + state: 'available' | 'generating' | 'eligible' | 'ineligible'; +} + interface InitialStateMeta { access_token: string; advanced_layout?: boolean; @@ -47,6 +52,7 @@ interface InitialStateMeta { status_page_url: string; terms_of_service_enabled: boolean; emoji_style?: string; + wrapstodon?: InitialWrapstodonState | null; } interface Role { @@ -128,6 +134,7 @@ export const criticalUpdatesPending = initialState?.critical_updates_pending; export const statusPageUrl = getMeta('status_page_url'); export const sso_redirect = getMeta('sso_redirect'); export const termsOfServiceEnabled = getMeta('terms_of_service_enabled'); +export const wrapstodon = getMeta('wrapstodon'); const displayNames = // Intl.DisplayNames can be undefined in old browsers diff --git a/app/javascript/mastodon/reducers/slices/annual_report.ts b/app/javascript/mastodon/reducers/slices/annual_report.ts index a687f558e1..5e7f44798a 100644 --- a/app/javascript/mastodon/reducers/slices/annual_report.ts +++ b/app/javascript/mastodon/reducers/slices/annual_report.ts @@ -11,6 +11,7 @@ import { apiGetAnnualReportState, apiRequestGenerateAnnualReport, } from '@/mastodon/api/annual_report'; +import { wrapstodon } from '@/mastodon/initial_state'; import type { AnnualReport } from '@/mastodon/models/annual_report'; import { @@ -20,13 +21,17 @@ import { } from '../../store/typed_functions'; interface AnnualReportState { + year?: number; state?: ApiAnnualReportState; report?: AnnualReport; } const annualReportSlice = createSlice({ name: 'annualReport', - initialState: {} as AnnualReportState, + initialState: { + year: wrapstodon?.year, + state: wrapstodon?.state, + } as AnnualReportState, reducers: { setReport(state, action: PayloadAction) { state.report = action.payload; @@ -53,8 +58,8 @@ export const annualReport = annualReportSlice.reducer; export const { setReport } = annualReportSlice.actions; export const selectWrapstodonYear = createAppSelector( - [(state) => state.server.getIn(['server', 'wrapstodon'])], - (year: unknown) => (typeof year === 'number' && year > 2000 ? year : null), + [(state) => state.annualReport.year], + (year: number | null | undefined) => year ?? null, ); // This kicks everything off, and is called after fetching the server info. diff --git a/app/lib/annual_report.rb b/app/lib/annual_report.rb index a9c9135ed4..f487cb883f 100644 --- a/app/lib/annual_report.rb +++ b/app/lib/annual_report.rb @@ -34,6 +34,25 @@ class AnnualReport end end + def state + return 'available' if GeneratedAnnualReport.exists?(account_id: @account.id, year: @year) + + async_refresh = AsyncRefresh.new(refresh_key) + + if async_refresh.running? + yield async_refresh if block_given? + 'generating' + elsif AnnualReport.current_campaign == @year && eligible? + 'eligible' + else + 'ineligible' + end + end + + def refresh_key + "wrapstodon:#{@account.id}:#{@year}" + end + def generate return if GeneratedAnnualReport.exists?(account: @account, year: @year) diff --git a/app/serializers/initial_state_serializer.rb b/app/serializers/initial_state_serializer.rb index 5f8921e246..fe2a857d50 100644 --- a/app/serializers/initial_state_serializer.rb +++ b/app/serializers/initial_state_serializer.rb @@ -32,6 +32,7 @@ class InitialStateSerializer < ActiveModel::Serializer store[:use_pending_items] = object_account_user.setting_use_pending_items store[:show_trends] = Setting.trends && object_account_user.setting_trends store[:emoji_style] = object_account_user.settings['web.emoji_style'] + store[:wrapstodon] = wrapstodon else store[:auto_play_gif] = Setting.auto_play_gif store[:display_media] = Setting.display_media @@ -94,6 +95,16 @@ class InitialStateSerializer < ActiveModel::Serializer private + def wrapstodon + current_campaign = AnnualReport.current_campaign + return if current_campaign.blank? + + { + year: current_campaign, + state: AnnualReport.new(object.current_account, current_campaign).state, + } + end + def default_meta_store { access_token: object.token,