[Glitch] Create new entrypoint for sharable Wrapstodon

Port 0dac31dfd5 to glitch-soc

Signed-off-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
Echo
2025-12-04 16:48:10 +01:00
committed by Claire
parent 2d93e63e43
commit 0061f9a699
5 changed files with 111 additions and 3 deletions

View File

@@ -1,3 +1,5 @@
import classNames from 'classnames';
import logo from '@/images/logo.svg';
export const WordmarkLogo: React.FC = () => (
@@ -7,8 +9,12 @@ export const WordmarkLogo: React.FC = () => (
</svg>
);
export const IconLogo: React.FC = () => (
<svg viewBox='0 0 79 79' className='logo logo--icon' role='img'>
export const IconLogo: React.FC<{ className?: string }> = ({ className }) => (
<svg
viewBox='0 0 79 79'
className={classNames('logo logo--icon', className)}
role='img'
>
<title>Mastodon</title>
<use xlinkHref='#logo-symbol-icon' />
</svg>

View File

@@ -0,0 +1,58 @@
import { createRoot } from 'react-dom/client';
import { Provider as ReduxProvider } from 'react-redux';
import {
importFetchedAccounts,
importFetchedStatuses,
} from '@/flavours/glitch/actions/importer';
import type { ApiAnnualReportResponse } from '@/flavours/glitch/api/annual_report';
import { Router } from '@/flavours/glitch/components/router';
import { WrapstodonShare } from '@/flavours/glitch/features/annual_report/share';
import { IntlProvider, loadLocale } from '@/flavours/glitch/locales';
import { loadPolyfills } from '@/flavours/glitch/polyfills';
import ready from '@/flavours/glitch/ready';
import { setReport } from '@/flavours/glitch/reducers/slices/annual_report';
import { store } from '@/flavours/glitch/store';
function loaded() {
const mountNode = document.getElementById('wrapstodon');
if (!mountNode) {
throw new Error('Mount node not found');
}
const propsNode = document.getElementById('wrapstodon-data');
if (!propsNode) {
throw new Error('Initial state prop not found');
}
const initialState = JSON.parse(
propsNode.textContent,
) as ApiAnnualReportResponse;
const report = initialState.annual_reports[0];
if (!report) {
throw new Error('Initial state report not found');
}
store.dispatch(importFetchedAccounts(initialState.accounts));
store.dispatch(importFetchedStatuses(initialState.statuses));
store.dispatch(setReport(report));
const root = createRoot(mountNode);
root.render(
<IntlProvider>
<ReduxProvider store={store}>
<Router>
<WrapstodonShare />
</Router>
</ReduxProvider>
</IntlProvider>,
);
}
loadPolyfills()
.then(loadLocale)
.then(() => ready(loaded))
.catch((err: unknown) => {
console.error(err);
});

View File

@@ -0,0 +1,19 @@
.wrapper {
max-width: 40rem;
margin: 0 auto;
}
.footer {
text-align: center;
margin-top: 1rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
align-items: center;
color: var(--color-text-secondary);
}
.logo {
width: 2rem;
opacity: 0.6;
}

View File

@@ -0,0 +1,18 @@
import type { FC } from 'react';
import { IconLogo } from '@/flavours/glitch/components/logo';
import { AnnualReport } from './index';
import classes from './share.module.css';
export const WrapstodonShare: FC = () => {
return (
<main className={classes.wrapper}>
<AnnualReport share={false} />
<footer className={classes.footer}>
<IconLogo className={classes.logo} />
Generated with by the Mastodon team
</footer>
</main>
);
};

View File

@@ -1,3 +1,4 @@
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import {
@@ -29,7 +30,12 @@ interface AnnualReportState {
const annualReportSlice = createSlice({
name: 'annualReport',
initialState: {} as AnnualReportState,
reducers: {},
reducers: {
setReport(state, action: PayloadAction<AnnualReport>) {
state.report = action.payload;
state.state = 'available';
},
},
extraReducers(builder) {
builder
.addCase(fetchReportState.fulfilled, (state, action) => {
@@ -47,6 +53,7 @@ const annualReportSlice = createSlice({
});
export const annualReport = annualReportSlice.reducer;
export const { setReport } = annualReportSlice.actions;
export const selectWrapstodonYear = createAppSelector(
[(state) => state.server.getIn(['server', 'wrapstodon'])],