Merge remote-tracking branch 'origin/develop' into chats

environments/review-chats-g56n7m/deployments/1581
Chewbacca 2 years ago
commit f7f40703cd

@ -28,6 +28,8 @@ busybox unzip soapbox.zip -o -d /opt/pleroma/instance
The change will take effect immediately, just refresh your browser tab. The change will take effect immediately, just refresh your browser tab.
It's not necessary to restart the Pleroma service. It's not necessary to restart the Pleroma service.
***For OTP releases,*** *unpack to /var/lib/pleroma instead.*
To remove Soapbox and revert to the default pleroma-fe, simply `rm /opt/pleroma/instance/static/index.html` (you can delete other stuff in there too, but be careful not to delete your own HTML files). To remove Soapbox and revert to the default pleroma-fe, simply `rm /opt/pleroma/instance/static/index.html` (you can delete other stuff in there too, but be careful not to delete your own HTML files).
## :elephant: Deploy on Mastodon ## :elephant: Deploy on Mastodon

@ -1,12 +0,0 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg xmlns="http://www.w3.org/2000/svg">
<metadata>Generated by IcoMoon</metadata>
<defs>
<font id="icomoon" horiz-adv-x="1024">
<font-face units-per-em="1024" ascent="960" descent="-64" />
<missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="spinster" d="M512 857.6c-226.216 0-409.6-183.384-409.6-409.6v0c0-226.216 183.384-409.6 409.6-409.6v0c226.216 0 409.6 183.384 409.6 409.6v0c0 226.216-183.384 409.6-409.6 409.6v0zM525.84 706.224c32.633 0 64.793-3.777 96.48-11.344 31.687-7.095 59.576-17.748 83.696-31.936l-43.264-104.272c-47.294 25.539-93.176 38.304-137.632 38.304-27.903 0-48.239-4.255-61.008-12.768-12.769-8.040-19.152-18.677-19.152-31.92s7.57-23.171 22.704-29.792c15.134-6.621 39.493-13.482 73.072-20.576 37.835-8.040 69.039-16.797 93.632-26.256 25.066-8.986 46.588-23.648 64.56-43.984 18.445-19.863 27.664-47.059 27.664-81.584 0-29.795-8.279-56.744-24.832-80.864s-41.374-43.515-74.48-58.176c-33.106-14.188-73.314-21.28-120.608-21.28-40.2 0-79.205 4.964-117.040 14.896s-68.577 23.175-92.224 39.728l46.112 103.568c22.228-14.661 48.006-26.486 77.328-35.472s58.168-13.472 86.544-13.472c53.915 0 80.864 13.475 80.864 40.432 0 14.188-7.801 24.595-23.408 31.216-15.134 7.094-39.724 14.432-73.776 22-37.362 8.040-68.582 16.551-93.648 25.536-25.066 9.459-46.572 24.352-64.544 44.688s-26.96 47.763-26.96 82.288c0 30.268 8.279 57.464 24.832 81.584 16.553 24.592 41.143 43.988 73.776 58.176 33.106 14.188 73.545 21.28 121.312 21.28z" />
<glyph unicode="&#xe901;" glyph-name="fediverse" d="M553.99 908.789c-46.369-0.785-83.969-37.261-86.545-83.096l-0.010-0.231c-0.083-1.432-0.13-3.108-0.13-4.794 0-46.987 36.77-85.385 83.105-87.99l0.231-0.010c1.432-0.083 3.107-0.13 4.794-0.13 46.988 0 85.387 36.772 87.99 83.108l0.010 0.231c0.083 1.431 0.13 3.106 0.13 4.791 0 46.988-36.771 85.387-83.108 87.99l-0.231 0.010c-1.441 0.084-3.127 0.132-4.823 0.132-0.497 0-0.993-0.004-1.487-0.012l0.075 0.001zM459.882 805.031l-251.29-127.347c13.547-13.809 23-31.679 26.366-51.617l0.080-0.57 251.287 127.353c-13.545 13.808-22.997 31.675-26.363 51.611l-0.080 0.57zM641.318 775.903c-9.415-17.78-23.636-31.938-40.939-41.021l-0.532-0.254 198.787-199.554c9.415 17.78 23.634 31.938 40.936 41.021l0.532 0.254zM487.306 751.83l-147.023-287.024 43.408-43.576 155.667 303.891c-20.483 3.55-38.302 13.087-52.060 26.716l0.007-0.007zM599.388 734.397c-12.846-6.718-28.060-10.66-44.195-10.66-1.77 0-3.529 0.047-5.276 0.141l0.244-0.010c-3.232 0.199-6.15 0.516-9.026 0.959l0.542-0.069 22.259-142.535 60.737-9.746zM138.038 697.983c-46.37-0.783-83.972-37.26-86.548-83.095l-0.010-0.231c-0.083-1.432-0.13-3.107-0.13-4.794 0-46.988 36.772-85.387 83.108-87.99l0.231-0.010c1.432-0.083 3.107-0.13 4.794-0.13 46.988 0 85.387 36.772 87.99 83.108l0.010 0.231c0.083 1.432 0.13 3.107 0.13 4.794 0 46.988-36.772 85.387-83.108 87.99l-0.231 0.010c-1.43 0.083-3.103 0.13-4.787 0.13-0.51 0-1.018-0.004-1.526-0.013l0.076 0.001zM235.216 624.428c0.752-4.537 1.182-9.766 1.182-15.095 0-1.667-0.042-3.325-0.125-4.972l0.009 0.231c-0.796-13.969-4.43-26.918-10.33-38.52l0.254 0.551 142.645-22.911 28.036 54.751zM479.695 585.167l-28.039-54.757 337.040-54.13c-0.697 4.368-1.096 9.405-1.096 14.535 0 1.678 0.043 3.346 0.127 5.002l-0.009-0.232c0.815 14.158 4.546 27.272 10.597 38.992l-0.254-0.542zM883.076 578.43c-46.37-0.783-83.972-37.26-86.548-83.095l-0.010-0.231c-0.083-1.432-0.13-3.107-0.13-4.794 0-46.988 36.772-85.387 83.108-87.99l0.231-0.010c1.432-0.083 3.107-0.13 4.794-0.13 46.988 0 85.387 36.772 87.99 83.108l0.010 0.231c0.083 1.432 0.13 3.107 0.13 4.794 0 46.988-36.772 85.387-83.108 87.99l-0.231 0.010c-1.438 0.084-3.119 0.131-4.812 0.131-0.501 0-1-0.004-1.499-0.012l0.075 0.001zM225.366 565.098c-9.414-17.777-23.632-31.933-40.931-41.016l-0.532-0.254 227.623-228.511 54.877 27.811zM182.639 523.19c-12.642-6.466-27.577-10.256-43.397-10.256-1.77 0-3.529 0.047-5.276 0.141l0.244-0.010c-3.521 0.199-6.741 0.548-9.909 1.050l0.551-0.072 43.485-278.147c12.642 6.466 27.577 10.256 43.397 10.256 1.77 0 3.529-0.047 5.276-0.141l-0.244 0.010c3.519-0.2 6.737-0.548 9.903-1.050l-0.55 0.072zM576.873 499.359l52.629-336.996c12.457 6.245 27.143 9.902 42.682 9.902 1.773 0 3.535-0.048 5.285-0.142l-0.244 0.010c3.8-0.219 7.286-0.616 10.711-1.192l-0.569 0.079-49.754 318.595zM788.965 474.681l-128.865-65.308 9.501-60.776 145.806 73.896c-13.546 13.809-22.998 31.679-26.363 51.617l-0.080 0.57zM816.386 421.477l-128.362-250.594c20.486-3.55 38.307-13.087 52.065-26.719l-0.007 0.007 128.359 250.591c-20.485 3.551-38.305 13.090-52.062 26.722l0.007-0.007zM302.044 390.153l-74.471-145.382c20.481-3.55 38.298-13.086 52.054-26.714l-0.007 0.007 65.83 128.515zM585.292 371.462l-304.691-154.416c13.549-13.81 23.003-31.682 26.368-51.622l0.080-0.57 287.744 145.83zM525.607 263.696l-54.877-27.811 115.337-115.788c9.415 17.78 23.636 31.938 40.939 41.021l0.532 0.254zM210.049 237.339c-46.369-0.785-83.969-37.261-86.545-83.096l-0.010-0.231c-0.083-1.432-0.13-3.107-0.13-4.794 0-46.988 36.772-85.387 83.108-87.99l0.231-0.010c1.432-0.083 3.107-0.13 4.794-0.13 46.988 0 85.387 36.772 87.99 83.108l0.010 0.231c0.083 1.432 0.13 3.107 0.13 4.794 0 46.988-36.772 85.387-83.108 87.99l-0.231 0.010c-1.438 0.084-3.12 0.132-4.813 0.132-0.501 0-1.002-0.004-1.501-0.013l0.075 0.001zM307.279 163.476c0.72-4.438 1.131-9.554 1.131-14.766 0-1.675-0.042-3.34-0.126-4.993l0.009 0.232c-0.806-14.078-4.495-27.122-10.481-38.793l0.254 0.546 278.1-44.626c-0.721 4.442-1.133 9.563-1.133 14.779 0 1.671 0.042 3.332 0.126 4.983l-0.009-0.232c0.807 14.078 4.497 27.12 10.484 38.79l-0.254-0.546zM670.509 163.451c-46.37-0.783-83.972-37.26-86.548-83.095l-0.010-0.231c-0.083-1.432-0.13-3.107-0.13-4.794 0-46.988 36.772-85.387 83.108-87.99l0.231-0.010c1.432-0.083 3.107-0.13 4.794-0.13 46.988 0 85.387 36.772 87.99 83.108l0.010 0.231c0.083 1.432 0.13 3.107 0.13 4.794 0 46.988-36.772 85.387-83.108 87.99l-0.231 0.010c-1.438 0.084-3.119 0.131-4.812 0.131-0.501 0-1-0.004-1.499-0.012l0.075 0.001z" />
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 6.0 KiB

@ -87,7 +87,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.type.hint": "Click to toggle poll type. Radio button (default) is single. Checkbox is multiple.", "compose_form.poll.type.hint": "Click to toggle poll type. Radio button (default) is single. Checkbox is multiple.",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",
"compose_form.publish_loud": "{publish}!", "compose_form.publish_loud": "{publish}!",
@ -566,7 +566,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.type.hint": "Click to toggle poll type. Radio button (default) is single. Checkbox is multiple.", "compose_form.poll.type.hint": "Click to toggle poll type. Radio button (default) is single. Checkbox is multiple.",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",
"compose_form.publish_loud": "{publish}!", "compose_form.publish_loud": "{publish}!",

@ -253,6 +253,10 @@ export const logOut = () =>
export const switchAccount = (accountId: string, background = false) => export const switchAccount = (accountId: string, background = false) =>
(dispatch: AppDispatch, getState: () => RootState) => { (dispatch: AppDispatch, getState: () => RootState) => {
const account = getState().accounts.get(accountId); const account = getState().accounts.get(accountId);
// Clear all stored cache from React Query
queryClient.invalidateQueries();
queryClient.clear();
return dispatch({ type: SWITCH_ACCOUNT, account, background }); return dispatch({ type: SWITCH_ACCOUNT, account, background });
}; };

@ -4,7 +4,7 @@ import { useDispatch } from 'react-redux';
import { unblockDomain } from 'soapbox/actions/domain-blocks'; import { unblockDomain } from 'soapbox/actions/domain-blocks';
import IconButton from './icon-button'; import { HStack, IconButton, Text } from './ui';
const messages = defineMessages({ const messages = defineMessages({
blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' }, blockDomainConfirm: { id: 'confirmations.domain_block.confirm', defaultMessage: 'Hide entire domain' },
@ -34,17 +34,12 @@ const Domain: React.FC<IDomain> = ({ domain }) => {
}; };
return ( return (
<div className='domain'> <HStack alignItems='center' justifyContent='between' space={1} className='p-2'>
<div className='domain__wrapper'> <Text tag='span'>
<span className='domain__domain-name'> {domain}
<strong>{domain}</strong> </Text>
</span> <IconButton iconClassName='h-5 w-5' src={require('@tabler/icons/lock-open.svg')} title={intl.formatMessage(messages.unblockDomain, { domain })} onClick={handleDomainUnblock} />
</HStack>
<div className='domain__buttons'>
<IconButton active src={require('@tabler/icons/lock-open.svg')} title={intl.formatMessage(messages.unblockDomain, { domain })} onClick={handleDomainUnblock} />
</div>
</div>
</div>
); );
}; };

@ -1,77 +1,77 @@
.status-content p { [data-markup] p {
@apply mb-4 whitespace-pre-wrap; @apply mb-4 whitespace-pre-wrap;
} }
.status-content p:last-child { [data-markup] p:last-child {
@apply mb-0; @apply mb-0;
} }
.status-content a { [data-markup] a {
@apply text-primary-600 dark:text-accent-blue hover:underline; @apply text-primary-600 dark:text-accent-blue hover:underline;
} }
.status-content strong { [data-markup] strong {
@apply font-bold; @apply font-bold;
} }
.status-content em { [data-markup] em {
@apply italic; @apply italic;
} }
.status-content ul, [data-markup] ul,
.status-content ol { [data-markup] ol {
@apply pl-10 mb-4; @apply pl-10 mb-4;
} }
.status-content ul { [data-markup] ul {
@apply list-disc list-outside; @apply list-disc list-outside;
} }
.status-content ol { [data-markup] ol {
@apply list-decimal list-outside; @apply list-decimal list-outside;
} }
.status-content blockquote { [data-markup] blockquote {
@apply py-1 pl-4 mb-4 border-l-4 border-solid border-gray-400 text-gray-500 dark:text-gray-400; @apply py-1 pl-4 mb-4 border-l-4 border-solid border-gray-400 text-gray-500 dark:text-gray-400;
} }
.status-content code { [data-markup] code {
@apply cursor-text font-mono; @apply cursor-text font-mono;
} }
.status-content p > code, [data-markup] p > code,
.status-content pre { [data-markup] pre {
@apply bg-gray-100 dark:bg-primary-800; @apply bg-gray-100 dark:bg-primary-800;
} }
/* Inline code */ /* Inline code */
.status-content p > code { [data-markup] p > code {
@apply py-0.5 px-1 rounded-sm; @apply py-0.5 px-1 rounded-sm;
} }
/* Code block */ /* Code block */
.status-content pre { [data-markup] pre {
@apply py-2 px-3 mb-4 leading-6 overflow-x-auto rounded-md break-all; @apply py-2 px-3 mb-4 leading-6 overflow-x-auto rounded-md break-all;
} }
.status-content pre:last-child { [data-markup] pre:last-child {
@apply mb-0; @apply mb-0;
} }
/* Markdown images */ /* Markdown images */
.status-content img:not(.emojione):not([width][height]) { [data-markup] img:not(.emojione):not([width][height]) {
@apply w-full h-72 object-contain rounded-lg overflow-hidden my-4 block; @apply w-full h-72 object-contain rounded-lg overflow-hidden my-4 block;
} }
/* User setting to underline links */ /* User setting to underline links */
body.underline-links .status-content a { body.underline-links [data-markup] a {
@apply underline; @apply underline;
} }
.status-content .big-emoji img.emojione { [data-markup] .big-emoji img.emojione {
@apply inline w-9 h-9 p-1; @apply inline w-9 h-9 p-1;
} }
.status-content .status-link { [data-markup] .status-link {
@apply hover:underline text-primary-600 dark:text-accent-blue hover:text-primary-800 dark:hover:text-accent-blue; @apply hover:underline text-primary-600 dark:text-accent-blue hover:text-primary-800 dark:hover:text-accent-blue;
} }

@ -0,0 +1,16 @@
import React from 'react';
import Text, { IText } from './ui/text/text';
import './markup.css';
interface IMarkup extends IText {
}
/** Styles HTML markup returned by the API, such as in account bios and statuses. */
const Markup = React.forwardRef<any, IMarkup>((props, ref) => {
return (
<Text ref={ref} {...props} data-markup />
);
});
export default Markup;

@ -1,5 +1,5 @@
import classNames from 'clsx'; import classNames from 'clsx';
import React, { MouseEventHandler, useState } from 'react'; import React, { MouseEventHandler, useEffect, useRef, 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';
@ -37,7 +37,16 @@ const QuotedStatus: React.FC<IQuotedStatus> = ({ status, onCancel, compose }) =>
const settings = useSettings(); const settings = useSettings();
const displayMedia = settings.get('displayMedia'); const displayMedia = settings.get('displayMedia');
const overlay = useRef<HTMLDivElement>(null);
const [showMedia, setShowMedia] = useState<boolean>(defaultMediaVisibility(status, displayMedia)); const [showMedia, setShowMedia] = useState<boolean>(defaultMediaVisibility(status, displayMedia));
const [minHeight, setMinHeight] = useState(208);
useEffect(() => {
if (overlay.current) {
setMinHeight(overlay.current.getBoundingClientRect().height);
}
}, [overlay.current]);
const handleExpandClick: MouseEventHandler<HTMLDivElement> = (e) => { const handleExpandClick: MouseEventHandler<HTMLDivElement> = (e) => {
if (!status) return; if (!status) return;
@ -103,15 +112,16 @@ const QuotedStatus: React.FC<IQuotedStatus> = ({ status, onCancel, compose }) =>
<StatusReplyMentions status={status} hoverable={false} /> <StatusReplyMentions status={status} hoverable={false} />
<Stack className={classNames('relative z-0', { <Stack
'min-h-[220px]': status.hidden, className='relative z-0'
})} style={{ minHeight: status.hidden ? Math.max(minHeight, 208) + 12 : undefined }}
> >
{(status.hidden) && ( {(status.hidden) && (
<SensitiveContentOverlay <SensitiveContentOverlay
status={status} status={status}
visible={showMedia} visible={showMedia}
onToggleVisibility={handleToggleMediaVisibility} onToggleVisibility={handleToggleMediaVisibility}
ref={overlay}
/> />
)} )}

@ -1,4 +1,3 @@
import classNames from 'clsx';
import { List as ImmutableList } from 'immutable'; import { List as ImmutableList } from 'immutable';
import React from 'react'; import React from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl'; import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
@ -16,6 +15,7 @@ import { initReport } from 'soapbox/actions/reports';
import { deleteStatus, editStatus, toggleMuteStatus } from 'soapbox/actions/statuses'; import { deleteStatus, editStatus, toggleMuteStatus } from 'soapbox/actions/statuses';
import EmojiButtonWrapper from 'soapbox/components/emoji-button-wrapper'; import EmojiButtonWrapper from 'soapbox/components/emoji-button-wrapper';
import StatusActionButton from 'soapbox/components/status-action-button'; import StatusActionButton from 'soapbox/components/status-action-button';
import { HStack } from 'soapbox/components/ui';
import DropdownMenuContainer from 'soapbox/containers/dropdown-menu-container'; import DropdownMenuContainer from 'soapbox/containers/dropdown-menu-container';
import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount, useSettings, useSoapboxConfig } from 'soapbox/hooks'; import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount, useSettings, useSoapboxConfig } from 'soapbox/hooks';
import { isLocal } from 'soapbox/utils/accounts'; import { isLocal } from 'soapbox/utils/accounts';
@ -127,8 +127,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
} else { } else {
onOpenUnauthorizedModal('REPLY'); onOpenUnauthorizedModal('REPLY');
} }
e.stopPropagation();
}; };
const handleShareClick = () => { const handleShareClick = () => {
@ -146,18 +144,13 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
} else { } else {
onOpenUnauthorizedModal('FAVOURITE'); onOpenUnauthorizedModal('FAVOURITE');
} }
e.stopPropagation();
}; };
const handleBookmarkClick: React.EventHandler<React.MouseEvent> = (e) => { const handleBookmarkClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
dispatch(toggleBookmark(status)); dispatch(toggleBookmark(status));
}; };
const handleReblogClick: React.EventHandler<React.MouseEvent> = e => { const handleReblogClick: React.EventHandler<React.MouseEvent> = e => {
e.stopPropagation();
if (me) { if (me) {
const modalReblog = () => dispatch(toggleReblog(status)); const modalReblog = () => dispatch(toggleReblog(status));
const boostModal = settings.get('boostModal'); const boostModal = settings.get('boostModal');
@ -172,8 +165,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
}; };
const handleQuoteClick: React.EventHandler<React.MouseEvent> = (e) => { const handleQuoteClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
if (me) { if (me) {
dispatch(quoteCompose(status)); dispatch(quoteCompose(status));
} else { } else {
@ -199,12 +190,10 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
}; };
const handleDeleteClick: React.EventHandler<React.MouseEvent> = (e) => { const handleDeleteClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
doDeleteStatus(); doDeleteStatus();
}; };
const handleRedraftClick: React.EventHandler<React.MouseEvent> = (e) => { const handleRedraftClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
doDeleteStatus(true); doDeleteStatus(true);
}; };
@ -213,35 +202,29 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
}; };
const handlePinClick: React.EventHandler<React.MouseEvent> = (e) => { const handlePinClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
dispatch(togglePin(status)); dispatch(togglePin(status));
}; };
const handleMentionClick: React.EventHandler<React.MouseEvent> = (e) => { const handleMentionClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
dispatch(mentionCompose(status.account as Account)); dispatch(mentionCompose(status.account as Account));
}; };
const handleDirectClick: React.EventHandler<React.MouseEvent> = (e) => { const handleDirectClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
dispatch(directCompose(status.account as Account)); dispatch(directCompose(status.account as Account));
}; };
const handleChatClick: React.EventHandler<React.MouseEvent> = (e) => { const handleChatClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
const account = status.account as Account; const account = status.account as Account;
dispatch(launchChat(account.id, history)); dispatch(launchChat(account.id, history));
}; };
const handleMuteClick: React.EventHandler<React.MouseEvent> = (e) => { const handleMuteClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
dispatch(initMuteModal(status.account as Account)); dispatch(initMuteModal(status.account as Account));
}; };
const handleBlockClick: React.EventHandler<React.MouseEvent> = (e) => { const handleBlockClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
const account = status.get('account') as Account; const account = status.get('account') as Account;
dispatch(openModal('CONFIRM', { dispatch(openModal('CONFIRM', {
icon: require('@tabler/icons/ban.svg'), icon: require('@tabler/icons/ban.svg'),
heading: <FormattedMessage id='confirmations.block.heading' defaultMessage='Block @{name}' values={{ name: account.get('acct') }} />, heading: <FormattedMessage id='confirmations.block.heading' defaultMessage='Block @{name}' values={{ name: account.get('acct') }} />,
@ -257,7 +240,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
}; };
const handleOpen: React.EventHandler<React.MouseEvent> = (e) => { const handleOpen: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
history.push(`/@${status.getIn(['account', 'acct'])}/posts/${status.id}`); history.push(`/@${status.getIn(['account', 'acct'])}/posts/${status.id}`);
}; };
@ -269,12 +251,10 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
}; };
const handleReport: React.EventHandler<React.MouseEvent> = (e) => { const handleReport: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
dispatch(initReport(status.account as Account, { status })); dispatch(initReport(status.account as Account, { status }));
}; };
const handleConversationMuteClick: React.EventHandler<React.MouseEvent> = (e) => { const handleConversationMuteClick: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
dispatch(toggleMuteStatus(status)); dispatch(toggleMuteStatus(status));
}; };
@ -282,8 +262,6 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
const { uri } = status; const { uri } = status;
const textarea = document.createElement('textarea'); const textarea = document.createElement('textarea');
e.stopPropagation();
textarea.textContent = uri; textarea.textContent = uri;
textarea.style.position = 'fixed'; textarea.style.position = 'fixed';
@ -300,18 +278,15 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
}; };
const onModerate: React.MouseEventHandler = (e) => { const onModerate: React.MouseEventHandler = (e) => {
e.stopPropagation();
const account = status.account as Account; const account = status.account as Account;
dispatch(openModal('ACCOUNT_MODERATION', { accountId: account.id })); dispatch(openModal('ACCOUNT_MODERATION', { accountId: account.id }));
}; };
const handleDeleteStatus: React.EventHandler<React.MouseEvent> = (e) => { const handleDeleteStatus: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
dispatch(deleteStatusModal(intl, status.id)); dispatch(deleteStatusModal(intl, status.id));
}; };
const handleToggleStatusSensitivity: React.EventHandler<React.MouseEvent> = (e) => { const handleToggleStatusSensitivity: React.EventHandler<React.MouseEvent> = (e) => {
e.stopPropagation();
dispatch(toggleStatusSensitivityModal(intl, status.id, status.sensitive)); dispatch(toggleStatusSensitivityModal(intl, status.id, status.sensitive));
}; };
@ -550,74 +525,75 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
const canShare = ('share' in navigator) && status.visibility === 'public'; const canShare = ('share' in navigator) && status.visibility === 'public';
return ( return (
<div <HStack data-testid='status-action-bar'>
data-testid='status-action-bar' <HStack
className={classNames('flex flex-row', { justifyContent={space === 'expand' ? 'between' : undefined}
'justify-between': space === 'expand', space={space === 'compact' ? 2 : undefined}
'space-x-2': space === 'compact', grow={space === 'expand'}
})} onClick={e => e.stopPropagation()}
> >
<StatusActionButton <StatusActionButton
title={replyTitle} title={replyTitle}
icon={require('@tabler/icons/message-circle-2.svg')} icon={require('@tabler/icons/message-circle-2.svg')}
onClick={handleReplyClick} onClick={handleReplyClick}
count={replyCount} count={replyCount}
text={withLabels ? intl.formatMessage(messages.reply) : undefined} text={withLabels ? intl.formatMessage(messages.reply) : undefined}
/> />
{(features.quotePosts && me) ? (
<DropdownMenuContainer
items={reblogMenu}
disabled={!publicStatus}
onShiftClick={handleReblogClick}
>
{reblogButton}
</DropdownMenuContainer>
) : (
reblogButton
)}
{features.emojiReacts ? ( {(features.quotePosts && me) ? (
<EmojiButtonWrapper statusId={status.id}> <DropdownMenuContainer
items={reblogMenu}
disabled={!publicStatus}
onShiftClick={handleReblogClick}
>
{reblogButton}
</DropdownMenuContainer>
) : (
reblogButton
)}
{features.emojiReacts ? (
<EmojiButtonWrapper statusId={status.id}>
<StatusActionButton
title={meEmojiTitle}
icon={require('@tabler/icons/heart.svg')}
filled
color='accent'
active={Boolean(meEmojiReact)}
count={emojiReactCount}
emoji={meEmojiReact}
text={withLabels ? meEmojiTitle : undefined}
/>
</EmojiButtonWrapper>
) : (
<StatusActionButton <StatusActionButton
title={meEmojiTitle} title={intl.formatMessage(messages.favourite)}
icon={require('@tabler/icons/heart.svg')} icon={require('@tabler/icons/heart.svg')}
filled
color='accent' color='accent'
filled
onClick={handleFavouriteClick}
active={Boolean(meEmojiReact)} active={Boolean(meEmojiReact)}
count={emojiReactCount} count={favouriteCount}
emoji={meEmojiReact}
text={withLabels ? meEmojiTitle : undefined} text={withLabels ? meEmojiTitle : undefined}
/> />
</EmojiButtonWrapper> )}
) : (
<StatusActionButton
title={intl.formatMessage(messages.favourite)}
icon={require('@tabler/icons/heart.svg')}
color='accent'
filled
onClick={handleFavouriteClick}
active={Boolean(meEmojiReact)}
count={favouriteCount}
text={withLabels ? meEmojiTitle : undefined}
/>
)}
{canShare && ( {canShare && (
<StatusActionButton <StatusActionButton
title={intl.formatMessage(messages.share)} title={intl.formatMessage(messages.share)}
icon={require('@tabler/icons/upload.svg')} icon={require('@tabler/icons/upload.svg')}
onClick={handleShareClick} onClick={handleShareClick}
/> />
)} )}
<DropdownMenuContainer items={menu} status={status}> <DropdownMenuContainer items={menu} status={status}>
<StatusActionButton <StatusActionButton
title={intl.formatMessage(messages.more)} title={intl.formatMessage(messages.more)}
icon={require('@tabler/icons/dots.svg')} icon={require('@tabler/icons/dots.svg')}
/> />
</DropdownMenuContainer> </DropdownMenuContainer>
</div> </HStack>
</HStack>
); );
}; };

@ -41,7 +41,7 @@ const StatusActionButton = React.forwardRef<HTMLButtonElement, IStatusActionButt
const renderIcon = () => { const renderIcon = () => {
if (emoji) { if (emoji) {
return ( return (
<span className='block w-6 h-6 flex items-center justify-center'> <span className='flex w-6 h-6 items-center justify-center'>
<Emoji className='w-full h-full p-0.5' emoji={emoji} /> <Emoji className='w-full h-full p-0.5' emoji={emoji} />
</span> </span>
); );

@ -10,19 +10,14 @@ import { onlyEmoji as isOnlyEmoji } from 'soapbox/utils/rich-content';
import { isRtl } from '../rtl'; import { isRtl } from '../rtl';
import Markup from './markup';
import Poll from './polls/poll'; import Poll from './polls/poll';
import './status-content.css';
import type { Status, Mention } from 'soapbox/types/entities'; import type { Status, Mention } from 'soapbox/types/entities';
const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top) const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
const BIG_EMOJI_LIMIT = 10; const BIG_EMOJI_LIMIT = 10;
type Point = [
x: number,
y: number,
]
interface IReadMoreButton { interface IReadMoreButton {
onClick: React.MouseEventHandler, onClick: React.MouseEventHandler,
} }
@ -49,7 +44,6 @@ const StatusContent: React.FC<IStatusContent> = ({ status, onClick, collapsable
const [collapsed, setCollapsed] = useState(false); const [collapsed, setCollapsed] = useState(false);
const [onlyEmoji, setOnlyEmoji] = useState(false); const [onlyEmoji, setOnlyEmoji] = useState(false);
const startXY = useRef<Point>();
const node = useRef<HTMLDivElement>(null); const node = useRef<HTMLDivElement>(null);
const { greentext } = useSoapboxConfig(); const { greentext } = useSoapboxConfig();
@ -131,29 +125,6 @@ const StatusContent: React.FC<IStatusContent> = ({ status, onClick, collapsable
updateStatusLinks(); updateStatusLinks();
}); });
const handleMouseDown: React.EventHandler<React.MouseEvent> = (e) => {
startXY.current = [e.clientX, e.clientY];
};
const handleMouseUp: React.EventHandler<React.MouseEvent> = (e) => {
if (!startXY.current) return;
const target = e.target as HTMLElement;
const parentNode = target.parentNode as HTMLElement;
const [startX, startY] = startXY.current;
const [deltaX, deltaY] = [Math.abs(e.clientX - startX), Math.abs(e.clientY - startY)];
if (target.localName === 'button' || target.localName === 'a' || (parentNode && (parentNode.localName === 'button' || parentNode.localName === 'a'))) {
return;
}
if (deltaX + deltaY < 5 && e.button === 0 && !(e.ctrlKey || e.metaKey) && onClick) {
onClick();
}
startXY.current = undefined;
};
const parsedHtml = useMemo((): string => { const parsedHtml = useMemo((): string => {
const html = translatable && status.translation ? status.translation.get('content')! : status.contentHtml; const html = translatable && status.translation ? status.translation.get('content')! : status.contentHtml;
@ -173,30 +144,24 @@ const StatusContent: React.FC<IStatusContent> = ({ status, onClick, collapsable
const baseClassName = 'text-gray-900 dark:text-gray-100 break-words text-ellipsis overflow-hidden relative focus:outline-none'; const baseClassName = 'text-gray-900 dark:text-gray-100 break-words text-ellipsis overflow-hidden relative focus:outline-none';
const content = { __html: parsedHtml }; const content = { __html: parsedHtml };
const directionStyle: React.CSSProperties = { direction: 'ltr' }; const direction = isRtl(status.search_index) ? 'rtl' : 'ltr';
const className = classNames(baseClassName, 'status-content', { const className = classNames(baseClassName, {
'cursor-pointer': onClick, 'cursor-pointer': onClick,
'whitespace-normal': withSpoiler, 'whitespace-normal': withSpoiler,
'max-h-[300px]': collapsed, 'max-h-[300px]': collapsed,
'leading-normal big-emoji': onlyEmoji, 'leading-normal big-emoji': onlyEmoji,
}); });
if (isRtl(status.search_index)) {
directionStyle.direction = 'rtl';
}
if (onClick) { if (onClick) {
const output = [ const output = [
<div <Markup
ref={node} ref={node}
tabIndex={0} tabIndex={0}
key='content' key='content'
className={className} className={className}
style={directionStyle} direction={direction}
dangerouslySetInnerHTML={content} dangerouslySetInnerHTML={content}
lang={status.language || undefined} lang={status.language || undefined}
onMouseDown={handleMouseDown}
onMouseUp={handleMouseUp}
/>, />,
]; ];
@ -212,14 +177,14 @@ const StatusContent: React.FC<IStatusContent> = ({ status, onClick, collapsable
return <div className={classNames({ 'bg-gray-100 dark:bg-primary-800 rounded-md p-4': hasPoll })}>{output}</div>; return <div className={classNames({ 'bg-gray-100 dark:bg-primary-800 rounded-md p-4': hasPoll })}>{output}</div>;
} else { } else {
const output = [ const output = [
<div <Markup
ref={node} ref={node}
tabIndex={0} tabIndex={0}
key='content' key='content'
className={classNames(baseClassName, 'status-content', { className={classNames(baseClassName, {
'leading-normal big-emoji': onlyEmoji, 'leading-normal big-emoji': onlyEmoji,
})} })}
style={directionStyle} direction={direction}
dangerouslySetInnerHTML={content} dangerouslySetInnerHTML={content}
lang={status.language || undefined} lang={status.language || undefined}
/>, />,

@ -173,7 +173,16 @@ const StatusMedia: React.FC<IStatusMedia> = ({
); );
} }
return media; if (media) {
return (
// eslint-disable-next-line jsx-a11y/no-static-element-interactions
<div onClick={e => e.stopPropagation()}>
{media}
</div>
);
} else {
return null;
}
}; };
export default StatusMedia; export default StatusMedia;

@ -79,8 +79,10 @@ const Status: React.FC<IStatus> = (props) => {
const displayMedia = settings.get('displayMedia') as string; const displayMedia = settings.get('displayMedia') as string;
const didShowCard = useRef(false); const didShowCard = useRef(false);
const node = useRef<HTMLDivElement>(null); const node = useRef<HTMLDivElement>(null);
const overlay = useRef<HTMLDivElement>(null);
const [showMedia, setShowMedia] = useState<boolean>(defaultMediaVisibility(status, displayMedia)); const [showMedia, setShowMedia] = useState<boolean>(defaultMediaVisibility(status, displayMedia));
const [minHeight, setMinHeight] = useState(208);
const actualStatus = getActualStatus(status); const actualStatus = getActualStatus(status);
@ -95,6 +97,12 @@ const Status: React.FC<IStatus> = (props) => {
setShowMedia(defaultMediaVisibility(status, displayMedia)); setShowMedia(defaultMediaVisibility(status, displayMedia));
}, [status.id]); }, [status.id]);
useEffect(() => {
if (overlay.current) {
setMinHeight(overlay.current.getBoundingClientRect().height);
}
}, [overlay.current]);
const handleToggleMediaVisibility = (): void => { const handleToggleMediaVisibility = (): void => {
setShowMedia(!showMedia); setShowMedia(!showMedia);
}; };
@ -102,6 +110,11 @@ const Status: React.FC<IStatus> = (props) => {
const handleClick = (e?: React.MouseEvent): void => { const handleClick = (e?: React.MouseEvent): void => {
e?.stopPropagation(); e?.stopPropagation();
// If the user is selecting text, don't focus the status.
if (getSelection()?.toString().length) {
return;
}
if (!e || !(e.ctrlKey || e.metaKey)) { if (!e || !(e.ctrlKey || e.metaKey)) {
if (onClick) { if (onClick) {
onClick(); onClick();
@ -358,17 +371,15 @@ const Status: React.FC<IStatus> = (props) => {
<StatusReplyMentions status={actualStatus} hoverable={hoverable} /> <StatusReplyMentions status={actualStatus} hoverable={hoverable} />
<Stack <Stack
className={ className='relative z-0'
classNames('relative z-0', { style={{ minHeight: isUnderReview || isSensitive ? Math.max(minHeight, 208) + 12 : undefined }}
'min-h-[220px]': isUnderReview || isSensitive,
})
}
> >
{(isUnderReview || isSensitive) && ( {(isUnderReview || isSensitive) && (
<SensitiveContentOverlay <SensitiveContentOverlay
status={status} status={status}
visible={showMedia} visible={showMedia}
onToggleVisibility={handleToggleMediaVisibility} onToggleVisibility={handleToggleMediaVisibility}
ref={overlay}
/> />
)} )}

@ -25,7 +25,7 @@ interface ISensitiveContentOverlay {
visible?: boolean visible?: boolean
} }
const SensitiveContentOverlay = (props: ISensitiveContentOverlay) => { const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveContentOverlay>((props, ref) => {
const { onToggleVisibility, status } = props; const { onToggleVisibility, status } = props;
const isUnderReview = status.visibility === 'self'; const isUnderReview = status.visibility === 'self';
@ -72,7 +72,7 @@ const SensitiveContentOverlay = (props: ISensitiveContentOverlay) => {
size='sm' size='sm'
/> />
) : ( ) : (
<div className='text-center w-3/4 mx-auto space-y-4'> <div className='text-center w-3/4 mx-auto space-y-4' ref={ref}>
<div className='space-y-1'> <div className='space-y-1'>
<Text theme='white' weight='semibold'> <Text theme='white' weight='semibold'>
{intl.formatMessage(isUnderReview ? messages.underReviewTitle : messages.sensitiveTitle)} {intl.formatMessage(isUnderReview ? messages.underReviewTitle : messages.sensitiveTitle)}
@ -84,7 +84,7 @@ const SensitiveContentOverlay = (props: ISensitiveContentOverlay) => {
{status.spoiler_text && ( {status.spoiler_text && (
<div className='py-4 italic'> <div className='py-4 italic'>
<Text theme='white' size='md' weight='medium'> <Text className='line-clamp-6' theme='white' size='md' weight='medium'>
&ldquo;<span dangerouslySetInnerHTML={{ __html: status.spoilerHtml }} />&rdquo; &ldquo;<span dangerouslySetInnerHTML={{ __html: status.spoilerHtml }} />&rdquo;
</Text> </Text>
</div> </div>
@ -127,6 +127,6 @@ const SensitiveContentOverlay = (props: ISensitiveContentOverlay) => {
)} )}
</div> </div>
); );
}; });
export default SensitiveContentOverlay; export default SensitiveContentOverlay;

@ -27,7 +27,7 @@ const spaces = {
8: 'space-x-8', 8: 'space-x-8',
}; };
interface IHStack { interface IHStack extends Pick<React.HTMLAttributes<HTMLDivElement>, 'onClick'> {
/** Vertical alignment of children. */ /** Vertical alignment of children. */
alignItems?: keyof typeof alignItemsOptions alignItems?: keyof typeof alignItemsOptions
/** Extra class names on the <div> element. */ /** Extra class names on the <div> element. */

@ -54,7 +54,9 @@ export type Sizes = keyof typeof sizes
type Tags = 'abbr' | 'p' | 'span' | 'pre' | 'time' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'label' type Tags = 'abbr' | 'p' | 'span' | 'pre' | 'time' | 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'label'
type Directions = 'ltr' | 'rtl' type Directions = 'ltr' | 'rtl'
interface IText extends Pick<React.HTMLAttributes<HTMLParagraphElement>, 'dangerouslySetInnerHTML'> { interface IText extends Pick<React.HTMLAttributes<HTMLParagraphElement>, 'dangerouslySetInnerHTML' | 'tabIndex' | 'lang'> {
/** Text content. */
children?: React.ReactNode,
/** How to align the text. */ /** How to align the text. */
align?: keyof typeof alignments, align?: keyof typeof alignments,
/** Extra class names for the outer element. */ /** Extra class names for the outer element. */
@ -84,8 +86,8 @@ interface IText extends Pick<React.HTMLAttributes<HTMLParagraphElement>, 'danger
} }
/** UI-friendly text container with dark mode support. */ /** UI-friendly text container with dark mode support. */
const Text: React.FC<IText> = React.forwardRef( const Text = React.forwardRef<any, IText>(
(props: IText, ref: React.LegacyRef<any>) => { (props, ref) => {
const { const {
align, align,
className, className,

@ -1,10 +1,9 @@
import React from 'react'; import React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { NavLink } from 'react-router-dom';
import AvatarOverlay from 'soapbox/components/avatar-overlay'; import Account from 'soapbox/components/account';
import DisplayName from 'soapbox/components/display-name';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
import { HStack, Text } from 'soapbox/components/ui';
import type { Account as AccountEntity } from 'soapbox/types/entities'; import type { Account as AccountEntity } from 'soapbox/types/entities';
@ -13,22 +12,30 @@ interface IMovedNote {
to: AccountEntity, to: AccountEntity,
} }
const MovedNote: React.FC<IMovedNote> = ({ from, to }) => { const MovedNote: React.FC<IMovedNote> = ({ from, to }) => (
const displayNameHtml = { __html: from.display_name_html }; <div className='account__moved-note'>
<HStack className='mb-2' alignItems='center' space={1.5}>
<Icon
src={require('@tabler/icons/briefcase.svg')}
className='text-primary-600 dark:text-primary-400 flex-none'
/>
return ( <div className='truncate'>
<div className='account__moved-note'> <Text theme='muted' size='sm' truncate>
<div className='account__moved-note__message'> <FormattedMessage
<div className='account__moved-note__icon-wrapper'><Icon src={require('feather-icons/dist/icons/briefcase.svg')} className='account__moved-note__icon' fixedWidth /></div> id='notification.move'
<FormattedMessage id='account.moved_to' defaultMessage='{name} has moved to:' values={{ name: <bdi><strong dangerouslySetInnerHTML={displayNameHtml} /></bdi> }} /> defaultMessage='{name} moved to {targetName}'
values={{
name: <span dangerouslySetInnerHTML={{ __html: from.display_name_html }} />,
targetName: to.acct,
}}
/>
</Text>
</div> </div>
</HStack>
<NavLink to={`/@${to.acct}`} className='detailed-status__display-name'> <Account account={to} withRelationship={false} />
<div className='detailed-status__display-avatar'><AvatarOverlay account={to} friend={from} /></div> </div>
<DisplayName account={to} /> );
</NavLink>
</div>
);
};
export default MovedNote; export default MovedNote;

@ -63,7 +63,7 @@ const Aliases = () => {
<FormattedMessage id='empty_column.aliases.suggestions' defaultMessage='There are no account suggestions available for the provided term.' /> <FormattedMessage id='empty_column.aliases.suggestions' defaultMessage='There are no account suggestions available for the provided term.' />
</div> </div>
) : ( ) : (
<div className='aliases__accounts'> <div className='aliases__accounts mb-4'>
{searchAccountIds.map(accountId => <Account key={accountId} accountId={accountId} aliases={aliases} />)} {searchAccountIds.map(accountId => <Account key={accountId} accountId={accountId} aliases={aliases} />)}
</div> </div>
) )

@ -449,6 +449,7 @@ const Audio: React.FC<IAudio> = (props) => {
onMouseLeave={handleMouseLeave} onMouseLeave={handleMouseLeave}
tabIndex={0} tabIndex={0}
onKeyDown={handleKeyDown} onKeyDown={handleKeyDown}
onClick={e => e.stopPropagation()}
> >
<audio <audio
src={src} src={src}

@ -13,7 +13,6 @@ import type { AutoSuggestion } from 'soapbox/components/autosuggest-input';
const messages = defineMessages({ const messages = defineMessages({
option_placeholder: { id: 'compose_form.poll.option_placeholder', defaultMessage: 'Answer #{number}' }, option_placeholder: { id: 'compose_form.poll.option_placeholder', defaultMessage: 'Answer #{number}' },
add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add an answer' }, add_option: { id: 'compose_form.poll.add_option', defaultMessage: 'Add an answer' },
remove_option: { id: 'compose_form.poll.remove_option', defaultMessage: 'Remove this answer' },
pollDuration: { id: 'compose_form.poll.duration', defaultMessage: 'Duration' }, pollDuration: { id: 'compose_form.poll.duration', defaultMessage: 'Duration' },
removePoll: { id: 'compose_form.poll.remove', defaultMessage: 'Remove poll' }, removePoll: { id: 'compose_form.poll.remove', defaultMessage: 'Remove poll' },
switchToMultiple: { id: 'compose_form.poll.switch_to_multiple', defaultMessage: 'Change poll to allow multiple answers' }, switchToMultiple: { id: 'compose_form.poll.switch_to_multiple', defaultMessage: 'Change poll to allow multiple answers' },
@ -95,7 +94,9 @@ const Option: React.FC<IOption> = ({
{index > 1 && ( {index > 1 && (
<div> <div>
<Button theme='danger' size='sm' onClick={handleOptionRemove}>Delete</Button> <Button theme='danger' size='sm' onClick={handleOptionRemove}>
<FormattedMessage id='compose_form.poll.remove_option' defaultMessage='Delete' />
</Button>
</div> </div>
)} )}
</HStack> </HStack>

@ -48,8 +48,9 @@ const DomainBlocks: React.FC = () => {
onLoadMore={() => handleLoadMore(dispatch)} onLoadMore={() => handleLoadMore(dispatch)}
hasMore={hasMore} hasMore={hasMore}
emptyMessage={emptyMessage} emptyMessage={emptyMessage}
className='divide-y divide-gray-200 dark:divide-gray-800'
> >
{domains.map((domain) => {['gab.com', 'gab.ai'].map((domain) =>
<Domain key={domain} domain={domain} />, <Domain key={domain} domain={domain} />,
)} )}
</ScrollableList> </ScrollableList>

@ -2,14 +2,13 @@ import * as React from 'react';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import { prepareRequest } from 'soapbox/actions/consumer-auth'; import { prepareRequest } from 'soapbox/actions/consumer-auth';
import Markup from 'soapbox/components/markup';
import { Button, Card, CardBody, Stack, Text } from 'soapbox/components/ui'; import { Button, Card, CardBody, Stack, Text } from 'soapbox/components/ui';
import VerificationBadge from 'soapbox/components/verification-badge'; import VerificationBadge from 'soapbox/components/verification-badge';
import RegistrationForm from 'soapbox/features/auth-login/components/registration-form'; import RegistrationForm from 'soapbox/features/auth-login/components/registration-form';
import { useAppDispatch, useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks'; import { useAppDispatch, useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks';
import { capitalize } from 'soapbox/utils/strings'; import { capitalize } from 'soapbox/utils/strings';
import './instance-description.css';
const LandingPage = () => { const LandingPage = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const features = useFeatures(); const features = useFeatures();
@ -114,12 +113,10 @@ const LandingPage = () => {
{instance.title} {instance.title}
</h1> </h1>
<Text size='lg'> <Markup
<span size='lg'
className='instance-description' dangerouslySetInnerHTML={{ __html: instance.short_description || instance.description }}
dangerouslySetInnerHTML={{ __html: instance.short_description || instance.description }} />
/>
</Text>
</Stack> </Stack>
</div> </div>
</div> </div>

@ -1,14 +0,0 @@
/* Instance HTML from the API. */
.instance-description a {
@apply underline;
}
.instance-description b,
.instance-description strong {
@apply font-bold;
}
.instance-description i,
.instance-description em {
@apply italic;
}

@ -1,5 +1,4 @@
import classNames from 'clsx'; import React, { useEffect, useRef, useState } from 'react';
import React, { useRef } from 'react';
import { FormattedDate, FormattedMessage, useIntl } from 'react-intl'; import { FormattedDate, FormattedMessage, useIntl } from 'react-intl';
import Icon from 'soapbox/components/icon'; import Icon from 'soapbox/components/icon';
@ -35,7 +34,17 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
showMedia, showMedia,
}) => { }) => {
const intl = useIntl(); const intl = useIntl();
const node = useRef<HTMLDivElement>(null); const node = useRef<HTMLDivElement>(null);
const overlay = useRef<HTMLDivElement>(null);
const [minHeight, setMinHeight] = useState(208);
useEffect(() => {
if (overlay.current) {
setMinHeight(overlay.current.getBoundingClientRect().height);
}
}, [overlay.current]);
const handleOpenCompareHistoryModal = () => { const handleOpenCompareHistoryModal = () => {
onOpenCompareHistoryModal(status); onOpenCompareHistoryModal(status);
@ -87,17 +96,15 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
<StatusReplyMentions status={actualStatus} /> <StatusReplyMentions status={actualStatus} />
<Stack <Stack
className={ className='relative z-0'
classNames('relative z-0', { style={{ minHeight: isUnderReview || isSensitive ? Math.max(minHeight, 208) + 12 : undefined }}
'min-h-[220px]': isUnderReview || isSensitive,
})
}
> >
{(isUnderReview || isSensitive) && ( {(isUnderReview || isSensitive) && (
<SensitiveContentOverlay <SensitiveContentOverlay
status={status} status={status}
visible={showMedia} visible={showMedia}
onToggleVisibility={onToggleMediaVisibility} onToggleVisibility={onToggleMediaVisibility}
ref={overlay}
/> />
)} )}

@ -402,7 +402,7 @@ const Thread: React.FC<IThread> = (props) => {
offset: -80, offset: -80,
}); });
setImmediate(() => statusRef.current?.querySelector<HTMLDivElement>('.detailed-status')?.focus()); setImmediate(() => statusRef.current?.querySelector<HTMLDivElement>('.detailed-actualStatus')?.focus());
}, [props.params.statusId, status?.id, ancestorsIds.size, isLoaded]); }, [props.params.statusId, status?.id, ancestorsIds.size, isLoaded]);
const handleRefresh = () => { const handleRefresh = () => {
@ -456,11 +456,11 @@ const Thread: React.FC<IThread> = (props) => {
const titleMessage = status.visibility === 'direct' ? messages.titleDirect : messages.title; const titleMessage = status.visibility === 'direct' ? messages.titleDirect : messages.title;
const focusedStatus = ( const focusedStatus = (
<div className={classNames('thread__detailed-status', { 'pb-4': hasDescendants })} key={status.id}> <div className={classNames({ 'pb-4': hasDescendants })} key={status.id}>
<HotKeys handlers={handlers}> <HotKeys handlers={handlers}>
<div <div
ref={statusRef} ref={statusRef}
className='detailed-status__wrapper focusable relative' className='focusable relative'
tabIndex={0} tabIndex={0}
// FIXME: no "reblogged by" text is added for the screen reader // FIXME: no "reblogged by" text is added for the screen reader
aria-label={textForScreenReader(intl, status)} aria-label={textForScreenReader(intl, status)}

@ -32,7 +32,7 @@ const BundleModalError: React.FC<IBundleModalError> = ({ onRetry, onClose }) =>
<div> <div>
<button <button
onClick={onClose} onClick={onClose}
className='error-modal__nav onboarding-modal__skip' className='error-modal__nav'
> >
{intl.formatMessage(messages.close)} {intl.formatMessage(messages.close)}
</button> </button>

@ -11,7 +11,7 @@ const ModalLoading = () => (
</div> </div>
<div className='error-modal__footer'> <div className='error-modal__footer'>
<div> <div>
<button className='error-modal__nav onboarding-modal__skip' /> <button className='error-modal__nav' />
</div> </div>
</div> </div>
</div> </div>

@ -246,6 +246,7 @@ const ReportModal = ({ onClose }: IReportModal) => {
<Modal <Modal
title={renderTitle()} title={renderTitle()}
onClose={onClose} onClose={onClose}
cancelText={<FormattedMessage id='common.cancel' defaultMessage='Cancel' />}
cancelAction={currentStep === Steps.THREE ? undefined : onClose} cancelAction={currentStep === Steps.THREE ? undefined : onClose}
confirmationAction={handleNextStep} confirmationAction={handleNextStep}
confirmationText={confirmationText} confirmationText={confirmationText}

@ -2,7 +2,8 @@ import classNames from 'clsx';
import React from 'react'; import React from 'react';
import { defineMessages, useIntl, FormattedMessage, FormatDateOptions } from 'react-intl'; import { defineMessages, useIntl, FormattedMessage, FormatDateOptions } from 'react-intl';
import { Widget, Stack, HStack, Icon, Text } from 'soapbox/components/ui'; import Markup from 'soapbox/components/markup';
import { Widget, Stack, HStack, Icon } from 'soapbox/components/ui';
import BundleContainer from 'soapbox/features/ui/containers/bundle-container'; import BundleContainer from 'soapbox/features/ui/containers/bundle-container';
import { CryptoAddress } from 'soapbox/features/ui/util/async-components'; import { CryptoAddress } from 'soapbox/features/ui/util/async-components';
@ -51,7 +52,7 @@ const ProfileField: React.FC<IProfileField> = ({ field }) => {
return ( return (
<dl> <dl>
<dt title={field.name}> <dt title={field.name}>
<Text weight='bold' tag='span' dangerouslySetInnerHTML={{ __html: field.name_emojified }} /> <Markup weight='bold' tag='span' dangerouslySetInnerHTML={{ __html: field.name_emojified }} />
</dt> </dt>
<dd <dd
@ -65,7 +66,7 @@ const ProfileField: React.FC<IProfileField> = ({ field }) => {
</span> </span>
)} )}
<Text className='break-words overflow-hidden' tag='span' dangerouslySetInnerHTML={{ __html: field.value_emojified }} /> <Markup className='break-words overflow-hidden' tag='span' dangerouslySetInnerHTML={{ __html: field.value_emojified }} />
</HStack> </HStack>
</dd> </dd>
</dl> </dl>

@ -4,6 +4,7 @@ import React from 'react';
import { defineMessages, useIntl, FormattedMessage } from 'react-intl'; import { defineMessages, useIntl, FormattedMessage } from 'react-intl';
import Badge from 'soapbox/components/badge'; import Badge from 'soapbox/components/badge';
import Markup from 'soapbox/components/markup';
import { Icon, HStack, Stack, Text } from 'soapbox/components/ui'; import { Icon, HStack, Stack, Text } from 'soapbox/components/ui';
import VerificationBadge from 'soapbox/components/verification-badge'; import VerificationBadge from 'soapbox/components/verification-badge';
import { useSoapboxConfig } from 'soapbox/hooks'; import { useSoapboxConfig } from 'soapbox/hooks';
@ -139,13 +140,6 @@ const ProfileInfoPanel: React.FC<IProfileInfoPanel> = ({ account, username }) =>
return ( return (
<div className='mt-6 min-w-0 flex-1 sm:px-2'> <div className='mt-6 min-w-0 flex-1 sm:px-2'>
<Stack space={2}> <Stack space={2}>
{/* Not sure if this is actual used. */}
{/* <div className='profile-info-panel-content__deactivated'>
<FormattedMessage
id='account.deactivated_description' defaultMessage='This account has been deactivated.'
/>
</div> */}
<Stack> <Stack>
<HStack space={1} alignItems='center'> <HStack space={1} alignItems='center'>
<Text size='lg' weight='bold' dangerouslySetInnerHTML={displayNameHtml} /> <Text size='lg' weight='bold' dangerouslySetInnerHTML={displayNameHtml} />
@ -178,8 +172,8 @@ const ProfileInfoPanel: React.FC<IProfileInfoPanel> = ({ account, username }) =>
<ProfileStats account={account} /> <ProfileStats account={account} />
{account.note.length > 0 && account.note !== '<p></p>' && ( {account.note.length > 0 && (
<Text size='sm' dangerouslySetInnerHTML={content} /> <Markup size='sm' dangerouslySetInnerHTML={content} />
)} )}
<div className='flex flex-col md:flex-row items-start md:flex-wrap md:items-center gap-2'> <div className='flex flex-col md:flex-row items-start md:flex-wrap md:items-center gap-2'>

@ -5,7 +5,7 @@ import { useDispatch } from 'react-redux';
import { openModal } from 'soapbox/actions/modals'; import { openModal } from 'soapbox/actions/modals';
import { expandAccountMediaTimeline } from 'soapbox/actions/timelines'; import { expandAccountMediaTimeline } from 'soapbox/actions/timelines';
import { Spinner, Widget } from 'soapbox/components/ui'; import { Spinner, Text, Widget } from 'soapbox/components/ui';
import { useAppSelector } from 'soapbox/hooks'; import { useAppSelector } from 'soapbox/hooks';
import { getAccountGallery } from 'soapbox/selectors'; import { getAccountGallery } from 'soapbox/selectors';
@ -52,7 +52,7 @@ const ProfileMediaPanel: React.FC<IProfileMediaPanel> = ({ account }) => {
if (!nineAttachments.isEmpty()) { if (!nineAttachments.isEmpty()) {
return ( return (
<div className='media-panel__list'> <div className='flex flex-wrap'>
{nineAttachments.map((attachment, _index) => ( {nineAttachments.map((attachment, _index) => (
<MediaItem <MediaItem
key={`${attachment.getIn(['status', 'id'])}+${attachment.id}`} key={`${attachment.getIn(['status', 'id'])}+${attachment.id}`}
@ -65,9 +65,9 @@ const ProfileMediaPanel: React.FC<IProfileMediaPanel> = ({ account }) => {
); );
} else { } else {
return ( return (
<div className='media-panel__empty'> <Text size='sm' theme='muted'>
<FormattedMessage id='media_panel.empty_message' defaultMessage='No media found.' /> <FormattedMessage id='media_panel.empty_message' defaultMessage='No media found.' />
</div> </Text>
); );
} }
}; };
@ -75,7 +75,7 @@ const ProfileMediaPanel: React.FC<IProfileMediaPanel> = ({ account }) => {
return ( return (
<Widget title={<FormattedMessage id='media_panel.title' defaultMessage='Media' />}> <Widget title={<FormattedMessage id='media_panel.title' defaultMessage='Media' />}>
{account && ( {account && (
<div className='media-panel__content'> <div className='w-full py-2'>
{loading ? ( {loading ? (
<Spinner /> <Spinner />
) : ( ) : (

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Раздумай", "compose_form.publish": "Раздумай",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",

File diff suppressed because it is too large Load Diff

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",

@ -4,7 +4,7 @@
"accordion.expand": "הרחבה", "accordion.expand": "הרחבה",
"account.add_or_remove_from_list": "הוסף או הסר מהרשימות", "account.add_or_remove_from_list": "הוסף או הסר מהרשימות",
"account.badges.bot": "בוט", "account.badges.bot": "בוט",
"account.birthday": "Born {date}", "account.birthday": "נולד ב-{date}",
"account.birthday_today": "Birthday is today!", "account.birthday_today": "Birthday is today!",
"account.block": "חסימת @{name}", "account.block": "חסימת @{name}",
"account.block_domain": "להסתיר הכל מהקהילה {domain}", "account.block_domain": "להסתיר הכל מהקהילה {domain}",
@ -122,11 +122,11 @@
"admin_nav.dashboard": "לוח מחוונים", "admin_nav.dashboard": "לוח מחוונים",
"admin_nav.reports": "דיווחים", "admin_nav.reports": "דיווחים",
"alert.unexpected.body": "We're sorry for the interruption. If the problem persists, please reach out to our support team. You may also try to {clearCookies} (this will log you out).", "alert.unexpected.body": "We're sorry for the interruption. If the problem persists, please reach out to our support team. You may also try to {clearCookies} (this will log you out).",
"alert.unexpected.browser": "Browser", "alert.unexpected.browser": "דפדפן",
"alert.unexpected.clear_cookies": "נקה קובצי 'עוגיות' ונתוני דפדפן", "alert.unexpected.clear_cookies": "נקה קובצי 'עוגיות' ונתוני דפדפן",
"alert.unexpected.links.help": "Help Center", "alert.unexpected.links.help": "Help Center",
"alert.unexpected.links.status": "Status", "alert.unexpected.links.status": "סטטוס",
"alert.unexpected.links.support": "Support", "alert.unexpected.links.support": "תמיכה",
"alert.unexpected.message": "אירעה שגיאה בלתי צפויה.", "alert.unexpected.message": "אירעה שגיאה בלתי צפויה.",
"alert.unexpected.return_home": "חזור הביתה", "alert.unexpected.return_home": "חזור הביתה",
"alert.unexpected.title": "אופס!", "alert.unexpected.title": "אופס!",
@ -154,8 +154,8 @@
"backups.empty_message": "לא נמצאו גיבויים. {action}", "backups.empty_message": "לא נמצאו גיבויים. {action}",
"backups.empty_message.action": "האם ליצור אחד עכשיו?", "backups.empty_message.action": "האם ליצור אחד עכשיו?",
"backups.pending": "בהמתנה", "backups.pending": "בהמתנה",
"beta.also_available": "Available in:", "beta.also_available": "זמין ב:",
"birthday_panel.title": "Birthdays", "birthday_panel.title": "ימי הולדת",
"boost_modal.combo": "ניתן להקיש {combo} כדי לדלג בפעם הבאה", "boost_modal.combo": "ניתן להקיש {combo} כדי לדלג בפעם הבאה",
"bundle_column_error.body": "משהו השתבש בעת הצגת הרכיב הזה.", "bundle_column_error.body": "משהו השתבש בעת הצגת הרכיב הזה.",
"bundle_column_error.retry": "לנסות שוב", "bundle_column_error.retry": "לנסות שוב",
@ -257,7 +257,7 @@
"column_forbidden.body": "אין לך הרשאה לגשת לדף זה.", "column_forbidden.body": "אין לך הרשאה לגשת לדף זה.",
"column_forbidden.title": "אסור", "column_forbidden.title": "אסור",
"column_header.show_settings": "הצגת העדפות", "column_header.show_settings": "הצגת העדפות",
"common.cancel": "Cancel", "common.cancel": "בטל",
"community.column_settings.media_only": "רק מדיה", "community.column_settings.media_only": "רק מדיה",
"community.column_settings.title": "הגדרות ציר זמן מקומי", "community.column_settings.title": "הגדרות ציר זמן מקומי",
"compose.character_counter.title": "השתמת ב{chars} מתוך {maxChars} תווים", "compose.character_counter.title": "השתמת ב{chars} מתוך {maxChars} תווים",
@ -345,21 +345,21 @@
"crypto_donate_panel.heading": "תרום מטבעות קריפטו", "crypto_donate_panel.heading": "תרום מטבעות קריפטו",
"crypto_donate_panel.intro.message": "{siteTitle} מקבל תרומות של מטבעות קריפטוגרפיים כדי לממן את השירות שלנו. תודה על תמיכתך!", "crypto_donate_panel.intro.message": "{siteTitle} מקבל תרומות של מטבעות קריפטוגרפיים כדי לממן את השירות שלנו. תודה על תמיכתך!",
"datepicker.hint": "מתוכנן לפרסם ב...", "datepicker.hint": "מתוכנן לפרסם ב...",
"datepicker.next_month": "Next month", "datepicker.next_month": "חודש הבא",
"datepicker.next_year": "Next year", "datepicker.next_year": "שנה הבאה",
"datepicker.previous_month": "Previous month", "datepicker.previous_month": "חודש קודם",
"datepicker.previous_year": "Previous year", "datepicker.previous_year": "שנה קודמת",
"developers.challenge.answer_label": "Answer", "developers.challenge.answer_label": "תשובה",
"developers.challenge.answer_placeholder": "Your answer", "developers.challenge.answer_placeholder": "התשובה שלך",
"developers.challenge.fail": "Wrong answer", "developers.challenge.fail": "תשובה שגויה",
"developers.challenge.message": "What is the result of calling {function}?", "developers.challenge.message": "What is the result of calling {function}?",
"developers.challenge.submit": "Become a developer", "developers.challenge.submit": "Become a developer",
"developers.challenge.success": "You are now a developer", "developers.challenge.success": "אתה עכשיו מפתח",
"developers.leave": "You have left developers", "developers.leave": "You have left developers",
"developers.navigation.app_create_label": "צור אפליקציה", "developers.navigation.app_create_label": "צור אפליקציה",
"developers.navigation.intentional_error_label": "הפעלת שגיאה", "developers.navigation.intentional_error_label": "הפעלת שגיאה",
"developers.navigation.leave_developers_label": "Leave developers", "developers.navigation.leave_developers_label": "Leave developers",
"developers.navigation.network_error_label": "Network error", "developers.navigation.network_error_label": "שגיאת רשת",
"developers.navigation.settings_store_label": "Settings store", "developers.navigation.settings_store_label": "Settings store",
"developers.navigation.test_timeline_label": "Test timeline", "developers.navigation.test_timeline_label": "Test timeline",
"developers.settings_store.hint": "It is possible to directly edit your user settings here. BE CAREFUL! Editing this section can break your account, and you will only be able to recover through the API.", "developers.settings_store.hint": "It is possible to directly edit your user settings here. BE CAREFUL! Editing this section can break your account, and you will only be able to recover through the API.",
@ -375,7 +375,7 @@
"edit_federation.save": "שמור", "edit_federation.save": "שמור",
"edit_federation.success": "הפדרציה של {host} עודכנה", "edit_federation.success": "הפדרציה של {host} עודכנה",
"edit_federation.unlisted": "לכפות פוסטים כלא רשומים", "edit_federation.unlisted": "לכפות פוסטים כלא רשומים",
"edit_password.header": "Change Password", "edit_password.header": "שנה סיסמא",
"edit_profile.error": "עדכון הפרופיל נכשל", "edit_profile.error": "עדכון הפרופיל נכשל",
"edit_profile.fields.accepts_email_list_label": "הירשם לעדכונים", "edit_profile.fields.accepts_email_list_label": "הירשם לעדכונים",
"edit_profile.fields.avatar_label": "אווטאר", "edit_profile.fields.avatar_label": "אווטאר",
@ -395,9 +395,9 @@
"edit_profile.fields.meta_fields.content_placeholder": "תוכן", "edit_profile.fields.meta_fields.content_placeholder": "תוכן",
"edit_profile.fields.meta_fields.label_placeholder": "תווית", "edit_profile.fields.meta_fields.label_placeholder": "תווית",
"edit_profile.fields.stranger_notifications_label": "חסום התראות מזרים", "edit_profile.fields.stranger_notifications_label": "חסום התראות מזרים",
"edit_profile.fields.website_label": "Website", "edit_profile.fields.website_label": "אתר",
"edit_profile.fields.website_placeholder": "Display a Link", "edit_profile.fields.website_placeholder": "Display a Link",
"edit_profile.header": "Edit Profile", "edit_profile.header": "ערוך פרופיל",
"edit_profile.hints.accepts_email_list": "הצטרפו לעדכוני חדשות ועדכונים שיווקיים.", "edit_profile.hints.accepts_email_list": "הצטרפו לעדכוני חדשות ועדכונים שיווקיים.",
"edit_profile.hints.avatar": "PNG, GIF או JPG. יוקטן ל-{size}", "edit_profile.hints.avatar": "PNG, GIF או JPG. יוקטן ל-{size}",
"edit_profile.hints.bot": "חשבון זה מבצע בעיקר פעולות אוטומטיות וייתכן שלא יהיה פיקוח", "edit_profile.hints.bot": "חשבון זה מבצע בעיקר פעולות אוטומטיות וייתכן שלא יהיה פיקוח",
@ -409,13 +409,13 @@
"edit_profile.save": "שמירה", "edit_profile.save": "שמירה",
"edit_profile.success": "הפרופיל נשמר!", "edit_profile.success": "הפרופיל נשמר!",
"email_passthru.confirmed.body": "Close this tab and continue the registration process on the {bold} from which you sent this email confirmation.", "email_passthru.confirmed.body": "Close this tab and continue the registration process on the {bold} from which you sent this email confirmation.",
"email_passthru.confirmed.heading": "Email Confirmed!", "email_passthru.confirmed.heading": "אימייל אומת!",
"email_passthru.generic_fail.body": "Please request a new email confirmation.", "email_passthru.generic_fail.body": "Please request a new email confirmation.",
"email_passthru.generic_fail.heading": "Something Went Wrong", "email_passthru.generic_fail.heading": "משהו השתבש",
"email_passthru.token_expired.body": "Your email token has expired. Please request a new email confirmation from the {bold} from which you sent this email confirmation.", "email_passthru.token_expired.body": "Your email token has expired. Please request a new email confirmation from the {bold} from which you sent this email confirmation.",
"email_passthru.token_expired.heading": "Token Expired", "email_passthru.token_expired.heading": "טוקן פג תוקף",
"email_passthru.token_not_found.body": "Your email token was not found. Please request a new email confirmation from the {bold} from which you sent this email confirmation.", "email_passthru.token_not_found.body": "Your email token was not found. Please request a new email confirmation from the {bold} from which you sent this email confirmation.",
"email_passthru.token_not_found.heading": "Invalid Token", "email_passthru.token_not_found.heading": "טוקן לא תקין",
"embed.instructions": "ניתן להטמיע את ההודעה באתרך ע\"י העתקת הקוד שלהלן.", "embed.instructions": "ניתן להטמיע את ההודעה באתרך ע\"י העתקת הקוד שלהלן.",
"embed.preview": "דוגמא כיצד זה יראה:", "embed.preview": "דוגמא כיצד זה יראה:",
"emoji_button.activity": "פעילות", "emoji_button.activity": "פעילות",
@ -564,8 +564,8 @@
"import_data.success.blocks": "חסימות יובאו בהצלחה", "import_data.success.blocks": "חסימות יובאו בהצלחה",
"import_data.success.followers": "מעקבים יובאו בהצלחה", "import_data.success.followers": "מעקבים יובאו בהצלחה",
"import_data.success.mutes": "השתקות יובאו בהצלחה", "import_data.success.mutes": "השתקות יובאו בהצלחה",
"input.password.hide_password": "Hide password", "input.password.hide_password": "הסתר סיסמא",
"input.password.show_password": "Show password", "input.password.show_password": "הצג סיסמא",
"intervals.full.days": "{number, plural, one {# יום} other {# ימים}}", "intervals.full.days": "{number, plural, one {# יום} other {# ימים}}",
"intervals.full.hours": "{number, plural, one {# שעה} other {# שעות}}", "intervals.full.hours": "{number, plural, one {# שעה} other {# שעות}}",
"intervals.full.minutes": "{number, plural, one {# דקה} other {# דקות}}", "intervals.full.minutes": "{number, plural, one {# דקה} other {# דקות}}",
@ -635,7 +635,7 @@
"login.fields.otp_code_hint": "הזן את קוד שני הגורמים שנוצר על ידי אפליקציות הטלפון שלך או השתמש באחד מקודי השחזור שלך", "login.fields.otp_code_hint": "הזן את קוד שני הגורמים שנוצר על ידי אפליקציות הטלפון שלך או השתמש באחד מקודי השחזור שלך",
"login.fields.otp_code_label": "קוד דו גורמי:", "login.fields.otp_code_label": "קוד דו גורמי:",
"login.fields.password_placeholder": "סיסמא", "login.fields.password_placeholder": "סיסמא",
"login.fields.username_label": "Email or username", "login.fields.username_label": "שם משתמש או אימייל",
"login.log_in": "התחברות", "login.log_in": "התחברות",
"login.otp_log_in": "התחברות OTP", "login.otp_log_in": "התחברות OTP",
"login.reset_password_hint": "בעיה בהתחברות?", "login.reset_password_hint": "בעיה בהתחברות?",
@ -659,12 +659,12 @@
"mfa.setup_warning": "רשום את הקודים האלה או שמור אותם במקום מאובטח - אחרת לא תראה אותם שוב. אם תאבד את הגישה לאפליקציית 2FA ולקודי השחזור שלך תינעל מחוץ לחשבון שלך.", "mfa.setup_warning": "רשום את הקודים האלה או שמור אותם במקום מאובטח - אחרת לא תראה אותם שוב. אם תאבד את הגישה לאפליקציית 2FA ולקודי השחזור שלך תינעל מחוץ לחשבון שלך.",
"migration.fields.acct.label": "Handle of the new account", "migration.fields.acct.label": "Handle of the new account",
"migration.fields.acct.placeholder": "username@domain", "migration.fields.acct.placeholder": "username@domain",
"migration.fields.confirm_password.label": "Current password", "migration.fields.confirm_password.label": "סיסמא נוכחית",
"migration.hint": "This will move your followers to the new account. No other data will be moved. To perform migration, you need to {link} on your new account first.", "migration.hint": "This will move your followers to the new account. No other data will be moved. To perform migration, you need to {link} on your new account first.",
"migration.hint.link": "create an account alias", "migration.hint.link": "create an account alias",
"migration.move_account.fail": "Account migration failed.", "migration.move_account.fail": "העברת חשבון נכשלה.",
"migration.move_account.success": "Account successfully moved.", "migration.move_account.success": "חשבון הועבר בהצלחה.",
"migration.submit": "Move followers", "migration.submit": "העבר עוקבים",
"missing_description_modal.cancel": "בטל", "missing_description_modal.cancel": "בטל",
"missing_description_modal.continue": "שלח", "missing_description_modal.continue": "שלח",
"missing_description_modal.description": "המשך בכל זאת?", "missing_description_modal.description": "המשך בכל זאת?",
@ -720,8 +720,8 @@
"notifications.clear_confirmation": "להסיר את כל ההתראות? בטוח?", "notifications.clear_confirmation": "להסיר את כל ההתראות? בטוח?",
"notifications.clear_heading": "Clear notifications", "notifications.clear_heading": "Clear notifications",
"notifications.column_settings.alert": "התראות לשולחן העבודה", "notifications.column_settings.alert": "התראות לשולחן העבודה",
"notifications.column_settings.birthdays.category": "Birthdays", "notifications.column_settings.birthdays.category": "ימי הולדת",
"notifications.column_settings.birthdays.show": "Show birthday reminders", "notifications.column_settings.birthdays.show": "הראה תזכורות לימי הולדת",
"notifications.column_settings.emoji_react": "הגבות אימוג'י:", "notifications.column_settings.emoji_react": "הגבות אימוג'י:",
"notifications.column_settings.favourite": "מחובבים:", "notifications.column_settings.favourite": "מחובבים:",
"notifications.column_settings.filter_bar.advanced": "הצג את כל הקטגוריות", "notifications.column_settings.filter_bar.advanced": "הצג את כל הקטגוריות",
@ -891,7 +891,7 @@
"security.fields.email.label": "אימייל", "security.fields.email.label": "אימייל",
"security.fields.new_password.label": "סיסמא חדשה", "security.fields.new_password.label": "סיסמא חדשה",
"security.fields.old_password.label": "סיסמא נוכחית", "security.fields.old_password.label": "סיסמא נוכחית",
"security.fields.password.label": "Password", "security.fields.password.label": "סיסמא",
"security.fields.password_confirmation.label": "סיסמא חדשה (שוב)", "security.fields.password_confirmation.label": "סיסמא חדשה (שוב)",
"security.headers.delete": "מחק חשבון", "security.headers.delete": "מחק חשבון",
"security.headers.tokens": "הפעלות", "security.headers.tokens": "הפעלות",
@ -910,16 +910,16 @@
"security.update_email.success": "האימייל עודכן בהצלחה.", "security.update_email.success": "האימייל עודכן בהצלחה.",
"security.update_password.fail": "עדכון הסיסמא נכשל.", "security.update_password.fail": "עדכון הסיסמא נכשל.",
"security.update_password.success": "הסיסמה עודכנה בהצלחה.", "security.update_password.success": "הסיסמה עודכנה בהצלחה.",
"settings.change_email": "Change Email", "settings.change_email": "שנה אימייל",
"settings.change_password": "Change Password", "settings.change_password": "שנה סיסמא",
"settings.configure_mfa": "Configure MFA", "settings.configure_mfa": "Configure MFA",
"settings.delete_account": "Delete Account", "settings.delete_account": "מחק חשבון",
"settings.edit_profile": "Edit Profile", "settings.edit_profile": "ערוך פרופיל",
"settings.preferences": "Preferences", "settings.preferences": "Preferences",
"settings.profile": "Profile", "settings.profile": "פרופיל",
"settings.save.success": "Your preferences have been saved!", "settings.save.success": "Your preferences have been saved!",
"settings.security": "Security", "settings.security": "Security",
"settings.settings": "Settings", "settings.settings": "הגדרות",
"signup_panel.subtitle": "הירשם כעת כדי לדון.", "signup_panel.subtitle": "הירשם כעת כדי לדון.",
"signup_panel.title": "חדש ל{site_title}?", "signup_panel.title": "חדש ל{site_title}?",
"snackbar.view": "View", "snackbar.view": "View",
@ -1029,12 +1029,12 @@
"tabs_bar.dashboard": "לוח מחוונים", "tabs_bar.dashboard": "לוח מחוונים",
"tabs_bar.fediverse": "פדרציה", "tabs_bar.fediverse": "פדרציה",
"tabs_bar.home": "בית", "tabs_bar.home": "בית",
"tabs_bar.more": "More", "tabs_bar.more": "עוד",
"tabs_bar.notifications": "התראות", "tabs_bar.notifications": "התראות",
"tabs_bar.post": "פוסט", "tabs_bar.post": "פוסט",
"tabs_bar.profile": "Profile", "tabs_bar.profile": "פרופיל",
"tabs_bar.search": "חיפוש", "tabs_bar.search": "חיפוש",
"tabs_bar.settings": "Settings", "tabs_bar.settings": "הגדרות",
"tabs_bar.theme_toggle_dark": "עבור לערכת נושא כהה", "tabs_bar.theme_toggle_dark": "עבור לערכת נושא כהה",
"tabs_bar.theme_toggle_light": "עבור לערכת נושא בהירה", "tabs_bar.theme_toggle_light": "עבור לערכת נושא בהירה",
"time_remaining.days": "{number, plural, one {# יום} other {# ימים}} נותרו", "time_remaining.days": "{number, plural, one {# יום} other {# ימים}} נותרו",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Թթել", "compose_form.publish": "Թթել",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Siflar", "compose_form.publish": "Siflar",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "ტუტი", "compose_form.publish": "ტუტი",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publicēt", "compose_form.publish": "Publicēt",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Publish", "compose_form.publish": "Publish",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Tut", "compose_form.publish": "Tut",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Postează", "compose_form.publish": "Postează",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Mesazh", "compose_form.publish": "Mesazh",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Tutni", "compose_form.publish": "Tutni",

@ -274,7 +274,7 @@
"compose_form.poll.add_option": "Add a choice", "compose_form.poll.add_option": "Add a choice",
"compose_form.poll.duration": "Poll duration", "compose_form.poll.duration": "Poll duration",
"compose_form.poll.option_placeholder": "Choice {number}", "compose_form.poll.option_placeholder": "Choice {number}",
"compose_form.poll.remove_option": "Remove this choice", "compose_form.poll.remove_option": "Delete",
"compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices", "compose_form.poll.switch_to_multiple": "Change poll to allow multiple choices",
"compose_form.poll.switch_to_single": "Change poll to allow for a single choice", "compose_form.poll.switch_to_single": "Change poll to allow for a single choice",
"compose_form.publish": "Труби", "compose_form.publish": "Труби",

@ -277,6 +277,15 @@ const fixBirthday = (account: ImmutableMap<string, any>) => {
return account.set('birthday', birthday || ''); return account.set('birthday', birthday || '');
}; };
/** Rewrite `<p></p>` to empty string. */
const fixNote = (account: ImmutableMap<string, any>) => {
if (account.get('note') === '<p></p>') {
return account.set('note', '');
} else {
return account;
}
};
export const normalizeAccount = (account: Record<string, any>) => { export const normalizeAccount = (account: Record<string, any>) => {
return AccountRecord( return AccountRecord(
ImmutableMap(fromJS(account)).withMutations(account => { ImmutableMap(fromJS(account)).withMutations(account => {
@ -298,6 +307,7 @@ export const normalizeAccount = (account: Record<string, any>) => {
fixUsername(account); fixUsername(account);
fixDisplayName(account); fixDisplayName(account);
fixBirthday(account); fixBirthday(account);
fixNote(account);
addInternalFields(account); addInternalFields(account);
}), }),
); );

@ -29,15 +29,6 @@
border-bottom: 1px solid var(--brand-color--med); border-bottom: 1px solid var(--brand-color--med);
} }
&.compact {
padding: 0;
border-bottom: 0;
.account__avatar-wrapper {
margin-left: 0;
}
}
.account__display-name { .account__display-name {
flex: 1 1 auto; flex: 1 1 auto;
display: block; display: block;
@ -50,13 +41,6 @@
display: flex; display: flex;
} }
} }
&__note {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: var(--primary-text-color--faint);
}
} }
.account__wrapper { .account__wrapper {
@ -69,30 +53,6 @@
margin-right: 12px; margin-right: 12px;
} }
.account__avatar {
@include avatar-radius;
position: relative;
background-color: var(--brand-color--faint);
&-inline {
display: inline-block;
vertical-align: middle;
margin-right: 5px;
}
&-composite {
@include avatar-radius;
overflow: hidden;
& > div {
@include avatar-radius;
float: left;
position: relative;
box-sizing: border-box;
}
}
}
a .account__avatar { a .account__avatar {
cursor: pointer; cursor: pointer;
} }
@ -136,16 +96,6 @@ a .account__avatar {
} }
} }
.account-authorize {
padding: 14px 10px;
.detailed-status__display-name {
display: block;
margin-bottom: 15px;
overflow: hidden;
}
}
.account-authorize__avatar { .account-authorize__avatar {
float: left; float: left;
margin-right: 10px; margin-right: 10px;
@ -230,35 +180,6 @@ a .account__avatar {
left: -26px; left: -26px;
position: absolute; position: absolute;
} }
.detailed-status__display-avatar {
position: relative;
}
.detailed-status__display-name {
margin-bottom: 0;
}
}
.relationship-tag {
color: var(--primary-text-color);
margin-bottom: 4px;
margin-left: 4px;
display: block;
vertical-align: top;
background-color: var(--background-color);
text-transform: uppercase;
font-size: 11px;
font-weight: 500;
padding: 4px;
border-radius: 4px;
opacity: 0.7;
white-space: nowrap;
transition: 0.2s;
&:hover {
opacity: 1;
}
} }
.account__joined-at { .account__joined-at {

@ -21,7 +21,6 @@
@import 'rtl'; @import 'rtl';
@import 'accessibility'; @import 'accessibility';
@import 'dyslexic'; @import 'dyslexic';
@import 'demetricator';
@import 'chats'; @import 'chats';
@import 'navigation'; @import 'navigation';
@import 'placeholder'; @import 'placeholder';
@ -46,8 +45,6 @@
@import 'components/search'; @import 'components/search';
@import 'components/react-toggle'; @import 'components/react-toggle';
@import 'components/still-image'; @import 'components/still-image';
@import 'components/profile-media-panel';
@import 'components/profile-info-panel';
@import 'components/spoiler-button'; @import 'components/spoiler-button';
@import 'components/video-player'; @import 'components/video-player';
@import 'components/audio-player'; @import 'components/audio-player';

@ -14,10 +14,6 @@
.search--account { .search--account {
border-top: 1px solid hsla(var(--primary-text-color_hsl), 0.2); border-top: 1px solid hsla(var(--primary-text-color_hsl), 0.2);
padding: 5px; padding: 5px;
input.search__input {
border-radius: 6px;
}
} }
&__header { &__header {
@ -64,17 +60,6 @@
transform: translateY(2px); transform: translateY(2px);
} }
} }
.icon-with-badge__badge {
position: static;
pointer-events: none;
width: 18px;
height: 18px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 7px;
}
} }
&__content { &__content {
@ -224,13 +209,6 @@
} }
} }
} }
.icon-with-badge__badge {
top: 0;
right: 0;
left: auto;
bottom: auto;
}
} }
.chat-box { .chat-box {
@ -321,16 +299,6 @@
} }
} }
.chatroom__back {
display: flex;
align-items: center;
background: var(--accent-color--faint);
.column-back-button {
background: transparent;
}
}
.chat { .chat {
&__attachment-icon { &__attachment-icon {
float: right; float: right;

@ -1,43 +1,4 @@
.account__header__subscribe {
position: absolute;
top: 10px;
right: 10px;
right: max(10px, env(safe-area-inset-right));
z-index: 1;
.subscription-button {
color: var(--primary-text-color);
margin-bottom: 4px;
display: flex;
align-items: center;
justify-content: center;
background-color: var(--background-color);
text-transform: uppercase;
font-size: 13px;
font-weight: 500;
padding: 4px;
border-radius: 4px;
opacity: 0.7;
&:active,
&:focus,
&:hover {
opacity: 1;
}
&:not(.button-active) i.fa {
margin: 0;
}
.svg-icon {
width: 20px;
height: 20px;
}
}
}
.account__header__content { .account__header__content {
color: var(--primary-text-color--faint);
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
overflow: hidden; overflow: hidden;

@ -1,53 +1,3 @@
.columns-area {
display: flex;
flex: 1 1 auto;
flex-direction: row;
justify-content: flex-start;
position: relative;
&__panels {
display: flex;
justify-content: center;
width: 100%;
height: 100%;
&__pane {
height: 100%;
pointer-events: none;
display: flex;
justify-content: flex-end;
padding-top: 15px;
&--start {
justify-content: flex-start;
}
&__inner {
width: 265px;
pointer-events: auto;
height: 100%;
}
}
&__main {
display: flex;
flex-direction: column;
box-sizing: border-box;
width: 100%;
max-width: 600px;
padding: 0 20px;
@media screen and (max-width: 580px) {
padding: 0;
}
@media screen and (min-width: 896px) {
margin: 0 20px;
padding: 0;
}
}
}
}
.column { .column {
width: 350px; width: 350px;
@ -59,10 +9,6 @@
} }
@media screen and (min-width: 631px) { @media screen and (min-width: 631px) {
.columns-area {
padding: 0;
}
.column { .column {
flex: 0 0 auto; flex: 0 0 auto;
padding: 10px; padding: 10px;
@ -77,154 +23,6 @@
padding-right: 10px; padding-right: 10px;
} }
} }
.columns-area > div {
.column {
padding-left: 5px;
padding-right: 5px;
}
}
}
.columns-area {
display: block;
flex-direction: column;
width: 100%;
margin: 0 auto;
padding-top: 15px;
@media screen and (max-width: 580px) {
padding-top: 0;
}
.column {
width: 100%;
padding: 0;
}
.search__input {
line-height: 18px;
font-size: 16px;
padding: 15px;
padding-right: 30px;
border-radius: 0;
background-color: var(--foreground-color);
}
.search__icon .fa {
top: 15px;
}
@media (max-width: 580px) {
.timeline-compose-block {
border-radius: 0;
margin-top: 10px;
}
}
@media screen and (min-width: 630px) {
.detailed-status {
padding: 15px;
.media-gallery,
.video-player {
margin-top: 15px;
}
}
.compose-form {
padding: 15px;
}
.status {
padding: 15px 15px 15px (48px + 15px * 2);
min-height: 48px + 2px;
&__avatar {
left: 15px;
top: 17px;
}
&__content {
padding-top: 5px;
}
&__prepend {
margin-left: 48px + 15px * 2;
padding-top: 15px;
}
&__prepend-icon-wrapper {
left: -32px;
}
.media-gallery,
.video-player {
margin-top: 10px;
}
}
.account {
padding: 15px 10px;
}
.notification {
&__message {
margin-left: 48px + 15px * 2;
padding-top: 15px;
}
&__favourite-icon-wrapper {
left: -32px;
}
.status {
padding-top: 8px;
}
.account {
padding-top: 8px;
}
.account__avatar-wrapper {
margin-left: 17px;
margin-right: 15px;
}
}
}
}
// This controls where the left column breaks.
@media screen and (max-width: 600px + (285px * 1) + (10px * 1)) {
.columns-area__panels__pane--left {
display: none;
}
}
@media screen and (max-width: 600px + (285px * 2) + (10px * 2)) {
.columns-area__panels__pane--right {
display: none;
}
}
.column-back-button {
background: var(--accent-color--faint);
color: var(--highlight-text-color);
cursor: pointer;
flex: 0 0 auto;
font-size: 16px;
line-height: inherit;
border: 0;
text-align: unset;
padding: 15px;
margin: 0;
z-index: 3;
outline: 0;
&:hover,
&:focus {
text-decoration: underline;
}
} }
.column-link { .column-link {
@ -289,24 +87,6 @@
cursor: default; cursor: default;
} }
.columns-area .column {
@include standard-panel;
&--transparent {
background: transparent;
border-radius: 0;
box-shadow: none;
}
@media screen and (max-width: 580px) {
border-radius: 0;
.material-status__status {
border-radius: 0;
}
}
}
.column-header__wrapper { .column-header__wrapper {
position: relative; position: relative;
flex: 0 0 auto; flex: 0 0 auto;
@ -611,10 +391,6 @@
} }
} }
.column-link--transparent .icon-with-badge__badge {
border-color: var(--background-color);
}
.column__switch .audio-toggle { .column__switch .audio-toggle {
position: absolute; position: absolute;
z-index: 4; z-index: 4;
@ -663,79 +439,3 @@
} }
} }
} }
.column-title {
text-align: center;
padding: 40px;
.logo {
fill: var(--primary-text-color);
width: 50px;
margin: 0 auto;
margin-bottom: 40px;
}
h3 {
font-size: 24px;
line-height: 1.5;
font-weight: 700;
margin-bottom: 10px;
}
p {
font-size: 16px;
line-height: 24px;
font-weight: 400;
color: var(--primary-text-color--faint);
}
}
.column-actions {
display: flex;
align-items: center;
justify-content: center;
padding: 40px;
padding-top: 40px;
&__background {
position: absolute;
left: 0;
bottom: 0;
height: 220px;
width: auto;
}
}
.column-list {
position: relative;
&__empty-message {
padding: 0 20px;
}
}
.follow_subhead {
margin: 50px 0;
font-size: 20px;
}
// Pull to refresh
.columns-area .column {
.ptr,
.ptr__children {
background: var(--foreground-color);
border-bottom-left-radius: 10px;
border-bottom-right-radius: 10px;
@media screen and (max-width: 580px) {
border-radius: 0;
}
}
&--transparent {
.ptr,
.ptr__children {
background: transparent;
}
}
}

@ -1,32 +1,4 @@
.compose-form { .compose-form {
&__sensitive-button {
padding: 10px;
padding-top: 0;
font-size: 14px;
font-weight: 500;
&.active { color: var(--highlight-text-color); }
input[type=checkbox] { display: none; }
.checkbox {
display: inline-block;
position: relative;
border: 1px solid var(--brand-color);
box-sizing: border-box;
width: 18px;
height: 18px;
flex: 0 0 auto;
margin-right: 10px;
top: -1px;
border-radius: 4px;
vertical-align: middle;
&.active {
border-color: var(--highlight-text-color);
background: var(--highlight-text-color);
}
}
}
&__warning { &__warning {
@apply text-xs mb-2.5 px-2.5 py-2 shadow-md rounded bg-accent-300 text-white; @apply text-xs mb-2.5 px-2.5 py-2 shadow-md rounded bg-accent-300 text-white;
@ -145,24 +117,6 @@
} }
} }
} // end .compose-form .compose-form__modifiers } // end .compose-form .compose-form__modifiers
&__publish {
display: flex;
justify-content: flex-end;
min-width: 0;
flex: 0 0 auto;
.compose-form__publish-button-wrapper {
overflow: hidden;
}
}
&__counter {
display: flex;
align-items: center;
align-self: center;
margin-left: auto;
}
} // end .compose-form } // end .compose-form
.privacy-dropdown__dropdown { .privacy-dropdown__dropdown {

@ -1,96 +1,3 @@
.detailed-status {
// padding: 14px 10px;
&--flex {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
align-items: flex-start;
.status__content {
flex: 100%;
}
}
.status__content {
font-size: 19px;
line-height: 24px;
.emojione {
width: 24px;
height: 24px;
margin: -1px 0 0;
}
&--big {
img.emojione {
width: 56px;
height: 56px;
}
}
}
.video-player,
.audio-player {
margin-top: 8px;
}
}
.detailed-status__timestamp {
display: flex;
align-items: center;
.svg-icon {
width: 20px;
height: 20px;
svg {
stroke-width: 1.3px;
}
}
.svg-icon {
margin-right: 5px;
}
}
.detailed-status__wrapper {
position: relative;
}
.detailed-status__display-name {
color: var(--primary-text-color--faint);
display: flex;
line-height: 24px;
margin-bottom: 15px;
overflow: hidden;
strong,
span {
text-overflow: ellipsis;
overflow: hidden;
}
strong {
font-size: 16px;
color: var(--primary-text-color);
}
span.hover-ref-wrapper {
display: inline;
}
.display-name__account {
display: block;
margin-top: -5px;
}
}
.detailed-status__display-avatar {
float: left;
margin-right: 10px;
}
.thread { .thread {
@apply bg-white dark:bg-primary-900 p-4 shadow-xl dark:shadow-none sm:p-6 sm:rounded-xl; @apply bg-white dark:bg-primary-900 p-4 shadow-xl dark:shadow-none sm:p-6 sm:rounded-xl;

@ -1,10 +1,7 @@
.status__display-name,
.detailed-status__display-name,
.account__display-name { .account__display-name {
text-decoration: none; text-decoration: none;
} }
.status__display-name,
.account__display-name { .account__display-name {
strong { strong {
@apply text-gray-800 dark:text-gray-200; @apply text-gray-800 dark:text-gray-200;
@ -17,8 +14,6 @@
} }
} }
.status__display-name,
.detailed-status__display-name,
a.account__display-name { a.account__display-name {
&:hover strong { &:hover strong {
text-decoration: underline; text-decoration: underline;

@ -86,11 +86,6 @@
} }
} }
.detailed-status__wrapper .emoji-react-selector {
bottom: 40px;
right: 10px;
}
.status .emoji-react-selector { .status .emoji-react-selector {
bottom: 100%; bottom: 100%;
left: -20px; left: -20px;

@ -92,8 +92,7 @@
} }
} }
.status__wrapper, .status__wrapper {
.detailed-status__wrapper {
.media-gallery__item-thumbnail.letterboxed { .media-gallery__item-thumbnail.letterboxed {
&, &,
.still-image { .still-image {

@ -6,18 +6,6 @@
overflow-y: hidden; overflow-y: hidden;
} }
.video-modal {
max-width: 100vw;
max-height: 100vh;
position: relative;
}
.video-modal {
.video-player video {
height: auto;
}
}
.media-modal { .media-modal {
width: 100%; width: 100%;
height: 100%; height: 100%;
@ -176,7 +164,6 @@
} }
} }
.onboarding-modal,
.error-modal { .error-modal {
background: var(--background-color); background: var(--background-color);
color: var(--primary-text-color); color: var(--primary-text-color);
@ -229,7 +216,6 @@
min-width: 33px; min-width: 33px;
} }
.onboarding-modal__nav,
.error-modal__nav { .error-modal__nav {
color: var(--highlight-text-color); color: var(--highlight-text-color);
border: 0; border: 0;
@ -266,12 +252,9 @@
position: relative; position: relative;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
width: 480px;
max-width: 90vw;
border-radius: 10px; border-radius: 10px;
border: 1px solid var(--background-color); border: 1px solid var(--background-color);
color: var(--primary-text-color--faint); color: var(--primary-text-color--faint);
background: var(--foreground-color);
.status__display-name { .status__display-name {
display: block; display: block;

@ -1,4 +0,0 @@
.profile-info-panel-content__deactivated {
color: var(--primary-text-color--faint);
display: block;
}

@ -1,16 +0,0 @@
.media-panel {
&__content {
width: 100%;
padding: 8px 0;
}
&__list {
display: flex;
flex-wrap: wrap;
}
&__empty {
font-size: 14px;
color: var(--primary-text-color--faint);
}
}

@ -6,8 +6,7 @@
} }
} }
.status__wrapper, .status__wrapper {
.detailed-status {
.reply-mentions { .reply-mentions {
display: block; display: block;

@ -2,12 +2,6 @@
position: relative; position: relative;
} }
input.search__input {
@include search-input;
display: block;
padding: 7px 30px 6px 10px;
}
.search__icon { .search__icon {
&::-moz-focus-inner { &::-moz-focus-inner {
border: 0; border: 0;
@ -55,52 +49,6 @@ input.search__input {
} }
} }
.search-header {
display: block;
width: 100%;
&__text-container {
display: none;
padding: 25px 0;
background-color: var(--accent-color--med);
@media (min-width: 896px) {
display: block;
}
}
&__title-text {
color: var(--primary-text-color);
font-size: 27px;
font-weight: bold;
line-height: 32px;
overflow: hidden;
padding-left: 20px;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 1200px;
margin: 0 auto;
}
&__type-filters-tabs {
display: flex;
width: 100%;
max-width: 1200px;
margin: 0 auto;
@media screen and (max-width: 895px) {
max-width: 580px;
}
}
@media (min-width: 896px) and (max-width: 1190px) {
&__title-text,
&__type-filters-tabs {
max-width: 900px;
}
}
}
.column { .column {
.search { .search {
padding: 10px 15px; padding: 10px 15px;
@ -108,12 +56,6 @@ input.search__input {
border-bottom: 1px solid hsla(var(--primary-text-color_hsl), 0.2); border-bottom: 1px solid hsla(var(--primary-text-color_hsl), 0.2);
} }
input.search__input {
background-color: var(--background-color);
border-radius: 8px;
padding: 12px 36px 12px 16px;
}
.search__icon .svg-icon { .search__icon .svg-icon {
right: 24px; right: 24px;
} }

@ -6,14 +6,6 @@
position: absolute; position: absolute;
z-index: 40; z-index: 40;
&--minified {
display: block;
left: 4px;
top: 4px;
width: auto;
height: auto;
}
&--hidden { &--hidden {
display: none; display: none;
} }

@ -218,21 +218,6 @@ a.status-card {
} }
} }
@media screen and (min-width: 630px) {
.columns-area .material-status .status {
padding: 15px;
&__avatar {
top: 0;
left: 0;
}
&__content {
padding-top: 10px;
}
}
}
.attachment-thumbs { .attachment-thumbs {
position: relative; position: relative;

@ -1,69 +1,3 @@
.video-error-cover {
align-items: center;
background: var(--background-color);
color: var(--primary-text-color);
cursor: pointer;
display: flex;
flex-direction: column;
height: 100%;
justify-content: center;
position: relative;
text-align: center;
z-index: 100;
}
.status__video-player {
background: var(--background-color);
box-sizing: border-box;
cursor: default; /* May not be needed */
margin-top: 8px;
overflow: hidden;
position: relative;
}
.status__video-player-video {
height: 100%;
object-fit: cover;
position: relative;
top: 50%;
transform: translateY(-50%);
width: 100%;
z-index: 1;
}
.status__video-player-expand,
.status__video-player-mute {
color: var(--primary-text-color);
opacity: 0.8;
position: absolute;
right: 4px;
text-shadow: 0 1px 1px $base-shadow-color, 1px 0 1px $base-shadow-color;
}
.status__video-player-spoiler {
display: none;
color: var(--primary-text-color);
left: 4px;
position: absolute;
text-shadow: 0 1px 1px $base-shadow-color, 1px 0 1px $base-shadow-color;
top: 4px;
z-index: 100;
&.status__video-player-spoiler--visible {
display: block;
}
}
.status__video-player-expand {
bottom: 4px;
z-index: 100;
}
.status__video-player-mute {
top: 4px;
z-index: 5;
}
.detailed, .detailed,
.fullscreen { .fullscreen {
.video-player__volume__current, .video-player__volume__current,
@ -423,14 +357,3 @@
border: 0; border: 0;
display: block; display: block;
} }
.media-spoiler-video-play-icon {
border-radius: 100px;
color: var(--primary-text-color--faint);
font-size: 36px;
left: 50%;
padding: 5px;
position: absolute;
top: 50%;
transform: translate(-50%, -50%);
}

@ -1,5 +0,0 @@
body.demetricator {
.icon-with-badge__badge {
display: none;
}
}

@ -58,25 +58,3 @@
line-height: #{$px + "px"}; line-height: #{$px + "px"};
line-height: #{$rem + "rem"}; line-height: #{$rem + "rem"};
} }
// Soapbox icon font
@font-face {
font-family: 'soapbox';
src: url('../assets/fonts/soapbox/soapbox.eot?pryg6i');
src: url('../assets/fonts/soapbox/soapbox.eot?pryg6i#iefix') format('embedded-opentype'),
url('../assets/fonts/soapbox/soapbox.ttf?pryg6i') format('truetype'),
url('../assets/fonts/soapbox/soapbox.woff?pryg6i') format('woff'),
url('../assets/fonts/soapbox/soapbox.svg?pryg6i#soapbox') format('svg');
font-weight: normal;
font-style: normal;
}
.fa-fediverse::before {
font-family: 'soapbox';
content: "\e901";
}
.fa-spinster::before {
font-family: 'soapbox';
content: "\e900";
}

@ -586,38 +586,6 @@ code {
margin-bottom: 14px; margin-bottom: 14px;
font-weight: bold; font-weight: bold;
} }
.showable-password {
position: relative;
input {
padding-right: 36px;
}
.icon-button {
@apply text-black dark:text-white;
position: absolute;
top: 0;
right: 0;
height: 38px;
width: 36px;
padding: 0;
margin: 0;
background: transparent;
.svg-icon {
height: 20px;
width: 20px;
}
}
}
}
.block-icon {
display: block;
margin: 0 auto;
margin-bottom: 10px;
font-size: 24px;
} }
.simple_form { .simple_form {
@ -660,14 +628,6 @@ code {
} }
} }
.columns-area {
form.simple_form--public {
@include standard-panel;
margin-top: 20px;
padding: 60px 30px;
}
}
.captcha { .captcha {
background-color: #fff; background-color: #fff;
border-radius: 4px; border-radius: 4px;

@ -13,11 +13,6 @@ body.rtl {
margin-left: 5px; margin-left: 5px;
} }
.search__input {
padding-right: 10px;
padding-left: 30px;
}
.search__icon .fa { .search__icon .fa {
right: auto; right: auto;
left: 10px; left: 10px;
@ -69,16 +64,6 @@ body.rtl {
margin-right: 0; margin-right: 0;
} }
.detailed-status__display-name .display-name {
text-align: right;
}
.detailed-status__display-avatar {
margin-right: 0;
margin-left: 10px;
float: right;
}
.fa-ul { .fa-ul {
margin-left: 0; margin-left: 0;
margin-left: 2.14285714em; margin-left: 2.14285714em;
@ -134,13 +119,6 @@ body.rtl {
padding-right: 10px; padding-right: 10px;
} }
} }
.columns-area > div {
.column {
padding-left: 5px;
padding-right: 5px;
}
}
} }
.public-layout { .public-layout {

@ -151,30 +151,6 @@
.ellipsis::after { content: ""; } .ellipsis::after { content: ""; }
.timeline-compose-block {
@include standard-panel;
display: flex;
align-items: flex-start;
padding: 20px;
margin-bottom: 10px;
.compose-form {
flex: 1 1;
padding: 0 0 0 20px !important;
position: relative;
@media (max-width: 405px) {
padding: 0 !important;
}
}
&__avatar {
display: block;
border-radius: 50%;
@media (max-width: 405px) { display: none; }
}
}
.no-reduce-motion .spoiler-input { .no-reduce-motion .spoiler-input {
transition: height 0.4s ease, opacity 0.4s ease; transition: height 0.4s ease, opacity 0.4s ease;
} }
@ -193,33 +169,6 @@
} }
} }
.domain {
padding: 10px;
border-bottom: 1px solid var(--brand-color--med);
.domain__domain-name {
flex: 1 1 auto;
display: block;
color: var(--primary-text-color);
text-decoration: none;
font-size: 14px;
font-weight: 500;
}
&__buttons .svg-icon {
height: 18px;
width: 18px;
}
}
article:last-child > .domain {
border-bottom: none;
}
.domain__wrapper {
display: flex;
}
.image-loader { .image-loader {
position: relative; position: relative;
width: 100%; width: 100%;
@ -253,7 +202,6 @@ article:last-child > .domain {
.react-swipeable-view-container { .react-swipeable-view-container {
&, &,
.columns-area,
.column { .column {
height: 100%; height: 100%;
} }
@ -320,26 +268,6 @@ article:last-child > .domain {
} }
} }
.icon-with-badge__badge {
@include font-size(14);
@include line-height(14);
position: absolute;
box-sizing: border-box;
left: -10px;
top: 3px;
min-width: 16px;
height: 16px;
padding: 1px 3px 0;
border-radius: 8px;
text-align: center;
color: #fff;
background: var(--accent-color);
@media screen and (max-width: 895px) {
top: 0;
}
}
.slist { .slist {
&--flex { &--flex {
display: flex; display: flex;
@ -589,12 +517,6 @@ article:last-child > .domain {
100% { opacity: 1; } 100% { opacity: 1; }
} }
.page__top + .page__columns .columns-area {
@media screen and (max-width: 580px) {
padding-top: 10px;
}
}
.text-muted { .text-muted {
color: var(--gray-500); color: var(--gray-500);
} }

@ -68,6 +68,7 @@
"@sentry/tracing": "^7.11.1", "@sentry/tracing": "^7.11.1",
"@tabler/icons": "^1.111.0", "@tabler/icons": "^1.111.0",
"@tailwindcss/forms": "^0.5.3", "@tailwindcss/forms": "^0.5.3",
"@tailwindcss/line-clamp": "^0.4.2",
"@tailwindcss/typography": "^0.5.7", "@tailwindcss/typography": "^0.5.7",
"@tanstack/react-query": "^4.0.10", "@tanstack/react-query": "^4.0.10",
"@testing-library/react": "^12.1.4", "@testing-library/react": "^12.1.4",

@ -86,6 +86,7 @@ module.exports = {
}, },
plugins: [ plugins: [
require('@tailwindcss/forms'), require('@tailwindcss/forms'),
require('@tailwindcss/line-clamp'),
require('@tailwindcss/typography'), require('@tailwindcss/typography'),
], ],
}; };

@ -2272,6 +2272,11 @@
dependencies: dependencies:
mini-svg-data-uri "^1.2.3" mini-svg-data-uri "^1.2.3"
"@tailwindcss/line-clamp@^0.4.2":
version "0.4.2"
resolved "https://registry.yarnpkg.com/@tailwindcss/line-clamp/-/line-clamp-0.4.2.tgz#f353c5a8ab2c939c6267ac5b907f012e5ee130f9"
integrity sha512-HFzAQuqYCjyy/SX9sLGB1lroPzmcnWv1FHkIpmypte10hptf4oPUfucryMKovZh2u0uiS9U5Ty3GghWfEJGwVw==
"@tailwindcss/typography@^0.5.7": "@tailwindcss/typography@^0.5.7":
version "0.5.7" version "0.5.7"
resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.7.tgz#e0b95bea787ee14c5a34a74fc824e6fe86ea8855" resolved "https://registry.yarnpkg.com/@tailwindcss/typography/-/typography-0.5.7.tgz#e0b95bea787ee14c5a34a74fc824e6fe86ea8855"

Loading…
Cancel
Save