[Glitch] Add stricter ESLint rules for Typescript files
Port 5eeb40bdbe
to glitch-soc
Signed-off-by: Claire <claire.github-309c@sitedethib.com>
pull/62/head
parent
e8fc445e14
commit
e6a7cfd12e
|
@ -319,7 +319,7 @@ module.exports = {
|
||||||
},
|
},
|
||||||
// Internal packages
|
// Internal packages
|
||||||
{
|
{
|
||||||
pattern: '{mastodon/**}',
|
pattern: '{mastodon/**,flavours/glitch-soc/**}',
|
||||||
group: 'internal',
|
group: 'internal',
|
||||||
position: 'after',
|
position: 'after',
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
import { createAction } from '@reduxjs/toolkit';
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import type { LayoutType } from '../is_mobile';
|
import type { LayoutType } from '../is_mobile';
|
||||||
|
|
||||||
type ChangeLayoutPayload = {
|
interface ChangeLayoutPayload {
|
||||||
layout: LayoutType;
|
layout: LayoutType;
|
||||||
};
|
}
|
||||||
export const changeLayout =
|
export const changeLayout =
|
||||||
createAction<ChangeLayoutPayload>('APP_LAYOUT_CHANGE');
|
createAction<ChangeLayoutPayload>('APP_LAYOUT_CHANGE');
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import api from '../api';
|
import api from '../api';
|
||||||
import { importFetchedStatuses } from './importer';
|
import { importFetchedStatuses } from './importer';
|
||||||
|
|
||||||
|
import { me } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
export const PINNED_STATUSES_FETCH_REQUEST = 'PINNED_STATUSES_FETCH_REQUEST';
|
export const PINNED_STATUSES_FETCH_REQUEST = 'PINNED_STATUSES_FETCH_REQUEST';
|
||||||
export const PINNED_STATUSES_FETCH_SUCCESS = 'PINNED_STATUSES_FETCH_SUCCESS';
|
export const PINNED_STATUSES_FETCH_SUCCESS = 'PINNED_STATUSES_FETCH_SUCCESS';
|
||||||
export const PINNED_STATUSES_FETCH_FAIL = 'PINNED_STATUSES_FETCH_FAIL';
|
export const PINNED_STATUSES_FETCH_FAIL = 'PINNED_STATUSES_FETCH_FAIL';
|
||||||
|
|
||||||
import { me } from 'flavours/glitch/initial_state';
|
|
||||||
|
|
||||||
export function fetchPinnedStatuses() {
|
export function fetchPinnedStatuses() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch, getState) => {
|
||||||
dispatch(fetchPinnedStatusesRequest());
|
dispatch(fetchPinnedStatusesRequest());
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import ShortNumber from './short_number';
|
|
||||||
import { TransitionMotion, spring } from 'react-motion';
|
import { TransitionMotion, spring } from 'react-motion';
|
||||||
|
|
||||||
import { reduceMotion } from '../initial_state';
|
import { reduceMotion } from '../initial_state';
|
||||||
|
|
||||||
|
import ShortNumber from './short_number';
|
||||||
|
|
||||||
const obfuscatedCount = (count: number) => {
|
const obfuscatedCount = (count: number) => {
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -13,10 +16,10 @@ const obfuscatedCount = (count: number) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
value: number;
|
value: number;
|
||||||
obfuscate?: boolean;
|
obfuscate?: boolean;
|
||||||
};
|
}
|
||||||
export const AnimatedNumber: React.FC<Props> = ({ value, obfuscate }) => {
|
export const AnimatedNumber: React.FC<Props> = ({ value, obfuscate }) => {
|
||||||
const [previousValue, setPreviousValue] = useState(value);
|
const [previousValue, setPreviousValue] = useState(value);
|
||||||
const [direction, setDirection] = useState<1 | -1>(1);
|
const [direction, setDirection] = useState<1 | -1>(1);
|
||||||
|
@ -64,7 +67,11 @@ export const AnimatedNumber: React.FC<Props> = ({ value, obfuscate }) => {
|
||||||
transform: `translateY(${style.y * 100}%)`,
|
transform: `translateY(${style.y * 100}%)`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{obfuscate ? obfuscatedCount(data) : <ShortNumber value={data} />}
|
{obfuscate ? (
|
||||||
|
obfuscatedCount(data as number)
|
||||||
|
) : (
|
||||||
|
<ShortNumber value={data as number} />
|
||||||
|
)}
|
||||||
</span>
|
</span>
|
||||||
))}
|
))}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,16 +1,18 @@
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { autoPlayGif } from 'flavours/glitch/initial_state';
|
|
||||||
import { useHovering } from 'flavours/glitch/hooks/useHovering';
|
import { useHovering } from 'flavours/glitch/hooks/useHovering';
|
||||||
|
import { autoPlayGif } from 'flavours/glitch/initial_state';
|
||||||
import type { Account } from 'flavours/glitch/types/resources';
|
import type { Account } from 'flavours/glitch/types/resources';
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
account: Account | undefined;
|
account: Account | undefined;
|
||||||
className?: string;
|
className?: string;
|
||||||
size: number;
|
size: number;
|
||||||
style?: React.CSSProperties;
|
style?: React.CSSProperties;
|
||||||
inline?: boolean;
|
inline?: boolean;
|
||||||
};
|
}
|
||||||
|
|
||||||
export const Avatar: React.FC<Props> = ({
|
export const Avatar: React.FC<Props> = ({
|
||||||
account,
|
account,
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { decode } from 'blurhash';
|
|
||||||
import React, { useRef, useEffect } from 'react';
|
import React, { useRef, useEffect } from 'react';
|
||||||
|
|
||||||
type Props = {
|
import { decode } from 'blurhash';
|
||||||
|
|
||||||
|
interface Props extends React.HTMLAttributes<HTMLCanvasElement> {
|
||||||
hash: string;
|
hash: string;
|
||||||
width?: number;
|
width?: number;
|
||||||
height?: number;
|
height?: number;
|
||||||
dummy?: boolean; // Whether dummy mode is enabled. If enabled, nothing is rendered and canvas left untouched
|
dummy?: boolean; // Whether dummy mode is enabled. If enabled, nothing is rendered and canvas left untouched
|
||||||
children?: never;
|
children?: never;
|
||||||
[key: string]: any;
|
}
|
||||||
};
|
|
||||||
const Blurhash: React.FC<Props> = ({
|
const Blurhash: React.FC<Props> = ({
|
||||||
hash,
|
hash,
|
||||||
width = 32,
|
width = 32,
|
||||||
|
@ -21,6 +21,7 @@ const Blurhash: React.FC<Props> = ({
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
const canvas = canvasRef.current!;
|
const canvas = canvasRef.current!;
|
||||||
|
|
||||||
// eslint-disable-next-line no-self-assign
|
// eslint-disable-next-line no-self-assign
|
||||||
canvas.width = canvas.width; // resets canvas
|
canvas.width = canvas.width; // resets canvas
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
|
||||||
|
import type { InjectedIntl } from 'react-intl';
|
||||||
|
import { defineMessages, injectIntl } from 'react-intl';
|
||||||
|
|
||||||
import { IconButton } from './icon_button';
|
import { IconButton } from './icon_button';
|
||||||
import { InjectedIntl, defineMessages, injectIntl } from 'react-intl';
|
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
unblockDomain: {
|
unblockDomain: {
|
||||||
|
@ -9,11 +12,11 @@ const messages = defineMessages({
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
domain: string;
|
domain: string;
|
||||||
onUnblockDomain: (domain: string) => void;
|
onUnblockDomain: (domain: string) => void;
|
||||||
intl: InjectedIntl;
|
intl: InjectedIntl;
|
||||||
};
|
}
|
||||||
const _Domain: React.FC<Props> = ({ domain, onUnblockDomain, intl }) => {
|
const _Domain: React.FC<Props> = ({ domain, onUnblockDomain, intl }) => {
|
||||||
const handleDomainUnblock = useCallback(() => {
|
const handleDomainUnblock = useCallback(() => {
|
||||||
onUnblockDomain(domain);
|
onUnblockDomain(domain);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
src: string;
|
src: string;
|
||||||
key: string;
|
key: string;
|
||||||
alt?: string;
|
alt?: string;
|
||||||
|
@ -8,7 +8,7 @@ type Props = {
|
||||||
width: number;
|
width: number;
|
||||||
height: number;
|
height: number;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
};
|
}
|
||||||
|
|
||||||
export const GIFV: React.FC<Props> = ({
|
export const GIFV: React.FC<Props> = ({
|
||||||
src,
|
src,
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
type Props = {
|
interface Props extends React.HTMLAttributes<HTMLImageElement> {
|
||||||
id: string;
|
id: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
fixedWidth?: boolean;
|
fixedWidth?: boolean;
|
||||||
children?: never;
|
children?: never;
|
||||||
[key: string]: any;
|
}
|
||||||
};
|
|
||||||
export const Icon: React.FC<Props> = ({
|
export const Icon: React.FC<Props> = ({
|
||||||
id,
|
id,
|
||||||
className,
|
className,
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import classNames from 'classnames';
|
|
||||||
import { Icon } from './icon';
|
|
||||||
import { AnimatedNumber } from './animated_number';
|
|
||||||
|
|
||||||
type Props = {
|
import classNames from 'classnames';
|
||||||
|
|
||||||
|
import { AnimatedNumber } from './animated_number';
|
||||||
|
import { Icon } from './icon';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
className?: string;
|
className?: string;
|
||||||
title: string;
|
title: string;
|
||||||
icon: string;
|
icon: string;
|
||||||
|
@ -26,11 +28,11 @@ type Props = {
|
||||||
obfuscateCount?: boolean;
|
obfuscateCount?: boolean;
|
||||||
href?: string;
|
href?: string;
|
||||||
ariaHidden: boolean;
|
ariaHidden: boolean;
|
||||||
};
|
}
|
||||||
type States = {
|
interface States {
|
||||||
activate: boolean;
|
activate: boolean;
|
||||||
deactivate: boolean;
|
deactivate: boolean;
|
||||||
};
|
}
|
||||||
export class IconButton extends React.PureComponent<Props, States> {
|
export class IconButton extends React.PureComponent<Props, States> {
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
size: 18,
|
size: 18,
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { Icon } from './icon';
|
import { Icon } from './icon';
|
||||||
|
|
||||||
const formatNumber = (num: number): number | string => (num > 40 ? '40+' : num);
|
const formatNumber = (num: number): number | string => (num > 40 ? '40+' : num);
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
id: string;
|
id: string;
|
||||||
count: number;
|
count: number;
|
||||||
issueBadge: boolean;
|
issueBadge: boolean;
|
||||||
className: string;
|
className: string;
|
||||||
};
|
}
|
||||||
export const IconWithBadge: React.FC<Props> = ({
|
export const IconWithBadge: React.FC<Props> = ({
|
||||||
id,
|
id,
|
||||||
count,
|
count,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
export const NotSignedInIndicator: React.FC = () => (
|
export const NotSignedInIndicator: React.FC = () => (
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
value: string;
|
value: string;
|
||||||
checked: boolean;
|
checked: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
||||||
label: React.ReactNode;
|
label: React.ReactNode;
|
||||||
};
|
}
|
||||||
|
|
||||||
export const RadioButton: React.FC<Props> = ({
|
export const RadioButton: React.FC<Props> = ({
|
||||||
name,
|
name,
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { injectIntl, defineMessages, InjectedIntl } from 'react-intl';
|
|
||||||
|
import type { InjectedIntl } from 'react-intl';
|
||||||
|
import { injectIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
today: { id: 'relative_time.today', defaultMessage: 'today' },
|
today: { id: 'relative_time.today', defaultMessage: 'today' },
|
||||||
|
@ -187,16 +189,16 @@ const timeRemainingString = (
|
||||||
return relativeTime;
|
return relativeTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Props = {
|
interface Props {
|
||||||
intl: InjectedIntl;
|
intl: InjectedIntl;
|
||||||
timestamp: string;
|
timestamp: string;
|
||||||
year: number;
|
year: number;
|
||||||
futureDate?: boolean;
|
futureDate?: boolean;
|
||||||
short?: boolean;
|
short?: boolean;
|
||||||
};
|
}
|
||||||
type States = {
|
interface States {
|
||||||
now: number;
|
now: number;
|
||||||
};
|
}
|
||||||
class RelativeTimestamp extends React.Component<Props, States> {
|
class RelativeTimestamp extends React.Component<Props, States> {
|
||||||
state = {
|
state = {
|
||||||
now: this.props.intl.now(),
|
now: this.props.intl.now(),
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import { Blurhash } from './blurhash';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
|
||||||
type Props = {
|
import { Blurhash } from './blurhash';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
src: string;
|
src: string;
|
||||||
srcSet?: string;
|
srcSet?: string;
|
||||||
blurhash?: string;
|
blurhash?: string;
|
||||||
className?: string;
|
className?: string;
|
||||||
};
|
}
|
||||||
|
|
||||||
export const ServerHeroImage: React.FC<Props> = ({
|
export const ServerHeroImage: React.FC<Props> = ({
|
||||||
src,
|
src,
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { connect } from 'react-redux';
|
||||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { lookupAccount, fetchAccount } from 'flavours/glitch/actions/accounts';
|
import { lookupAccount, fetchAccount } from 'flavours/glitch/actions/accounts';
|
||||||
import { expandAccountFeaturedTimeline, expandAccountTimeline } from 'flavours/glitch/actions/timelines';
|
import { expandAccountFeaturedTimeline, expandAccountTimeline } from '../../actions/timelines';
|
||||||
import StatusList from '../../components/status_list';
|
import StatusList from '../../components/status_list';
|
||||||
import LoadingIndicator from '../../components/loading_indicator';
|
import LoadingIndicator from '../../components/loading_indicator';
|
||||||
import Column from '../ui/components/column';
|
import Column from '../ui/components/column';
|
||||||
|
|
|
@ -18,7 +18,7 @@ import {
|
||||||
BookmarkedStatuses,
|
BookmarkedStatuses,
|
||||||
ListTimeline,
|
ListTimeline,
|
||||||
Directory,
|
Directory,
|
||||||
} from '../../ui/util/async-components';
|
} from '../util/async-components';
|
||||||
import ComposePanel from './compose_panel';
|
import ComposePanel from './compose_panel';
|
||||||
import NavigationPanel from './navigation_panel';
|
import NavigationPanel from './navigation_panel';
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
||||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import { changeUploadCompose, uploadThumbnail, onChangeMediaDescription, onChangeMediaFocus } from 'flavours/glitch/actions/compose';
|
import { changeUploadCompose, uploadThumbnail, onChangeMediaDescription, onChangeMediaFocus } from '../../../actions/compose';
|
||||||
import Video, { getPointerPosition } from 'flavours/glitch/features/video';
|
import Video, { getPointerPosition } from 'flavours/glitch/features/video';
|
||||||
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
|
||||||
import { IconButton } from 'flavours/glitch/components/icon_button';
|
import { IconButton } from 'flavours/glitch/components/icon_button';
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import Motion from '../../ui/util/optional_motion';
|
import Motion from '../util/optional_motion';
|
||||||
import spring from 'react-motion/lib/spring';
|
import spring from 'react-motion/lib/spring';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ import Header from './components/header';
|
||||||
|
|
||||||
// Dummy import, to make sure that <Status /> ends up in the application bundle.
|
// Dummy import, to make sure that <Status /> ends up in the application bundle.
|
||||||
// Without this it ends up in ~8 very commonly used bundles.
|
// Without this it ends up in ~8 very commonly used bundles.
|
||||||
import '../../../glitch/components/status';
|
import "../../components/status";
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
beforeUnload: { id: 'ui.beforeunload', defaultMessage: 'Your draft will be lost if you leave Mastodon.' },
|
beforeUnload: { id: 'ui.beforeunload', defaultMessage: 'Your draft will be lost if you leave Mastodon.' },
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { supportsPassiveEvents } from 'detect-passive-events';
|
import { supportsPassiveEvents } from 'detect-passive-events';
|
||||||
|
|
||||||
import { forceSingleColumn } from 'flavours/glitch/initial_state';
|
import { forceSingleColumn } from 'flavours/glitch/initial_state';
|
||||||
|
|
||||||
const LAYOUT_BREAKPOINT = 630;
|
const LAYOUT_BREAKPOINT = 630;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import 'packs/public-path';
|
import 'packs/public-path';
|
||||||
import { start } from '@rails/ujs';
|
import { start } from '@rails/ujs';
|
||||||
|
|
||||||
start();
|
|
||||||
|
|
||||||
import 'flavours/glitch/styles/index.scss';
|
import 'flavours/glitch/styles/index.scss';
|
||||||
|
|
||||||
|
start();
|
||||||
|
|
||||||
// This ensures that webpack compiles our images.
|
// This ensures that webpack compiles our images.
|
||||||
require.context('../images', true);
|
require.context('../images', true);
|
||||||
|
|
|
@ -10,8 +10,13 @@ if (!HTMLCanvasElement.prototype.toBlob) {
|
||||||
const BASE64_MARKER = ';base64,';
|
const BASE64_MARKER = ';base64,';
|
||||||
|
|
||||||
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
|
Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
|
||||||
value(callback: BlobCallback, type = 'image/png', quality: any) {
|
value: function (
|
||||||
const dataURL = this.toDataURL(type, quality);
|
this: HTMLCanvasElement,
|
||||||
|
callback: BlobCallback,
|
||||||
|
type = 'image/png',
|
||||||
|
quality: unknown
|
||||||
|
) {
|
||||||
|
const dataURL: string = this.toDataURL(type, quality);
|
||||||
let data;
|
let data;
|
||||||
|
|
||||||
if (dataURL.indexOf(BASE64_MARKER) >= 0) {
|
if (dataURL.indexOf(BASE64_MARKER) >= 0) {
|
||||||
|
|
|
@ -1,48 +1,49 @@
|
||||||
import { combineReducers } from 'redux-immutable';
|
|
||||||
import dropdown_menu from './dropdown_menu';
|
|
||||||
import timelines from './timelines';
|
|
||||||
import meta from './meta';
|
|
||||||
import alerts from './alerts';
|
|
||||||
import { loadingBarReducer } from 'react-redux-loading-bar';
|
import { loadingBarReducer } from 'react-redux-loading-bar';
|
||||||
import modal from './modal';
|
import { combineReducers } from 'redux-immutable';
|
||||||
import user_lists from './user_lists';
|
|
||||||
import domain_lists from './domain_lists';
|
import account_notes from './account_notes';
|
||||||
import accounts from './accounts';
|
import accounts from './accounts';
|
||||||
import accounts_counters from './accounts_counters';
|
import accounts_counters from './accounts_counters';
|
||||||
import statuses from './statuses';
|
import accounts_map from './accounts_map';
|
||||||
import relationships from './relationships';
|
import alerts from './alerts';
|
||||||
import settings from './settings';
|
import announcements from './announcements';
|
||||||
import local_settings from './local_settings';
|
|
||||||
import push_notifications from './push_notifications';
|
|
||||||
import status_lists from './status_lists';
|
|
||||||
import mutes from './mutes';
|
|
||||||
import blocks from './blocks';
|
import blocks from './blocks';
|
||||||
import server from './server';
|
|
||||||
import boosts from './boosts';
|
import boosts from './boosts';
|
||||||
import contexts from './contexts';
|
|
||||||
import compose from './compose';
|
import compose from './compose';
|
||||||
import search from './search';
|
import contexts from './contexts';
|
||||||
import media_attachments from './media_attachments';
|
|
||||||
import notifications from './notifications';
|
|
||||||
import height_cache from './height_cache';
|
|
||||||
import custom_emojis from './custom_emojis';
|
|
||||||
import lists from './lists';
|
|
||||||
import listEditor from './list_editor';
|
|
||||||
import listAdder from './list_adder';
|
|
||||||
import filters from './filters';
|
|
||||||
import conversations from './conversations';
|
import conversations from './conversations';
|
||||||
import suggestions from './suggestions';
|
import custom_emojis from './custom_emojis';
|
||||||
|
import domain_lists from './domain_lists';
|
||||||
|
import dropdown_menu from './dropdown_menu';
|
||||||
|
import filters from './filters';
|
||||||
|
import followed_tags from './followed_tags';
|
||||||
|
import height_cache from './height_cache';
|
||||||
|
import history from './history';
|
||||||
|
import listAdder from './list_adder';
|
||||||
|
import listEditor from './list_editor';
|
||||||
|
import lists from './lists';
|
||||||
|
import local_settings from './local_settings';
|
||||||
|
import markers from './markers';
|
||||||
|
import media_attachments from './media_attachments';
|
||||||
|
import meta from './meta';
|
||||||
|
import modal from './modal';
|
||||||
|
import mutes from './mutes';
|
||||||
|
import notifications from './notifications';
|
||||||
|
import picture_in_picture from './picture_in_picture';
|
||||||
import pinnedAccountsEditor from './pinned_accounts_editor';
|
import pinnedAccountsEditor from './pinned_accounts_editor';
|
||||||
import polls from './polls';
|
import polls from './polls';
|
||||||
import trends from './trends';
|
import push_notifications from './push_notifications';
|
||||||
import announcements from './announcements';
|
import relationships from './relationships';
|
||||||
import markers from './markers';
|
import search from './search';
|
||||||
import account_notes from './account_notes';
|
import server from './server';
|
||||||
import picture_in_picture from './picture_in_picture';
|
import settings from './settings';
|
||||||
import accounts_map from './accounts_map';
|
import status_lists from './status_lists';
|
||||||
import history from './history';
|
import statuses from './statuses';
|
||||||
|
import suggestions from './suggestions';
|
||||||
import tags from './tags';
|
import tags from './tags';
|
||||||
import followed_tags from './followed_tags';
|
import timelines from './timelines';
|
||||||
|
import trends from './trends';
|
||||||
|
import user_lists from './user_lists';
|
||||||
|
|
||||||
const reducers = {
|
const reducers = {
|
||||||
announcements,
|
announcements,
|
||||||
|
|
|
@ -2,13 +2,13 @@ import {
|
||||||
MARKERS_SUBMIT_SUCCESS,
|
MARKERS_SUBMIT_SUCCESS,
|
||||||
} from '../actions/markers';
|
} from '../actions/markers';
|
||||||
|
|
||||||
|
import { Map as ImmutableMap } from 'immutable';
|
||||||
|
|
||||||
const initialState = ImmutableMap({
|
const initialState = ImmutableMap({
|
||||||
home: '0',
|
home: '0',
|
||||||
notifications: '0',
|
notifications: '0',
|
||||||
});
|
});
|
||||||
|
|
||||||
import { Map as ImmutableMap } from 'immutable';
|
|
||||||
|
|
||||||
export default function markers(state = initialState, action) {
|
export default function markers(state = initialState, action) {
|
||||||
switch(action.type) {
|
switch(action.type) {
|
||||||
case MARKERS_SUBMIT_SUCCESS:
|
case MARKERS_SUBMIT_SUCCESS:
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
|
import type { TypedUseSelectorHook } from 'react-redux';
|
||||||
|
import { useDispatch, useSelector } from 'react-redux';
|
||||||
|
|
||||||
import { configureStore } from '@reduxjs/toolkit';
|
import { configureStore } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
import { rootReducer } from '../reducers';
|
import { rootReducer } from '../reducers';
|
||||||
import { loadingBarMiddleware } from './middlewares/loading_bar';
|
|
||||||
import { errorsMiddleware } from './middlewares/errors';
|
import { errorsMiddleware } from './middlewares/errors';
|
||||||
|
import { loadingBarMiddleware } from './middlewares/loading_bar';
|
||||||
import { soundsMiddleware } from './middlewares/sounds';
|
import { soundsMiddleware } from './middlewares/sounds';
|
||||||
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
|
|
||||||
|
|
||||||
export const store = configureStore({
|
export const store = configureStore({
|
||||||
reducer: rootReducer,
|
reducer: rootReducer,
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
import { Middleware } from 'redux';
|
import type { AnyAction, Middleware } from 'redux';
|
||||||
|
|
||||||
import { showAlertForError } from 'flavours/glitch/actions/alerts';
|
import { showAlertForError } from 'flavours/glitch/actions/alerts';
|
||||||
import { RootState } from '..';
|
|
||||||
|
import type { RootState } from '..';
|
||||||
|
|
||||||
const defaultFailSuffix = 'FAIL';
|
const defaultFailSuffix = 'FAIL';
|
||||||
|
|
||||||
export const errorsMiddleware: Middleware<Record<string, never>, RootState> =
|
export const errorsMiddleware: Middleware<Record<string, never>, RootState> =
|
||||||
({ dispatch }) =>
|
({ dispatch }) =>
|
||||||
(next) =>
|
(next) =>
|
||||||
(action) => {
|
(action: AnyAction & { skipAlert?: boolean; skipNotFound?: boolean }) => {
|
||||||
if (action.type && !action.skipAlert) {
|
if (action.type && !action.skipAlert) {
|
||||||
const isFail = new RegExp(`${defaultFailSuffix}$`, 'g');
|
const isFail = new RegExp(`${defaultFailSuffix}$`, 'g');
|
||||||
|
|
||||||
if (action.type.match(isFail)) {
|
if (typeof action.type === 'string' && action.type.match(isFail)) {
|
||||||
dispatch(showAlertForError(action.error, action.skipNotFound));
|
dispatch(showAlertForError(action.error, action.skipNotFound));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { showLoading, hideLoading } from 'react-redux-loading-bar';
|
import { showLoading, hideLoading } from 'react-redux-loading-bar';
|
||||||
import { Middleware } from 'redux';
|
import type { AnyAction, Middleware } from 'redux';
|
||||||
import { RootState } from '..';
|
|
||||||
|
import type { RootState } from '..';
|
||||||
|
|
||||||
interface Config {
|
interface Config {
|
||||||
promiseTypeSuffixes?: string[];
|
promiseTypeSuffixes?: string[];
|
||||||
|
@ -19,7 +20,7 @@ export const loadingBarMiddleware = (
|
||||||
|
|
||||||
return ({ dispatch }) =>
|
return ({ dispatch }) =>
|
||||||
(next) =>
|
(next) =>
|
||||||
(action) => {
|
(action: AnyAction) => {
|
||||||
if (action.type && !action.skipLoading) {
|
if (action.type && !action.skipLoading) {
|
||||||
const [PENDING, FULFILLED, REJECTED] = promiseTypeSuffixes;
|
const [PENDING, FULFILLED, REJECTED] = promiseTypeSuffixes;
|
||||||
|
|
||||||
|
@ -27,6 +28,7 @@ export const loadingBarMiddleware = (
|
||||||
const isFulfilled = new RegExp(`${FULFILLED}$`, 'g');
|
const isFulfilled = new RegExp(`${FULFILLED}$`, 'g');
|
||||||
const isRejected = new RegExp(`${REJECTED}$`, 'g');
|
const isRejected = new RegExp(`${REJECTED}$`, 'g');
|
||||||
|
|
||||||
|
if (typeof action.type === 'string') {
|
||||||
if (action.type.match(isPending)) {
|
if (action.type.match(isPending)) {
|
||||||
dispatch(showLoading());
|
dispatch(showLoading());
|
||||||
} else if (
|
} else if (
|
||||||
|
@ -36,6 +38,7 @@ export const loadingBarMiddleware = (
|
||||||
dispatch(hideLoading());
|
dispatch(hideLoading());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return next(action);
|
return next(action);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import { Middleware, AnyAction } from 'redux';
|
import type { Middleware, AnyAction } from 'redux';
|
||||||
import { RootState } from '..';
|
|
||||||
|
import type { RootState } from '..';
|
||||||
|
|
||||||
interface AudioSource {
|
interface AudioSource {
|
||||||
src: string;
|
src: string;
|
||||||
|
@ -27,7 +28,7 @@ const play = (audio: HTMLAudioElement) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
audio.play();
|
void audio.play();
|
||||||
};
|
};
|
||||||
|
|
||||||
export const soundsMiddleware = (): Middleware<
|
export const soundsMiddleware = (): Middleware<
|
||||||
|
@ -47,7 +48,9 @@ export const soundsMiddleware = (): Middleware<
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
return () => (next) => (action: AnyAction) => {
|
return () =>
|
||||||
|
(next) =>
|
||||||
|
(action: AnyAction & { meta?: { sound?: string } }) => {
|
||||||
const sound = action?.meta?.sound;
|
const sound = action?.meta?.sound;
|
||||||
|
|
||||||
if (sound && soundCache[sound]) {
|
if (sound && soundCache[sound]) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ type AccountField = Record<{
|
||||||
verified_at: string | null;
|
verified_at: string | null;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
type AccountApiResponseValues = {
|
interface AccountApiResponseValues {
|
||||||
acct: string;
|
acct: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
avatar_static: string;
|
avatar_static: string;
|
||||||
|
@ -34,7 +34,7 @@ type AccountApiResponseValues = {
|
||||||
statuses_count: number;
|
statuses_count: number;
|
||||||
url: string;
|
url: string;
|
||||||
username: string;
|
username: string;
|
||||||
};
|
}
|
||||||
|
|
||||||
type NormalizedAccountField = Record<{
|
type NormalizedAccountField = Record<{
|
||||||
name_emojified: string;
|
name_emojified: string;
|
||||||
|
@ -42,12 +42,12 @@ type NormalizedAccountField = Record<{
|
||||||
value_plain: string;
|
value_plain: string;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
type NormalizedAccountValues = {
|
interface NormalizedAccountValues {
|
||||||
display_name_html: string;
|
display_name_html: string;
|
||||||
fields: NormalizedAccountField[];
|
fields: NormalizedAccountField[];
|
||||||
note_emojified: string;
|
note_emojified: string;
|
||||||
note_plain: string;
|
note_plain: string;
|
||||||
};
|
}
|
||||||
|
|
||||||
export type Account = Record<
|
export type Account = Record<
|
||||||
AccountApiResponseValues & NormalizedAccountValues
|
AccountApiResponseValues & NormalizedAccountValues
|
||||||
|
|
|
@ -170,7 +170,7 @@ const resizeImage = (img, type = 'image/png') => new Promise((resolve, reject) =
|
||||||
.catch(reject);
|
.catch(reject);
|
||||||
});
|
});
|
||||||
|
|
||||||
export default inputFile => new Promise((resolve) => {
|
const resizeFile = (inputFile) => new Promise((resolve) => {
|
||||||
if (!inputFile.type.match(/image.*/) || inputFile.type === 'image/gif') {
|
if (!inputFile.type.match(/image.*/) || inputFile.type === 'image/gif') {
|
||||||
resolve(inputFile);
|
resolve(inputFile);
|
||||||
return;
|
return;
|
||||||
|
@ -187,3 +187,5 @@ export default inputFile => new Promise((resolve) => {
|
||||||
.catch(() => resolve(inputFile));
|
.catch(() => resolve(inputFile));
|
||||||
}).catch(() => resolve(inputFile));
|
}).catch(() => resolve(inputFile));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default resizeFile;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
export function uuid(a?: string): string {
|
export function uuid(a?: string): string {
|
||||||
return a
|
return a
|
||||||
? (
|
? (
|
||||||
(a as any as number) ^
|
(a as unknown as number) ^
|
||||||
((Math.random() * 16) >> ((a as any as number) / 4))
|
((Math.random() * 16) >> ((a as unknown as number) / 4))
|
||||||
).toString(16)
|
).toString(16)
|
||||||
: ('' + 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);
|
: // eslint-disable-next-line @typescript-eslint/restrict-plus-operands
|
||||||
|
('' + 1e7 + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, uuid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"paths": {
|
"paths": {
|
||||||
"locales": ["app/javascript/locales"],
|
"locales": ["app/javascript/locales"],
|
||||||
|
"styles/*": ["app/javascript/styles/*"],
|
||||||
|
"packs/public-path": ["app/javascript/packs/public-path"],
|
||||||
"flavours/glitch": ["app/javascript/flavours/glitch"],
|
"flavours/glitch": ["app/javascript/flavours/glitch"],
|
||||||
"flavours/glitch/*": ["app/javascript/flavours/glitch/*"],
|
"flavours/glitch/*": ["app/javascript/flavours/glitch/*"],
|
||||||
"mastodon": ["app/javascript/mastodon"],
|
"mastodon": ["app/javascript/mastodon"],
|
||||||
|
|
Loading…
Reference in New Issue