Merge branch 'rm-require' into 'main'
Rewrite all `require` to ES6 imports Closes #1773 See merge request soapbox-pub/soapbox!3216
This commit is contained in:
commit
6c9f3f339a
|
@ -152,7 +152,6 @@
|
||||||
"vite": "^5.4.8",
|
"vite": "^5.4.8",
|
||||||
"vite-plugin-compile-time": "^0.2.1",
|
"vite-plugin-compile-time": "^0.2.1",
|
||||||
"vite-plugin-html": "^3.2.2",
|
"vite-plugin-html": "^3.2.2",
|
||||||
"vite-plugin-require": "^1.2.14",
|
|
||||||
"vite-plugin-static-copy": "^1.0.6",
|
"vite-plugin-static-copy": "^1.0.6",
|
||||||
"zod": "^3.23.5",
|
"zod": "^3.23.5",
|
||||||
"zustand": "^5.0.0"
|
"zustand": "^5.0.0"
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import alertTriangleIcon from '@tabler/icons/outline/alert-triangle.svg';
|
||||||
|
import trashIcon from '@tabler/icons/outline/trash.svg';
|
||||||
|
import userMinusIcon from '@tabler/icons/outline/user-minus.svg';
|
||||||
|
import userOffIcon from '@tabler/icons/outline/user-off.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, IntlShape } from 'react-intl';
|
import { defineMessages, IntlShape } from 'react-intl';
|
||||||
|
|
||||||
|
@ -58,7 +62,7 @@ const deactivateUserModal = (intl: IntlShape, accountId: string, afterConfirm =
|
||||||
);
|
);
|
||||||
|
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/user-off.svg'),
|
icon: userOffIcon,
|
||||||
heading: intl.formatMessage(messages.deactivateUserHeading, { acct }),
|
heading: intl.formatMessage(messages.deactivateUserHeading, { acct }),
|
||||||
message,
|
message,
|
||||||
confirm: intl.formatMessage(messages.deactivateUserConfirm, { name }),
|
confirm: intl.formatMessage(messages.deactivateUserConfirm, { name }),
|
||||||
|
@ -96,7 +100,7 @@ const deleteUserModal = (intl: IntlShape, accountId: string, afterConfirm = () =
|
||||||
const checkbox = local ? intl.formatMessage(messages.deleteLocalUserCheckbox) : false;
|
const checkbox = local ? intl.formatMessage(messages.deleteLocalUserCheckbox) : false;
|
||||||
|
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/user-minus.svg'),
|
icon: userMinusIcon,
|
||||||
heading: intl.formatMessage(messages.deleteUserHeading, { acct }),
|
heading: intl.formatMessage(messages.deleteUserHeading, { acct }),
|
||||||
message,
|
message,
|
||||||
confirm,
|
confirm,
|
||||||
|
@ -118,7 +122,7 @@ const toggleStatusSensitivityModal = (intl: IntlShape, statusId: string, sensiti
|
||||||
const acct = state.statuses.get(statusId)!.account.acct;
|
const acct = state.statuses.get(statusId)!.account.acct;
|
||||||
|
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/alert-triangle.svg'),
|
icon: alertTriangleIcon,
|
||||||
heading: intl.formatMessage(sensitive === false ? messages.markStatusSensitiveHeading : messages.markStatusNotSensitiveHeading),
|
heading: intl.formatMessage(sensitive === false ? messages.markStatusSensitiveHeading : messages.markStatusNotSensitiveHeading),
|
||||||
message: intl.formatMessage(sensitive === false ? messages.markStatusSensitivePrompt : messages.markStatusNotSensitivePrompt, { acct }),
|
message: intl.formatMessage(sensitive === false ? messages.markStatusSensitivePrompt : messages.markStatusNotSensitivePrompt, { acct }),
|
||||||
confirm: intl.formatMessage(sensitive === false ? messages.markStatusSensitiveConfirm : messages.markStatusNotSensitiveConfirm),
|
confirm: intl.formatMessage(sensitive === false ? messages.markStatusSensitiveConfirm : messages.markStatusNotSensitiveConfirm),
|
||||||
|
@ -138,7 +142,7 @@ const deleteStatusModal = (intl: IntlShape, statusId: string, afterConfirm = ()
|
||||||
const acct = state.statuses.get(statusId)!.account.acct;
|
const acct = state.statuses.get(statusId)!.account.acct;
|
||||||
|
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
heading: intl.formatMessage(messages.deleteStatusHeading),
|
heading: intl.formatMessage(messages.deleteStatusHeading),
|
||||||
message: intl.formatMessage(messages.deleteStatusPrompt, { acct: <strong className='break-words'>{acct}</strong> }),
|
message: intl.formatMessage(messages.deleteStatusPrompt, { acct: <strong className='break-words'>{acct}</strong> }),
|
||||||
confirm: intl.formatMessage(messages.deleteStatusConfirm),
|
confirm: intl.formatMessage(messages.deleteStatusConfirm),
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import searchIcon from '@tabler/icons/outline/search.svg';
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -76,12 +78,12 @@ const AccountSearch: React.FC<IAccountSearch> = ({ onSelected, ...rest }) => {
|
||||||
onClick={handleClear}
|
onClick={handleClear}
|
||||||
>
|
>
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
src={require('@tabler/icons/outline/search.svg')}
|
src={searchIcon}
|
||||||
className={clsx('size-4 text-gray-400', { hidden: !isEmpty() })}
|
className={clsx('size-4 text-gray-400', { hidden: !isEmpty() })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
src={require('@tabler/icons/outline/x.svg')}
|
src={xIcon}
|
||||||
className={clsx('size-4 text-gray-400', { hidden: isEmpty() })}
|
className={clsx('size-4 text-gray-400', { hidden: isEmpty() })}
|
||||||
aria-label={intl.formatMessage(messages.placeholder)}
|
aria-label={intl.formatMessage(messages.placeholder)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import pencilIcon from '@tabler/icons/outline/pencil.svg';
|
||||||
import React, { useRef, useState } from 'react';
|
import React, { useRef, useState } from 'react';
|
||||||
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
|
||||||
import { Link, useHistory } from 'react-router-dom';
|
import { Link, useHistory } from 'react-router-dom';
|
||||||
|
@ -275,7 +276,7 @@ const Account = ({
|
||||||
<>
|
<>
|
||||||
<Text tag='span' theme='muted' size='sm'>·</Text> {/* eslint-disable-line formatjs/no-literal-string-in-jsx */}
|
<Text tag='span' theme='muted' size='sm'>·</Text> {/* eslint-disable-line formatjs/no-literal-string-in-jsx */}
|
||||||
|
|
||||||
<Icon className='size-5 text-gray-700 dark:text-gray-600' src={require('@tabler/icons/outline/pencil.svg')} />
|
<Icon className='size-5 text-gray-700 dark:text-gray-600' src={pencilIcon} />
|
||||||
</>
|
</>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import playerStopFilledIcon from '@tabler/icons/filled/player-stop.svg';
|
||||||
|
import checkIcon from '@tabler/icons/outline/check.svg';
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
@ -106,7 +109,7 @@ const AuthorizeRejectButtons: React.FC<IAuthorizeRejectButtons> = ({ onAuthorize
|
||||||
<HStack space={3} alignItems='center'>
|
<HStack space={3} alignItems='center'>
|
||||||
<AuthorizeRejectButton
|
<AuthorizeRejectButton
|
||||||
theme='danger'
|
theme='danger'
|
||||||
icon={require('@tabler/icons/outline/x.svg')}
|
icon={xIcon}
|
||||||
action={handleReject}
|
action={handleReject}
|
||||||
isLoading={state === 'rejecting'}
|
isLoading={state === 'rejecting'}
|
||||||
disabled={state === 'authorizing'}
|
disabled={state === 'authorizing'}
|
||||||
|
@ -114,7 +117,7 @@ const AuthorizeRejectButtons: React.FC<IAuthorizeRejectButtons> = ({ onAuthorize
|
||||||
/>
|
/>
|
||||||
<AuthorizeRejectButton
|
<AuthorizeRejectButton
|
||||||
theme='primary'
|
theme='primary'
|
||||||
icon={require('@tabler/icons/outline/check.svg')}
|
icon={checkIcon}
|
||||||
action={handleAuthorize}
|
action={handleAuthorize}
|
||||||
isLoading={state === 'authorizing'}
|
isLoading={state === 'authorizing'}
|
||||||
disabled={state === 'rejecting'}
|
disabled={state === 'rejecting'}
|
||||||
|
@ -162,7 +165,7 @@ const AuthorizeRejectButton: React.FC<IAuthorizeRejectButton> = ({ theme, icon,
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={isLoading ? require('@tabler/icons/filled/player-stop.svg') : icon}
|
src={isLoading ? playerStopFilledIcon : icon}
|
||||||
onClick={action}
|
onClick={action}
|
||||||
theme='seamless'
|
theme='seamless'
|
||||||
className='size-10 items-center justify-center bg-white focus:!ring-0 dark:!bg-gray-900'
|
className='size-10 items-center justify-center bg-white focus:!ring-0 dark:!bg-gray-900'
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
|
import buildingCommunityIcon from '@tabler/icons/outline/building-community.svg';
|
||||||
|
import homeIcon from '@tabler/icons/outline/home-2.svg';
|
||||||
|
import mapPinIcon from '@tabler/icons/outline/map-pin.svg';
|
||||||
|
import roadIcon from '@tabler/icons/outline/road.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { useAppSelector } from 'soapbox/hooks';
|
import { useAppSelector } from 'soapbox/hooks';
|
||||||
|
|
||||||
import { HStack, Icon, Stack, Text } from './ui';
|
import { HStack, Icon, Stack, Text } from './ui';
|
||||||
|
|
||||||
const buildingCommunityIcon = require('@tabler/icons/outline/building-community.svg');
|
|
||||||
const homeIcon = require('@tabler/icons/outline/home-2.svg');
|
|
||||||
const mapPinIcon = require('@tabler/icons/outline/map-pin.svg');
|
|
||||||
const roadIcon = require('@tabler/icons/outline/road.svg');
|
|
||||||
|
|
||||||
export const ADDRESS_ICONS: Record<string, string> = {
|
export const ADDRESS_ICONS: Record<string, string> = {
|
||||||
house: homeIcon,
|
house: homeIcon,
|
||||||
street: roadIcon,
|
street: roadIcon,
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { Card, CardBody, Stack, Text } from 'soapbox/components/ui';
|
import { Card, CardBody, Stack, Text } from 'soapbox/components/ui';
|
||||||
import IconButton from 'soapbox/components/ui/icon-button/icon-button';
|
import IconButton from 'soapbox/components/ui/icon-button/icon-button';
|
||||||
|
|
||||||
const closeIcon = require('@tabler/icons/outline/x.svg');
|
const closeIcon = xIcon;
|
||||||
|
|
||||||
interface IBigCard {
|
interface IBigCard {
|
||||||
title: React.ReactNode;
|
title: React.ReactNode;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import lockOpenIcon from '@tabler/icons/outline/lock-open.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -21,7 +22,7 @@ const Domain: React.FC<IDomain> = ({ domain }) => {
|
||||||
|
|
||||||
// const onBlockDomain = () => {
|
// const onBlockDomain = () => {
|
||||||
// dispatch(openModal('CONFIRM', {
|
// dispatch(openModal('CONFIRM', {
|
||||||
// icon: require('@tabler/icons/outline/ban.svg'),
|
// icon: banIcon,
|
||||||
// heading: <FormattedMessage id='confirmations.domain_block.heading' defaultMessage='Block {domain}' values={{ domain }} />,
|
// heading: <FormattedMessage id='confirmations.domain_block.heading' defaultMessage='Block {domain}' values={{ domain }} />,
|
||||||
// message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.' values={{ domain: <strong>{domain}</strong> }} />,
|
// message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.' values={{ domain: <strong>{domain}</strong> }} />,
|
||||||
// confirm: intl.formatMessage(messages.blockDomainConfirm),
|
// confirm: intl.formatMessage(messages.blockDomainConfirm),
|
||||||
|
@ -38,7 +39,7 @@ const Domain: React.FC<IDomain> = ({ domain }) => {
|
||||||
<Text tag='span'>
|
<Text tag='span'>
|
||||||
{domain}
|
{domain}
|
||||||
</Text>
|
</Text>
|
||||||
<IconButton iconClassName='h-5 w-5' src={require('@tabler/icons/outline/lock-open.svg')} title={intl.formatMessage(messages.unblockDomain, { domain })} onClick={handleDomainUnblock} />
|
<IconButton iconClassName='h-5 w-5' src={lockOpenIcon} title={intl.formatMessage(messages.unblockDomain, { domain })} onClick={handleDomainUnblock} />
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { offset, Placement, useFloating, flip, arrow, shift } from '@floating-ui/react';
|
import { offset, Placement, useFloating, flip, arrow, shift } from '@floating-ui/react';
|
||||||
|
import dotsIcon from '@tabler/icons/outline/dots.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { supportsPassiveEvents } from 'detect-passive-events';
|
import { supportsPassiveEvents } from 'detect-passive-events';
|
||||||
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
import React, { useEffect, useMemo, useRef, useState } from 'react';
|
||||||
|
@ -43,7 +44,7 @@ const DropdownMenu = (props: IDropdownMenu) => {
|
||||||
onOpen,
|
onOpen,
|
||||||
onShiftClick,
|
onShiftClick,
|
||||||
placement: initialPlacement = 'top',
|
placement: initialPlacement = 'top',
|
||||||
src = require('@tabler/icons/outline/dots.svg'),
|
src = dotsIcon,
|
||||||
title = 'Menu',
|
title = 'Menu',
|
||||||
...filteredProps
|
...filteredProps
|
||||||
} = props;
|
} = props;
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import mapPinIcon from '@tabler/icons/outline/map-pin.svg';
|
||||||
|
import userIcon from '@tabler/icons/outline/user.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
@ -67,7 +69,7 @@ const EventPreview: React.FC<IEventPreview> = ({ status, className, hideAction,
|
||||||
|
|
||||||
<div className='flex flex-wrap gap-x-2 gap-y-1 text-gray-700 dark:text-gray-600'>
|
<div className='flex flex-wrap gap-x-2 gap-y-1 text-gray-700 dark:text-gray-600'>
|
||||||
<HStack alignItems='center' space={2}>
|
<HStack alignItems='center' space={2}>
|
||||||
<Icon src={require('@tabler/icons/outline/user.svg')} />
|
<Icon src={userIcon} />
|
||||||
<HStack space={1} alignItems='center' grow>
|
<HStack space={1} alignItems='center' grow>
|
||||||
<span dangerouslySetInnerHTML={{ __html: account.display_name_html }} />
|
<span dangerouslySetInnerHTML={{ __html: account.display_name_html }} />
|
||||||
{account.verified && <VerificationBadge />}
|
{account.verified && <VerificationBadge />}
|
||||||
|
@ -78,7 +80,7 @@ const EventPreview: React.FC<IEventPreview> = ({ status, className, hideAction,
|
||||||
|
|
||||||
{event.location && (
|
{event.location && (
|
||||||
<HStack alignItems='center' space={2}>
|
<HStack alignItems='center' space={2}>
|
||||||
<Icon src={require('@tabler/icons/outline/map-pin.svg')} />
|
<Icon src={mapPinIcon} />
|
||||||
<span>
|
<span>
|
||||||
{event.location.get('name')}
|
{event.location.get('name')}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,193 +0,0 @@
|
||||||
// @ts-ignore No types available
|
|
||||||
// eslint-disable-next-line import/no-unresolved
|
|
||||||
import { WasmBoy } from '@soapbox.pub/wasmboy';
|
|
||||||
import clsx from 'clsx';
|
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
|
||||||
|
|
||||||
import { exitFullscreen, isFullscreen, requestFullscreen } from 'soapbox/features/ui/util/fullscreen';
|
|
||||||
|
|
||||||
import { HStack, IconButton } from './ui';
|
|
||||||
|
|
||||||
let gainNode: GainNode | undefined;
|
|
||||||
|
|
||||||
interface IGameboy extends Pick<React.HTMLAttributes<HTMLDivElement>, 'onFocus' | 'onBlur'> {
|
|
||||||
/** Classname of the outer `<div>`. */
|
|
||||||
className?: string;
|
|
||||||
/** URL to the ROM. */
|
|
||||||
src: string;
|
|
||||||
/** Aspect ratio of the canvas. */
|
|
||||||
aspect?: 'normal' | 'stretched';
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Component to display a playable Gameboy emulator. */
|
|
||||||
const Gameboy: React.FC<IGameboy> = ({ className, src, aspect = 'normal', onFocus, onBlur, ...rest }) => {
|
|
||||||
const node = useRef<HTMLDivElement>(null);
|
|
||||||
const canvas = useRef<HTMLCanvasElement>(null);
|
|
||||||
|
|
||||||
const [paused, setPaused] = useState(false);
|
|
||||||
const [muted, setMuted] = useState(true);
|
|
||||||
const [fullscreen, setFullscreen] = useState(false);
|
|
||||||
const [showControls, setShowControls] = useState(true);
|
|
||||||
|
|
||||||
async function init() {
|
|
||||||
await WasmBoy.config(WasmBoyOptions, canvas.current!);
|
|
||||||
await WasmBoy.loadROM(src);
|
|
||||||
await play();
|
|
||||||
|
|
||||||
if (document.activeElement === canvas.current) {
|
|
||||||
await WasmBoy.enableDefaultJoypad();
|
|
||||||
} else {
|
|
||||||
await WasmBoy.disableDefaultJoypad();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const handleFocus: React.FocusEventHandler<HTMLDivElement> = useCallback(() => {
|
|
||||||
WasmBoy.enableDefaultJoypad();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleBlur: React.FocusEventHandler<HTMLDivElement> = useCallback(() => {
|
|
||||||
WasmBoy.disableDefaultJoypad();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleFullscreenChange = useCallback(() => {
|
|
||||||
setFullscreen(isFullscreen());
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleCanvasClick = useCallback(() => {
|
|
||||||
setShowControls(!showControls);
|
|
||||||
}, [showControls]);
|
|
||||||
|
|
||||||
const pause = async () => {
|
|
||||||
await WasmBoy.pause();
|
|
||||||
setPaused(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const play = async () => {
|
|
||||||
await WasmBoy.play();
|
|
||||||
setPaused(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const togglePaused = () => paused ? play() : pause();
|
|
||||||
const toggleMuted = () => setMuted(!muted);
|
|
||||||
|
|
||||||
const toggleFullscreen = () => {
|
|
||||||
if (isFullscreen()) {
|
|
||||||
exitFullscreen();
|
|
||||||
} else if (node.current) {
|
|
||||||
requestFullscreen(node.current);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleDownload = () => {
|
|
||||||
window.open(src);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
init();
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
WasmBoy.pause();
|
|
||||||
WasmBoy.disableDefaultJoypad();
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
document.addEventListener('fullscreenchange', handleFullscreenChange, true);
|
|
||||||
return () => {
|
|
||||||
document.removeEventListener('fullscreenchange', handleFullscreenChange, true);
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (fullscreen) {
|
|
||||||
node.current?.focus();
|
|
||||||
}
|
|
||||||
}, [fullscreen]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (gainNode) {
|
|
||||||
gainNode.gain.value = muted ? 0 : 1;
|
|
||||||
}
|
|
||||||
}, [gainNode, muted]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
ref={node}
|
|
||||||
tabIndex={0}
|
|
||||||
className={clsx(className, 'relative outline-none')}
|
|
||||||
onFocus={onFocus ?? handleFocus}
|
|
||||||
onBlur={onBlur ?? handleBlur}
|
|
||||||
>
|
|
||||||
<canvas
|
|
||||||
ref={canvas}
|
|
||||||
onClick={handleCanvasClick}
|
|
||||||
className={clsx('size-full bg-black ', {
|
|
||||||
'object-contain': aspect === 'normal',
|
|
||||||
'object-cover': aspect === 'stretched',
|
|
||||||
})}
|
|
||||||
{...rest}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<HStack
|
|
||||||
justifyContent='between'
|
|
||||||
className={clsx('pointer-events-none absolute inset-x-0 bottom-0 w-full bg-gradient-to-t from-black/50 to-transparent p-2 opacity-0 transition-opacity', {
|
|
||||||
'pointer-events-auto opacity-100': showControls,
|
|
||||||
})}
|
|
||||||
>
|
|
||||||
<HStack space={2}>
|
|
||||||
<IconButton
|
|
||||||
theme='transparent'
|
|
||||||
className='text-white'
|
|
||||||
onClick={togglePaused}
|
|
||||||
src={paused ? require('@tabler/icons/outline/player-play.svg') : require('@tabler/icons/outline/player-pause.svg')}
|
|
||||||
/>
|
|
||||||
<IconButton
|
|
||||||
theme='transparent'
|
|
||||||
className='text-white'
|
|
||||||
onClick={toggleMuted}
|
|
||||||
src={muted ? require('@tabler/icons/outline/volume-3.svg') : require('@tabler/icons/outline/volume.svg')}
|
|
||||||
/>
|
|
||||||
</HStack>
|
|
||||||
|
|
||||||
<HStack space={2}>
|
|
||||||
<IconButton
|
|
||||||
theme='transparent'
|
|
||||||
className='text-white'
|
|
||||||
src={require('@tabler/icons/outline/download.svg')}
|
|
||||||
onClick={handleDownload}
|
|
||||||
/>
|
|
||||||
<IconButton
|
|
||||||
theme='transparent'
|
|
||||||
className='text-white'
|
|
||||||
onClick={toggleFullscreen}
|
|
||||||
src={fullscreen ? require('@tabler/icons/outline/arrows-minimize.svg') : require('@tabler/icons/outline/arrows-maximize.svg')}
|
|
||||||
/>
|
|
||||||
</HStack>
|
|
||||||
</HStack>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
const WasmBoyOptions = {
|
|
||||||
headless: false,
|
|
||||||
useGbcWhenOptional: true,
|
|
||||||
isAudioEnabled: true,
|
|
||||||
frameSkip: 1,
|
|
||||||
audioBatchProcessing: true,
|
|
||||||
timersBatchProcessing: false,
|
|
||||||
audioAccumulateSamples: true,
|
|
||||||
graphicsBatchProcessing: false,
|
|
||||||
graphicsDisableScanlineRendering: false,
|
|
||||||
tileRendering: true,
|
|
||||||
tileCaching: true,
|
|
||||||
gameboyFPSCap: 60,
|
|
||||||
updateGraphicsCallback: false,
|
|
||||||
updateAudioCallback: (audioContext: AudioContext, audioBufferSourceNode: AudioBufferSourceNode) => {
|
|
||||||
gainNode = gainNode ?? audioContext.createGain();
|
|
||||||
audioBufferSourceNode.connect(gainNode);
|
|
||||||
return gainNode;
|
|
||||||
},
|
|
||||||
saveStateCallback: false,
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Gameboy;
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import checkIcon from '@tabler/icons/outline/check.svg';
|
||||||
|
import chevronRightIcon from '@tabler/icons/outline/chevron-right.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
@ -72,7 +74,7 @@ const ListItem: React.FC<IListItem> = ({ label, hint, children, to, onClick, onS
|
||||||
<HStack space={1} alignItems='center' className='overflow-hidden text-gray-700 dark:text-gray-600'>
|
<HStack space={1} alignItems='center' className='overflow-hidden text-gray-700 dark:text-gray-600'>
|
||||||
{children}
|
{children}
|
||||||
|
|
||||||
<Icon src={require('@tabler/icons/outline/chevron-right.svg')} className='ml-1 rtl:rotate-180' />
|
<Icon src={chevronRightIcon} className='ml-1 rtl:rotate-180' />
|
||||||
</HStack>
|
</HStack>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
|
@ -90,7 +92,7 @@ const ListItem: React.FC<IListItem> = ({ label, hint, children, to, onClick, onS
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/check.svg')}
|
src={checkIcon}
|
||||||
className={
|
className={
|
||||||
clsx({
|
clsx({
|
||||||
'h-4 w-4 text-white dark:text-white transition-all duration-500': true,
|
'h-4 w-4 text-white dark:text-white transition-all duration-500': true,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import dotsIcon from '@tabler/icons/outline/dots.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -20,7 +21,7 @@ const LoadGap: React.FC<ILoadGap> = ({ disabled, maxId, onClick }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<button className='load-more load-gap' disabled={disabled} onClick={handleClick} aria-label={intl.formatMessage(messages.load_more)}>
|
<button className='load-more load-gap' disabled={disabled} onClick={handleClick} aria-label={intl.formatMessage(messages.load_more)}>
|
||||||
<Icon src={require('@tabler/icons/outline/dots.svg')} />
|
<Icon src={dotsIcon} />
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import backspaceIcon from '@tabler/icons/outline/backspace.svg';
|
||||||
|
import searchIcon from '@tabler/icons/outline/search.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||||
import throttle from 'lodash/throttle';
|
import throttle from 'lodash/throttle';
|
||||||
|
@ -100,8 +102,8 @@ const LocationSearch: React.FC<ILocationSearch> = ({ onSelected }) => {
|
||||||
renderSuggestion={AutosuggestLocation}
|
renderSuggestion={AutosuggestLocation}
|
||||||
/>
|
/>
|
||||||
<div role='button' tabIndex={0} className='search__icon' onClick={handleClear}>
|
<div role='button' tabIndex={0} className='search__icon' onClick={handleClear}>
|
||||||
<Icon src={require('@tabler/icons/outline/search.svg')} className={clsx('svg-icon--search', { active: isEmpty() })} />
|
<Icon src={searchIcon} className={clsx('svg-icon--search', { active: isEmpty() })} />
|
||||||
<Icon src={require('@tabler/icons/outline/backspace.svg')} className={clsx('svg-icon--backspace', { active: !isEmpty() })} aria-label={intl.formatMessage(messages.placeholder)} />
|
<Icon src={backspaceIcon} className={clsx('svg-icon--backspace', { active: !isEmpty() })} aria-label={intl.formatMessage(messages.placeholder)} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import paperclipIcon from '@tabler/icons/outline/paperclip.svg';
|
||||||
|
import volumeIcon from '@tabler/icons/outline/volume.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useState, useRef, useLayoutEffect, CSSProperties } from 'react';
|
import React, { useState, useRef, useLayoutEffect, CSSProperties } from 'react';
|
||||||
|
|
||||||
|
@ -156,7 +158,7 @@ const Item: React.FC<IItem> = ({
|
||||||
const attachmentIcon = (
|
const attachmentIcon = (
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
className={clsx('size-16 text-gray-800 dark:text-gray-200', { 'size-8': compact })}
|
className={clsx('size-16 text-gray-800 dark:text-gray-200', { 'size-8': compact })}
|
||||||
src={MIMETYPE_ICONS[attachment.getIn(['pleroma', 'mime_type']) as string] || require('@tabler/icons/outline/paperclip.svg')}
|
src={MIMETYPE_ICONS[attachment.getIn(['pleroma', 'mime_type']) as string] || paperclipIcon}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -233,7 +235,7 @@ const Item: React.FC<IItem> = ({
|
||||||
target='_blank'
|
target='_blank'
|
||||||
title={attachment.description}
|
title={attachment.description}
|
||||||
>
|
>
|
||||||
<span className='absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'><SvgIcon className='size-24' src={require('@tabler/icons/outline/volume.svg')} /></span>
|
<span className='absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'><SvgIcon className='size-24' src={volumeIcon} /></span>
|
||||||
<span className={clsx('pointer-events-none absolute bottom-1.5 left-1.5 z-[1] block bg-black/50 px-1.5 py-0.5 text-[11px] font-semibold uppercase leading-[18px] text-white opacity-90 transition-opacity duration-100 ease-linear', { 'hidden': compact })}>{ext}</span>
|
<span className={clsx('pointer-events-none absolute bottom-1.5 left-1.5 z-[1] block bg-black/50 px-1.5 py-0.5 text-[11px] font-semibold uppercase leading-[18px] text-white opacity-90 transition-opacity duration-100 ease-linear', { 'hidden': compact })}>{ext}</span>
|
||||||
</a>
|
</a>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import trashIcon from '@tabler/icons/outline/trash.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -74,7 +75,7 @@ const ModalRoot: React.FC<IModalRoot> = ({ children, onCancel, onClose, type })
|
||||||
if (hasComposeContent && type === 'COMPOSE') {
|
if (hasComposeContent && type === 'COMPOSE') {
|
||||||
const isEditing = compose!.id !== null;
|
const isEditing = compose!.id !== null;
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
heading: isEditing
|
heading: isEditing
|
||||||
? <FormattedMessage id='confirmations.cancel_editing.heading' defaultMessage='Cancel post editing' />
|
? <FormattedMessage id='confirmations.cancel_editing.heading' defaultMessage='Cancel post editing' />
|
||||||
: <FormattedMessage id='confirmations.cancel.heading' defaultMessage='Discard post' />,
|
: <FormattedMessage id='confirmations.cancel.heading' defaultMessage='Discard post' />,
|
||||||
|
@ -93,7 +94,7 @@ const ModalRoot: React.FC<IModalRoot> = ({ children, onCancel, onClose, type })
|
||||||
} else if (hasEventComposeContent && type === 'COMPOSE_EVENT') {
|
} else if (hasEventComposeContent && type === 'COMPOSE_EVENT') {
|
||||||
const isEditing = getState().compose_event.id !== null;
|
const isEditing = getState().compose_event.id !== null;
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
heading: isEditing
|
heading: isEditing
|
||||||
? <FormattedMessage id='confirmations.cancel_event_editing.heading' defaultMessage='Cancel event editing' />
|
? <FormattedMessage id='confirmations.cancel_event_editing.heading' defaultMessage='Cancel event editing' />
|
||||||
: <FormattedMessage id='confirmations.delete_event.heading' defaultMessage='Delete event' />,
|
: <FormattedMessage id='confirmations.delete_event.heading' defaultMessage='Delete event' />,
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import chevronRightIcon from '@tabler/icons/outline/chevron-right.svg';
|
||||||
|
import exclamationCircleIcon from '@tabler/icons/outline/exclamation-circle.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
@ -25,7 +27,7 @@ const PendingItemsRow: React.FC<IPendingItemsRow> = ({ to, count, size = 'md' })
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/exclamation-circle.svg')}
|
src={exclamationCircleIcon}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
'h-5 w-5': size === 'md',
|
'h-5 w-5': size === 'md',
|
||||||
'h-7 w-7': size === 'lg',
|
'h-7 w-7': size === 'lg',
|
||||||
|
@ -43,7 +45,7 @@ const PendingItemsRow: React.FC<IPendingItemsRow> = ({ to, count, size = 'md' })
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/chevron-right.svg')}
|
src={chevronRightIcon}
|
||||||
className='size-5 text-gray-600 transition-colors group-hover:text-gray-700 dark:text-gray-600 dark:group-hover:text-gray-500'
|
className='size-5 text-gray-600 transition-colors group-hover:text-gray-700 dark:text-gray-600 dark:group-hover:text-gray-500'
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import checkIcon from '@tabler/icons/outline/check.svg';
|
||||||
|
import circleCheckIcon from '@tabler/icons/outline/circle-check.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -86,7 +88,7 @@ const PollOptionText: React.FC<IPollOptionText> = ({ poll, option, index, active
|
||||||
aria-label={option.title}
|
aria-label={option.title}
|
||||||
>
|
>
|
||||||
{active && (
|
{active && (
|
||||||
<Icon src={require('@tabler/icons/outline/check.svg')} className='size-4 text-white dark:text-primary-900' />
|
<Icon src={checkIcon} className='size-4 text-white dark:text-primary-900' />
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@ -143,7 +145,7 @@ const PollOption: React.FC<IPollOption> = (props): JSX.Element | null => {
|
||||||
<HStack space={2} alignItems='center' className='relative'>
|
<HStack space={2} alignItems='center' className='relative'>
|
||||||
{voted ? (
|
{voted ? (
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/circle-check.svg')}
|
src={circleCheckIcon}
|
||||||
alt={intl.formatMessage(messages.voted)}
|
alt={intl.formatMessage(messages.voted)}
|
||||||
className='size-4 text-primary-600 dark:fill-white dark:text-primary-800'
|
className='size-4 text-primary-600 dark:fill-white dark:text-primary-800'
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import externalLinkIcon from '@tabler/icons/outline/external-link.svg';
|
||||||
|
import linkIcon from '@tabler/icons/outline/link.svg';
|
||||||
|
import playerPlayIcon from '@tabler/icons/outline/player-play.svg';
|
||||||
|
import zoomInIcon from '@tabler/icons/outline/zoom-in.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
@ -135,7 +139,7 @@ const PreviewCard: React.FC<IPreviewCard> = ({
|
||||||
)}
|
)}
|
||||||
<HStack space={1} alignItems='center'>
|
<HStack space={1} alignItems='center'>
|
||||||
<Text tag='span' theme='muted'>
|
<Text tag='span' theme='muted'>
|
||||||
<Icon src={require('@tabler/icons/outline/link.svg')} />
|
<Icon src={linkIcon} />
|
||||||
</Text>
|
</Text>
|
||||||
<Text tag='span' theme='muted' size='sm' direction={direction}>
|
<Text tag='span' theme='muted' size='sm' direction={direction}>
|
||||||
{card.provider_name}
|
{card.provider_name}
|
||||||
|
@ -168,10 +172,10 @@ const PreviewCard: React.FC<IPreviewCard> = ({
|
||||||
if (embedded) {
|
if (embedded) {
|
||||||
embed = renderVideo();
|
embed = renderVideo();
|
||||||
} else {
|
} else {
|
||||||
let iconVariant = require('@tabler/icons/outline/player-play.svg');
|
let iconVariant = playerPlayIcon;
|
||||||
|
|
||||||
if (card.type === 'photo') {
|
if (card.type === 'photo') {
|
||||||
iconVariant = require('@tabler/icons/outline/zoom-in.svg');
|
iconVariant = zoomInIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
embed = (
|
embed = (
|
||||||
|
@ -198,7 +202,7 @@ const PreviewCard: React.FC<IPreviewCard> = ({
|
||||||
className='text-gray-700 hover:text-gray-900 dark:text-gray-500 dark:hover:text-gray-100'
|
className='text-gray-700 hover:text-gray-900 dark:text-gray-500 dark:hover:text-gray-100'
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/external-link.svg')}
|
src={externalLinkIcon}
|
||||||
className='size-6 text-inherit'
|
className='size-6 text-inherit'
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { useFloating } from '@floating-ui/react';
|
import { useFloating } from '@floating-ui/react';
|
||||||
|
import calendarIcon from '@tabler/icons/outline/calendar.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
import { useIntl, FormattedMessage } from 'react-intl';
|
import { useIntl, FormattedMessage } from 'react-intl';
|
||||||
|
@ -123,7 +124,7 @@ export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }
|
||||||
{account.local ? (
|
{account.local ? (
|
||||||
<HStack alignItems='center' space={0.5}>
|
<HStack alignItems='center' space={0.5}>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/calendar.svg')}
|
src={calendarIcon}
|
||||||
className='size-4 text-gray-800 dark:text-gray-200'
|
className='size-4 text-gray-800 dark:text-gray-200'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import quoteIcon from '@tabler/icons/outline/quote.svg';
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
|
||||||
import { HStack, Icon, Text } from 'soapbox/components/ui';
|
import { HStack, Icon, Text } from 'soapbox/components/ui';
|
||||||
|
@ -18,7 +19,7 @@ const QuotedStatusIndicator: React.FC<IQuotedStatusIndicator> = ({ statusId }) =
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HStack alignItems='center' space={1}>
|
<HStack alignItems='center' space={1}>
|
||||||
<Icon className='size-5' src={require('@tabler/icons/outline/quote.svg')} aria-hidden />
|
<Icon className='size-5' src={quoteIcon} aria-hidden />
|
||||||
<Text truncate>{status.url}</Text>
|
<Text truncate>{status.url}</Text>
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { MouseEventHandler, useEffect, useRef, useState } from 'react';
|
import React, { MouseEventHandler, useEffect, useRef, useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -85,7 +86,7 @@ const QuotedStatus: React.FC<IQuotedStatus> = ({ status, onCancel, compose }) =>
|
||||||
if (onCancel) {
|
if (onCancel) {
|
||||||
actions = {
|
actions = {
|
||||||
onActionClick: handleClose,
|
onActionClick: handleClose,
|
||||||
actionIcon: require('@tabler/icons/outline/x.svg'),
|
actionIcon: xIcon,
|
||||||
actionAlignment: 'top',
|
actionAlignment: 'top',
|
||||||
actionTitle: intl.formatMessage(messages.cancel),
|
actionTitle: intl.formatMessage(messages.cancel),
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import arrowBarToUpIcon from '@tabler/icons/outline/arrow-bar-to-up.svg';
|
||||||
import throttle from 'lodash/throttle';
|
import throttle from 'lodash/throttle';
|
||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import { useIntl, MessageDescriptor } from 'react-intl';
|
import { useIntl, MessageDescriptor } from 'react-intl';
|
||||||
|
@ -92,7 +93,7 @@ const ScrollTopButton: React.FC<IScrollTopButton> = ({
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
className='size-4'
|
className='size-4'
|
||||||
src={require('@tabler/icons/outline/arrow-bar-to-up.svg')}
|
src={arrowBarToUpIcon}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Text theme='inherit' size='sm'>
|
<Text theme='inherit' size='sm'>
|
||||||
|
|
|
@ -1,3 +1,21 @@
|
||||||
|
import atIcon from '@tabler/icons/outline/at.svg';
|
||||||
|
import banIcon from '@tabler/icons/outline/ban.svg';
|
||||||
|
import bookmarkIcon from '@tabler/icons/outline/bookmark.svg';
|
||||||
|
import calendarEventIcon from '@tabler/icons/outline/calendar-event.svg';
|
||||||
|
import chevronDownIcon from '@tabler/icons/outline/chevron-down.svg';
|
||||||
|
import circleXIcon from '@tabler/icons/outline/circle-x.svg';
|
||||||
|
import circlesIcon from '@tabler/icons/outline/circles.svg';
|
||||||
|
import codeIcon from '@tabler/icons/outline/code.svg';
|
||||||
|
import filterIcon from '@tabler/icons/outline/filter.svg';
|
||||||
|
import hashIcon from '@tabler/icons/outline/hash.svg';
|
||||||
|
import listIcon from '@tabler/icons/outline/list.svg';
|
||||||
|
import logoutIcon from '@tabler/icons/outline/logout.svg';
|
||||||
|
import plusIcon from '@tabler/icons/outline/plus.svg';
|
||||||
|
import settingsIcon from '@tabler/icons/outline/settings.svg';
|
||||||
|
import userPlusIcon from '@tabler/icons/outline/user-plus.svg';
|
||||||
|
import userIcon from '@tabler/icons/outline/user.svg';
|
||||||
|
import worldIcon from '@tabler/icons/outline/world.svg';
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
/* eslint-disable jsx-a11y/interactive-supports-focus */
|
/* eslint-disable jsx-a11y/interactive-supports-focus */
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useCallback } from 'react';
|
import React, { useCallback } from 'react';
|
||||||
|
@ -163,7 +181,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
<IconButton
|
<IconButton
|
||||||
title={intl.formatMessage(messages.close)}
|
title={intl.formatMessage(messages.close)}
|
||||||
onClick={handleClose}
|
onClick={handleClose}
|
||||||
src={require('@tabler/icons/outline/x.svg')}
|
src={xIcon}
|
||||||
ref={closeButtonRef}
|
ref={closeButtonRef}
|
||||||
iconClassName='h-6 w-6'
|
iconClassName='h-6 w-6'
|
||||||
className='absolute right-0 top-0 -mr-11 mt-2 text-gray-600 hover:text-gray-600 dark:text-gray-400 dark:hover:text-gray-300'
|
className='absolute right-0 top-0 -mr-11 mt-2 text-gray-600 hover:text-gray-600 dark:text-gray-400 dark:hover:text-gray-300'
|
||||||
|
@ -186,7 +204,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
|
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to={`/@${account.acct}`}
|
to={`/@${account.acct}`}
|
||||||
icon={require('@tabler/icons/outline/user.svg')}
|
icon={userIcon}
|
||||||
text={intl.formatMessage(messages.profile)}
|
text={intl.formatMessage(messages.profile)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -194,7 +212,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{(account.locked || followRequestsCount > 0) && (
|
{(account.locked || followRequestsCount > 0) && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/follow_requests'
|
to='/follow_requests'
|
||||||
icon={require('@tabler/icons/outline/user-plus.svg')}
|
icon={userPlusIcon}
|
||||||
text={intl.formatMessage(messages.followRequests)}
|
text={intl.formatMessage(messages.followRequests)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -203,7 +221,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{features.bookmarks && (
|
{features.bookmarks && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/bookmarks'
|
to='/bookmarks'
|
||||||
icon={require('@tabler/icons/outline/bookmark.svg')}
|
icon={bookmarkIcon}
|
||||||
text={intl.formatMessage(messages.bookmarks)}
|
text={intl.formatMessage(messages.bookmarks)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -212,7 +230,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{features.groups && (
|
{features.groups && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/groups'
|
to='/groups'
|
||||||
icon={require('@tabler/icons/outline/circles.svg')}
|
icon={circlesIcon}
|
||||||
text={intl.formatMessage(messages.groups)}
|
text={intl.formatMessage(messages.groups)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -221,7 +239,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{features.lists && (
|
{features.lists && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/lists'
|
to='/lists'
|
||||||
icon={require('@tabler/icons/outline/list.svg')}
|
icon={listIcon}
|
||||||
text={intl.formatMessage(messages.lists)}
|
text={intl.formatMessage(messages.lists)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -230,7 +248,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{features.events && (
|
{features.events && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/events'
|
to='/events'
|
||||||
icon={require('@tabler/icons/outline/calendar-event.svg')}
|
icon={calendarEventIcon}
|
||||||
text={intl.formatMessage(messages.events)}
|
text={intl.formatMessage(messages.events)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -239,7 +257,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{settings.get('isDeveloper') && (
|
{settings.get('isDeveloper') && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/developers'
|
to='/developers'
|
||||||
icon={require('@tabler/icons/outline/code.svg')}
|
icon={codeIcon}
|
||||||
text={intl.formatMessage(messages.developers)}
|
text={intl.formatMessage(messages.developers)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -250,7 +268,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
|
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/timeline/local'
|
to='/timeline/local'
|
||||||
icon={features.federating ? require('@tabler/icons/outline/at.svg') : require('@tabler/icons/outline/world.svg')}
|
icon={features.federating ? atIcon : worldIcon}
|
||||||
text={features.federating ? instance.domain : <FormattedMessage id='tabs_bar.all' defaultMessage='All' />}
|
text={features.federating ? instance.domain : <FormattedMessage id='tabs_bar.all' defaultMessage='All' />}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -258,7 +276,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{features.federating && (
|
{features.federating && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/timeline/global'
|
to='/timeline/global'
|
||||||
icon={require('@tabler/icons/outline/world.svg')}
|
icon={worldIcon}
|
||||||
text={<FormattedMessage id='tabs_bar.global' defaultMessage='Global' />}
|
text={<FormattedMessage id='tabs_bar.global' defaultMessage='Global' />}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -270,7 +288,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{features.blocks && (
|
{features.blocks && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/blocks'
|
to='/blocks'
|
||||||
icon={require('@tabler/icons/outline/ban.svg')}
|
icon={banIcon}
|
||||||
text={intl.formatMessage(messages.blocks)}
|
text={intl.formatMessage(messages.blocks)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -278,14 +296,14 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
|
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/mutes'
|
to='/mutes'
|
||||||
icon={require('@tabler/icons/outline/circle-x.svg')}
|
icon={circleXIcon}
|
||||||
text={intl.formatMessage(messages.mutes)}
|
text={intl.formatMessage(messages.mutes)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/settings/preferences'
|
to='/settings/preferences'
|
||||||
icon={require('@tabler/icons/outline/settings.svg')}
|
icon={settingsIcon}
|
||||||
text={intl.formatMessage(messages.preferences)}
|
text={intl.formatMessage(messages.preferences)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
count={settingsNotifications.size}
|
count={settingsNotifications.size}
|
||||||
|
@ -294,7 +312,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{features.federating && (
|
{features.federating && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/domain_blocks'
|
to='/domain_blocks'
|
||||||
icon={require('@tabler/icons/outline/ban.svg')}
|
icon={banIcon}
|
||||||
text={intl.formatMessage(messages.domainBlocks)}
|
text={intl.formatMessage(messages.domainBlocks)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -303,7 +321,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{(features.filters || features.filtersV2) && (
|
{(features.filters || features.filtersV2) && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/filters'
|
to='/filters'
|
||||||
icon={require('@tabler/icons/outline/filter.svg')}
|
icon={filterIcon}
|
||||||
text={intl.formatMessage(messages.filters)}
|
text={intl.formatMessage(messages.filters)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -312,7 +330,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{features.followedHashtagsList && (
|
{features.followedHashtagsList && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/followed_tags'
|
to='/followed_tags'
|
||||||
icon={require('@tabler/icons/outline/hash.svg')}
|
icon={hashIcon}
|
||||||
text={intl.formatMessage(messages.followedTags)}
|
text={intl.formatMessage(messages.followedTags)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -321,7 +339,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{account.admin && (
|
{account.admin && (
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/soapbox/config'
|
to='/soapbox/config'
|
||||||
icon={require('@tabler/icons/outline/settings.svg')}
|
icon={settingsIcon}
|
||||||
text={intl.formatMessage(messages.soapboxConfig)}
|
text={intl.formatMessage(messages.soapboxConfig)}
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
/>
|
/>
|
||||||
|
@ -331,7 +349,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
|
|
||||||
<SidebarLink
|
<SidebarLink
|
||||||
to='/logout'
|
to='/logout'
|
||||||
icon={require('@tabler/icons/outline/logout.svg')}
|
icon={logoutIcon}
|
||||||
text={intl.formatMessage(messages.logout)}
|
text={intl.formatMessage(messages.logout)}
|
||||||
onClick={onClickLogOut}
|
onClick={onClickLogOut}
|
||||||
/>
|
/>
|
||||||
|
@ -346,7 +364,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/chevron-down.svg')}
|
src={chevronDownIcon}
|
||||||
className={clsx('size-4 text-gray-900 transition-transform dark:text-gray-100', {
|
className={clsx('size-4 text-gray-900 transition-transform dark:text-gray-100', {
|
||||||
'rotate-180': switcher,
|
'rotate-180': switcher,
|
||||||
})}
|
})}
|
||||||
|
@ -359,7 +377,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||||
{otherAccounts.map(account => renderAccount(account))}
|
{otherAccounts.map(account => renderAccount(account))}
|
||||||
|
|
||||||
<NavLink className='flex items-center space-x-1 py-2' to='/login/add' onClick={handleClose}>
|
<NavLink className='flex items-center space-x-1 py-2' to='/login/add' onClick={handleClose}>
|
||||||
<Icon className='size-4 text-primary-500' src={require('@tabler/icons/outline/plus.svg')} />
|
<Icon className='size-4 text-primary-500' src={plusIcon} />
|
||||||
<Text size='sm' weight='medium'>{intl.formatMessage(messages.addAccount)}</Text>
|
<Text size='sm' weight='medium'>{intl.formatMessage(messages.addAccount)}</Text>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,25 @@
|
||||||
|
import bellFilledIcon from '@tabler/icons/filled/bell.svg';
|
||||||
|
import circlesFilledIcon from '@tabler/icons/filled/circles.svg';
|
||||||
|
import homeFilledIcon from '@tabler/icons/filled/home.svg';
|
||||||
|
import settingsFilledIcon from '@tabler/icons/filled/settings.svg';
|
||||||
|
import userFilledIcon from '@tabler/icons/filled/user.svg';
|
||||||
|
import atIcon from '@tabler/icons/outline/at.svg';
|
||||||
|
import bellIcon from '@tabler/icons/outline/bell.svg';
|
||||||
|
import bookmarkIcon from '@tabler/icons/outline/bookmark.svg';
|
||||||
|
import calendarEventIcon from '@tabler/icons/outline/calendar-event.svg';
|
||||||
|
import circlesIcon from '@tabler/icons/outline/circles.svg';
|
||||||
|
import codeIcon from '@tabler/icons/outline/code.svg';
|
||||||
|
import dashboardIcon from '@tabler/icons/outline/dashboard.svg';
|
||||||
|
import dotsCircleHorizontalIcon from '@tabler/icons/outline/dots-circle-horizontal.svg';
|
||||||
|
import homeIcon from '@tabler/icons/outline/home.svg';
|
||||||
|
import listIcon from '@tabler/icons/outline/list.svg';
|
||||||
|
import mailIcon from '@tabler/icons/outline/mail.svg';
|
||||||
|
import messagesIcon from '@tabler/icons/outline/messages.svg';
|
||||||
|
import searchIcon from '@tabler/icons/outline/search.svg';
|
||||||
|
import settingsIcon from '@tabler/icons/outline/settings.svg';
|
||||||
|
import userPlusIcon from '@tabler/icons/outline/user-plus.svg';
|
||||||
|
import userIcon from '@tabler/icons/outline/user.svg';
|
||||||
|
import worldIcon from '@tabler/icons/outline/world.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -43,7 +65,7 @@ const SidebarNavigation = () => {
|
||||||
menu.push({
|
menu.push({
|
||||||
to: '/follow_requests',
|
to: '/follow_requests',
|
||||||
text: intl.formatMessage(messages.follow_requests),
|
text: intl.formatMessage(messages.follow_requests),
|
||||||
icon: require('@tabler/icons/outline/user-plus.svg'),
|
icon: userPlusIcon,
|
||||||
count: followRequestsCount,
|
count: followRequestsCount,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -52,7 +74,7 @@ const SidebarNavigation = () => {
|
||||||
menu.push({
|
menu.push({
|
||||||
to: '/bookmarks',
|
to: '/bookmarks',
|
||||||
text: intl.formatMessage(messages.bookmarks),
|
text: intl.formatMessage(messages.bookmarks),
|
||||||
icon: require('@tabler/icons/outline/bookmark.svg'),
|
icon: bookmarkIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +82,7 @@ const SidebarNavigation = () => {
|
||||||
menu.push({
|
menu.push({
|
||||||
to: '/lists',
|
to: '/lists',
|
||||||
text: intl.formatMessage(messages.lists),
|
text: intl.formatMessage(messages.lists),
|
||||||
icon: require('@tabler/icons/outline/list.svg'),
|
icon: listIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,14 +90,14 @@ const SidebarNavigation = () => {
|
||||||
menu.push({
|
menu.push({
|
||||||
to: '/events',
|
to: '/events',
|
||||||
text: intl.formatMessage(messages.events),
|
text: intl.formatMessage(messages.events),
|
||||||
icon: require('@tabler/icons/outline/calendar-event.svg'),
|
icon: calendarEventIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDeveloper) {
|
if (isDeveloper) {
|
||||||
menu.push({
|
menu.push({
|
||||||
to: '/developers',
|
to: '/developers',
|
||||||
icon: require('@tabler/icons/outline/code.svg'),
|
icon: codeIcon,
|
||||||
text: intl.formatMessage(messages.developers),
|
text: intl.formatMessage(messages.developers),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -92,7 +114,7 @@ const SidebarNavigation = () => {
|
||||||
return (
|
return (
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/chats'
|
to='/chats'
|
||||||
icon={require('@tabler/icons/outline/messages.svg')}
|
icon={messagesIcon}
|
||||||
count={unreadChatsCount}
|
count={unreadChatsCount}
|
||||||
countMax={9}
|
countMax={9}
|
||||||
text={<FormattedMessage id='navigation.chats' defaultMessage='Chats' />}
|
text={<FormattedMessage id='navigation.chats' defaultMessage='Chats' />}
|
||||||
|
@ -104,7 +126,7 @@ const SidebarNavigation = () => {
|
||||||
return (
|
return (
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/messages'
|
to='/messages'
|
||||||
icon={require('@tabler/icons/outline/mail.svg')}
|
icon={mailIcon}
|
||||||
text={<FormattedMessage id='navigation.direct_messages' defaultMessage='Messages' />}
|
text={<FormattedMessage id='navigation.direct_messages' defaultMessage='Messages' />}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
@ -118,14 +140,14 @@ const SidebarNavigation = () => {
|
||||||
<Stack space={2}>
|
<Stack space={2}>
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/'
|
to='/'
|
||||||
icon={require('@tabler/icons/outline/home.svg')}
|
icon={homeIcon}
|
||||||
activeIcon={require('@tabler/icons/filled/home.svg')}
|
activeIcon={homeFilledIcon}
|
||||||
text={<FormattedMessage id='tabs_bar.home' defaultMessage='Home' />}
|
text={<FormattedMessage id='tabs_bar.home' defaultMessage='Home' />}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/search'
|
to='/search'
|
||||||
icon={require('@tabler/icons/outline/search.svg')}
|
icon={searchIcon}
|
||||||
text={<FormattedMessage id='tabs_bar.search' defaultMessage='Discover' />}
|
text={<FormattedMessage id='tabs_bar.search' defaultMessage='Discover' />}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -133,8 +155,8 @@ const SidebarNavigation = () => {
|
||||||
<>
|
<>
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/notifications'
|
to='/notifications'
|
||||||
icon={require('@tabler/icons/outline/bell.svg')}
|
icon={bellIcon}
|
||||||
activeIcon={require('@tabler/icons/filled/bell.svg')}
|
activeIcon={bellFilledIcon}
|
||||||
count={notificationCount}
|
count={notificationCount}
|
||||||
text={<FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' />}
|
text={<FormattedMessage id='tabs_bar.notifications' defaultMessage='Notifications' />}
|
||||||
/>
|
/>
|
||||||
|
@ -144,23 +166,23 @@ const SidebarNavigation = () => {
|
||||||
{features.groups && (
|
{features.groups && (
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/groups'
|
to='/groups'
|
||||||
icon={require('@tabler/icons/outline/circles.svg')}
|
icon={circlesIcon}
|
||||||
activeIcon={require('@tabler/icons/filled/circles.svg')}
|
activeIcon={circlesFilledIcon}
|
||||||
text={<FormattedMessage id='tabs_bar.groups' defaultMessage='Groups' />}
|
text={<FormattedMessage id='tabs_bar.groups' defaultMessage='Groups' />}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to={`/@${account.acct}`}
|
to={`/@${account.acct}`}
|
||||||
icon={require('@tabler/icons/outline/user.svg')}
|
icon={userIcon}
|
||||||
activeIcon={require('@tabler/icons/filled/user.svg')}
|
activeIcon={userFilledIcon}
|
||||||
text={<FormattedMessage id='tabs_bar.profile' defaultMessage='Profile' />}
|
text={<FormattedMessage id='tabs_bar.profile' defaultMessage='Profile' />}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/settings'
|
to='/settings'
|
||||||
icon={require('@tabler/icons/outline/settings.svg')}
|
icon={settingsIcon}
|
||||||
activeIcon={require('@tabler/icons/filled/settings.svg')}
|
activeIcon={settingsFilledIcon}
|
||||||
text={<FormattedMessage id='tabs_bar.settings' defaultMessage='Settings' />}
|
text={<FormattedMessage id='tabs_bar.settings' defaultMessage='Settings' />}
|
||||||
count={settingsNotifications.size}
|
count={settingsNotifications.size}
|
||||||
/>
|
/>
|
||||||
|
@ -168,7 +190,7 @@ const SidebarNavigation = () => {
|
||||||
{account.staff && (
|
{account.staff && (
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/soapbox/admin'
|
to='/soapbox/admin'
|
||||||
icon={require('@tabler/icons/outline/dashboard.svg')}
|
icon={dashboardIcon}
|
||||||
count={dashboardCount}
|
count={dashboardCount}
|
||||||
text={<FormattedMessage id='tabs_bar.dashboard' defaultMessage='Dashboard' />}
|
text={<FormattedMessage id='tabs_bar.dashboard' defaultMessage='Dashboard' />}
|
||||||
/>
|
/>
|
||||||
|
@ -181,7 +203,7 @@ const SidebarNavigation = () => {
|
||||||
{(account || !restrictUnauth.timelines.local) && (
|
{(account || !restrictUnauth.timelines.local) && (
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/timeline/local'
|
to='/timeline/local'
|
||||||
icon={features.federating ? require('@tabler/icons/outline/at.svg') : require('@tabler/icons/outline/world.svg')}
|
icon={features.federating ? atIcon : worldIcon}
|
||||||
text={features.federating ? instance.domain : <FormattedMessage id='tabs_bar.global' defaultMessage='Global' />}
|
text={features.federating ? instance.domain : <FormattedMessage id='tabs_bar.global' defaultMessage='Global' />}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -189,7 +211,7 @@ const SidebarNavigation = () => {
|
||||||
{(features.federating && (account || !restrictUnauth.timelines.federated)) && (
|
{(features.federating && (account || !restrictUnauth.timelines.federated)) && (
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
to='/timeline/global'
|
to='/timeline/global'
|
||||||
icon={require('@tabler/icons/outline/world.svg')}
|
icon={worldIcon}
|
||||||
text={<FormattedMessage id='tabs_bar.global' defaultMessage='Global' />}
|
text={<FormattedMessage id='tabs_bar.global' defaultMessage='Global' />}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -199,7 +221,7 @@ const SidebarNavigation = () => {
|
||||||
{menu.length > 0 && (
|
{menu.length > 0 && (
|
||||||
<DropdownMenu items={menu} placement='top'>
|
<DropdownMenu items={menu} placement='top'>
|
||||||
<SidebarNavigationLink
|
<SidebarNavigationLink
|
||||||
icon={require('@tabler/icons/outline/dots-circle-horizontal.svg')}
|
icon={dotsCircleHorizontalIcon}
|
||||||
text={<FormattedMessage id='tabs_bar.more' defaultMessage='More' />}
|
text={<FormattedMessage id='tabs_bar.more' defaultMessage='More' />}
|
||||||
/>
|
/>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
import soapboxLogoWhiteSrc from 'soapbox/assets/images/soapbox-logo-white.svg';
|
||||||
|
import soapboxLogoSrc from 'soapbox/assets/images/soapbox-logo.svg';
|
||||||
import { useSoapboxConfig, useSettings, useTheme } from 'soapbox/hooks';
|
import { useSoapboxConfig, useSettings, useTheme } from 'soapbox/hooks';
|
||||||
|
|
||||||
interface ISiteLogo extends React.ComponentProps<'img'> {
|
interface ISiteLogo extends React.ComponentProps<'img'> {
|
||||||
|
@ -19,9 +21,7 @@ const SiteLogo: React.FC<ISiteLogo> = ({ className, theme, ...rest }) => {
|
||||||
if (theme === 'dark') darkMode = true;
|
if (theme === 'dark') darkMode = true;
|
||||||
|
|
||||||
/** Soapbox logo. */
|
/** Soapbox logo. */
|
||||||
const soapboxLogo = darkMode
|
const soapboxLogo = darkMode ? soapboxLogoWhiteSrc : soapboxLogoSrc;
|
||||||
? require('soapbox/assets/images/soapbox-logo-white.svg')
|
|
||||||
: require('soapbox/assets/images/soapbox-logo.svg');
|
|
||||||
|
|
||||||
// Use the right logo if provided, then use fallbacks.
|
// Use the right logo if provided, then use fallbacks.
|
||||||
const getSrc = () => {
|
const getSrc = () => {
|
||||||
|
|
|
@ -1,3 +1,35 @@
|
||||||
|
import alertTriangleIcon from '@tabler/icons/outline/alert-triangle.svg';
|
||||||
|
import arrowsVerticalIcon from '@tabler/icons/outline/arrows-vertical.svg';
|
||||||
|
import atIcon from '@tabler/icons/outline/at.svg';
|
||||||
|
import banIcon from '@tabler/icons/outline/ban.svg';
|
||||||
|
import bellOffIcon from '@tabler/icons/outline/bell-off.svg';
|
||||||
|
import bellIcon from '@tabler/icons/outline/bell.svg';
|
||||||
|
import boltIcon from '@tabler/icons/outline/bolt.svg';
|
||||||
|
import bookmarkOffIcon from '@tabler/icons/outline/bookmark-off.svg';
|
||||||
|
import bookmarkIcon from '@tabler/icons/outline/bookmark.svg';
|
||||||
|
import clipboardCopyIcon from '@tabler/icons/outline/clipboard-copy.svg';
|
||||||
|
import dotsIcon from '@tabler/icons/outline/dots.svg';
|
||||||
|
import editIcon from '@tabler/icons/outline/edit.svg';
|
||||||
|
import externalLinkIcon from '@tabler/icons/outline/external-link.svg';
|
||||||
|
import flagIcon from '@tabler/icons/outline/flag.svg';
|
||||||
|
import foldersIcon from '@tabler/icons/outline/folders.svg';
|
||||||
|
import gavelIcon from '@tabler/icons/outline/gavel.svg';
|
||||||
|
import heartIcon from '@tabler/icons/outline/heart.svg';
|
||||||
|
import lockIcon from '@tabler/icons/outline/lock.svg';
|
||||||
|
import mailIcon from '@tabler/icons/outline/mail.svg';
|
||||||
|
import messageCircleIcon from '@tabler/icons/outline/message-circle.svg';
|
||||||
|
import messagesIcon from '@tabler/icons/outline/messages.svg';
|
||||||
|
import pencilIcon from '@tabler/icons/outline/pencil.svg';
|
||||||
|
import pinIcon from '@tabler/icons/outline/pin.svg';
|
||||||
|
import pinnedOffIcon from '@tabler/icons/outline/pinned-off.svg';
|
||||||
|
import quoteIcon from '@tabler/icons/outline/quote.svg';
|
||||||
|
import repeatIcon from '@tabler/icons/outline/repeat.svg';
|
||||||
|
import shareIcon from '@tabler/icons/outline/share.svg';
|
||||||
|
import thumbDownIcon from '@tabler/icons/outline/thumb-down.svg';
|
||||||
|
import thumbUpIcon from '@tabler/icons/outline/thumb-up.svg';
|
||||||
|
import trashIcon from '@tabler/icons/outline/trash.svg';
|
||||||
|
import uploadIcon from '@tabler/icons/outline/upload.svg';
|
||||||
|
import volume3Icon from '@tabler/icons/outline/volume-3.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
import { useHistory, useRouteMatch } from 'react-router-dom';
|
import { useHistory, useRouteMatch } from 'react-router-dom';
|
||||||
|
@ -238,7 +270,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
dispatch(deleteStatus(status.id, withRedraft));
|
dispatch(deleteStatus(status.id, withRedraft));
|
||||||
} else {
|
} else {
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: withRedraft ? require('@tabler/icons/outline/edit.svg') : require('@tabler/icons/outline/trash.svg'),
|
icon: withRedraft ? editIcon : trashIcon,
|
||||||
heading: intl.formatMessage(withRedraft ? messages.redraftHeading : messages.deleteHeading),
|
heading: intl.formatMessage(withRedraft ? messages.redraftHeading : messages.deleteHeading),
|
||||||
message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
|
message: intl.formatMessage(withRedraft ? messages.redraftMessage : messages.deleteMessage),
|
||||||
confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
|
confirm: intl.formatMessage(withRedraft ? messages.redraftConfirm : messages.deleteConfirm),
|
||||||
|
@ -319,7 +351,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
const account = status.account;
|
const account = status.account;
|
||||||
|
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
heading: <FormattedMessage id='confirmations.block.heading' defaultMessage='Block @{name}' values={{ name: account.acct }} />,
|
heading: <FormattedMessage id='confirmations.block.heading' defaultMessage='Block @{name}' values={{ name: account.acct }} />,
|
||||||
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong className='break-words'>@{account.acct}</strong> }} />, // eslint-disable-line formatjs/no-literal-string-in-jsx
|
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong className='break-words'>@{account.acct}</strong> }} />, // eslint-disable-line formatjs/no-literal-string-in-jsx
|
||||||
confirm: intl.formatMessage(messages.blockConfirm),
|
confirm: intl.formatMessage(messages.blockConfirm),
|
||||||
|
@ -409,7 +441,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
if (expandable) {
|
if (expandable) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.open),
|
text: intl.formatMessage(messages.open),
|
||||||
icon: require('@tabler/icons/outline/arrows-vertical.svg'),
|
icon: arrowsVerticalIcon,
|
||||||
to: `/@${status.account.acct}/posts/${status.id}`,
|
to: `/@${status.account.acct}/posts/${status.id}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -418,14 +450,14 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.copy),
|
text: intl.formatMessage(messages.copy),
|
||||||
action: handleCopy,
|
action: handleCopy,
|
||||||
icon: require('@tabler/icons/outline/clipboard-copy.svg'),
|
icon: clipboardCopyIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (features.embeds && account.local) {
|
if (features.embeds && account.local) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.embed),
|
text: intl.formatMessage(messages.embed),
|
||||||
action: handleEmbed,
|
action: handleEmbed,
|
||||||
icon: require('@tabler/icons/outline/share.svg'),
|
icon: shareIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -436,7 +468,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
|
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.external, { domain }),
|
text: intl.formatMessage(messages.external, { domain }),
|
||||||
icon: require('@tabler/icons/outline/external-link.svg'),
|
icon: externalLinkIcon,
|
||||||
href: externalNostrUrl || status.uri,
|
href: externalNostrUrl || status.uri,
|
||||||
target: '_blank',
|
target: '_blank',
|
||||||
});
|
});
|
||||||
|
@ -454,7 +486,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(status.pinned ? messages.unpinFromGroup : messages.pinToGroup),
|
text: intl.formatMessage(status.pinned ? messages.unpinFromGroup : messages.pinToGroup),
|
||||||
action: handleGroupPinClick,
|
action: handleGroupPinClick,
|
||||||
icon: status.pinned ? require('@tabler/icons/outline/pinned-off.svg') : require('@tabler/icons/outline/pin.svg'),
|
icon: status.pinned ? pinnedOffIcon : pinIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -463,7 +495,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(status.bookmarked ? messages.unbookmark : messages.bookmark),
|
text: intl.formatMessage(status.bookmarked ? messages.unbookmark : messages.bookmark),
|
||||||
action: handleBookmarkClick,
|
action: handleBookmarkClick,
|
||||||
icon: status.bookmarked ? require('@tabler/icons/outline/bookmark-off.svg') : require('@tabler/icons/outline/bookmark.svg'),
|
icon: status.bookmarked ? bookmarkOffIcon : bookmarkIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -471,7 +503,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(status.pleroma.get('bookmark_folder') ? messages.bookmarkChangeFolder : messages.bookmarkSetFolder),
|
text: intl.formatMessage(status.pleroma.get('bookmark_folder') ? messages.bookmarkChangeFolder : messages.bookmarkSetFolder),
|
||||||
action: handleBookmarkFolderClick,
|
action: handleBookmarkFolderClick,
|
||||||
icon: require('@tabler/icons/outline/folders.svg'),
|
icon: foldersIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -480,7 +512,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation),
|
text: intl.formatMessage(mutingConversation ? messages.unmuteConversation : messages.muteConversation),
|
||||||
action: handleConversationMuteClick,
|
action: handleConversationMuteClick,
|
||||||
icon: mutingConversation ? require('@tabler/icons/outline/bell.svg') : require('@tabler/icons/outline/bell-off.svg'),
|
icon: mutingConversation ? bellIcon : bellOffIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
|
@ -490,14 +522,14 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(status.pinned ? messages.unpin : messages.pin),
|
text: intl.formatMessage(status.pinned ? messages.unpin : messages.pin),
|
||||||
action: handlePinClick,
|
action: handlePinClick,
|
||||||
icon: status.pinned ? require('@tabler/icons/outline/pinned-off.svg') : require('@tabler/icons/outline/pin.svg'),
|
icon: status.pinned ? pinnedOffIcon : pinIcon,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if (status.visibility === 'private') {
|
if (status.visibility === 'private') {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(status.reblogged ? messages.cancel_reblog_private : messages.reblog_private),
|
text: intl.formatMessage(status.reblogged ? messages.cancel_reblog_private : messages.reblog_private),
|
||||||
action: handleReblogClick,
|
action: handleReblogClick,
|
||||||
icon: require('@tabler/icons/outline/repeat.svg'),
|
icon: repeatIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,20 +537,20 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.delete),
|
text: intl.formatMessage(messages.delete),
|
||||||
action: handleDeleteClick,
|
action: handleDeleteClick,
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
});
|
});
|
||||||
if (features.editStatuses) {
|
if (features.editStatuses) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.edit),
|
text: intl.formatMessage(messages.edit),
|
||||||
action: handleEditClick,
|
action: handleEditClick,
|
||||||
icon: require('@tabler/icons/outline/edit.svg'),
|
icon: editIcon,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.redraft),
|
text: intl.formatMessage(messages.redraft),
|
||||||
action: handleRedraftClick,
|
action: handleRedraftClick,
|
||||||
icon: require('@tabler/icons/outline/edit.svg'),
|
icon: editIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -526,20 +558,20 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.mention, { name: username }),
|
text: intl.formatMessage(messages.mention, { name: username }),
|
||||||
action: handleMentionClick,
|
action: handleMentionClick,
|
||||||
icon: require('@tabler/icons/outline/at.svg'),
|
icon: atIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (status.account.pleroma?.accepts_chat_messages === true) {
|
if (status.account.pleroma?.accepts_chat_messages === true) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.chat, { name: username }),
|
text: intl.formatMessage(messages.chat, { name: username }),
|
||||||
action: handleChatClick,
|
action: handleChatClick,
|
||||||
icon: require('@tabler/icons/outline/messages.svg'),
|
icon: messagesIcon,
|
||||||
});
|
});
|
||||||
} else if (features.privacyScopes) {
|
} else if (features.privacyScopes) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.direct, { name: username }),
|
text: intl.formatMessage(messages.direct, { name: username }),
|
||||||
action: handleDirectClick,
|
action: handleDirectClick,
|
||||||
icon: require('@tabler/icons/outline/mail.svg'),
|
icon: mailIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -547,7 +579,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
if (features.groupsMuting && status.group) {
|
if (features.groupsMuting && status.group) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: isMutingGroup ? intl.formatMessage(messages.unmuteGroup) : intl.formatMessage(messages.muteGroup),
|
text: isMutingGroup ? intl.formatMessage(messages.unmuteGroup) : intl.formatMessage(messages.muteGroup),
|
||||||
icon: require('@tabler/icons/outline/volume-3.svg'),
|
icon: volume3Icon,
|
||||||
action: isMutingGroup ? handleUnmuteGroupClick : handleMuteGroupClick,
|
action: isMutingGroup ? handleUnmuteGroupClick : handleMuteGroupClick,
|
||||||
});
|
});
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
|
@ -556,19 +588,19 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.mute, { name: username }),
|
text: intl.formatMessage(messages.mute, { name: username }),
|
||||||
action: handleMuteClick,
|
action: handleMuteClick,
|
||||||
icon: require('@tabler/icons/outline/volume-3.svg'),
|
icon: volume3Icon,
|
||||||
});
|
});
|
||||||
if (features.blocks) {
|
if (features.blocks) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.block, { name: username }),
|
text: intl.formatMessage(messages.block, { name: username }),
|
||||||
action: handleBlockClick,
|
action: handleBlockClick,
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.report, { name: username }),
|
text: intl.formatMessage(messages.report, { name: username }),
|
||||||
action: handleReport,
|
action: handleReport,
|
||||||
icon: require('@tabler/icons/outline/flag.svg'),
|
icon: flagIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -590,7 +622,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: 'Ban from Group',
|
text: 'Ban from Group',
|
||||||
action: handleBlockFromGroup,
|
action: handleBlockFromGroup,
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -599,7 +631,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.groupModDelete),
|
text: intl.formatMessage(messages.groupModDelete),
|
||||||
action: handleDeleteFromGroup,
|
action: handleDeleteFromGroup,
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -611,28 +643,28 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.adminAccount, { name: username }),
|
text: intl.formatMessage(messages.adminAccount, { name: username }),
|
||||||
action: onModerate,
|
action: onModerate,
|
||||||
icon: require('@tabler/icons/outline/gavel.svg'),
|
icon: gavelIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.admin_status),
|
text: intl.formatMessage(messages.admin_status),
|
||||||
href: `/pleroma/admin/#/statuses/${status.id}/`,
|
href: `/pleroma/admin/#/statuses/${status.id}/`,
|
||||||
icon: require('@tabler/icons/outline/pencil.svg'),
|
icon: pencilIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(status.sensitive === false ? messages.markStatusSensitive : messages.markStatusNotSensitive),
|
text: intl.formatMessage(status.sensitive === false ? messages.markStatusSensitive : messages.markStatusNotSensitive),
|
||||||
action: handleToggleStatusSensitivity,
|
action: handleToggleStatusSensitivity,
|
||||||
icon: require('@tabler/icons/outline/alert-triangle.svg'),
|
icon: alertTriangleIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!ownAccount) {
|
if (!ownAccount) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.deleteStatus),
|
text: intl.formatMessage(messages.deleteStatus),
|
||||||
action: handleDeleteStatus,
|
action: handleDeleteStatus,
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -670,14 +702,14 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
const meEmojiTitle = intl.formatMessage(reactMessages[meEmojiName || ''] || messages.favourite);
|
const meEmojiTitle = intl.formatMessage(reactMessages[meEmojiName || ''] || messages.favourite);
|
||||||
|
|
||||||
const menu = _makeMenu(publicStatus);
|
const menu = _makeMenu(publicStatus);
|
||||||
let reblogIcon = require('@tabler/icons/outline/repeat.svg');
|
let reblogIcon = repeatIcon;
|
||||||
let replyTitle;
|
let replyTitle;
|
||||||
let replyDisabled = false;
|
let replyDisabled = false;
|
||||||
|
|
||||||
if (status.visibility === 'direct') {
|
if (status.visibility === 'direct') {
|
||||||
reblogIcon = require('@tabler/icons/outline/mail.svg');
|
reblogIcon = mailIcon;
|
||||||
} else if (status.visibility === 'private') {
|
} else if (status.visibility === 'private') {
|
||||||
reblogIcon = require('@tabler/icons/outline/lock.svg');
|
reblogIcon = lockIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((status.group as Group)?.membership_required && !groupRelationship?.member) {
|
if ((status.group as Group)?.membership_required && !groupRelationship?.member) {
|
||||||
|
@ -688,11 +720,11 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
const reblogMenu = [{
|
const reblogMenu = [{
|
||||||
text: intl.formatMessage(status.reblogged ? messages.cancel_reblog_private : messages.reblog),
|
text: intl.formatMessage(status.reblogged ? messages.cancel_reblog_private : messages.reblog),
|
||||||
action: handleReblogClick,
|
action: handleReblogClick,
|
||||||
icon: require('@tabler/icons/outline/repeat.svg'),
|
icon: repeatIcon,
|
||||||
}, {
|
}, {
|
||||||
text: intl.formatMessage(messages.quotePost),
|
text: intl.formatMessage(messages.quotePost),
|
||||||
action: handleQuoteClick,
|
action: handleQuoteClick,
|
||||||
icon: require('@tabler/icons/outline/quote.svg'),
|
icon: quoteIcon,
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const reblogButton = (
|
const reblogButton = (
|
||||||
|
@ -741,7 +773,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
>
|
>
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
title={replyTitle}
|
title={replyTitle}
|
||||||
icon={require('@tabler/icons/outline/message-circle.svg')}
|
icon={messageCircleIcon}
|
||||||
onClick={handleReplyClick}
|
onClick={handleReplyClick}
|
||||||
count={replyCount}
|
count={replyCount}
|
||||||
text={withLabels ? intl.formatMessage(messages.reply) : undefined}
|
text={withLabels ? intl.formatMessage(messages.reply) : undefined}
|
||||||
|
@ -766,7 +798,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
<StatusReactionWrapper statusId={status.id}>
|
<StatusReactionWrapper statusId={status.id}>
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
title={meEmojiTitle}
|
title={meEmojiTitle}
|
||||||
icon={require('@tabler/icons/outline/heart.svg')}
|
icon={heartIcon}
|
||||||
filled
|
filled
|
||||||
color='accent'
|
color='accent'
|
||||||
active={Boolean(meEmojiName)}
|
active={Boolean(meEmojiName)}
|
||||||
|
@ -779,7 +811,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
) : (
|
) : (
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
title={intl.formatMessage(messages.favourite)}
|
title={intl.formatMessage(messages.favourite)}
|
||||||
icon={features.dislikes ? require('@tabler/icons/outline/thumb-up.svg') : require('@tabler/icons/outline/heart.svg')}
|
icon={features.dislikes ? thumbUpIcon : heartIcon}
|
||||||
color='accent'
|
color='accent'
|
||||||
filled
|
filled
|
||||||
onClick={handleFavouriteClick}
|
onClick={handleFavouriteClick}
|
||||||
|
@ -793,7 +825,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
{features.dislikes && (
|
{features.dislikes && (
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
title={intl.formatMessage(messages.disfavourite)}
|
title={intl.formatMessage(messages.disfavourite)}
|
||||||
icon={require('@tabler/icons/outline/thumb-down.svg')}
|
icon={thumbDownIcon}
|
||||||
color='accent'
|
color='accent'
|
||||||
filled
|
filled
|
||||||
onClick={handleDislikeClick}
|
onClick={handleDislikeClick}
|
||||||
|
@ -807,7 +839,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
{(acceptsZaps) && (
|
{(acceptsZaps) && (
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
title={intl.formatMessage(messages.zap)}
|
title={intl.formatMessage(messages.zap)}
|
||||||
icon={require('@tabler/icons/outline/bolt.svg')}
|
icon={boltIcon}
|
||||||
color='accent'
|
color='accent'
|
||||||
filled
|
filled
|
||||||
onClick={handleZapClick}
|
onClick={handleZapClick}
|
||||||
|
@ -821,7 +853,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
{canShare && (
|
{canShare && (
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
title={intl.formatMessage(messages.share)}
|
title={intl.formatMessage(messages.share)}
|
||||||
icon={require('@tabler/icons/outline/upload.svg')}
|
icon={uploadIcon}
|
||||||
onClick={handleShareClick}
|
onClick={handleShareClick}
|
||||||
theme={statusActionButtonTheme}
|
theme={statusActionButtonTheme}
|
||||||
/>
|
/>
|
||||||
|
@ -830,7 +862,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
<DropdownMenu items={menu} status={status}>
|
<DropdownMenu items={menu} status={status}>
|
||||||
<StatusActionButton
|
<StatusActionButton
|
||||||
title={intl.formatMessage(messages.more)}
|
title={intl.formatMessage(messages.more)}
|
||||||
icon={require('@tabler/icons/outline/dots.svg')}
|
icon={dotsIcon}
|
||||||
theme={statusActionButtonTheme}
|
theme={statusActionButtonTheme}
|
||||||
/>
|
/>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import chevronRightIcon from '@tabler/icons/outline/chevron-right.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import parse, { Element, type HTMLReactParserOptions, domToReact, type DOMNode } from 'html-react-parser';
|
import parse, { Element, type HTMLReactParserOptions, domToReact, type DOMNode } from 'html-react-parser';
|
||||||
import React, { useState, useRef, useLayoutEffect, useMemo } from 'react';
|
import React, { useState, useRef, useLayoutEffect, useMemo } from 'react';
|
||||||
|
@ -27,7 +28,7 @@ interface IReadMoreButton {
|
||||||
const ReadMoreButton: React.FC<IReadMoreButton> = ({ onClick }) => (
|
const ReadMoreButton: React.FC<IReadMoreButton> = ({ onClick }) => (
|
||||||
<button className='flex items-center border-0 bg-transparent p-0 pt-2 text-gray-900 hover:underline active:underline dark:text-gray-300' onClick={onClick}>
|
<button className='flex items-center border-0 bg-transparent p-0 pt-2 text-gray-900 hover:underline active:underline dark:text-gray-300' onClick={onClick}>
|
||||||
<FormattedMessage id='status.read_more' defaultMessage='Read more' />
|
<FormattedMessage id='status.read_more' defaultMessage='Read more' />
|
||||||
<Icon className='inline-block size-5' src={require('@tabler/icons/outline/chevron-right.svg')} />
|
<Icon className='inline-block size-5' src={chevronRightIcon} />
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import circlesIcon from '@tabler/icons/outline/circles.svg';
|
||||||
|
import pinnedIcon from '@tabler/icons/outline/pinned.svg';
|
||||||
|
import repeatIcon from '@tabler/icons/outline/repeat.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useEffect, useRef, useState } from 'react';
|
import React, { useEffect, useRef, useState } from 'react';
|
||||||
import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
|
import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
|
||||||
|
@ -212,7 +215,7 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
return (
|
return (
|
||||||
<StatusInfo
|
<StatusInfo
|
||||||
avatarSize={avatarSize}
|
avatarSize={avatarSize}
|
||||||
icon={<Icon src={require('@tabler/icons/outline/repeat.svg')} className='size-4 text-green-600' />}
|
icon={<Icon src={repeatIcon} className='size-4 text-green-600' />}
|
||||||
text={
|
text={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='status.reblogged_by_with_group'
|
id='status.reblogged_by_with_group'
|
||||||
|
@ -252,7 +255,7 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
return (
|
return (
|
||||||
<StatusInfo
|
<StatusInfo
|
||||||
avatarSize={avatarSize}
|
avatarSize={avatarSize}
|
||||||
icon={<Icon src={require('@tabler/icons/outline/repeat.svg')} className='size-4 text-green-600' />}
|
icon={<Icon src={repeatIcon} className='size-4 text-green-600' />}
|
||||||
text={
|
text={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='status.reblogged_by'
|
id='status.reblogged_by'
|
||||||
|
@ -279,7 +282,7 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
return (
|
return (
|
||||||
<StatusInfo
|
<StatusInfo
|
||||||
avatarSize={avatarSize}
|
avatarSize={avatarSize}
|
||||||
icon={<Icon src={require('@tabler/icons/outline/pinned.svg')} className='size-4 text-gray-600 dark:text-gray-400' />}
|
icon={<Icon src={pinnedIcon} className='size-4 text-gray-600 dark:text-gray-400' />}
|
||||||
text={
|
text={
|
||||||
<FormattedMessage id='status.pinned' defaultMessage='Pinned post' />
|
<FormattedMessage id='status.pinned' defaultMessage='Pinned post' />
|
||||||
}
|
}
|
||||||
|
@ -289,7 +292,7 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
return (
|
return (
|
||||||
<StatusInfo
|
<StatusInfo
|
||||||
avatarSize={avatarSize}
|
avatarSize={avatarSize}
|
||||||
icon={<Icon src={require('@tabler/icons/outline/circles.svg')} className='size-4 text-primary-600 dark:text-accent-blue' />}
|
icon={<Icon src={circlesIcon} className='size-4 text-primary-600 dark:text-accent-blue' />}
|
||||||
text={
|
text={
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='status.group'
|
id='status.group'
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
import dotsIcon from '@tabler/icons/outline/dots.svg';
|
||||||
|
import eyeOffIcon from '@tabler/icons/outline/eye-off.svg';
|
||||||
|
import eyeIcon from '@tabler/icons/outline/eye.svg';
|
||||||
|
import headsetIcon from '@tabler/icons/outline/headset.svg';
|
||||||
|
import trashIcon from '@tabler/icons/outline/trash.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useEffect, useMemo, useState } from 'react';
|
import React, { useEffect, useMemo, useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -61,7 +66,7 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
|
||||||
dispatch(deleteStatus(status.id, false));
|
dispatch(deleteStatus(status.id, false));
|
||||||
} else {
|
} else {
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
heading: intl.formatMessage(messages.deleteHeading),
|
heading: intl.formatMessage(messages.deleteHeading),
|
||||||
message: intl.formatMessage(messages.deleteMessage),
|
message: intl.formatMessage(messages.deleteMessage),
|
||||||
confirm: intl.formatMessage(messages.deleteConfirm),
|
confirm: intl.formatMessage(messages.deleteConfirm),
|
||||||
|
@ -75,7 +80,7 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
|
||||||
{
|
{
|
||||||
text: intl.formatMessage(messages.delete),
|
text: intl.formatMessage(messages.delete),
|
||||||
action: handleDeleteStatus,
|
action: handleDeleteStatus,
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -99,7 +104,7 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
|
||||||
{visible ? (
|
{visible ? (
|
||||||
<Button
|
<Button
|
||||||
text={intl.formatMessage(messages.hide)}
|
text={intl.formatMessage(messages.hide)}
|
||||||
icon={require('@tabler/icons/outline/eye-off.svg')}
|
icon={eyeOffIcon}
|
||||||
onClick={toggleVisibility}
|
onClick={toggleVisibility}
|
||||||
theme='primary'
|
theme='primary'
|
||||||
size='sm'
|
size='sm'
|
||||||
|
@ -140,7 +145,7 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
|
||||||
type='button'
|
type='button'
|
||||||
theme='outline'
|
theme='outline'
|
||||||
size='sm'
|
size='sm'
|
||||||
icon={require('@tabler/icons/outline/headset.svg')}
|
icon={headsetIcon}
|
||||||
>
|
>
|
||||||
{intl.formatMessage(messages.contact)}
|
{intl.formatMessage(messages.contact)}
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -153,7 +158,7 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
|
||||||
type='button'
|
type='button'
|
||||||
theme='outline'
|
theme='outline'
|
||||||
size='sm'
|
size='sm'
|
||||||
icon={require('@tabler/icons/outline/eye.svg')}
|
icon={eyeIcon}
|
||||||
onClick={toggleVisibility}
|
onClick={toggleVisibility}
|
||||||
>
|
>
|
||||||
{intl.formatMessage(messages.show)}
|
{intl.formatMessage(messages.show)}
|
||||||
|
@ -162,7 +167,7 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
|
||||||
{(isUnderReview && isOwnStatus) ? (
|
{(isUnderReview && isOwnStatus) ? (
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
items={menu}
|
items={menu}
|
||||||
src={require('@tabler/icons/outline/dots.svg')}
|
src={dotsIcon}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
|
@ -1,3 +1,14 @@
|
||||||
|
import bellFilledIcon from '@tabler/icons/filled/bell.svg';
|
||||||
|
import circlesFilledIcon from '@tabler/icons/filled/circles.svg';
|
||||||
|
import homeFilledIcon from '@tabler/icons/filled/home.svg';
|
||||||
|
import mailFilledIcon from '@tabler/icons/filled/mail.svg';
|
||||||
|
import bellIcon from '@tabler/icons/outline/bell.svg';
|
||||||
|
import circlesIcon from '@tabler/icons/outline/circles.svg';
|
||||||
|
import dashboardIcon from '@tabler/icons/outline/dashboard.svg';
|
||||||
|
import homeIcon from '@tabler/icons/outline/home.svg';
|
||||||
|
import mailIcon from '@tabler/icons/outline/mail.svg';
|
||||||
|
import messagesIcon from '@tabler/icons/outline/messages.svg';
|
||||||
|
import searchIcon from '@tabler/icons/outline/search.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
@ -19,7 +30,7 @@ const ThumbNavigation: React.FC = (): JSX.Element => {
|
||||||
if (features.chats) {
|
if (features.chats) {
|
||||||
return (
|
return (
|
||||||
<ThumbNavigationLink
|
<ThumbNavigationLink
|
||||||
src={require('@tabler/icons/outline/messages.svg')}
|
src={messagesIcon}
|
||||||
text={<FormattedMessage id='navigation.chats' defaultMessage='Chats' />}
|
text={<FormattedMessage id='navigation.chats' defaultMessage='Chats' />}
|
||||||
to='/chats'
|
to='/chats'
|
||||||
exact
|
exact
|
||||||
|
@ -32,8 +43,8 @@ const ThumbNavigation: React.FC = (): JSX.Element => {
|
||||||
if (features.directTimeline || features.conversations) {
|
if (features.directTimeline || features.conversations) {
|
||||||
return (
|
return (
|
||||||
<ThumbNavigationLink
|
<ThumbNavigationLink
|
||||||
src={require('@tabler/icons/outline/mail.svg')}
|
src={mailIcon}
|
||||||
activeSrc={require('@tabler/icons/filled/mail.svg')}
|
activeSrc={mailFilledIcon}
|
||||||
text={<FormattedMessage id='navigation.direct_messages' defaultMessage='Messages' />}
|
text={<FormattedMessage id='navigation.direct_messages' defaultMessage='Messages' />}
|
||||||
to='/messages'
|
to='/messages'
|
||||||
paths={['/messages', '/conversations']}
|
paths={['/messages', '/conversations']}
|
||||||
|
@ -47,8 +58,8 @@ const ThumbNavigation: React.FC = (): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<div className='thumb-navigation'>
|
<div className='thumb-navigation'>
|
||||||
<ThumbNavigationLink
|
<ThumbNavigationLink
|
||||||
src={require('@tabler/icons/outline/home.svg')}
|
src={homeIcon}
|
||||||
activeSrc={require('@tabler/icons/filled/home.svg')}
|
activeSrc={homeFilledIcon}
|
||||||
text={<FormattedMessage id='navigation.home' defaultMessage='Home' />}
|
text={<FormattedMessage id='navigation.home' defaultMessage='Home' />}
|
||||||
to='/'
|
to='/'
|
||||||
exact
|
exact
|
||||||
|
@ -56,8 +67,8 @@ const ThumbNavigation: React.FC = (): JSX.Element => {
|
||||||
|
|
||||||
{features.groups && (
|
{features.groups && (
|
||||||
<ThumbNavigationLink
|
<ThumbNavigationLink
|
||||||
src={require('@tabler/icons/outline/circles.svg')}
|
src={circlesIcon}
|
||||||
activeSrc={require('@tabler/icons/filled/circles.svg')}
|
activeSrc={circlesFilledIcon}
|
||||||
text={<FormattedMessage id='tabs_bar.groups' defaultMessage='Groups' />}
|
text={<FormattedMessage id='tabs_bar.groups' defaultMessage='Groups' />}
|
||||||
to='/groups'
|
to='/groups'
|
||||||
exact
|
exact
|
||||||
|
@ -65,7 +76,7 @@ const ThumbNavigation: React.FC = (): JSX.Element => {
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<ThumbNavigationLink
|
<ThumbNavigationLink
|
||||||
src={require('@tabler/icons/outline/search.svg')}
|
src={searchIcon}
|
||||||
text={<FormattedMessage id='navigation.search' defaultMessage='Discover' />}
|
text={<FormattedMessage id='navigation.search' defaultMessage='Discover' />}
|
||||||
to='/search'
|
to='/search'
|
||||||
exact
|
exact
|
||||||
|
@ -73,8 +84,8 @@ const ThumbNavigation: React.FC = (): JSX.Element => {
|
||||||
|
|
||||||
{account && (
|
{account && (
|
||||||
<ThumbNavigationLink
|
<ThumbNavigationLink
|
||||||
src={require('@tabler/icons/outline/bell.svg')}
|
src={bellIcon}
|
||||||
activeSrc={require('@tabler/icons/filled/bell.svg')}
|
activeSrc={bellFilledIcon}
|
||||||
text={<FormattedMessage id='navigation.notifications' defaultMessage='Notifications' />}
|
text={<FormattedMessage id='navigation.notifications' defaultMessage='Notifications' />}
|
||||||
to='/notifications'
|
to='/notifications'
|
||||||
exact
|
exact
|
||||||
|
@ -86,7 +97,7 @@ const ThumbNavigation: React.FC = (): JSX.Element => {
|
||||||
|
|
||||||
{(account && account.staff) && (
|
{(account && account.staff) && (
|
||||||
<ThumbNavigationLink
|
<ThumbNavigationLink
|
||||||
src={require('@tabler/icons/outline/dashboard.svg')}
|
src={dashboardIcon}
|
||||||
text={<FormattedMessage id='navigation.dashboard' defaultMessage='Dashboard' />}
|
text={<FormattedMessage id='navigation.dashboard' defaultMessage='Dashboard' />}
|
||||||
to='/soapbox/admin'
|
to='/soapbox/admin'
|
||||||
count={dashboardCount}
|
count={dashboardCount}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import languageIcon from '@tabler/icons/outline/language.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage, useIntl } from 'react-intl';
|
import { FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -53,7 +54,7 @@ const TranslateButton: React.FC<ITranslateButton> = ({ status }) => {
|
||||||
<Button
|
<Button
|
||||||
theme='muted'
|
theme='muted'
|
||||||
text={<FormattedMessage id='status.show_original' defaultMessage='Show original' />}
|
text={<FormattedMessage id='status.show_original' defaultMessage='Show original' />}
|
||||||
icon={require('@tabler/icons/outline/language.svg')}
|
icon={languageIcon}
|
||||||
onClick={handleTranslate}
|
onClick={handleTranslate}
|
||||||
/>
|
/>
|
||||||
<Text theme='muted'>
|
<Text theme='muted'>
|
||||||
|
@ -68,7 +69,7 @@ const TranslateButton: React.FC<ITranslateButton> = ({ status }) => {
|
||||||
<Button
|
<Button
|
||||||
theme='muted'
|
theme='muted'
|
||||||
text={<FormattedMessage id='status.translate' defaultMessage='Translate' />}
|
text={<FormattedMessage id='status.translate' defaultMessage='Translate' />}
|
||||||
icon={require('@tabler/icons/outline/language.svg')}
|
icon={languageIcon}
|
||||||
onClick={handleTranslate}
|
onClick={handleTranslate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import chevronDownIcon from '@tabler/icons/outline/chevron-down.svg';
|
||||||
|
import chevronUpIcon from '@tabler/icons/outline/chevron-up.svg';
|
||||||
|
import dotsVerticalIcon from '@tabler/icons/outline/dots-vertical.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -60,7 +63,7 @@ const Accordion: React.FC<IAccordion> = ({ headline, children, menu, expanded =
|
||||||
{menu && (
|
{menu && (
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
items={menu}
|
items={menu}
|
||||||
src={require('@tabler/icons/outline/dots-vertical.svg')}
|
src={dotsVerticalIcon}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{action && actionIcon && (
|
{action && actionIcon && (
|
||||||
|
@ -72,7 +75,7 @@ const Accordion: React.FC<IAccordion> = ({ headline, children, menu, expanded =
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
<Icon
|
<Icon
|
||||||
src={expanded ? require('@tabler/icons/outline/chevron-up.svg') : require('@tabler/icons/outline/chevron-down.svg')}
|
src={expanded ? chevronUpIcon : chevronDownIcon}
|
||||||
className='size-5 text-gray-700 dark:text-gray-600'
|
className='size-5 text-gray-700 dark:text-gray-600'
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import photoOffIcon from '@tabler/icons/outline/photo-off.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ const Avatar = (props: IAvatar) => {
|
||||||
className={clsx('flex items-center justify-center rounded-full bg-gray-200 dark:bg-gray-900', className)}
|
className={clsx('flex items-center justify-center rounded-full bg-gray-200 dark:bg-gray-900', className)}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/photo-off.svg')}
|
src={photoOffIcon}
|
||||||
className='size-4 text-gray-500 dark:text-gray-700'
|
className='size-4 text-gray-500 dark:text-gray-700'
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import arrowLeftIcon from '@tabler/icons/outline/arrow-left.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -72,7 +73,7 @@ const CardHeader: React.FC<ICardHeader> = ({ className, children, backHref, onBa
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Comp {...backAttributes} className='rounded-full text-gray-900 focus:ring-2 focus:ring-primary-500 dark:text-gray-100' aria-label={intl.formatMessage(messages.back)}>
|
<Comp {...backAttributes} className='rounded-full text-gray-900 focus:ring-2 focus:ring-primary-500 dark:text-gray-100' aria-label={intl.formatMessage(messages.back)}>
|
||||||
<SvgIcon src={require('@tabler/icons/outline/arrow-left.svg')} className='size-6 rtl:rotate-180' />
|
<SvgIcon src={arrowLeftIcon} className='size-6 rtl:rotate-180' />
|
||||||
<span className='sr-only' data-testid='back-button'>{intl.formatMessage(messages.back)}</span>
|
<span className='sr-only' data-testid='back-button'>{intl.formatMessage(messages.back)}</span>
|
||||||
</Comp>
|
</Comp>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import chevronLeftIcon from '@tabler/icons/outline/chevron-left.svg';
|
||||||
|
import chevronRightIcon from '@tabler/icons/outline/chevron-right.svg';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
import { useDimensions } from 'soapbox/hooks';
|
import { useDimensions } from 'soapbox/hooks';
|
||||||
|
@ -68,7 +70,7 @@ const Carousel: React.FC<ICarousel> = (props): JSX.Element => {
|
||||||
disabled={!hasPrevPage || isDisabled}
|
disabled={!hasPrevPage || isDisabled}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/chevron-left.svg')}
|
src={chevronLeftIcon}
|
||||||
className='size-5 text-black dark:text-white'
|
className='size-5 text-black dark:text-white'
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
@ -100,7 +102,7 @@ const Carousel: React.FC<ICarousel> = (props): JSX.Element => {
|
||||||
disabled={!hasNextPage || isDisabled}
|
disabled={!hasNextPage || isDisabled}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/chevron-right.svg')}
|
src={chevronRightIcon}
|
||||||
className='size-5 text-black dark:text-white'
|
className='size-5 text-black dark:text-white'
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { shift, useFloating, Placement, offset, OffsetOptions } from '@floating-ui/react';
|
import { shift, useFloating, Placement, offset, OffsetOptions } from '@floating-ui/react';
|
||||||
|
import dotsIcon from '@tabler/icons/outline/dots.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useEffect, useState } from 'react';
|
import React, { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
@ -134,7 +135,7 @@ const EmojiSelector: React.FC<IEmojiSelector> = ({
|
||||||
{all && (
|
{all && (
|
||||||
<IconButton
|
<IconButton
|
||||||
className='text-gray-600 hover:text-gray-600 dark:hover:text-white'
|
className='text-gray-600 hover:text-gray-600 dark:hover:text-white'
|
||||||
src={require('@tabler/icons/outline/dots.svg')}
|
src={dotsIcon}
|
||||||
onClick={handleExpand}
|
onClick={handleExpand}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import eyeOffIcon from '@tabler/icons/outline/eye-off.svg';
|
||||||
|
import eyeIcon from '@tabler/icons/outline/eye.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -123,7 +125,7 @@ const Input = React.forwardRef<HTMLInputElement, IInput>(
|
||||||
className='h-full px-2 text-gray-700 hover:text-gray-500 focus:ring-2 focus:ring-primary-500 dark:text-gray-600 dark:hover:text-gray-400'
|
className='h-full px-2 text-gray-700 hover:text-gray-500 focus:ring-2 focus:ring-primary-500 dark:text-gray-600 dark:hover:text-gray-400'
|
||||||
>
|
>
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
src={revealed ? require('@tabler/icons/outline/eye-off.svg') : require('@tabler/icons/outline/eye.svg')}
|
src={revealed ? eyeOffIcon : eyeIcon}
|
||||||
className='size-4'
|
className='size-4'
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import worldIcon from '@tabler/icons/outline/world.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { openDropdownMenu } from 'soapbox/actions/dropdown-menu';
|
import { openDropdownMenu } from 'soapbox/actions/dropdown-menu';
|
||||||
|
@ -26,7 +27,7 @@ const LanguageDropdown: React.FC<ILanguageDropdown> = ({ language, setLanguage }
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
const formattedLanguages = formatLanguages(languages);
|
const formattedLanguages = formatLanguages(languages);
|
||||||
|
|
||||||
const newMenu: MenuItem[] = [{ icon: require('@tabler/icons/outline/world.svg'), text: 'Default', action: () => {
|
const newMenu: MenuItem[] = [{ icon: worldIcon, text: 'Default', action: () => {
|
||||||
setLanguage('');
|
setLanguage('');
|
||||||
} }];
|
} }];
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ const LanguageDropdown: React.FC<ILanguageDropdown> = ({ language, setLanguage }
|
||||||
{language.toUpperCase()}
|
{language.toUpperCase()}
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<SvgIcon src={require('@tabler/icons/outline/world.svg')} className='text-gray-700 hover:cursor-pointer hover:text-gray-500 black:absolute black:right-0 black:top-4 black:text-white black:hover:text-gray-600 dark:text-white sm:mr-4' />
|
<SvgIcon src={worldIcon} className='text-gray-700 hover:cursor-pointer hover:text-gray-500 black:absolute black:right-0 black:top-4 black:text-white black:hover:text-gray-600 dark:text-white sm:mr-4' />
|
||||||
)}
|
)}
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import arrowLeftIcon from '@tabler/icons/outline/arrow-left.svg';
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -72,7 +74,7 @@ const Modal = React.forwardRef<HTMLDivElement, IModal>(({
|
||||||
cancelAction,
|
cancelAction,
|
||||||
cancelText,
|
cancelText,
|
||||||
children,
|
children,
|
||||||
closeIcon = require('@tabler/icons/outline/x.svg'),
|
closeIcon = xIcon,
|
||||||
closePosition = 'right',
|
closePosition = 'right',
|
||||||
confirmationAction,
|
confirmationAction,
|
||||||
confirmationDisabled,
|
confirmationDisabled,
|
||||||
|
@ -115,7 +117,7 @@ const Modal = React.forwardRef<HTMLDivElement, IModal>(({
|
||||||
>
|
>
|
||||||
{onBack && (
|
{onBack && (
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/arrow-left.svg')}
|
src={arrowLeftIcon}
|
||||||
title={intl.formatMessage(messages.back)}
|
title={intl.formatMessage(messages.back)}
|
||||||
onClick={onBack}
|
onClick={onBack}
|
||||||
className='text-gray-500 hover:text-gray-700 dark:text-gray-300 dark:hover:text-gray-200 rtl:rotate-180'
|
className='text-gray-500 hover:text-gray-700 dark:text-gray-300 dark:hover:text-gray-200 rtl:rotate-180'
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useIntl, defineMessages } from 'react-intl';
|
import { useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
@ -83,7 +84,7 @@ const Streamfield: React.FC<IStreamfield> = ({
|
||||||
<IconButton
|
<IconButton
|
||||||
iconClassName='h-4 w-4'
|
iconClassName='h-4 w-4'
|
||||||
className='bg-transparent text-gray-600 hover:text-gray-600'
|
className='bg-transparent text-gray-600 hover:text-gray-600'
|
||||||
src={require('@tabler/icons/outline/x.svg')}
|
src={xIcon}
|
||||||
onClick={() => onRemoveItem(i)}
|
onClick={() => onRemoveItem(i)}
|
||||||
title={intl.formatMessage(messages.remove)}
|
title={intl.formatMessage(messages.remove)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import IconButton from '../icon-button/icon-button';
|
import IconButton from '../icon-button/icon-button';
|
||||||
|
@ -18,7 +19,7 @@ const Tag: React.FC<ITag> = ({ tag, onDelete }) => {
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
iconClassName='h-4 w-4'
|
iconClassName='h-4 w-4'
|
||||||
src={require('@tabler/icons/outline/x.svg')}
|
src={xIcon}
|
||||||
onClick={() => onDelete(tag)}
|
onClick={() => onDelete(tag)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import alertCircleIcon from '@tabler/icons/outline/alert-circle.svg';
|
||||||
|
import circleCheckIcon from '@tabler/icons/outline/circle-check.svg';
|
||||||
|
import infoCircleIcon from '@tabler/icons/outline/info-circle.svg';
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import toast, { Toast as RHToast } from 'react-hot-toast';
|
import toast, { Toast as RHToast } from 'react-hot-toast';
|
||||||
|
@ -42,7 +46,7 @@ const Toast = (props: IToast) => {
|
||||||
case 'success':
|
case 'success':
|
||||||
return (
|
return (
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/circle-check.svg')}
|
src={circleCheckIcon}
|
||||||
className='size-6 text-success-500 dark:text-success-400'
|
className='size-6 text-success-500 dark:text-success-400'
|
||||||
aria-hidden
|
aria-hidden
|
||||||
/>
|
/>
|
||||||
|
@ -50,7 +54,7 @@ const Toast = (props: IToast) => {
|
||||||
case 'info':
|
case 'info':
|
||||||
return (
|
return (
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/info-circle.svg')}
|
src={infoCircleIcon}
|
||||||
className='size-6 text-primary-600 dark:text-accent-blue'
|
className='size-6 text-primary-600 dark:text-accent-blue'
|
||||||
aria-hidden
|
aria-hidden
|
||||||
/>
|
/>
|
||||||
|
@ -58,7 +62,7 @@ const Toast = (props: IToast) => {
|
||||||
case 'error':
|
case 'error':
|
||||||
return (
|
return (
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/alert-circle.svg')}
|
src={alertCircleIcon}
|
||||||
className='size-6 text-danger-600'
|
className='size-6 text-danger-600'
|
||||||
aria-hidden
|
aria-hidden
|
||||||
/>
|
/>
|
||||||
|
@ -143,7 +147,7 @@ const Toast = (props: IToast) => {
|
||||||
data-testid='toast-dismiss'
|
data-testid='toast-dismiss'
|
||||||
>
|
>
|
||||||
<span className='sr-only'><FormattedMessage id='lightbox.close' defaultMessage='Close' /></span>
|
<span className='sr-only'><FormattedMessage id='lightbox.close' defaultMessage='Close' /></span>
|
||||||
<Icon src={require('@tabler/icons/outline/x.svg')} className='size-5' />
|
<Icon src={xIcon} className='size-5' />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import arrowRightIcon from '@tabler/icons/outline/arrow-right.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import HStack from 'soapbox/components/ui/hstack/hstack';
|
import HStack from 'soapbox/components/ui/hstack/hstack';
|
||||||
|
@ -42,7 +43,7 @@ const Widget: React.FC<IWidget> = ({
|
||||||
title,
|
title,
|
||||||
children,
|
children,
|
||||||
onActionClick,
|
onActionClick,
|
||||||
actionIcon = require('@tabler/icons/outline/arrow-right.svg'),
|
actionIcon = arrowRightIcon,
|
||||||
actionTitle,
|
actionTitle,
|
||||||
action,
|
action,
|
||||||
}): JSX.Element => {
|
}): JSX.Element => {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import cloudUploadIcon from '@tabler/icons/outline/cloud-upload.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
@ -13,7 +14,7 @@ const UploadProgress: React.FC<IUploadProgress> = ({ progress }) => {
|
||||||
return (
|
return (
|
||||||
<HStack alignItems='center' space={2}>
|
<HStack alignItems='center' space={2}>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/cloud-upload.svg')}
|
src={cloudUploadIcon}
|
||||||
className='size-7 text-gray-500'
|
className='size-7 text-gray-500'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import alertTriangleIcon from '@tabler/icons/outline/alert-triangle.svg';
|
||||||
import bookIcon from '@tabler/icons/outline/book.svg';
|
import bookIcon from '@tabler/icons/outline/book.svg';
|
||||||
import fileCodeIcon from '@tabler/icons/outline/file-code.svg';
|
import fileCodeIcon from '@tabler/icons/outline/file-code.svg';
|
||||||
import fileSpreadsheetIcon from '@tabler/icons/outline/file-spreadsheet.svg';
|
import fileSpreadsheetIcon from '@tabler/icons/outline/file-spreadsheet.svg';
|
||||||
|
@ -240,7 +241,7 @@ const Upload: React.FC<IUpload> = ({
|
||||||
'opacity-100': !active,
|
'opacity-100': !active,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Icon className='size-4' src={require('@tabler/icons/outline/alert-triangle.svg')} />
|
<Icon className='size-4' src={alertTriangleIcon} />
|
||||||
<FormattedMessage id='upload_form.description_missing.indicator' defaultMessage='Alt' />
|
<FormattedMessage id='upload_form.description_missing.indicator' defaultMessage='Alt' />
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import checkIcon from '@tabler/icons/outline/check.svg';
|
||||||
|
import pointIcon from '@tabler/icons/outline/point.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
@ -12,7 +14,7 @@ const ValidationCheckmark = ({ isValid, text }: IValidationCheckmark) => {
|
||||||
return (
|
return (
|
||||||
<HStack alignItems='center' space={2} data-testid='validation-checkmark'>
|
<HStack alignItems='center' space={2} data-testid='validation-checkmark'>
|
||||||
<Icon
|
<Icon
|
||||||
src={isValid ? require('@tabler/icons/outline/check.svg') : require('@tabler/icons/outline/point.svg')}
|
src={isValid ? checkIcon : pointIcon}
|
||||||
className={clsx({
|
className={clsx({
|
||||||
'w-4 h-4': true,
|
'w-4 h-4': true,
|
||||||
'text-gray-400 dark:text-gray-600 dark:fill-gray-600 fill-gray-400': !isValid,
|
'text-gray-400 dark:text-gray-600 dark:fill-gray-600 fill-gray-400': !isValid,
|
||||||
|
|
|
@ -2,6 +2,7 @@ import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useIntl, defineMessages } from 'react-intl';
|
import { useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
import verifiedIcon from 'soapbox/assets/icons/verified.svg';
|
||||||
import { Icon } from 'soapbox/components/ui';
|
import { Icon } from 'soapbox/components/ui';
|
||||||
import { useSoapboxConfig } from 'soapbox/hooks';
|
import { useSoapboxConfig } from 'soapbox/hooks';
|
||||||
|
|
||||||
|
@ -18,7 +19,7 @@ const VerificationBadge: React.FC<IVerificationBadge> = ({ className }) => {
|
||||||
const soapboxConfig = useSoapboxConfig();
|
const soapboxConfig = useSoapboxConfig();
|
||||||
|
|
||||||
// Prefer a custom icon if found
|
// Prefer a custom icon if found
|
||||||
const icon = soapboxConfig.verifiedIcon || require('soapbox/assets/icons/verified.svg');
|
const icon = soapboxConfig.verifiedIcon || verifiedIcon;
|
||||||
|
|
||||||
// Render component based on file extension
|
// Render component based on file extension
|
||||||
const Element = icon.endsWith('.svg') ? Icon : 'img';
|
const Element = icon.endsWith('.svg') ? Icon : 'img';
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import eyeOffIcon from '@tabler/icons/outline/eye-off.svg';
|
||||||
|
import volumeIcon from '@tabler/icons/outline/volume.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
|
||||||
|
@ -103,7 +105,7 @@ const MediaItem: React.FC<IMediaItem> = ({ attachment, onOpenMedia }) => {
|
||||||
const fileExtension = remoteURL.slice(fileExtensionLastIndex + 1).toUpperCase();
|
const fileExtension = remoteURL.slice(fileExtensionLastIndex + 1).toUpperCase();
|
||||||
thumbnail = (
|
thumbnail = (
|
||||||
<div className='relative z-[1] block size-full cursor-zoom-in leading-none text-gray-400 no-underline'>
|
<div className='relative z-[1] block size-full cursor-zoom-in leading-none text-gray-400 no-underline'>
|
||||||
<span className='absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'><SvgIcon className='size-24' src={require('@tabler/icons/outline/volume.svg')} /></span>
|
<span className='absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'><SvgIcon className='size-24' src={volumeIcon} /></span>
|
||||||
<span className='pointer-events-none absolute bottom-1.5 left-1.5 z-[1] block bg-black/50 px-1.5 py-0.5 text-[11px] font-semibold leading-[18px] text-white opacity-90 transition-opacity duration-100 ease-linear'>{fileExtension}</span>
|
<span className='pointer-events-none absolute bottom-1.5 left-1.5 z-[1] block bg-black/50 px-1.5 py-0.5 text-[11px] font-semibold leading-[18px] text-white opacity-90 transition-opacity duration-100 ease-linear'>{fileExtension}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -112,7 +114,7 @@ const MediaItem: React.FC<IMediaItem> = ({ attachment, onOpenMedia }) => {
|
||||||
if (!visible) {
|
if (!visible) {
|
||||||
icon = (
|
icon = (
|
||||||
<span className='absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'>
|
<span className='absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2'>
|
||||||
<SvgIcon className='size-24' src={require('@tabler/icons/outline/eye-off.svg')} />
|
<SvgIcon className='size-24' src={eyeOffIcon} />
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import briefcaseIcon from '@tabler/icons/outline/briefcase.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ const MovedNote: React.FC<IMovedNote> = ({ from, to }) => (
|
||||||
<div className='p-4'>
|
<div className='p-4'>
|
||||||
<HStack className='mb-2' alignItems='center' space={1.5}>
|
<HStack className='mb-2' alignItems='center' space={1.5}>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/briefcase.svg')}
|
src={briefcaseIcon}
|
||||||
className='flex-none text-primary-600 dark:text-primary-400'
|
className='flex-none text-primary-600 dark:text-primary-400'
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
import atIcon from '@tabler/icons/outline/at.svg';
|
||||||
|
import banIcon from '@tabler/icons/outline/ban.svg';
|
||||||
|
import boltIcon from '@tabler/icons/outline/bolt.svg';
|
||||||
|
import circleXIcon from '@tabler/icons/outline/circle-x.svg';
|
||||||
|
import clipboardCopyIcon from '@tabler/icons/outline/clipboard-copy.svg';
|
||||||
|
import dotsIcon from '@tabler/icons/outline/dots.svg';
|
||||||
|
import externalLinkIcon from '@tabler/icons/outline/external-link.svg';
|
||||||
|
import flagIcon from '@tabler/icons/outline/flag.svg';
|
||||||
|
import gavelIcon from '@tabler/icons/outline/gavel.svg';
|
||||||
|
import listIcon from '@tabler/icons/outline/list.svg';
|
||||||
|
import mailIcon from '@tabler/icons/outline/mail.svg';
|
||||||
|
import messagesIcon from '@tabler/icons/outline/messages.svg';
|
||||||
|
import repeatIcon from '@tabler/icons/outline/repeat.svg';
|
||||||
|
import rssIcon from '@tabler/icons/outline/rss.svg';
|
||||||
|
import searchIcon from '@tabler/icons/outline/search.svg';
|
||||||
|
import settingsIcon from '@tabler/icons/outline/settings.svg';
|
||||||
|
import uploadIcon from '@tabler/icons/outline/upload.svg';
|
||||||
|
import userCheckIcon from '@tabler/icons/outline/user-check.svg';
|
||||||
|
import userXIcon from '@tabler/icons/outline/user-x.svg';
|
||||||
|
import userIcon from '@tabler/icons/outline/user.svg';
|
||||||
import { useMutation } from '@tanstack/react-query';
|
import { useMutation } from '@tanstack/react-query';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
|
@ -135,7 +155,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
dispatch(unblockAccount(account.id));
|
dispatch(unblockAccount(account.id));
|
||||||
} else {
|
} else {
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
heading: <FormattedMessage id='confirmations.block.heading' defaultMessage='Block @{name}' values={{ name: account.acct }} />,
|
heading: <FormattedMessage id='confirmations.block.heading' defaultMessage='Block @{name}' values={{ name: account.acct }} />,
|
||||||
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong className='break-words'>@{account.acct}</strong> }} />, // eslint-disable-line formatjs/no-literal-string-in-jsx
|
message: <FormattedMessage id='confirmations.block.message' defaultMessage='Are you sure you want to block {name}?' values={{ name: <strong className='break-words'>@{account.acct}</strong> }} />, // eslint-disable-line formatjs/no-literal-string-in-jsx
|
||||||
confirm: intl.formatMessage(messages.blockConfirm),
|
confirm: intl.formatMessage(messages.blockConfirm),
|
||||||
|
@ -191,7 +211,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
|
|
||||||
const onBlockDomain = (domain: string) => {
|
const onBlockDomain = (domain: string) => {
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
heading: <FormattedMessage id='confirmations.domain_block.heading' defaultMessage='Block {domain}' values={{ domain }} />,
|
heading: <FormattedMessage id='confirmations.domain_block.heading' defaultMessage='Block {domain}' values={{ domain }} />,
|
||||||
message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications.' values={{ domain: <strong>{domain}</strong> }} />,
|
message: <FormattedMessage id='confirmations.domain_block.message' defaultMessage='Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable. You will not see content from that domain in any public timelines or your notifications.' values={{ domain: <strong>{domain}</strong> }} />,
|
||||||
confirm: intl.formatMessage(messages.blockDomainConfirm),
|
confirm: intl.formatMessage(messages.blockDomainConfirm),
|
||||||
|
@ -298,7 +318,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
if (features.rssFeeds && account.local) {
|
if (features.rssFeeds && account.local) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.subscribeFeed),
|
text: intl.formatMessage(messages.subscribeFeed),
|
||||||
icon: require('@tabler/icons/outline/rss.svg'),
|
icon: rssIcon,
|
||||||
href: software === MASTODON ? `${account.url}.rss` : `${account.url}/feed.rss`,
|
href: software === MASTODON ? `${account.url}.rss` : `${account.url}/feed.rss`,
|
||||||
target: '_blank',
|
target: '_blank',
|
||||||
});
|
});
|
||||||
|
@ -308,7 +328,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.share, { name: account.username }),
|
text: intl.formatMessage(messages.share, { name: account.username }),
|
||||||
action: handleShare,
|
action: handleShare,
|
||||||
icon: require('@tabler/icons/outline/upload.svg'),
|
icon: uploadIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +341,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.profileExternal, { domain }),
|
text: intl.formatMessage(messages.profileExternal, { domain }),
|
||||||
action: () => onProfileExternal(url),
|
action: () => onProfileExternal(url),
|
||||||
icon: require('@tabler/icons/outline/external-link.svg'),
|
icon: externalLinkIcon,
|
||||||
href: url,
|
href: url,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -330,14 +350,14 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.copy),
|
text: intl.formatMessage(messages.copy),
|
||||||
action: handleCopy,
|
action: handleCopy,
|
||||||
icon: require('@tabler/icons/outline/clipboard-copy.svg'),
|
icon: clipboardCopyIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (account.nostr.pubkey) {
|
if (account.nostr.pubkey) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.npub),
|
text: intl.formatMessage(messages.npub),
|
||||||
action: handleCopyNpub,
|
action: handleCopyNpub,
|
||||||
icon: require('@tabler/icons/outline/clipboard-copy.svg'),
|
icon: clipboardCopyIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +367,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(account.id === ownAccount.id ? messages.searchSelf : messages.search, { name: account.username }),
|
text: intl.formatMessage(account.id === ownAccount.id ? messages.searchSelf : messages.search, { name: account.username }),
|
||||||
action: onSearch,
|
action: onSearch,
|
||||||
icon: require('@tabler/icons/outline/search.svg'),
|
icon: searchIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,38 +379,38 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.edit_profile),
|
text: intl.formatMessage(messages.edit_profile),
|
||||||
to: '/settings/profile',
|
to: '/settings/profile',
|
||||||
icon: require('@tabler/icons/outline/user.svg'),
|
icon: userIcon,
|
||||||
});
|
});
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.preferences),
|
text: intl.formatMessage(messages.preferences),
|
||||||
to: '/settings',
|
to: '/settings',
|
||||||
icon: require('@tabler/icons/outline/settings.svg'),
|
icon: settingsIcon,
|
||||||
});
|
});
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.mutes),
|
text: intl.formatMessage(messages.mutes),
|
||||||
to: '/mutes',
|
to: '/mutes',
|
||||||
icon: require('@tabler/icons/outline/circle-x.svg'),
|
icon: circleXIcon,
|
||||||
});
|
});
|
||||||
if (features.blocks) {
|
if (features.blocks) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.blocks),
|
text: intl.formatMessage(messages.blocks),
|
||||||
to: '/blocks',
|
to: '/blocks',
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.mention, { name: account.username }),
|
text: intl.formatMessage(messages.mention, { name: account.username }),
|
||||||
action: onMention,
|
action: onMention,
|
||||||
icon: require('@tabler/icons/outline/at.svg'),
|
icon: atIcon,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (features.privacyScopes) {
|
if (features.privacyScopes) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.direct, { name: account.username }),
|
text: intl.formatMessage(messages.direct, { name: account.username }),
|
||||||
action: onDirect,
|
action: onDirect,
|
||||||
icon: require('@tabler/icons/outline/mail.svg'),
|
icon: mailIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,13 +419,13 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.hideReblogs, { name: account.username }),
|
text: intl.formatMessage(messages.hideReblogs, { name: account.username }),
|
||||||
action: onReblogToggle,
|
action: onReblogToggle,
|
||||||
icon: require('@tabler/icons/outline/repeat.svg'),
|
icon: repeatIcon,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.showReblogs, { name: account.username }),
|
text: intl.formatMessage(messages.showReblogs, { name: account.username }),
|
||||||
action: onReblogToggle,
|
action: onReblogToggle,
|
||||||
icon: require('@tabler/icons/outline/repeat.svg'),
|
icon: repeatIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +433,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.add_or_remove_from_list),
|
text: intl.formatMessage(messages.add_or_remove_from_list),
|
||||||
action: onAddToList,
|
action: onAddToList,
|
||||||
icon: require('@tabler/icons/outline/list.svg'),
|
icon: listIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -421,14 +441,14 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(account.relationship?.endorsed ? messages.unendorse : messages.endorse),
|
text: intl.formatMessage(account.relationship?.endorsed ? messages.unendorse : messages.endorse),
|
||||||
action: onEndorseToggle,
|
action: onEndorseToggle,
|
||||||
icon: require('@tabler/icons/outline/user-check.svg'),
|
icon: userCheckIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (features.lists && features.unrestrictedLists) {
|
} else if (features.lists && features.unrestrictedLists) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.add_or_remove_from_list),
|
text: intl.formatMessage(messages.add_or_remove_from_list),
|
||||||
action: onAddToList,
|
action: onAddToList,
|
||||||
icon: require('@tabler/icons/outline/list.svg'),
|
icon: listIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +458,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.removeFromFollowers),
|
text: intl.formatMessage(messages.removeFromFollowers),
|
||||||
action: onRemoveFromFollowers,
|
action: onRemoveFromFollowers,
|
||||||
icon: require('@tabler/icons/outline/user-x.svg'),
|
icon: userXIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,13 +466,13 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.unmute, { name: account.username }),
|
text: intl.formatMessage(messages.unmute, { name: account.username }),
|
||||||
action: onMute,
|
action: onMute,
|
||||||
icon: require('@tabler/icons/outline/circle-x.svg'),
|
icon: circleXIcon,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.mute, { name: account.username }),
|
text: intl.formatMessage(messages.mute, { name: account.username }),
|
||||||
action: onMute,
|
action: onMute,
|
||||||
icon: require('@tabler/icons/outline/circle-x.svg'),
|
icon: circleXIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -461,13 +481,13 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.unblock, { name: account.username }),
|
text: intl.formatMessage(messages.unblock, { name: account.username }),
|
||||||
action: onBlock,
|
action: onBlock,
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.block, { name: account.username }),
|
text: intl.formatMessage(messages.block, { name: account.username }),
|
||||||
action: onBlock,
|
action: onBlock,
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -475,7 +495,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.report, { name: account.username }),
|
text: intl.formatMessage(messages.report, { name: account.username }),
|
||||||
action: onReport,
|
action: onReport,
|
||||||
icon: require('@tabler/icons/outline/flag.svg'),
|
icon: flagIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -488,13 +508,13 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.unblockDomain, { domain }),
|
text: intl.formatMessage(messages.unblockDomain, { domain }),
|
||||||
action: () => onUnblockDomain(domain),
|
action: () => onUnblockDomain(domain),
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.blockDomain, { domain }),
|
text: intl.formatMessage(messages.blockDomain, { domain }),
|
||||||
action: () => onBlockDomain(domain),
|
action: () => onBlockDomain(domain),
|
||||||
icon: require('@tabler/icons/outline/ban.svg'),
|
icon: banIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -505,7 +525,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.adminAccount, { name: account.username }),
|
text: intl.formatMessage(messages.adminAccount, { name: account.username }),
|
||||||
action: onModerate,
|
action: onModerate,
|
||||||
icon: require('@tabler/icons/outline/gavel.svg'),
|
icon: gavelIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -592,7 +612,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/messages.svg')}
|
src={messagesIcon}
|
||||||
onClick={() => createAndNavigateToChat.mutate(account.id)}
|
onClick={() => createAndNavigateToChat.mutate(account.id)}
|
||||||
title={intl.formatMessage(messages.chat, { name: account.username })}
|
title={intl.formatMessage(messages.chat, { name: account.username })}
|
||||||
theme='outlined'
|
theme='outlined'
|
||||||
|
@ -604,7 +624,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
} else if (account.pleroma?.accepts_chat_messages) {
|
} else if (account.pleroma?.accepts_chat_messages) {
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/messages.svg')}
|
src={messagesIcon}
|
||||||
onClick={() => createAndNavigateToChat.mutate(account.id)}
|
onClick={() => createAndNavigateToChat.mutate(account.id)}
|
||||||
title={intl.formatMessage(messages.chat, { name: account.username })}
|
title={intl.formatMessage(messages.chat, { name: account.username })}
|
||||||
theme='outlined'
|
theme='outlined'
|
||||||
|
@ -626,7 +646,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/upload.svg')}
|
src={uploadIcon}
|
||||||
onClick={handleShare}
|
onClick={handleShare}
|
||||||
title={intl.formatMessage(messages.share, { name: account.username })}
|
title={intl.formatMessage(messages.share, { name: account.username })}
|
||||||
theme='outlined'
|
theme='outlined'
|
||||||
|
@ -639,7 +659,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
const renderZapAccount = () => {
|
const renderZapAccount = () => {
|
||||||
return (
|
return (
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/bolt.svg')}
|
src={boltIcon}
|
||||||
onClick={handleZapAccount}
|
onClick={handleZapAccount}
|
||||||
title={intl.formatMessage(messages.zap, { target: account.display_name })}
|
title={intl.formatMessage(messages.zap, { target: account.display_name })}
|
||||||
theme='outlined'
|
theme='outlined'
|
||||||
|
@ -698,7 +718,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
{menu.length > 0 && (
|
{menu.length > 0 && (
|
||||||
<DropdownMenu items={menu} placement='bottom-end'>
|
<DropdownMenu items={menu} placement='bottom-end'>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/dots.svg')}
|
src={dotsIcon}
|
||||||
theme='outlined'
|
theme='outlined'
|
||||||
className='px-2'
|
className='px-2'
|
||||||
iconClassName='h-4 w-4'
|
iconClassName='h-4 w-4'
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import plusIcon from '@tabler/icons/outline/plus.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedDate, FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedDate, FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -103,7 +104,7 @@ const Announcements: React.FC = () => {
|
||||||
<Stack className='gap-4'>
|
<Stack className='gap-4'>
|
||||||
<Button
|
<Button
|
||||||
className='sm:w-fit sm:self-end'
|
className='sm:w-fit sm:self-end'
|
||||||
icon={require('@tabler/icons/outline/plus.svg')}
|
icon={plusIcon}
|
||||||
onClick={handleCreateAnnouncement}
|
onClick={handleCreateAnnouncement}
|
||||||
theme='secondary'
|
theme='secondary'
|
||||||
block
|
block
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import dotsVerticalIcon from '@tabler/icons/outline/dots-vertical.svg';
|
||||||
|
import pencilIcon from '@tabler/icons/outline/pencil.svg';
|
||||||
|
import trashIcon from '@tabler/icons/outline/trash.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useIntl, defineMessages } from 'react-intl';
|
import { useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
@ -34,11 +37,11 @@ const ReportStatus: React.FC<IReportStatus> = ({ status }) => {
|
||||||
return [{
|
return [{
|
||||||
text: intl.formatMessage(messages.viewStatus, { acct: `@${acct}` }),
|
text: intl.formatMessage(messages.viewStatus, { acct: `@${acct}` }),
|
||||||
to: `/@${acct}/posts/${status.id}`,
|
to: `/@${acct}/posts/${status.id}`,
|
||||||
icon: require('@tabler/icons/outline/pencil.svg'),
|
icon: pencilIcon,
|
||||||
}, {
|
}, {
|
||||||
text: intl.formatMessage(messages.deleteStatus, { acct: `@${acct}` }),
|
text: intl.formatMessage(messages.deleteStatus, { acct: `@${acct}` }),
|
||||||
action: handleDeleteStatus,
|
action: handleDeleteStatus,
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
@ -55,7 +58,7 @@ const ReportStatus: React.FC<IReportStatus> = ({ status }) => {
|
||||||
<div className='flex-none'>
|
<div className='flex-none'>
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
items={menu}
|
items={menu}
|
||||||
src={require('@tabler/icons/outline/dots-vertical.svg')}
|
src={dotsVerticalIcon}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import dotsVerticalIcon from '@tabler/icons/outline/dots-vertical.svg';
|
||||||
|
import hourglassEmptyIcon from '@tabler/icons/outline/hourglass-empty.svg';
|
||||||
|
import trashIcon from '@tabler/icons/outline/trash.svg';
|
||||||
import React, { useCallback, useState } from 'react';
|
import React, { useCallback, useState } from 'react';
|
||||||
import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
|
import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
@ -45,11 +48,11 @@ const Report: React.FC<IReport> = ({ id }) => {
|
||||||
return [{
|
return [{
|
||||||
text: intl.formatMessage(messages.deactivateUser, { name: targetAccount.username }),
|
text: intl.formatMessage(messages.deactivateUser, { name: targetAccount.username }),
|
||||||
action: handleDeactivateUser,
|
action: handleDeactivateUser,
|
||||||
icon: require('@tabler/icons/outline/hourglass-empty.svg'),
|
icon: hourglassEmptyIcon,
|
||||||
}, {
|
}, {
|
||||||
text: intl.formatMessage(messages.deleteUser, { name: targetAccount.username }),
|
text: intl.formatMessage(messages.deleteUser, { name: targetAccount.username }),
|
||||||
action: handleDeleteUser,
|
action: handleDeleteUser,
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
}];
|
}];
|
||||||
};
|
};
|
||||||
|
@ -149,7 +152,7 @@ const Report: React.FC<IReport> = ({ id }) => {
|
||||||
<FormattedMessage id='admin.reports.actions.close' defaultMessage='Close' />
|
<FormattedMessage id='admin.reports.actions.close' defaultMessage='Close' />
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<DropdownMenu items={menu} src={require('@tabler/icons/outline/dots-vertical.svg')} />
|
<DropdownMenu items={menu} src={dotsVerticalIcon} />
|
||||||
</HStack>
|
</HStack>
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import plusIcon from '@tabler/icons/outline/plus.svg';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -122,7 +123,7 @@ const Domains: React.FC = () => {
|
||||||
<Stack className='gap-4'>
|
<Stack className='gap-4'>
|
||||||
<Button
|
<Button
|
||||||
className='sm:w-fit sm:self-end'
|
className='sm:w-fit sm:self-end'
|
||||||
icon={require('@tabler/icons/outline/plus.svg')}
|
icon={plusIcon}
|
||||||
onClick={handleCreateDomain}
|
onClick={handleCreateDomain}
|
||||||
theme='secondary'
|
theme='secondary'
|
||||||
block
|
block
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ import { useManageZapSplit } from '../../api/hooks/admin/useManageZapSplit';
|
||||||
import AddNewAccount from '../ui/components/new-account-zap-split';
|
import AddNewAccount from '../ui/components/new-account-zap-split';
|
||||||
import { ZapSplitSlider } from '../zap/components/zap-split-account-item';
|
import { ZapSplitSlider } from '../zap/components/zap-split-account-item';
|
||||||
|
|
||||||
const closeIcon = require('@tabler/icons/outline/x.svg');
|
const closeIcon = xIcon;
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
heading: { id: 'column.admin.zap_split', defaultMessage: 'Manage Zap Split' },
|
heading: { id: 'column.admin.zap_split', defaultMessage: 'Manage Zap Split' },
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import plusIcon from '@tabler/icons/outline/plus.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -85,7 +86,7 @@ const Rules: React.FC = () => {
|
||||||
<Stack className='gap-4'>
|
<Stack className='gap-4'>
|
||||||
<Button
|
<Button
|
||||||
className='sm:w-fit sm:self-end'
|
className='sm:w-fit sm:self-end'
|
||||||
icon={require('@tabler/icons/outline/plus.svg')}
|
icon={plusIcon}
|
||||||
onClick={handleCreateRule}
|
onClick={handleCreateRule}
|
||||||
theme='secondary'
|
theme='secondary'
|
||||||
block
|
block
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import downloadIcon from '@tabler/icons/outline/download.svg';
|
||||||
|
import externalLinkIcon from '@tabler/icons/outline/external-link.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
@ -155,7 +157,7 @@ const Dashboard: React.FC = () => {
|
||||||
|
|
||||||
<Icon
|
<Icon
|
||||||
className='size-4'
|
className='size-4'
|
||||||
src={require('@tabler/icons/outline/external-link.svg')}
|
src={externalLinkIcon}
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
</ListItem>
|
</ListItem>
|
||||||
|
@ -174,7 +176,7 @@ const Dashboard: React.FC = () => {
|
||||||
<List>
|
<List>
|
||||||
<ListItem label='subscribers.csv'>
|
<ListItem label='subscribers.csv'>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/download.svg')}
|
src={downloadIcon}
|
||||||
onClick={handleSubscribersClick}
|
onClick={handleSubscribersClick}
|
||||||
iconClassName='h-5 w-5'
|
iconClassName='h-5 w-5'
|
||||||
/>
|
/>
|
||||||
|
@ -182,7 +184,7 @@ const Dashboard: React.FC = () => {
|
||||||
|
|
||||||
<ListItem label='unsubscribers.csv'>
|
<ListItem label='unsubscribers.csv'>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/download.svg')}
|
src={downloadIcon}
|
||||||
onClick={handleUnsubscribersClick}
|
onClick={handleUnsubscribersClick}
|
||||||
iconClassName='h-5 w-5'
|
iconClassName='h-5 w-5'
|
||||||
/>
|
/>
|
||||||
|
@ -190,7 +192,7 @@ const Dashboard: React.FC = () => {
|
||||||
|
|
||||||
<ListItem label='combined.csv'>
|
<ListItem label='combined.csv'>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/download.svg')}
|
src={downloadIcon}
|
||||||
onClick={handleCombinedClick}
|
onClick={handleCombinedClick}
|
||||||
iconClassName='h-5 w-5'
|
iconClassName='h-5 w-5'
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import plusIcon from '@tabler/icons/outline/plus.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -37,7 +38,7 @@ const Account: React.FC<IAccount> = ({ accountId, aliases }) => {
|
||||||
|
|
||||||
if (!added && accountId !== me) {
|
if (!added && accountId !== me) {
|
||||||
button = (
|
button = (
|
||||||
<IconButton src={require('@tabler/icons/outline/plus.svg')} iconClassName='h-5 w-5' title={intl.formatMessage(messages.add)} onClick={handleOnAdd} />
|
<IconButton src={plusIcon} iconClassName='h-5 w-5' title={intl.formatMessage(messages.add)} onClick={handleOnAdd} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import backspaceIcon from '@tabler/icons/outline/backspace.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -53,7 +54,7 @@ const Search: React.FC = () => {
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div role='button' tabIndex={hasValue ? 0 : -1} className='search__icon' onClick={handleClear}>
|
<div role='button' tabIndex={hasValue ? 0 : -1} className='search__icon' onClick={handleClear}>
|
||||||
<Icon src={require('@tabler/icons/outline/backspace.svg')} aria-label={intl.formatMessage(messages.search)} className={clsx('svg-icon--backspace', { active: hasValue })} />
|
<Icon src={backspaceIcon} aria-label={intl.formatMessage(messages.search)} className={clsx('svg-icon--backspace', { active: hasValue })} />
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
<Button onClick={handleSubmit}>{intl.formatMessage(messages.searchTitle)}</Button>
|
<Button onClick={handleSubmit}>{intl.formatMessage(messages.searchTitle)}</Button>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -79,7 +80,7 @@ const Aliases = () => {
|
||||||
<Text tag='span'>{alias}</Text>
|
<Text tag='span'>{alias}</Text>
|
||||||
</div>
|
</div>
|
||||||
<div className='flex items-center' role='button' tabIndex={0} onClick={handleFilterDelete} data-value={alias} aria-label={intl.formatMessage(messages.delete)}>
|
<div className='flex items-center' role='button' tabIndex={0} onClick={handleFilterDelete} data-value={alias} aria-label={intl.formatMessage(messages.delete)}>
|
||||||
<Icon className='mr-1.5' src={require('@tabler/icons/outline/x.svg')} />
|
<Icon className='mr-1.5' src={xIcon} />
|
||||||
<Text weight='bold' theme='muted'><FormattedMessage id='aliases.aliases_list_delete' defaultMessage='Unlink alias' /></Text>
|
<Text weight='bold' theme='muted'><FormattedMessage id='aliases.aliases_list_delete' defaultMessage='Unlink alias' /></Text>
|
||||||
</div>
|
</div>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
|
import downloadIcon from '@tabler/icons/outline/download.svg';
|
||||||
|
import playerPauseIcon from '@tabler/icons/outline/player-pause.svg';
|
||||||
|
import playerPlayIcon from '@tabler/icons/outline/player-play.svg';
|
||||||
|
import volume3Icon from '@tabler/icons/outline/volume-3.svg';
|
||||||
|
import volumeIcon from '@tabler/icons/outline/volume.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import throttle from 'lodash/throttle';
|
import throttle from 'lodash/throttle';
|
||||||
|
@ -534,7 +539,7 @@ const Audio: React.FC<IAudio> = (props) => {
|
||||||
className={clsx('inline-block flex-none border-0 bg-transparent px-[6px] py-[5px] text-[16px] text-white/75 opacity-75 outline-none hover:text-white hover:opacity-100 active:text-white active:opacity-100 ')}
|
className={clsx('inline-block flex-none border-0 bg-transparent px-[6px] py-[5px] text-[16px] text-white/75 opacity-75 outline-none hover:text-white hover:opacity-100 active:text-white active:opacity-100 ')}
|
||||||
onClick={togglePlay}
|
onClick={togglePlay}
|
||||||
>
|
>
|
||||||
<SvgIcon className='w-5' src={paused ? require('@tabler/icons/outline/player-play.svg') : require('@tabler/icons/outline/player-pause.svg')} />
|
<SvgIcon className='w-5' src={paused ? playerPlayIcon : playerPauseIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
@ -546,7 +551,7 @@ const Audio: React.FC<IAudio> = (props) => {
|
||||||
className={clsx('inline-block flex-none border-0 bg-transparent px-[6px] py-[5px] text-[16px] text-white/75 opacity-75 outline-none hover:text-white hover:opacity-100 active:text-white active:opacity-100')}
|
className={clsx('inline-block flex-none border-0 bg-transparent px-[6px] py-[5px] text-[16px] text-white/75 opacity-75 outline-none hover:text-white hover:opacity-100 active:text-white active:opacity-100')}
|
||||||
onClick={toggleMute}
|
onClick={toggleMute}
|
||||||
>
|
>
|
||||||
<SvgIcon className='w-5' src={muted ? require('@tabler/icons/outline/volume-3.svg') : require('@tabler/icons/outline/volume.svg')} />
|
<SvgIcon className='w-5' src={muted ? volume3Icon : volumeIcon} />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
@ -594,7 +599,7 @@ const Audio: React.FC<IAudio> = (props) => {
|
||||||
download
|
download
|
||||||
target='_blank'
|
target='_blank'
|
||||||
>
|
>
|
||||||
<SvgIcon className='w-5' src={require('@tabler/icons/outline/download.svg')} />
|
<SvgIcon className='w-5' src={downloadIcon} />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,10 @@
|
||||||
|
import brandFacebookIcon from '@tabler/icons/outline/brand-facebook.svg';
|
||||||
|
import brandGithubIcon from '@tabler/icons/outline/brand-github.svg';
|
||||||
|
import brandGoogleIcon from '@tabler/icons/outline/brand-google.svg';
|
||||||
|
import brandSlackIcon from '@tabler/icons/outline/brand-slack.svg';
|
||||||
|
import brandTwitterIcon from '@tabler/icons/outline/brand-twitter.svg';
|
||||||
|
import brandWindowsIcon from '@tabler/icons/outline/brand-windows.svg';
|
||||||
|
import keyIcon from '@tabler/icons/outline/key.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { useIntl, defineMessages } from 'react-intl';
|
import { useIntl, defineMessages } from 'react-intl';
|
||||||
|
|
||||||
|
@ -12,12 +19,12 @@ const messages = defineMessages({
|
||||||
|
|
||||||
/** Map between OAuth providers and brand icons. */
|
/** Map between OAuth providers and brand icons. */
|
||||||
const BRAND_ICONS: Record<string, string> = {
|
const BRAND_ICONS: Record<string, string> = {
|
||||||
twitter: require('@tabler/icons/outline/brand-twitter.svg'),
|
twitter: brandTwitterIcon,
|
||||||
facebook: require('@tabler/icons/outline/brand-facebook.svg'),
|
facebook: brandFacebookIcon,
|
||||||
google: require('@tabler/icons/outline/brand-google.svg'),
|
google: brandGoogleIcon,
|
||||||
microsoft: require('@tabler/icons/outline/brand-windows.svg'),
|
microsoft: brandWindowsIcon,
|
||||||
slack: require('@tabler/icons/outline/brand-slack.svg'),
|
slack: brandSlackIcon,
|
||||||
github: require('@tabler/icons/outline/brand-github.svg'),
|
github: brandGithubIcon,
|
||||||
};
|
};
|
||||||
|
|
||||||
interface IConsumerButton {
|
interface IConsumerButton {
|
||||||
|
@ -29,7 +36,7 @@ const ConsumerButton: React.FC<IConsumerButton> = ({ provider }) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const dispatch = useAppDispatch();
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
const icon = BRAND_ICONS[provider] || require('@tabler/icons/outline/key.svg');
|
const icon = BRAND_ICONS[provider] || keyIcon;
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
dispatch(prepareRequest(provider));
|
dispatch(prepareRequest(provider));
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import atIcon from '@tabler/icons/outline/at.svg';
|
||||||
|
import checkIcon from '@tabler/icons/outline/check.svg';
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Map as ImmutableMap } from 'immutable';
|
import { Map as ImmutableMap } from 'immutable';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
|
@ -152,7 +154,7 @@ const RegistrationForm: React.FC<IRegistrationForm> = ({ inviteToken }) => {
|
||||||
const heading = confirmationHeading || approvalHeading;
|
const heading = confirmationHeading || approvalHeading;
|
||||||
|
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/check.svg'),
|
icon: checkIcon,
|
||||||
heading: heading,
|
heading: heading,
|
||||||
message,
|
message,
|
||||||
confirm: intl.formatMessage(messages.close),
|
confirm: intl.formatMessage(messages.close),
|
||||||
|
@ -255,7 +257,7 @@ const RegistrationForm: React.FC<IRegistrationForm> = ({ inviteToken }) => {
|
||||||
autoCorrect='off'
|
autoCorrect='off'
|
||||||
autoCapitalize='off'
|
autoCapitalize='off'
|
||||||
pattern='^[a-zA-Z\d_-]+'
|
pattern='^[a-zA-Z\d_-]+'
|
||||||
icon={require('@tabler/icons/outline/at.svg')}
|
icon={atIcon}
|
||||||
onChange={onUsernameChange}
|
onChange={onUsernameChange}
|
||||||
value={params.get('username', '')}
|
value={params.get('username', '')}
|
||||||
required
|
required
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import alertTriangleIcon from '@tabler/icons/outline/alert-triangle.svg';
|
||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { defineMessages, FormattedDate, useIntl } from 'react-intl';
|
import { defineMessages, FormattedDate, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -27,7 +28,7 @@ const AuthToken: React.FC<IAuthToken> = ({ token, isCurrent }) => {
|
||||||
const handleRevoke = () => {
|
const handleRevoke = () => {
|
||||||
if (isCurrent)
|
if (isCurrent)
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/outline/alert-triangle.svg'),
|
icon: alertTriangleIcon,
|
||||||
heading: intl.formatMessage(messages.revokeSessionHeading),
|
heading: intl.formatMessage(messages.revokeSessionHeading),
|
||||||
message: intl.formatMessage(messages.revokeSessionMessage),
|
message: intl.formatMessage(messages.revokeSessionMessage),
|
||||||
confirm: intl.formatMessage(messages.revokeSessionConfirm),
|
confirm: intl.formatMessage(messages.revokeSessionConfirm),
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import balloonIcon from '@tabler/icons/outline/balloon.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -36,7 +37,7 @@ const Account: React.FC<IAccount> = ({ accountId }) => {
|
||||||
date: formattedBirthday,
|
date: formattedBirthday,
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Icon src={require('@tabler/icons/outline/balloon.svg')} />
|
<Icon src={balloonIcon} />
|
||||||
{formattedBirthday}
|
{formattedBirthday}
|
||||||
</div>
|
</div>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import bookmarksIcon from '@tabler/icons/outline/bookmarks.svg';
|
||||||
|
import folderIcon from '@tabler/icons/outline/folder.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
import { Redirect } from 'react-router-dom';
|
import { Redirect } from 'react-router-dom';
|
||||||
|
@ -40,7 +42,7 @@ const BookmarkFolders: React.FC = () => {
|
||||||
to='/bookmarks/all'
|
to='/bookmarks/all'
|
||||||
label={
|
label={
|
||||||
<HStack alignItems='center' space={2}>
|
<HStack alignItems='center' space={2}>
|
||||||
<Icon src={require('@tabler/icons/outline/bookmarks.svg')} size={20} />
|
<Icon src={bookmarksIcon} size={20} />
|
||||||
<span><FormattedMessage id='bookmark_folders.all_bookmarks' defaultMessage='All bookmarks' /></span>
|
<span><FormattedMessage id='bookmark_folders.all_bookmarks' defaultMessage='All bookmarks' /></span>
|
||||||
</HStack>
|
</HStack>
|
||||||
}
|
}
|
||||||
|
@ -57,7 +59,7 @@ const BookmarkFolders: React.FC = () => {
|
||||||
src={folder.emoji_url || undefined}
|
src={folder.emoji_url || undefined}
|
||||||
className='size-5 flex-none'
|
className='size-5 flex-none'
|
||||||
/>
|
/>
|
||||||
) : <Icon src={require('@tabler/icons/outline/folder.svg')} size={20} />}
|
) : <Icon src={folderIcon} size={20} />}
|
||||||
<span>{folder.name}</span>
|
<span>{folder.name}</span>
|
||||||
</HStack>
|
</HStack>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import dotsVerticalIcon from '@tabler/icons/outline/dots-vertical.svg';
|
||||||
|
import editIcon from '@tabler/icons/outline/edit.svg';
|
||||||
|
import trashIcon from '@tabler/icons/outline/trash.svg';
|
||||||
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
import { OrderedSet as ImmutableOrderedSet } from 'immutable';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -93,12 +96,12 @@ const Bookmarks: React.FC<IBookmarks> = ({ params }) => {
|
||||||
{
|
{
|
||||||
text: intl.formatMessage(messages.editFolder),
|
text: intl.formatMessage(messages.editFolder),
|
||||||
action: handleEditFolder,
|
action: handleEditFolder,
|
||||||
icon: require('@tabler/icons/outline/edit.svg'),
|
icon: editIcon,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: intl.formatMessage(messages.deleteFolder),
|
text: intl.formatMessage(messages.deleteFolder),
|
||||||
action: handleDeleteFolder,
|
action: handleDeleteFolder,
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
},
|
},
|
||||||
] : [];
|
] : [];
|
||||||
|
|
||||||
|
@ -106,7 +109,7 @@ const Bookmarks: React.FC<IBookmarks> = ({ params }) => {
|
||||||
<Column
|
<Column
|
||||||
label={folder ? folder.name : intl.formatMessage(messages.heading)}
|
label={folder ? folder.name : intl.formatMessage(messages.heading)}
|
||||||
action={
|
action={
|
||||||
<DropdownMenu items={items} src={require('@tabler/icons/outline/dots-vertical.svg')} />
|
<DropdownMenu items={items} src={dotsVerticalIcon} />
|
||||||
}
|
}
|
||||||
transparent={!isMobile}
|
transparent={!isMobile}
|
||||||
>
|
>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import sendIcon from '@tabler/icons/outline/send.svg';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { defineMessages, IntlShape, useIntl } from 'react-intl';
|
import { defineMessages, IntlShape, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -230,7 +231,7 @@ const ChatComposer = React.forwardRef<HTMLTextAreaElement | null, IChatComposer>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/send.svg')}
|
src={sendIcon}
|
||||||
iconClassName='h-5 w-5'
|
iconClassName='h-5 w-5'
|
||||||
className='text-primary-500'
|
className='text-primary-500'
|
||||||
disabled={isSubmitDisabled}
|
disabled={isSubmitDisabled}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import dotsIcon from '@tabler/icons/outline/dots.svg';
|
||||||
|
import logoutIcon from '@tabler/icons/outline/logout.svg';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
@ -59,7 +61,7 @@ const ChatListItem: React.FC<IChatListItemInterface> = ({ chat, onClick }) => {
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
icon: require('@tabler/icons/outline/logout.svg'),
|
icon: logoutIcon,
|
||||||
}], []);
|
}], []);
|
||||||
|
|
||||||
const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event) => {
|
const handleKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event) => {
|
||||||
|
@ -124,7 +126,7 @@ const ChatListItem: React.FC<IChatListItemInterface> = ({ chat, onClick }) => {
|
||||||
<div className='hidden text-gray-600 hover:text-gray-100 group-hover:block'>
|
<div className='hidden text-gray-600 hover:text-gray-100 group-hover:block'>
|
||||||
<DropdownMenu items={menu}>
|
<DropdownMenu items={menu}>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/dots.svg')}
|
src={dotsIcon}
|
||||||
title='Settings'
|
title='Settings'
|
||||||
className='text-gray-600 hover:text-gray-700 dark:text-gray-600 dark:hover:text-gray-500'
|
className='text-gray-600 hover:text-gray-700 dark:text-gray-600 dark:hover:text-gray-500'
|
||||||
iconClassName='h-4 w-4'
|
iconClassName='h-4 w-4'
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import clockIcon from '@tabler/icons/outline/clock.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -107,7 +108,7 @@ const ChatMessageListIntro = () => {
|
||||||
</HStack>
|
</HStack>
|
||||||
) : (
|
) : (
|
||||||
<HStack justifyContent='center' alignItems='center' space={1} className='shrink-0'>
|
<HStack justifyContent='center' alignItems='center' space={1} className='shrink-0'>
|
||||||
<Icon src={require('@tabler/icons/outline/clock.svg')} className='size-4 text-gray-600' />
|
<Icon src={clockIcon} className='size-4 text-gray-600' />
|
||||||
{chat.message_expiration && (
|
{chat.message_expiration && (
|
||||||
<Text size='sm' theme='muted'>
|
<Text size='sm' theme='muted'>
|
||||||
{intl.formatMessage(messages.messageLifespan, { day: secondsToDays(chat.message_expiration) })}
|
{intl.formatMessage(messages.messageLifespan, { day: secondsToDays(chat.message_expiration) })}
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
import checkIcon from '@tabler/icons/outline/check.svg';
|
||||||
|
import copyIcon from '@tabler/icons/outline/copy.svg';
|
||||||
|
import dotsIcon from '@tabler/icons/outline/dots.svg';
|
||||||
|
import flagIcon from '@tabler/icons/outline/flag.svg';
|
||||||
|
import moodSmileIcon from '@tabler/icons/outline/mood-smile.svg';
|
||||||
|
import trashIcon from '@tabler/icons/outline/trash.svg';
|
||||||
import { useMutation } from '@tanstack/react-query';
|
import { useMutation } from '@tanstack/react-query';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
import { List as ImmutableList, Map as ImmutableMap } from 'immutable';
|
||||||
|
@ -159,7 +165,7 @@ const ChatMessage = (props: IChatMessage) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.copy),
|
text: intl.formatMessage(messages.copy),
|
||||||
action: () => handleCopyText(chatMessage),
|
action: () => handleCopyText(chatMessage),
|
||||||
icon: require('@tabler/icons/outline/copy.svg'),
|
icon: copyIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,7 +173,7 @@ const ChatMessage = (props: IChatMessage) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.delete),
|
text: intl.formatMessage(messages.delete),
|
||||||
action: () => handleDeleteMessage.mutate(chatMessage.id),
|
action: () => handleDeleteMessage.mutate(chatMessage.id),
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
@ -175,13 +181,13 @@ const ChatMessage = (props: IChatMessage) => {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.report),
|
text: intl.formatMessage(messages.report),
|
||||||
action: () => dispatch(initReport(ReportableEntities.CHAT_MESSAGE, chat.account, { chatMessage })),
|
action: () => dispatch(initReport(ReportableEntities.CHAT_MESSAGE, chat.account, { chatMessage })),
|
||||||
icon: require('@tabler/icons/outline/flag.svg'),
|
icon: flagIcon,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.deleteForMe),
|
text: intl.formatMessage(messages.deleteForMe),
|
||||||
action: () => handleDeleteMessage.mutate(chatMessage.id),
|
action: () => handleDeleteMessage.mutate(chatMessage.id),
|
||||||
icon: require('@tabler/icons/outline/trash.svg'),
|
icon: trashIcon,
|
||||||
destructive: true,
|
destructive: true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -222,7 +228,7 @@ const ChatMessage = (props: IChatMessage) => {
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/mood-smile.svg')}
|
src={moodSmileIcon}
|
||||||
className='size-4'
|
className='size-4'
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
@ -244,7 +250,7 @@ const ChatMessage = (props: IChatMessage) => {
|
||||||
data-testid='chat-message-menu'
|
data-testid='chat-message-menu'
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/dots.svg')}
|
src={dotsIcon}
|
||||||
className='size-4'
|
className='size-4'
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
@ -362,7 +368,7 @@ const ChatMessage = (props: IChatMessage) => {
|
||||||
{isRead ? (
|
{isRead ? (
|
||||||
<span className='flex flex-col items-center justify-center rounded-full border border-solid border-primary-500 bg-primary-500 p-0.5 text-white dark:border-primary-400 dark:bg-primary-400 dark:text-primary-900'>
|
<span className='flex flex-col items-center justify-center rounded-full border border-solid border-primary-500 bg-primary-500 p-0.5 text-white dark:border-primary-400 dark:bg-primary-400 dark:text-primary-900'>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/check.svg')}
|
src={checkIcon}
|
||||||
strokeWidth={3}
|
strokeWidth={3}
|
||||||
className='size-2.5'
|
className='size-2.5'
|
||||||
/>
|
/>
|
||||||
|
@ -370,7 +376,7 @@ const ChatMessage = (props: IChatMessage) => {
|
||||||
) : (
|
) : (
|
||||||
<span className='flex flex-col items-center justify-center rounded-full border border-solid border-primary-500 bg-transparent p-0.5 text-primary-500 dark:border-primary-400 dark:text-primary-400'>
|
<span className='flex flex-col items-center justify-center rounded-full border border-solid border-primary-500 bg-transparent p-0.5 text-primary-500 dark:border-primary-400 dark:text-primary-400'>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/check.svg')}
|
src={checkIcon}
|
||||||
strokeWidth={3}
|
strokeWidth={3}
|
||||||
className='size-2.5'
|
className='size-2.5'
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import arrowLeftIcon from '@tabler/icons/outline/arrow-left.svg';
|
||||||
|
import banIcon from '@tabler/icons/outline/ban.svg';
|
||||||
|
import infoCircleIcon from '@tabler/icons/outline/info-circle.svg';
|
||||||
|
import logoutIcon from '@tabler/icons/outline/logout.svg';
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { Link, useHistory, useParams } from 'react-router-dom';
|
import { Link, useHistory, useParams } from 'react-router-dom';
|
||||||
|
@ -120,7 +124,7 @@ const ChatPageMain = () => {
|
||||||
<HStack alignItems='center' space={2} className='overflow-hidden'>
|
<HStack alignItems='center' space={2} className='overflow-hidden'>
|
||||||
<HStack alignItems='center'>
|
<HStack alignItems='center'>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/arrow-left.svg')}
|
src={arrowLeftIcon}
|
||||||
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
||||||
onClick={() => history.push('/chats')}
|
onClick={() => history.push('/chats')}
|
||||||
/>
|
/>
|
||||||
|
@ -162,7 +166,7 @@ const ChatPageMain = () => {
|
||||||
<Menu>
|
<Menu>
|
||||||
<MenuButton
|
<MenuButton
|
||||||
as={IconButton}
|
as={IconButton}
|
||||||
src={require('@tabler/icons/outline/info-circle.svg')}
|
src={infoCircleIcon}
|
||||||
iconClassName='h-5 w-5 text-gray-600'
|
iconClassName='h-5 w-5 text-gray-600'
|
||||||
children={null}
|
children={null}
|
||||||
/>
|
/>
|
||||||
|
@ -213,7 +217,7 @@ const ChatPageMain = () => {
|
||||||
className='!px-0 hover:!bg-transparent'
|
className='!px-0 hover:!bg-transparent'
|
||||||
>
|
>
|
||||||
<div className='flex w-full items-center space-x-2 text-sm font-bold text-primary-500 dark:text-accent-blue'>
|
<div className='flex w-full items-center space-x-2 text-sm font-bold text-primary-500 dark:text-accent-blue'>
|
||||||
<Icon src={require('@tabler/icons/outline/ban.svg')} className='size-5' />
|
<Icon src={banIcon} className='size-5' />
|
||||||
<span>{intl.formatMessage(isBlocking ? messages.unblockUser : messages.blockUser, { acct: chat.account.acct })}</span>
|
<span>{intl.formatMessage(isBlocking ? messages.unblockUser : messages.blockUser, { acct: chat.account.acct })}</span>
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
@ -225,7 +229,7 @@ const ChatPageMain = () => {
|
||||||
className='!px-0 hover:!bg-transparent'
|
className='!px-0 hover:!bg-transparent'
|
||||||
>
|
>
|
||||||
<div className='flex w-full items-center space-x-2 text-sm font-bold text-danger-600 dark:text-danger-500'>
|
<div className='flex w-full items-center space-x-2 text-sm font-bold text-danger-600 dark:text-danger-500'>
|
||||||
<Icon src={require('@tabler/icons/outline/logout.svg')} className='size-5' />
|
<Icon src={logoutIcon} className='size-5' />
|
||||||
<span>{intl.formatMessage(messages.leaveChat)}</span>
|
<span>{intl.formatMessage(messages.leaveChat)}</span>
|
||||||
</div>
|
</div>
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import arrowLeftIcon from '@tabler/icons/outline/arrow-left.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
@ -23,7 +24,7 @@ const ChatPageNew: React.FC<IChatPageNew> = () => {
|
||||||
<Stack className='grow px-4 pt-6 sm:px-6'>
|
<Stack className='grow px-4 pt-6 sm:px-6'>
|
||||||
<HStack alignItems='center'>
|
<HStack alignItems='center'>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/arrow-left.svg')}
|
src={arrowLeftIcon}
|
||||||
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
||||||
onClick={() => history.push('/chats')}
|
onClick={() => history.push('/chats')}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import arrowLeftIcon from '@tabler/icons/outline/arrow-left.svg';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
@ -50,7 +51,7 @@ const ChatPageSettings = () => {
|
||||||
<Stack className='h-full space-y-8 px-4 py-6 sm:p-6'>
|
<Stack className='h-full space-y-8 px-4 py-6 sm:p-6'>
|
||||||
<HStack alignItems='center'>
|
<HStack alignItems='center'>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/arrow-left.svg')}
|
src={arrowLeftIcon}
|
||||||
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
className='mr-2 size-7 sm:mr-0 sm:hidden rtl:rotate-180'
|
||||||
onClick={() => history.push('/chats')}
|
onClick={() => history.push('/chats')}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import editIcon from '@tabler/icons/outline/edit.svg';
|
||||||
|
import settingsIcon from '@tabler/icons/outline/settings.svg';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
|
@ -42,13 +44,13 @@ const ChatPageSidebar = () => {
|
||||||
|
|
||||||
<HStack space={1}>
|
<HStack space={1}>
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/settings.svg')}
|
src={settingsIcon}
|
||||||
iconClassName='h-5 w-5 text-gray-600'
|
iconClassName='h-5 w-5 text-gray-600'
|
||||||
onClick={handleSettingsClick}
|
onClick={handleSettingsClick}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
src={require('@tabler/icons/outline/edit.svg')}
|
src={editIcon}
|
||||||
iconClassName='h-5 w-5 text-gray-600'
|
iconClassName='h-5 w-5 text-gray-600'
|
||||||
onClick={handleChatCreate}
|
onClick={handleChatCreate}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import editIcon from '@tabler/icons/outline/edit.svg';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
|
@ -111,7 +112,7 @@ const ChatPane = () => {
|
||||||
toggleChatPane();
|
toggleChatPane();
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
secondaryActionIcon={require('@tabler/icons/outline/edit.svg')}
|
secondaryActionIcon={editIcon}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{isOpen ? renderBody() : null}
|
{isOpen ? renderBody() : null}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import searchIcon from '@tabler/icons/outline/search.svg';
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -34,7 +36,7 @@ const ChatSearchInput: React.FC<IChatSearchInput> = ({ value, onChange, onClear
|
||||||
append={
|
append={
|
||||||
<button onClick={onClear}>
|
<button onClick={onClear}>
|
||||||
<Icon
|
<Icon
|
||||||
src={value.length ? require('@tabler/icons/outline/x.svg') : require('@tabler/icons/outline/search.svg')}
|
src={value.length ? xIcon : searchIcon}
|
||||||
className='size-4 text-gray-700 dark:text-gray-600'
|
className='size-4 text-gray-700 dark:text-gray-600'
|
||||||
aria-hidden='true'
|
aria-hidden='true'
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import searchIcon from '@tabler/icons/outline/search.svg';
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import { useMutation } from '@tanstack/react-query';
|
import { useMutation } from '@tanstack/react-query';
|
||||||
import { AxiosError } from 'axios';
|
import { AxiosError } from 'axios';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
@ -101,7 +103,7 @@ const ChatSearch = (props: IChatSearch) => {
|
||||||
append={
|
append={
|
||||||
<button onClick={clearValue}>
|
<button onClick={clearValue}>
|
||||||
<Icon
|
<Icon
|
||||||
src={hasSearchValue ? require('@tabler/icons/outline/x.svg') : require('@tabler/icons/outline/search.svg')}
|
src={hasSearchValue ? xIcon : searchIcon}
|
||||||
className='size-4 text-gray-700 dark:text-gray-600'
|
className='size-4 text-gray-700 dark:text-gray-600'
|
||||||
aria-hidden='true'
|
aria-hidden='true'
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import paperclipIcon from '@tabler/icons/outline/paperclip.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { Icon } from 'soapbox/components/ui';
|
import { Icon } from 'soapbox/components/ui';
|
||||||
|
@ -5,7 +6,7 @@ import { MIMETYPE_ICONS } from 'soapbox/components/upload';
|
||||||
|
|
||||||
import type { Attachment } from 'soapbox/types/entities';
|
import type { Attachment } from 'soapbox/types/entities';
|
||||||
|
|
||||||
const defaultIcon = require('@tabler/icons/outline/paperclip.svg');
|
const defaultIcon = paperclipIcon;
|
||||||
|
|
||||||
interface IChatUploadPreview {
|
interface IChatUploadPreview {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { List as ImmutableList } from 'immutable';
|
import { List as ImmutableList } from 'immutable';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
@ -57,7 +58,7 @@ const RemoveButton: React.FC<IRemoveButton> = ({ onClick }) => {
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
className='size-3 text-white'
|
className='size-3 text-white'
|
||||||
src={require('@tabler/icons/outline/x.svg')}
|
src={xIcon}
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import chevronDownIcon from '@tabler/icons/outline/chevron-down.svg';
|
||||||
|
import chevronUpIcon from '@tabler/icons/outline/chevron-up.svg';
|
||||||
import React, { HTMLAttributes } from 'react';
|
import React, { HTMLAttributes } from 'react';
|
||||||
|
|
||||||
import { HStack, IconButton, Text } from 'soapbox/components/ui';
|
import { HStack, IconButton, Text } from 'soapbox/components/ui';
|
||||||
|
@ -65,7 +67,7 @@ const ChatPaneHeader = (props: IChatPaneHeader) => {
|
||||||
|
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={onToggle}
|
onClick={onToggle}
|
||||||
src={isOpen ? require('@tabler/icons/outline/chevron-down.svg') : require('@tabler/icons/outline/chevron-up.svg')}
|
src={isOpen ? chevronDownIcon : chevronUpIcon}
|
||||||
iconClassName='h-5 w-5 text-gray-600'
|
iconClassName='h-5 w-5 text-gray-600'
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import arrowLeftIcon from '@tabler/icons/outline/arrow-left.svg';
|
||||||
|
import banIcon from '@tabler/icons/outline/ban.svg';
|
||||||
|
import logoutIcon from '@tabler/icons/outline/logout.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -95,7 +98,7 @@ const ChatSettings = () => {
|
||||||
<HStack alignItems='center' space={2}>
|
<HStack alignItems='center' space={2}>
|
||||||
<button onClick={closeSettings}>
|
<button onClick={closeSettings}>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/arrow-left.svg')}
|
src={arrowLeftIcon}
|
||||||
className='size-6 text-gray-600 dark:text-gray-400 rtl:rotate-180'
|
className='size-6 text-gray-600 dark:text-gray-400 rtl:rotate-180'
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
@ -136,13 +139,13 @@ const ChatSettings = () => {
|
||||||
|
|
||||||
<Stack space={5}>
|
<Stack space={5}>
|
||||||
<button onClick={isBlocking ? handleUnblockUser : handleBlockUser} className='flex w-full items-center space-x-2 text-sm font-bold text-primary-600 dark:text-accent-blue'>
|
<button onClick={isBlocking ? handleUnblockUser : handleBlockUser} className='flex w-full items-center space-x-2 text-sm font-bold text-primary-600 dark:text-accent-blue'>
|
||||||
<Icon src={require('@tabler/icons/outline/ban.svg')} className='size-5' />
|
<Icon src={banIcon} className='size-5' />
|
||||||
<span>{intl.formatMessage(isBlocking ? messages.unblockUser : messages.blockUser, { acct: chat.account.acct })}</span>
|
<span>{intl.formatMessage(isBlocking ? messages.unblockUser : messages.blockUser, { acct: chat.account.acct })}</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{features.chatsDelete && (
|
{features.chatsDelete && (
|
||||||
<button onClick={handleLeaveChat} className='flex w-full items-center space-x-2 text-sm font-bold text-danger-600'>
|
<button onClick={handleLeaveChat} className='flex w-full items-center space-x-2 text-sm font-bold text-danger-600'>
|
||||||
<Icon src={require('@tabler/icons/outline/logout.svg')} className='size-5' />
|
<Icon src={logoutIcon} className='size-5' />
|
||||||
<span>{intl.formatMessage(messages.leaveChat)}</span>
|
<span>{intl.formatMessage(messages.leaveChat)}</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
import arrowLeftIcon from '@tabler/icons/outline/arrow-left.svg';
|
||||||
|
import editIcon from '@tabler/icons/outline/edit.svg';
|
||||||
|
import infoCircleIcon from '@tabler/icons/outline/info-circle.svg';
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
@ -72,7 +75,7 @@ const ChatWindow = () => {
|
||||||
{isOpen && (
|
{isOpen && (
|
||||||
<button onClick={closeChat}>
|
<button onClick={closeChat}>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/arrow-left.svg')}
|
src={arrowLeftIcon}
|
||||||
className='size-6 text-gray-600 dark:text-gray-400 rtl:rotate-180'
|
className='size-6 text-gray-600 dark:text-gray-400 rtl:rotate-180'
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
@ -107,7 +110,7 @@ const ChatWindow = () => {
|
||||||
</HStack>
|
</HStack>
|
||||||
}
|
}
|
||||||
secondaryAction={secondaryAction()}
|
secondaryAction={secondaryAction()}
|
||||||
secondaryActionIcon={isOpen ? require('@tabler/icons/outline/info-circle.svg') : require('@tabler/icons/outline/edit.svg')}
|
secondaryActionIcon={isOpen ? infoCircleIcon : editIcon}
|
||||||
isToggleable={!isOpen}
|
isToggleable={!isOpen}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
onToggle={toggleChatPane}
|
onToggle={toggleChatPane}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import arrowLeftIcon from '@tabler/icons/outline/arrow-left.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ const ChatSearchHeader = () => {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/outline/arrow-left.svg')}
|
src={arrowLeftIcon}
|
||||||
className='size-6 text-gray-600 dark:text-gray-400 rtl:rotate-180'
|
className='size-6 text-gray-600 dark:text-gray-400 rtl:rotate-180'
|
||||||
/>
|
/>
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import lockIcon from '@tabler/icons/outline/lock.svg';
|
||||||
|
import mailIcon from '@tabler/icons/outline/mail.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { CLEAR_EDITOR_COMMAND, TextNode, type LexicalEditor, $getRoot } from 'lexical';
|
import { CLEAR_EDITOR_COMMAND, TextNode, type LexicalEditor, $getRoot } from 'lexical';
|
||||||
import React, { Suspense, useCallback, useEffect, useRef, useState } from 'react';
|
import React, { Suspense, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
@ -229,10 +231,10 @@ const ComposeForm = <ID extends string>({ id, shouldCondense, autoFocus, clickab
|
||||||
if (isEditing) {
|
if (isEditing) {
|
||||||
publishText = intl.formatMessage(messages.saveChanges);
|
publishText = intl.formatMessage(messages.saveChanges);
|
||||||
} else if (privacy === 'direct') {
|
} else if (privacy === 'direct') {
|
||||||
publishIcon = require('@tabler/icons/outline/mail.svg');
|
publishIcon = mailIcon;
|
||||||
publishText = intl.formatMessage(messages.message);
|
publishText = intl.formatMessage(messages.message);
|
||||||
} else if (privacy === 'private') {
|
} else if (privacy === 'private') {
|
||||||
publishIcon = require('@tabler/icons/outline/lock.svg');
|
publishIcon = lockIcon;
|
||||||
publishText = intl.formatMessage(messages.publish);
|
publishText = intl.formatMessage(messages.publish);
|
||||||
} else {
|
} else {
|
||||||
publishText = privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
|
publishText = privacy !== 'unlisted' ? intl.formatMessage(messages.publishLoud, { publish: intl.formatMessage(messages.publish) }) : intl.formatMessage(messages.publish);
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import markdownIcon from '@tabler/icons/outline/markdown.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -25,7 +26,7 @@ const MarkdownButton: React.FC<IMarkdownButton> = ({ composeId }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ComposeFormButton
|
<ComposeFormButton
|
||||||
icon={require('@tabler/icons/outline/markdown.svg')}
|
icon={markdownIcon}
|
||||||
title={intl.formatMessage(active ? messages.marked : messages.unmarked)}
|
title={intl.formatMessage(active ? messages.marked : messages.unmarked)}
|
||||||
active={active}
|
active={active}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import chartBarIcon from '@tabler/icons/outline/chart-bar.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ const PollButton: React.FC<IPollButton> = ({ composeId, disabled }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ComposeFormButton
|
<ComposeFormButton
|
||||||
icon={require('@tabler/icons/outline/chart-bar.svg')}
|
icon={chartBarIcon}
|
||||||
title={intl.formatMessage(active ? messages.remove_poll : messages.add_poll)}
|
title={intl.formatMessage(active ? messages.remove_poll : messages.add_poll)}
|
||||||
active={active}
|
active={active}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
import lockOpenIcon from '@tabler/icons/outline/lock-open.svg';
|
||||||
|
import lockIcon from '@tabler/icons/outline/lock.svg';
|
||||||
|
import mailIcon from '@tabler/icons/outline/mail.svg';
|
||||||
|
import worldIcon from '@tabler/icons/outline/world.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import { supportsPassiveEvents } from 'detect-passive-events';
|
import { supportsPassiveEvents } from 'detect-passive-events';
|
||||||
import React, { useState, useRef, useEffect } from 'react';
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
|
@ -160,10 +164,10 @@ const PrivacyDropdown: React.FC<IPrivacyDropdown> = ({
|
||||||
const [placement, setPlacement] = useState('bottom');
|
const [placement, setPlacement] = useState('bottom');
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{ icon: require('@tabler/icons/outline/world.svg'), value: 'public', text: intl.formatMessage(messages.public_short), meta: intl.formatMessage(messages.public_long) },
|
{ icon: worldIcon, value: 'public', text: intl.formatMessage(messages.public_short), meta: intl.formatMessage(messages.public_long) },
|
||||||
{ icon: require('@tabler/icons/outline/lock-open.svg'), value: 'unlisted', text: intl.formatMessage(messages.unlisted_short), meta: intl.formatMessage(messages.unlisted_long) },
|
{ icon: lockOpenIcon, value: 'unlisted', text: intl.formatMessage(messages.unlisted_short), meta: intl.formatMessage(messages.unlisted_long) },
|
||||||
{ icon: require('@tabler/icons/outline/lock.svg'), value: 'private', text: intl.formatMessage(messages.private_short), meta: intl.formatMessage(messages.private_long) },
|
{ icon: lockIcon, value: 'private', text: intl.formatMessage(messages.private_short), meta: intl.formatMessage(messages.private_long) },
|
||||||
{ icon: require('@tabler/icons/outline/mail.svg'), value: 'direct', text: intl.formatMessage(messages.direct_short), meta: intl.formatMessage(messages.direct_long) },
|
{ icon: mailIcon, value: 'direct', text: intl.formatMessage(messages.direct_short), meta: intl.formatMessage(messages.direct_long) },
|
||||||
];
|
];
|
||||||
|
|
||||||
const onChange = (value: string | null) => value && dispatch(changeComposeVisibility(composeId, value));
|
const onChange = (value: string | null) => value && dispatch(changeComposeVisibility(composeId, value));
|
||||||
|
@ -246,7 +250,7 @@ const PrivacyDropdown: React.FC<IPrivacyDropdown> = ({
|
||||||
'text-gray-600 hover:text-gray-700 dark:hover:text-gray-500': !open,
|
'text-gray-600 hover:text-gray-700 dark:hover:text-gray-500': !open,
|
||||||
'text-primary-500 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-400': open,
|
'text-primary-500 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-400': open,
|
||||||
})}
|
})}
|
||||||
src={valueOption?.icon}
|
src={valueOption!.icon}
|
||||||
title={intl.formatMessage(messages.change_privacy)}
|
title={intl.formatMessage(messages.change_privacy)}
|
||||||
onClick={handleToggle}
|
onClick={handleToggle}
|
||||||
onMouseDown={handleMouseDown}
|
onMouseDown={handleMouseDown}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ const ReplyIndicator: React.FC<IReplyIndicator> = ({ className, status, hideActi
|
||||||
if (!hideActions && onCancel) {
|
if (!hideActions && onCancel) {
|
||||||
actions = {
|
actions = {
|
||||||
onActionClick: handleClick,
|
onActionClick: handleClick,
|
||||||
actionIcon: require('@tabler/icons/outline/x.svg'),
|
actionIcon: xIcon,
|
||||||
actionAlignment: 'top',
|
actionAlignment: 'top',
|
||||||
actionTitle: 'Dismiss',
|
actionTitle: 'Dismiss',
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import calendarStatsIcon from '@tabler/icons/outline/calendar-stats.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -39,7 +40,7 @@ const ScheduleButton: React.FC<IScheduleButton> = ({ composeId, disabled }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ComposeFormButton
|
<ComposeFormButton
|
||||||
icon={require('@tabler/icons/outline/calendar-stats.svg')}
|
icon={calendarStatsIcon}
|
||||||
title={intl.formatMessage(active ? messages.remove_schedule : messages.add_schedule)}
|
title={intl.formatMessage(active ? messages.remove_schedule : messages.add_schedule)}
|
||||||
active={active}
|
active={active}
|
||||||
disabled={disabled}
|
disabled={disabled}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ const ScheduleForm: React.FC<IScheduleForm> = ({ composeId }) => {
|
||||||
<IconButton
|
<IconButton
|
||||||
iconClassName='h-4 w-4'
|
iconClassName='h-4 w-4'
|
||||||
className='bg-transparent text-gray-400 hover:text-gray-600'
|
className='bg-transparent text-gray-400 hover:text-gray-600'
|
||||||
src={require('@tabler/icons/outline/x.svg')}
|
src={xIcon}
|
||||||
onClick={handleRemove}
|
onClick={handleRemove}
|
||||||
title={intl.formatMessage(messages.remove)}
|
title={intl.formatMessage(messages.remove)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
|
@ -213,7 +214,7 @@ const SearchResults = () => {
|
||||||
<>
|
<>
|
||||||
{filterByAccount ? (
|
{filterByAccount ? (
|
||||||
<HStack className='mb-4 border-b border-solid border-gray-200 px-2 pb-4 dark:border-gray-800' space={2}>
|
<HStack className='mb-4 border-b border-solid border-gray-200 px-2 pb-4 dark:border-gray-800' space={2}>
|
||||||
<IconButton iconClassName='h-5 w-5' src={require('@tabler/icons/outline/x.svg')} onClick={handleUnsetAccount} />
|
<IconButton iconClassName='h-5 w-5' src={xIcon} onClick={handleUnsetAccount} />
|
||||||
<Text truncate>
|
<Text truncate>
|
||||||
<FormattedMessage
|
<FormattedMessage
|
||||||
id='search_results.filter_message'
|
id='search_results.filter_message'
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import React, { useCallback, useEffect } from 'react';
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
@ -153,7 +154,7 @@ const SearchZapSplit = (props: ISearchZapSplit) => {
|
||||||
>
|
>
|
||||||
|
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
src={require('@tabler/icons/outline/x.svg')}
|
src={xIcon}
|
||||||
className={clsx('size-4 text-gray-600', { hidden: !hasValue })}
|
className={clsx('size-4 text-gray-600', { hidden: !hasValue })}
|
||||||
aria-label={intl.formatMessage(messages.placeholder)}
|
aria-label={intl.formatMessage(messages.placeholder)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import searchIcon from '@tabler/icons/outline/search.svg';
|
||||||
|
import xIcon from '@tabler/icons/outline/x.svg';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import debounce from 'lodash/debounce';
|
import debounce from 'lodash/debounce';
|
||||||
import React, { useCallback, useEffect } from 'react';
|
import React, { useCallback, useEffect } from 'react';
|
||||||
|
@ -111,7 +113,7 @@ const Search = (props: ISearch) => {
|
||||||
const makeMenu = () => [
|
const makeMenu = () => [
|
||||||
{
|
{
|
||||||
text: intl.formatMessage(messages.action, { query: value }),
|
text: intl.formatMessage(messages.action, { query: value }),
|
||||||
icon: require('@tabler/icons/outline/search.svg'),
|
icon: searchIcon,
|
||||||
action: handleSubmit,
|
action: handleSubmit,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -166,12 +168,12 @@ const Search = (props: ISearch) => {
|
||||||
onClick={handleClear}
|
onClick={handleClear}
|
||||||
>
|
>
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
src={require('@tabler/icons/outline/search.svg')}
|
src={searchIcon}
|
||||||
className={clsx('size-4 text-gray-600', { hidden: hasValue })}
|
className={clsx('size-4 text-gray-600', { hidden: hasValue })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<SvgIcon
|
<SvgIcon
|
||||||
src={require('@tabler/icons/outline/x.svg')}
|
src={xIcon}
|
||||||
className={clsx('size-4 text-gray-600', { hidden: !hasValue })}
|
className={clsx('size-4 text-gray-600', { hidden: !hasValue })}
|
||||||
aria-label={intl.formatMessage(messages.placeholder)}
|
aria-label={intl.formatMessage(messages.placeholder)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import alertTriangleIcon from '@tabler/icons/outline/alert-triangle.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { defineMessages, useIntl } from 'react-intl';
|
import { defineMessages, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ const SpoilerButton: React.FC<ISpoilerButton> = ({ composeId }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ComposeFormButton
|
<ComposeFormButton
|
||||||
icon={require('@tabler/icons/outline/alert-triangle.svg')}
|
icon={alertTriangleIcon}
|
||||||
title={intl.formatMessage(active ? messages.marked : messages.unmarked)}
|
title={intl.formatMessage(active ? messages.marked : messages.unmarked)}
|
||||||
active={active}
|
active={active}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import paperclipIcon from '@tabler/icons/outline/paperclip.svg';
|
||||||
|
import photoIcon from '@tabler/icons/outline/photo.svg';
|
||||||
import React, { useRef } from 'react';
|
import React, { useRef } from 'react';
|
||||||
import { defineMessages, IntlShape, useIntl } from 'react-intl';
|
import { defineMessages, IntlShape, useIntl } from 'react-intl';
|
||||||
|
|
||||||
|
@ -54,8 +56,8 @@ const UploadButton: React.FC<IUploadButton> = ({
|
||||||
|
|
||||||
const src = icon || (
|
const src = icon || (
|
||||||
onlyImages(attachmentTypes)
|
onlyImages(attachmentTypes)
|
||||||
? require('@tabler/icons/outline/photo.svg')
|
? photoIcon
|
||||||
: require('@tabler/icons/outline/paperclip.svg')
|
: paperclipIcon
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import externalLinkIcon from '@tabler/icons/outline/external-link.svg';
|
||||||
|
import qrcodeIcon from '@tabler/icons/outline/qrcode.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { openModal } from 'soapbox/actions/modals';
|
import { openModal } from 'soapbox/actions/modals';
|
||||||
|
@ -42,12 +44,12 @@ const CryptoAddress: React.FC<ICryptoAddress> = (props): JSX.Element => {
|
||||||
|
|
||||||
<HStack alignItems='center' className='ml-auto'>
|
<HStack alignItems='center' className='ml-auto'>
|
||||||
<a className='ml-1 text-gray-500 rtl:ml-0 rtl:mr-1' href='#' onClick={handleModalClick}>
|
<a className='ml-1 text-gray-500 rtl:ml-0 rtl:mr-1' href='#' onClick={handleModalClick}>
|
||||||
<Icon src={require('@tabler/icons/outline/qrcode.svg')} size={20} />
|
<Icon src={qrcodeIcon} size={20} />
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
{explorerUrl && (
|
{explorerUrl && (
|
||||||
<a className='ml-1 text-gray-500 rtl:ml-0 rtl:mr-1' href={explorerUrl} target='_blank'>
|
<a className='ml-1 text-gray-500 rtl:ml-0 rtl:mr-1' href={explorerUrl} target='_blank'>
|
||||||
<Icon src={require('@tabler/icons/outline/external-link.svg')} size={20} />
|
<Icon src={externalLinkIcon} size={20} />
|
||||||
</a>
|
</a>
|
||||||
)}
|
)}
|
||||||
</HStack>
|
</HStack>
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import externalLinkIcon from '@tabler/icons/outline/external-link.svg';
|
||||||
import { QRCodeCanvas as QRCode } from 'qrcode.react';
|
import { QRCodeCanvas as QRCode } from 'qrcode.react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ const DetailedCryptoAddress: React.FC<IDetailedCryptoAddress> = ({ address, tick
|
||||||
<div className='crypto-address__title'>{title || ticker.toUpperCase()}</div>
|
<div className='crypto-address__title'>{title || ticker.toUpperCase()}</div>
|
||||||
<div className='crypto-address__actions'>
|
<div className='crypto-address__actions'>
|
||||||
{explorerUrl && <a href={explorerUrl} target='_blank'>
|
{explorerUrl && <a href={explorerUrl} target='_blank'>
|
||||||
<Icon src={require('@tabler/icons/outline/external-link.svg')} />
|
<Icon src={externalLinkIcon} />
|
||||||
</a>}
|
</a>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
import appsIcon from '@tabler/icons/outline/apps.svg';
|
||||||
|
import codePlusIcon from '@tabler/icons/outline/code-plus.svg';
|
||||||
|
import homeIcon from '@tabler/icons/outline/home.svg';
|
||||||
|
import logoutIcon from '@tabler/icons/outline/logout.svg';
|
||||||
|
import moodSadIcon from '@tabler/icons/outline/mood-sad.svg';
|
||||||
|
import refreshIcon from '@tabler/icons/outline/refresh.svg';
|
||||||
|
import scriptIcon from '@tabler/icons/outline/script.svg';
|
||||||
|
import urgentIcon from '@tabler/icons/outline/urgent.svg';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
|
||||||
import { Link, useHistory } from 'react-router-dom';
|
import { Link, useHistory } from 'react-router-dom';
|
||||||
|
@ -57,7 +65,7 @@ const Developers: React.FC = () => {
|
||||||
<Column label={intl.formatMessage(messages.heading)}>
|
<Column label={intl.formatMessage(messages.heading)}>
|
||||||
<div className='grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3'>
|
<div className='grid grid-cols-1 gap-2 sm:grid-cols-2 lg:grid-cols-3'>
|
||||||
<DashWidget to='/developers/apps/create'>
|
<DashWidget to='/developers/apps/create'>
|
||||||
<SvgIcon src={require('@tabler/icons/outline/apps.svg')} className='text-gray-700 dark:text-gray-600' />
|
<SvgIcon src={appsIcon} className='text-gray-700 dark:text-gray-600' />
|
||||||
|
|
||||||
<Text>
|
<Text>
|
||||||
<FormattedMessage id='developers.navigation.app_create_label' defaultMessage='Create an app' />
|
<FormattedMessage id='developers.navigation.app_create_label' defaultMessage='Create an app' />
|
||||||
|
@ -65,7 +73,7 @@ const Developers: React.FC = () => {
|
||||||
</DashWidget>
|
</DashWidget>
|
||||||
|
|
||||||
<DashWidget to='/developers/settings_store'>
|
<DashWidget to='/developers/settings_store'>
|
||||||
<SvgIcon src={require('@tabler/icons/outline/code-plus.svg')} className='text-gray-700 dark:text-gray-600' />
|
<SvgIcon src={codePlusIcon} className='text-gray-700 dark:text-gray-600' />
|
||||||
|
|
||||||
<Text>
|
<Text>
|
||||||
<FormattedMessage id='developers.navigation.settings_store_label' defaultMessage='Settings store' />
|
<FormattedMessage id='developers.navigation.settings_store_label' defaultMessage='Settings store' />
|
||||||
|
@ -73,7 +81,7 @@ const Developers: React.FC = () => {
|
||||||
</DashWidget>
|
</DashWidget>
|
||||||
|
|
||||||
<DashWidget to='/developers/timeline'>
|
<DashWidget to='/developers/timeline'>
|
||||||
<SvgIcon src={require('@tabler/icons/outline/home.svg')} className='text-gray-700 dark:text-gray-600' />
|
<SvgIcon src={homeIcon} className='text-gray-700 dark:text-gray-600' />
|
||||||
|
|
||||||
<Text>
|
<Text>
|
||||||
<FormattedMessage id='developers.navigation.test_timeline_label' defaultMessage='Test timeline' />
|
<FormattedMessage id='developers.navigation.test_timeline_label' defaultMessage='Test timeline' />
|
||||||
|
@ -81,7 +89,7 @@ const Developers: React.FC = () => {
|
||||||
</DashWidget>
|
</DashWidget>
|
||||||
|
|
||||||
<DashWidget to='/error'>
|
<DashWidget to='/error'>
|
||||||
<SvgIcon src={require('@tabler/icons/outline/mood-sad.svg')} className='text-gray-700 dark:text-gray-600' />
|
<SvgIcon src={moodSadIcon} className='text-gray-700 dark:text-gray-600' />
|
||||||
|
|
||||||
<Text>
|
<Text>
|
||||||
<FormattedMessage id='developers.navigation.intentional_error_label' defaultMessage='Trigger an error' />
|
<FormattedMessage id='developers.navigation.intentional_error_label' defaultMessage='Trigger an error' />
|
||||||
|
@ -89,7 +97,7 @@ const Developers: React.FC = () => {
|
||||||
</DashWidget>
|
</DashWidget>
|
||||||
|
|
||||||
<DashWidget to='/error/network'>
|
<DashWidget to='/error/network'>
|
||||||
<SvgIcon src={require('@tabler/icons/outline/refresh.svg')} className='text-gray-700 dark:text-gray-600' />
|
<SvgIcon src={refreshIcon} className='text-gray-700 dark:text-gray-600' />
|
||||||
|
|
||||||
<Text>
|
<Text>
|
||||||
<FormattedMessage id='developers.navigation.network_error_label' defaultMessage='Network error' />
|
<FormattedMessage id='developers.navigation.network_error_label' defaultMessage='Network error' />
|
||||||
|
@ -97,7 +105,7 @@ const Developers: React.FC = () => {
|
||||||
</DashWidget>
|
</DashWidget>
|
||||||
|
|
||||||
<DashWidget to='/developers/sw'>
|
<DashWidget to='/developers/sw'>
|
||||||
<SvgIcon src={require('@tabler/icons/outline/script.svg')} className='text-gray-700 dark:text-gray-600' />
|
<SvgIcon src={scriptIcon} className='text-gray-700 dark:text-gray-600' />
|
||||||
|
|
||||||
<Text>
|
<Text>
|
||||||
<FormattedMessage id='developers.navigation.service_worker_label' defaultMessage='Service Worker' />
|
<FormattedMessage id='developers.navigation.service_worker_label' defaultMessage='Service Worker' />
|
||||||
|
@ -105,7 +113,7 @@ const Developers: React.FC = () => {
|
||||||
</DashWidget>
|
</DashWidget>
|
||||||
|
|
||||||
<DashWidget onClick={leaveDevelopers}>
|
<DashWidget onClick={leaveDevelopers}>
|
||||||
<SvgIcon src={require('@tabler/icons/outline/logout.svg')} className='text-gray-700 dark:text-gray-600' />
|
<SvgIcon src={logoutIcon} className='text-gray-700 dark:text-gray-600' />
|
||||||
|
|
||||||
<Text>
|
<Text>
|
||||||
<FormattedMessage id='developers.navigation.leave_developers_label' defaultMessage='Leave developers' />
|
<FormattedMessage id='developers.navigation.leave_developers_label' defaultMessage='Leave developers' />
|
||||||
|
@ -113,7 +121,7 @@ const Developers: React.FC = () => {
|
||||||
</DashWidget>
|
</DashWidget>
|
||||||
|
|
||||||
<DashWidget onClick={showToast}>
|
<DashWidget onClick={showToast}>
|
||||||
<SvgIcon src={require('@tabler/icons/outline/urgent.svg')} className='text-gray-700 dark:text-gray-600' />
|
<SvgIcon src={urgentIcon} className='text-gray-700 dark:text-gray-600' />
|
||||||
|
|
||||||
<Text>
|
<Text>
|
||||||
<FormattedMessage id='developers.navigation.show_toast' defaultMessage='Trigger Toast' />
|
<FormattedMessage id='developers.navigation.show_toast' defaultMessage='Trigger Toast' />
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue