mirror of
https://git.bsd.gay/fef/nyastodon.git
synced 2024-12-25 07:23:43 +01:00
[Glitch] [Proposal] Make able to write React in Typescript (#2190)
Port 4520e6473a
to glitch-soc
Signed-off-by: Plastikmensch <plastikmensch@users.noreply.github.com>
This commit is contained in:
parent
678480d4d3
commit
1565af1caf
16 changed files with 105 additions and 92 deletions
|
@ -23,6 +23,7 @@ export const PICTURE_IN_PICTURE_REMOVE = 'PICTURE_IN_PICTURE_REMOVE';
|
||||||
* @return {object}
|
* @return {object}
|
||||||
*/
|
*/
|
||||||
export const deployPictureInPicture = (statusId, accountId, playerType, props) => {
|
export const deployPictureInPicture = (statusId, accountId, playerType, props) => {
|
||||||
|
// @ts-expect-error
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
// Do not open a player for a toot that does not exist
|
// Do not open a player for a toot that does not exist
|
||||||
if (getState().hasIn(['statuses', statusId])) {
|
if (getState().hasIn(['statuses', statusId])) {
|
||||||
|
|
|
@ -46,6 +46,7 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
|
||||||
connectStream(channelName, params, (dispatch, getState) => {
|
connectStream(channelName, params, (dispatch, getState) => {
|
||||||
const locale = getState().getIn(['meta', 'locale']);
|
const locale = getState().getIn(['meta', 'locale']);
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
let pollingId;
|
let pollingId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,6 +62,7 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
|
||||||
onConnect() {
|
onConnect() {
|
||||||
dispatch(connectTimeline(timelineId));
|
dispatch(connectTimeline(timelineId));
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
if (pollingId) {
|
if (pollingId) {
|
||||||
clearTimeout(pollingId);
|
clearTimeout(pollingId);
|
||||||
pollingId = null;
|
pollingId = null;
|
||||||
|
@ -75,6 +77,7 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
|
||||||
dispatch(disconnectTimeline(timelineId));
|
dispatch(disconnectTimeline(timelineId));
|
||||||
|
|
||||||
if (options.fallback) {
|
if (options.fallback) {
|
||||||
|
// @ts-expect-error
|
||||||
pollingId = setTimeout(() => useFallback(options.fallback), randomUpTo(40000));
|
pollingId = setTimeout(() => useFallback(options.fallback), randomUpTo(40000));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -82,24 +85,30 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
|
||||||
onReceive (data) {
|
onReceive (data) {
|
||||||
switch(data.event) {
|
switch(data.event) {
|
||||||
case 'update':
|
case 'update':
|
||||||
|
// @ts-expect-error
|
||||||
dispatch(updateTimeline(timelineId, JSON.parse(data.payload), options.accept));
|
dispatch(updateTimeline(timelineId, JSON.parse(data.payload), options.accept));
|
||||||
break;
|
break;
|
||||||
case 'status.update':
|
case 'status.update':
|
||||||
|
// @ts-expect-error
|
||||||
dispatch(updateStatus(JSON.parse(data.payload)));
|
dispatch(updateStatus(JSON.parse(data.payload)));
|
||||||
break;
|
break;
|
||||||
case 'delete':
|
case 'delete':
|
||||||
dispatch(deleteFromTimelines(data.payload));
|
dispatch(deleteFromTimelines(data.payload));
|
||||||
break;
|
break;
|
||||||
case 'notification':
|
case 'notification':
|
||||||
|
// @ts-expect-error
|
||||||
dispatch(updateNotifications(JSON.parse(data.payload), messages, locale));
|
dispatch(updateNotifications(JSON.parse(data.payload), messages, locale));
|
||||||
break;
|
break;
|
||||||
case 'conversation':
|
case 'conversation':
|
||||||
|
// @ts-expect-error
|
||||||
dispatch(updateConversations(JSON.parse(data.payload)));
|
dispatch(updateConversations(JSON.parse(data.payload)));
|
||||||
break;
|
break;
|
||||||
case 'announcement':
|
case 'announcement':
|
||||||
|
// @ts-expect-error
|
||||||
dispatch(updateAnnouncements(JSON.parse(data.payload)));
|
dispatch(updateAnnouncements(JSON.parse(data.payload)));
|
||||||
break;
|
break;
|
||||||
case 'announcement.reaction':
|
case 'announcement.reaction':
|
||||||
|
// @ts-expect-error
|
||||||
dispatch(updateAnnouncementsReaction(JSON.parse(data.payload)));
|
dispatch(updateAnnouncementsReaction(JSON.parse(data.payload)));
|
||||||
break;
|
break;
|
||||||
case 'announcement.delete':
|
case 'announcement.delete':
|
||||||
|
@ -115,7 +124,9 @@ export const connectTimelineStream = (timelineId, channelName, params = {}, opti
|
||||||
* @param {function(): void} done
|
* @param {function(): void} done
|
||||||
*/
|
*/
|
||||||
const refreshHomeTimelineAndNotification = (dispatch, done) => {
|
const refreshHomeTimelineAndNotification = (dispatch, done) => {
|
||||||
|
// @ts-expect-error
|
||||||
dispatch(expandHomeTimeline({}, () =>
|
dispatch(expandHomeTimeline({}, () =>
|
||||||
|
// @ts-expect-error
|
||||||
dispatch(expandNotifications({}, () =>
|
dispatch(expandNotifications({}, () =>
|
||||||
dispatch(fetchAnnouncements(done))))));
|
dispatch(fetchAnnouncements(done))))));
|
||||||
};
|
};
|
||||||
|
@ -124,6 +135,7 @@ const refreshHomeTimelineAndNotification = (dispatch, done) => {
|
||||||
* @return {function(): void}
|
* @return {function(): void}
|
||||||
*/
|
*/
|
||||||
export const connectUserStream = () =>
|
export const connectUserStream = () =>
|
||||||
|
// @ts-expect-error
|
||||||
connectTimelineStream('home', 'user', {}, { fallback: refreshHomeTimelineAndNotification, fillGaps: fillHomeTimelineGaps });
|
connectTimelineStream('home', 'user', {}, { fallback: refreshHomeTimelineAndNotification, fillGaps: fillHomeTimelineGaps });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -36,7 +36,7 @@ const setCSRFHeader = () => {
|
||||||
ready(setCSRFHeader);
|
ready(setCSRFHeader);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {() => import('immutable').Map} getState
|
* @param {() => import('immutable').Map<string,any>} getState
|
||||||
* @returns {import('axios').RawAxiosRequestHeaders}
|
* @returns {import('axios').RawAxiosRequestHeaders}
|
||||||
*/
|
*/
|
||||||
const authorizationHeaderFromState = getState => {
|
const authorizationHeaderFromState = getState => {
|
||||||
|
@ -52,7 +52,7 @@ const authorizationHeaderFromState = getState => {
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {() => import('immutable').Map} getState
|
* @param {() => import('immutable').Map<string,any>} getState
|
||||||
* @returns {import('axios').AxiosInstance}
|
* @returns {import('axios').AxiosInstance}
|
||||||
*/
|
*/
|
||||||
export default function api(getState) {
|
export default function api(getState) {
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
|
||||||
import { autoPlayGif } from 'flavours/glitch/initial_state';
|
|
||||||
import classNames from 'classnames';
|
|
||||||
|
|
||||||
export default class Avatar extends React.PureComponent {
|
|
||||||
|
|
||||||
static propTypes = {
|
|
||||||
account: ImmutablePropTypes.map,
|
|
||||||
className: PropTypes.string,
|
|
||||||
size: PropTypes.number.isRequired,
|
|
||||||
style: PropTypes.object,
|
|
||||||
inline: PropTypes.bool,
|
|
||||||
animate: PropTypes.bool,
|
|
||||||
};
|
|
||||||
|
|
||||||
static defaultProps = {
|
|
||||||
animate: autoPlayGif,
|
|
||||||
size: 20,
|
|
||||||
inline: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
state = {
|
|
||||||
hovering: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
handleMouseEnter = () => {
|
|
||||||
if (this.props.animate) return;
|
|
||||||
this.setState({ hovering: true });
|
|
||||||
};
|
|
||||||
|
|
||||||
handleMouseLeave = () => {
|
|
||||||
if (this.props.animate) return;
|
|
||||||
this.setState({ hovering: false });
|
|
||||||
};
|
|
||||||
|
|
||||||
render () {
|
|
||||||
const {
|
|
||||||
account,
|
|
||||||
animate,
|
|
||||||
className,
|
|
||||||
inline,
|
|
||||||
size,
|
|
||||||
} = this.props;
|
|
||||||
const { hovering } = this.state;
|
|
||||||
|
|
||||||
const style = {
|
|
||||||
...this.props.style,
|
|
||||||
width: `${size}px`,
|
|
||||||
height: `${size}px`,
|
|
||||||
backgroundSize: `${size}px ${size}px`,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (account) {
|
|
||||||
const src = account.get('avatar');
|
|
||||||
const staticSrc = account.get('avatar_static');
|
|
||||||
|
|
||||||
if (hovering || animate) {
|
|
||||||
style.backgroundImage = `url(${src})`;
|
|
||||||
} else {
|
|
||||||
style.backgroundImage = `url(${staticSrc})`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
className={classNames('account__avatar', { 'account__avatar-inline': inline }, className)}
|
|
||||||
onMouseEnter={this.handleMouseEnter}
|
|
||||||
onMouseLeave={this.handleMouseLeave}
|
|
||||||
style={style}
|
|
||||||
data-avatar-of={account && `@${account.get('acct')}`}
|
|
||||||
role='img'
|
|
||||||
aria-label={account?.get('acct')}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
48
app/javascript/flavours/glitch/components/avatar.tsx
Normal file
48
app/javascript/flavours/glitch/components/avatar.tsx
Normal file
|
@ -0,0 +1,48 @@
|
||||||
|
import * as React from 'react';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { autoPlayGif } from 'flavours/glitch/initial_state';
|
||||||
|
import { useHovering } from 'hooks/useHovering';
|
||||||
|
import type { Account } from 'types/resources';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
account: Account | undefined;
|
||||||
|
className?: string;
|
||||||
|
size: number;
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
inline?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Avatar: React.FC<Props> = ({
|
||||||
|
account,
|
||||||
|
className,
|
||||||
|
size = 20,
|
||||||
|
inline = false,
|
||||||
|
style: styleFromParent,
|
||||||
|
}) => {
|
||||||
|
const { hovering, handleMouseEnter, handleMouseLeave } = useHovering(autoPlayGif);
|
||||||
|
|
||||||
|
const style = {
|
||||||
|
...styleFromParent,
|
||||||
|
width: `${size}px`,
|
||||||
|
height: `${size}px`,
|
||||||
|
backgroundSize: `${size}px ${size}px`,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (account) {
|
||||||
|
style.backgroundImage = `url(${account.get(hovering ? 'avatar' : 'avatar_static')})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames('account__avatar', { 'account__avatar-inline': inline }, className)}
|
||||||
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseLeave={handleMouseLeave}
|
||||||
|
style={style}
|
||||||
|
data-avatar-of={account && `@${account.get('acct')}`}
|
||||||
|
role='img'
|
||||||
|
aria-label={account?.get('acct')}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Avatar;
|
|
@ -44,6 +44,7 @@ function Blurhash({
|
||||||
const ctx = canvas.getContext('2d');
|
const ctx = canvas.getContext('2d');
|
||||||
const imageData = new ImageData(pixels, width, height);
|
const imageData = new ImageData(pixels, width, height);
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
ctx.putImageData(imageData, 0, 0);
|
ctx.putImageData(imageData, 0, 0);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Blurhash decoding failure', { err, hash });
|
console.error('Blurhash decoding failure', { err, hash });
|
||||||
|
|
|
@ -50,12 +50,14 @@ export const accountsCountRenderer = (displayNumber, pluralReady) => (
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
export const ImmutableHashtag = ({ hashtag }) => (
|
export const ImmutableHashtag = ({ hashtag }) => (
|
||||||
<Hashtag
|
<Hashtag
|
||||||
name={hashtag.get('name')}
|
name={hashtag.get('name')}
|
||||||
href={hashtag.get('url')}
|
href={hashtag.get('url')}
|
||||||
to={`/tags/${hashtag.get('name')}`}
|
to={`/tags/${hashtag.get('name')}`}
|
||||||
people={hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1}
|
people={hashtag.getIn(['history', 0, 'accounts']) * 1 + hashtag.getIn(['history', 1, 'accounts']) * 1}
|
||||||
|
// @ts-expect-error
|
||||||
history={hashtag.get('history').reverse().map((day) => day.get('uses')).toArray()}
|
history={hashtag.get('history').reverse().map((day) => day.get('uses')).toArray()}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -64,6 +66,7 @@ ImmutableHashtag.propTypes = {
|
||||||
hashtag: ImmutablePropTypes.map.isRequired,
|
hashtag: ImmutablePropTypes.map.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
const Hashtag = ({ name, href, to, people, uses, history, className, description, withGraph }) => (
|
const Hashtag = ({ name, href, to, people, uses, history, className, description, withGraph }) => (
|
||||||
<div className={classNames('trends__item', className)}>
|
<div className={classNames('trends__item', className)}>
|
||||||
<div className='trends__item__name'>
|
<div className='trends__item__name'>
|
||||||
|
|
|
@ -9,7 +9,7 @@ const emojis = {};
|
||||||
// decompress
|
// decompress
|
||||||
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
|
Object.keys(shortCodesToEmojiData).forEach((shortCode) => {
|
||||||
let [
|
let [
|
||||||
filenameData, // eslint-disable-line no-unused-vars
|
filenameData, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
searchData,
|
searchData,
|
||||||
] = shortCodesToEmojiData[shortCode];
|
] = shortCodesToEmojiData[shortCode];
|
||||||
let [
|
let [
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
|
|
||||||
const [
|
const [
|
||||||
shortCodesToEmojiData,
|
shortCodesToEmojiData,
|
||||||
skins, // eslint-disable-line no-unused-vars
|
skins, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
categories, // eslint-disable-line no-unused-vars
|
categories, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
short_names, // eslint-disable-line no-unused-vars
|
short_names, // eslint-disable-line @typescript-eslint/no-unused-vars
|
||||||
emojisWithoutShortCodes,
|
emojisWithoutShortCodes,
|
||||||
] = require('./emoji_compressed');
|
] = require('./emoji_compressed');
|
||||||
const { unicodeToFilename } = require('./unicode_to_filename');
|
const { unicodeToFilename } = require('./unicode_to_filename');
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
* @property {boolean} activity_api_enabled
|
* @property {boolean} activity_api_enabled
|
||||||
* @property {string} admin
|
* @property {string} admin
|
||||||
* @property {boolean=} boost_modal
|
* @property {boolean=} boost_modal
|
||||||
|
* @property {boolean=} favourite_modal
|
||||||
* @property {boolean} crop_images
|
* @property {boolean} crop_images
|
||||||
* @property {boolean=} delete_modal
|
* @property {boolean=} delete_modal
|
||||||
* @property {boolean=} disable_swiping
|
* @property {boolean=} disable_swiping
|
||||||
|
@ -81,7 +82,9 @@
|
||||||
* @property {boolean=} use_pending_items
|
* @property {boolean=} use_pending_items
|
||||||
* @property {string} version
|
* @property {string} version
|
||||||
* @property {boolean} translation_enabled
|
* @property {boolean} translation_enabled
|
||||||
* @property {object} local_settings
|
* @property {string} status_page_url
|
||||||
|
* @property {boolean} system_emoji_font
|
||||||
|
* @property {string} default_content_type
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -89,6 +92,9 @@
|
||||||
* @property {Record<string, Account>} accounts
|
* @property {Record<string, Account>} accounts
|
||||||
* @property {InitialStateLanguage[]} languages
|
* @property {InitialStateLanguage[]} languages
|
||||||
* @property {InitialStateMeta} meta
|
* @property {InitialStateMeta} meta
|
||||||
|
* @property {object} local_settings
|
||||||
|
* @property {number} max_toot_chars
|
||||||
|
* @property {number} poll_limits
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const element = document.getElementById('initial-state');
|
const element = document.getElementById('initial-state');
|
||||||
|
@ -98,6 +104,7 @@ const initialState = element?.textContent && JSON.parse(element.textContent);
|
||||||
// Glitch-soc-specific “local settings”
|
// Glitch-soc-specific “local settings”
|
||||||
if (initialState) {
|
if (initialState) {
|
||||||
try {
|
try {
|
||||||
|
// @ts-expect-error
|
||||||
initialState.local_settings = JSON.parse(localStorage.getItem('mastodon-settings'));
|
initialState.local_settings = JSON.parse(localStorage.getItem('mastodon-settings'));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
initialState.local_settings = {};
|
initialState.local_settings = {};
|
||||||
|
|
|
@ -36,6 +36,7 @@ export const layoutFromWindow = (layout_local_setting) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
const iOS = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
||||||
|
|
||||||
const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
|
const listenerOptions = supportsPassiveEvents ? { passive: true } : false;
|
||||||
|
@ -45,7 +46,7 @@ let userTouching = false;
|
||||||
const touchListener = () => {
|
const touchListener = () => {
|
||||||
userTouching = true;
|
userTouching = true;
|
||||||
|
|
||||||
window.removeEventListener('touchstart', touchListener, listenerOptions);
|
window.removeEventListener('touchstart', touchListener);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener('touchstart', touchListener, listenerOptions);
|
window.addEventListener('touchstart', touchListener, listenerOptions);
|
||||||
|
|
|
@ -59,6 +59,7 @@ const subscribe = ({ channelName, params, onConnect }) => {
|
||||||
subscriptionCounters[key] = subscriptionCounters[key] || 0;
|
subscriptionCounters[key] = subscriptionCounters[key] || 0;
|
||||||
|
|
||||||
if (subscriptionCounters[key] === 0) {
|
if (subscriptionCounters[key] === 0) {
|
||||||
|
// @ts-expect-error
|
||||||
sharedConnection.send(JSON.stringify({ type: 'subscribe', stream: channelName, ...params }));
|
sharedConnection.send(JSON.stringify({ type: 'subscribe', stream: channelName, ...params }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +75,9 @@ const unsubscribe = ({ channelName, params, onDisconnect }) => {
|
||||||
|
|
||||||
subscriptionCounters[key] = subscriptionCounters[key] || 1;
|
subscriptionCounters[key] = subscriptionCounters[key] || 1;
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
if (subscriptionCounters[key] === 1 && sharedConnection.readyState === WebSocketClient.OPEN) {
|
if (subscriptionCounters[key] === 1 && sharedConnection.readyState === WebSocketClient.OPEN) {
|
||||||
|
// @ts-expect-error
|
||||||
sharedConnection.send(JSON.stringify({ type: 'unsubscribe', stream: channelName, ...params }));
|
sharedConnection.send(JSON.stringify({ type: 'unsubscribe', stream: channelName, ...params }));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,6 +90,7 @@ const sharedCallbacks = {
|
||||||
subscriptions.forEach(subscription => subscribe(subscription));
|
subscriptions.forEach(subscription => subscribe(subscription));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
received (data) {
|
received (data) {
|
||||||
const { stream } = data;
|
const { stream } = data;
|
||||||
|
|
||||||
|
@ -138,6 +142,7 @@ const channelNameWithInlineParams = (channelName, params) => {
|
||||||
* @param {function(Function, Function): { onConnect: (function(): void), onReceive: (function(StreamEvent): void), onDisconnect: (function(): void) }} callbacks
|
* @param {function(Function, Function): { onConnect: (function(): void), onReceive: (function(StreamEvent): void), onDisconnect: (function(): void) }} callbacks
|
||||||
* @return {function(): void}
|
* @return {function(): void}
|
||||||
*/
|
*/
|
||||||
|
// @ts-expect-error
|
||||||
export const connectStream = (channelName, params, callbacks) => (dispatch, getState) => {
|
export const connectStream = (channelName, params, callbacks) => (dispatch, getState) => {
|
||||||
const streamingAPIBaseURL = getState().getIn(['meta', 'streaming_api_base_url']);
|
const streamingAPIBaseURL = getState().getIn(['meta', 'streaming_api_base_url']);
|
||||||
const accessToken = getState().getIn(['meta', 'access_token']);
|
const accessToken = getState().getIn(['meta', 'access_token']);
|
||||||
|
@ -227,14 +232,19 @@ const handleEventSourceMessage = (e, received) => {
|
||||||
const createConnection = (streamingAPIBaseURL, accessToken, channelName, { connected, received, disconnected, reconnected }) => {
|
const createConnection = (streamingAPIBaseURL, accessToken, channelName, { connected, received, disconnected, reconnected }) => {
|
||||||
const params = channelName.split('&');
|
const params = channelName.split('&');
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
channelName = params.shift();
|
channelName = params.shift();
|
||||||
|
|
||||||
if (streamingAPIBaseURL.startsWith('ws')) {
|
if (streamingAPIBaseURL.startsWith('ws')) {
|
||||||
|
// @ts-expect-error
|
||||||
const ws = new WebSocketClient(`${streamingAPIBaseURL}/api/v1/streaming/?${params.join('&')}`, accessToken);
|
const ws = new WebSocketClient(`${streamingAPIBaseURL}/api/v1/streaming/?${params.join('&')}`, accessToken);
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
ws.onopen = connected;
|
ws.onopen = connected;
|
||||||
ws.onmessage = e => received(JSON.parse(e.data));
|
ws.onmessage = e => received(JSON.parse(e.data));
|
||||||
|
// @ts-expect-error
|
||||||
ws.onclose = disconnected;
|
ws.onclose = disconnected;
|
||||||
|
// @ts-expect-error
|
||||||
ws.onreconnect = reconnected;
|
ws.onreconnect = reconnected;
|
||||||
|
|
||||||
return ws;
|
return ws;
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
export default function uuid(a) {
|
|
||||||
return a ? (a^Math.random() * 16 >> a / 4).toString(16) : ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, uuid);
|
|
||||||
}
|
|
3
app/javascript/flavours/glitch/uuid.ts
Normal file
3
app/javascript/flavours/glitch/uuid.ts
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
export default function uuid(a?: string): string {
|
||||||
|
return a ? ((a as any as number) ^ Math.random() * 16 >> (a as any as number) / 4).toString(16) : ('' + 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);
|
||||||
|
}
|
|
@ -87,6 +87,7 @@
|
||||||
* @property {Record<string, Account>} accounts
|
* @property {Record<string, Account>} accounts
|
||||||
* @property {InitialStateLanguage[]} languages
|
* @property {InitialStateLanguage[]} languages
|
||||||
* @property {InitialStateMeta} meta
|
* @property {InitialStateMeta} meta
|
||||||
|
* @property {number} max_toot_chars
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const element = document.getElementById('initial-state');
|
const element = document.getElementById('initial-state');
|
||||||
|
|
|
@ -7,7 +7,15 @@
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"skipLibCheck": true
|
"skipLibCheck": true,
|
||||||
|
"baseUrl": ".",
|
||||||
|
"paths": {
|
||||||
|
"*": ["app/javascript/*"]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"include": ["app/javascript/mastodon", "app/javascript/packs"]
|
"include": [
|
||||||
|
"app/javascript/mastodon",
|
||||||
|
"app/javascript/flavours/glitch",
|
||||||
|
"app/javascript/packs"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue