Merge branch 'main' into fix-font-problem
This commit is contained in:
commit
c070f64309
|
@ -146,7 +146,6 @@ const messages = defineMessages({
|
|||
|
||||
interface IStatusActionBar {
|
||||
status: Status;
|
||||
withLabels?: boolean;
|
||||
expandable?: boolean;
|
||||
space?: 'sm' | 'md' | 'lg';
|
||||
statusActionButtonTheme?: 'default' | 'inverse';
|
||||
|
@ -155,7 +154,6 @@ interface IStatusActionBar {
|
|||
|
||||
const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||
status,
|
||||
withLabels = false,
|
||||
expandable = true,
|
||||
space = 'sm',
|
||||
statusActionButtonTheme = 'default',
|
||||
|
@ -740,7 +738,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
|||
active={status.reblogged}
|
||||
onClick={handleReblogClick}
|
||||
count={reblogCount}
|
||||
text={withLabels ? intl.formatMessage(messages.reblog) : undefined}
|
||||
theme={statusActionButtonTheme}
|
||||
/>
|
||||
);
|
||||
|
@ -780,7 +777,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
|||
icon={messageCircleIcon}
|
||||
onClick={handleReplyClick}
|
||||
count={replyCount}
|
||||
text={withLabels ? intl.formatMessage(messages.reply) : undefined}
|
||||
disabled={replyDisabled}
|
||||
theme={statusActionButtonTheme}
|
||||
/>
|
||||
|
@ -808,7 +804,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
|||
active={Boolean(meEmojiName)}
|
||||
count={emojiReactCount}
|
||||
emoji={meEmojiReact}
|
||||
text={withLabels ? meEmojiTitle : undefined}
|
||||
theme={statusActionButtonTheme}
|
||||
/>
|
||||
</StatusReactionWrapper>
|
||||
|
@ -821,7 +816,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
|||
onClick={handleFavouriteClick}
|
||||
active={Boolean(meEmojiName)}
|
||||
count={favouriteCount}
|
||||
text={withLabels ? meEmojiTitle : undefined}
|
||||
theme={statusActionButtonTheme}
|
||||
/>
|
||||
)}
|
||||
|
@ -835,7 +829,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
|||
onClick={handleDislikeClick}
|
||||
active={status.disliked}
|
||||
count={status.dislikes_count}
|
||||
text={withLabels ? intl.formatMessage(messages.disfavourite) : undefined}
|
||||
theme={statusActionButtonTheme}
|
||||
/>
|
||||
)}
|
||||
|
@ -848,7 +841,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
|||
filled
|
||||
onClick={handleZapClick}
|
||||
active={status.zapped}
|
||||
text={withLabels ? intl.formatMessage(messages.zap) : undefined}
|
||||
theme={statusActionButtonTheme}
|
||||
count={status?.zaps_amount ? status.zaps_amount / 1000 : 0}
|
||||
/>
|
||||
|
|
|
@ -36,12 +36,11 @@ interface IStatusActionButton extends React.ButtonHTMLAttributes<HTMLButtonEleme
|
|||
color?: Color;
|
||||
filled?: boolean;
|
||||
emoji?: EmojiReaction;
|
||||
text?: React.ReactNode;
|
||||
theme?: 'default' | 'inverse';
|
||||
}
|
||||
|
||||
const StatusActionButton = forwardRef<HTMLButtonElement, IStatusActionButton>((props, ref): JSX.Element => {
|
||||
const { icon, className, iconClassName, active, color, filled = false, count = 0, emoji, text, theme = 'default', ...filteredProps } = props;
|
||||
const { icon, className, iconClassName, active, color, filled = false, count = 0, emoji, theme = 'default', ...filteredProps } = props;
|
||||
|
||||
const renderIcon = () => {
|
||||
if (emoji) {
|
||||
|
@ -70,13 +69,7 @@ const StatusActionButton = forwardRef<HTMLButtonElement, IStatusActionButton>((p
|
|||
};
|
||||
|
||||
const renderText = () => {
|
||||
if (text) {
|
||||
return (
|
||||
<Text tag='span' theme='inherit' size='sm'>
|
||||
{text}
|
||||
</Text>
|
||||
);
|
||||
} else if (count) {
|
||||
if (count) {
|
||||
return (
|
||||
<StatusActionCounter count={count} />
|
||||
);
|
||||
|
@ -88,7 +81,7 @@ const StatusActionButton = forwardRef<HTMLButtonElement, IStatusActionButton>((p
|
|||
ref={ref}
|
||||
type='button'
|
||||
className={clsx(
|
||||
'flex items-center rounded-full p-1 rtl:space-x-reverse',
|
||||
'flex items-center space-x-1 rounded-full p-1 rtl:space-x-reverse',
|
||||
'focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 dark:ring-offset-0',
|
||||
{
|
||||
'text-gray-600 hover:text-gray-600 dark:hover:text-white bg-white dark:bg-transparent': theme === 'default',
|
||||
|
@ -97,8 +90,6 @@ const StatusActionButton = forwardRef<HTMLButtonElement, IStatusActionButton>((p
|
|||
'hover:text-gray-600 dark:hover:text-white': !filteredProps.disabled,
|
||||
'text-accent-300 hover:text-accent-300 dark:hover:text-accent-300': active && !emoji && color === COLORS.accent,
|
||||
'text-success-600 hover:text-success-600 dark:hover:text-success-600': active && !emoji && color === COLORS.success,
|
||||
'space-x-1': !text,
|
||||
'space-x-2': text,
|
||||
},
|
||||
className,
|
||||
)}
|
||||
|
|
|
@ -9,11 +9,14 @@ import Form from 'soapbox/components/ui/form.tsx';
|
|||
import Stack from 'soapbox/components/ui/stack.tsx';
|
||||
import RelayEditor, { RelayData } from 'soapbox/features/nostr-relays/components/relay-editor.tsx';
|
||||
import { useApi } from 'soapbox/hooks/useApi.ts';
|
||||
import { queryClient } from 'soapbox/queries/client.ts';
|
||||
import toast from 'soapbox/toast.tsx';
|
||||
|
||||
import { useAdminNostrRelays } from './hooks/useAdminNostrRelays.ts';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'column.admin.nostr_relays', defaultMessage: 'Relays' },
|
||||
success: { id: 'generic.saved', defaultMessage: 'Saved' },
|
||||
});
|
||||
|
||||
const AdminNostrRelays: React.FC = () => {
|
||||
|
@ -25,6 +28,13 @@ const AdminNostrRelays: React.FC = () => {
|
|||
|
||||
const mutation = useMutation({
|
||||
mutationFn: async () => api.put('/api/v1/admin/ditto/relays', relays),
|
||||
onSuccess: () => {
|
||||
queryClient.refetchQueries({ queryKey: ['NostrRelay'] });
|
||||
toast.success(messages.success);
|
||||
},
|
||||
onError: (data) => {
|
||||
toast.error(data.message); // `data.message` is a generic error message, not the `error` message returned from the backend
|
||||
},
|
||||
});
|
||||
|
||||
const handleSubmit = () => {
|
||||
|
|
|
@ -390,7 +390,6 @@ const Thread = (props: IThread) => {
|
|||
status={status}
|
||||
expandable={false}
|
||||
space='lg'
|
||||
withLabels
|
||||
/>
|
||||
</>
|
||||
) : null}
|
||||
|
|
|
@ -135,13 +135,13 @@ class ImageLoader extends PureComponent<IImageLoader> {
|
|||
const { alt, src, width, height, onClick } = this.props;
|
||||
const { loading } = this.state;
|
||||
|
||||
const className = 'relative size-full flex items-center justify-center flex-col';
|
||||
const className = 'relative h-screen flex items-center justify-center flex-col';
|
||||
|
||||
return (
|
||||
<div className={className}>
|
||||
{loading ? (
|
||||
<canvas
|
||||
className={clsx('max-h-[80%] max-w-full object-contain', { 'hidden': !this.hasSize() })}
|
||||
className={clsx('max-h-[100%] max-w-full object-contain', { 'hidden': !this.hasSize() })}
|
||||
style={{
|
||||
background: 'url(\'../assets/images/void.png\') repeat',
|
||||
}}
|
||||
|
|
|
@ -243,7 +243,7 @@ const MediaModal: React.FC<IMediaModal> = (props) => {
|
|||
};
|
||||
|
||||
return (
|
||||
<div className='pointer-events-auto fixed inset-0 z-[9999] h-full bg-gray-900/90'>
|
||||
<div className='media-modal pointer-events-auto fixed inset-0 z-[9999] flex size-full bg-gray-900/90'>
|
||||
<div
|
||||
className='absolute inset-0'
|
||||
role='presentation'
|
||||
|
@ -258,95 +258,99 @@ const MediaModal: React.FC<IMediaModal> = (props) => {
|
|||
}
|
||||
justifyContent='between'
|
||||
>
|
||||
<HStack
|
||||
alignItems='center'
|
||||
justifyContent='between'
|
||||
className={clsx('flex-[0_0_60px] p-4 transition-opacity', navigationHiddenClassName)}
|
||||
>
|
||||
<IconButton
|
||||
title={intl.formatMessage(messages.close)}
|
||||
src={xIcon}
|
||||
onClick={onClose}
|
||||
theme='dark'
|
||||
className='!p-1.5 hover:scale-105 hover:bg-gray-900'
|
||||
iconClassName='h-5 w-5'
|
||||
/>
|
||||
|
||||
<HStack alignItems='center' space={2}>
|
||||
<Stack className='relative h-full'>
|
||||
<HStack
|
||||
alignItems='center'
|
||||
justifyContent='between'
|
||||
className={clsx('absolute z-[9999] flex w-full p-4 transition-opacity', navigationHiddenClassName)}
|
||||
>
|
||||
<IconButton
|
||||
src={downloadIcon}
|
||||
title={intl.formatMessage(messages.close)}
|
||||
src={xIcon}
|
||||
onClick={onClose}
|
||||
theme='dark'
|
||||
className='!p-1.5 hover:scale-105 hover:bg-gray-900'
|
||||
iconClassName='h-5 w-5'
|
||||
onClick={handleDownload}
|
||||
/>
|
||||
|
||||
{status && (
|
||||
<HStack alignItems='center' space={2}>
|
||||
<IconButton
|
||||
src={isFullScreen ? arrowsMinimizeIcon : arrowsMaximizeIcon}
|
||||
title={intl.formatMessage(isFullScreen ? messages.minimize : messages.expand)}
|
||||
src={downloadIcon}
|
||||
theme='dark'
|
||||
className='hidden !p-1.5 hover:scale-105 hover:bg-gray-900 xl:block'
|
||||
className='!p-1.5 hover:scale-105 hover:bg-gray-900'
|
||||
iconClassName='h-5 w-5'
|
||||
onClick={() => setIsFullScreen(!isFullScreen)}
|
||||
onClick={handleDownload}
|
||||
/>
|
||||
|
||||
{status && (
|
||||
<IconButton
|
||||
src={isFullScreen ? arrowsMinimizeIcon : arrowsMaximizeIcon}
|
||||
title={intl.formatMessage(isFullScreen ? messages.minimize : messages.expand)}
|
||||
theme='dark'
|
||||
className='hidden !p-1.5 hover:scale-105 hover:bg-gray-900 xl:block'
|
||||
iconClassName='h-5 w-5'
|
||||
onClick={() => setIsFullScreen(!isFullScreen)}
|
||||
/>
|
||||
)}
|
||||
</HStack>
|
||||
</HStack>
|
||||
|
||||
{/* Height based on height of top/bottom bars */}
|
||||
<div
|
||||
className='relative h-[calc(100vh-120px)] w-full grow'
|
||||
>
|
||||
{hasMultipleImages && (
|
||||
<div className={clsx('absolute inset-y-0 left-5 z-10 flex items-center transition-opacity', navigationHiddenClassName)}>
|
||||
<button
|
||||
tabIndex={0}
|
||||
className='flex size-10 items-center justify-center rounded-full bg-gray-900 text-white'
|
||||
onClick={handlePrevClick}
|
||||
aria-label={intl.formatMessage(messages.previous)}
|
||||
>
|
||||
<Icon src={arrowLeftIcon} className='size-5' />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</HStack>
|
||||
</HStack>
|
||||
|
||||
{/* Height based on height of top/bottom bars */}
|
||||
<div
|
||||
className='relative h-[calc(100vh-120px)] w-full grow'
|
||||
>
|
||||
{hasMultipleImages && (
|
||||
<div className={clsx('absolute inset-y-0 left-5 z-10 flex items-center transition-opacity', navigationHiddenClassName)}>
|
||||
<button
|
||||
tabIndex={0}
|
||||
className='flex size-10 items-center justify-center rounded-full bg-gray-900 text-white'
|
||||
onClick={handlePrevClick}
|
||||
aria-label={intl.formatMessage(messages.previous)}
|
||||
<div className='size-full'>
|
||||
<ReactSwipeableViews
|
||||
style={swipeableViewsStyle}
|
||||
containerStyle={containerStyle}
|
||||
onChangeIndex={handleSwipe}
|
||||
className='flex items-center justify-center'
|
||||
index={getIndex()}
|
||||
>
|
||||
<Icon src={arrowLeftIcon} className='size-5' />
|
||||
</button>
|
||||
{content}
|
||||
</ReactSwipeableViews>
|
||||
</div>
|
||||
|
||||
{hasMultipleImages && (
|
||||
<div className={clsx('absolute inset-y-0 right-5 z-10 flex items-center transition-opacity', navigationHiddenClassName)}>
|
||||
<button
|
||||
tabIndex={0}
|
||||
className='flex size-10 items-center justify-center rounded-full bg-gray-900 text-white'
|
||||
onClick={handleNextClick}
|
||||
aria-label={intl.formatMessage(messages.next)}
|
||||
>
|
||||
<Icon src={arrowRightIcon} className='size-5' />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{actualStatus && (
|
||||
<HStack
|
||||
justifyContent='center'
|
||||
className={clsx('absolute bottom-2 flex w-full transition-opacity', navigationHiddenClassName)}
|
||||
>
|
||||
<StatusActionBar
|
||||
status={actualStatus}
|
||||
space='md'
|
||||
statusActionButtonTheme='inverse'
|
||||
/>
|
||||
</HStack>
|
||||
)}
|
||||
|
||||
<ReactSwipeableViews
|
||||
style={swipeableViewsStyle}
|
||||
containerStyle={containerStyle}
|
||||
onChangeIndex={handleSwipe}
|
||||
className='flex items-center justify-center '
|
||||
index={getIndex()}
|
||||
>
|
||||
{content}
|
||||
</ReactSwipeableViews>
|
||||
|
||||
{hasMultipleImages && (
|
||||
<div className={clsx('absolute inset-y-0 right-5 z-10 flex items-center transition-opacity', navigationHiddenClassName)}>
|
||||
<button
|
||||
tabIndex={0}
|
||||
className='flex size-10 items-center justify-center rounded-full bg-gray-900 text-white'
|
||||
onClick={handleNextClick}
|
||||
aria-label={intl.formatMessage(messages.next)}
|
||||
>
|
||||
<Icon src={arrowRightIcon} className='size-5' />
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{actualStatus && (
|
||||
<HStack
|
||||
justifyContent='center'
|
||||
className={clsx('flex-[0_0_60px] transition-opacity', navigationHiddenClassName)}
|
||||
>
|
||||
<StatusActionBar
|
||||
status={actualStatus}
|
||||
space='md'
|
||||
statusActionButtonTheme='inverse'
|
||||
/>
|
||||
</HStack>
|
||||
)}
|
||||
</Stack>
|
||||
</Stack>
|
||||
|
||||
{actualStatus && (
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import clsx from 'clsx';
|
||||
import { PureComponent } from 'react';
|
||||
|
||||
const MIN_SCALE = 1;
|
||||
|
@ -132,7 +133,7 @@ class ZoomableImage extends PureComponent<IZoomableImage> {
|
|||
role='presentation'
|
||||
ref={this.setImageRef}
|
||||
alt={alt}
|
||||
className='size-auto max-h-[80%] max-w-full object-contain shadow-2xl'
|
||||
className={clsx('size-auto max-h-[80%] max-w-full object-contain', { 'size-full max-h-full': scale !== 1 })}
|
||||
title={alt}
|
||||
src={src}
|
||||
style={{
|
||||
|
|
|
@ -1217,17 +1217,16 @@
|
|||
"onboarding.avatar.title": "Escolha uma foto de perfil",
|
||||
"onboarding.bio.hint": "Máx 500 caracteres",
|
||||
"onboarding.bio.placeholder": "Conte um pouco sobre você…",
|
||||
"onboarding.display_identity.fields.reason_placeholder": "Por que você quer fazer parte da comunidade {siteTitle}?",
|
||||
"onboarding.display_identity.help_text": "Este identificador é um nome de usuário único que representa você na plataforma. Ele é gerado automaticamente com base no site, garantindo que você tenha uma identidade distinta para interagir com outros usuários. Este nome de usuário pode ser usado para personalizar sua experiência e facilitar a comunicação dentro da comunidade.",
|
||||
"onboarding.display_identity.label": "Identidade",
|
||||
"onboarding.display_identity.request": "Nome de usúario solicitado",
|
||||
"onboarding.display_identity.subtitle": "Mostre quem você é! Crie um nome de usuário único e deixe sua marca.",
|
||||
"onboarding.display_identity.title": "Escolha uma Identidade",
|
||||
"onboarding.display_name.label": "Nome de exibição",
|
||||
"onboarding.display_name.placeholder": "Ex. João Silva",
|
||||
"onboarding.display_name.subtitle": "Você pode sempre editar isso depois.",
|
||||
"onboarding.display_name.title": "Escolha um nome de exibição",
|
||||
"onboarding.display_identity.title": "Escolha uma Identidade",
|
||||
"onboarding.display_identity.label": "Identidade",
|
||||
"onboarding.display_identity.request": "Nome de usúario solicitado",
|
||||
"onboarding.display_identity.subtitle": "Mostre quem você é! Crie um nome de usuário único e deixe sua marca.",
|
||||
"onboarding.display_identity.help_text": "Este identificador é um nome de usuário único que representa você na plataforma. Ele é gerado automaticamente com base no site, garantindo que você tenha uma identidade distinta para interagir com outros usuários. Este nome de usuário pode ser usado para personalizar sua experiência e facilitar a comunicação dentro da comunidade.",
|
||||
"onboarding.display_identity.fields.nip05_label": "Nome de usuário",
|
||||
"onboarding.display_identity.fields.reason_placeholder": "Por que você quer fazer parte da comunidade {siteTitle}?",
|
||||
"onboarding.done": "Concluído",
|
||||
"onboarding.error": "Ocorreu um erro inesperado. Por favor, tente novamente ou pule esta etapa.",
|
||||
"onboarding.finished.message": "Estamos muito empolgados para te receber em nossa comunidade! Toque no botão abaixo para começar.",
|
||||
|
|
|
@ -883,6 +883,7 @@ const getInstanceFeatures = (instance: InstanceV1 | InstanceV2) => {
|
|||
v.software === MASTODON,
|
||||
v.software === PLEROMA,
|
||||
v.software === TAKAHE && gte(v.version, '0.7.0'),
|
||||
v.software === DITTO,
|
||||
]),
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue