Merge remote-tracking branch 'origin/next' into next-colors

This commit is contained in:
Alex Gleason 2022-03-23 13:05:53 -05:00
commit 12617bf7de
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7
70 changed files with 171 additions and 165 deletions

View file

@ -9,33 +9,6 @@
<link href="/manifest.json" rel="manifest">
<!--server-generated-meta-->
<link rel="icon" type="image/png" href="/favicon.png">
<link href='/icons/icon-57x57.png' rel='apple-touch-icon' sizes='57x57'>
<link href='/icons/icon-64x64.png' rel='apple-touch-icon' sizes='64x64'>
<link href='/icons/icon-72x72.png' rel='apple-touch-icon' sizes='72x72'>
<link href='/icons/icon-114x114.png' rel='apple-touch-icon' sizes='114x114'>
<link href='/icons/icon-120x120.png' rel='apple-touch-icon' sizes='120x120'>
<link href='/icons/icon-180x180.png' rel='apple-touch-icon' sizes='180x180'>
<link href='/icons/icon-192x192.png' rel='apple-touch-icon' sizes='192x192'>
<link href='/icons/icon-512x512.png' rel='apple-touch-icon' sizes='512x512'>
<script>
if(window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.didBeginLoadingSoapbox) {
window.webkit.messageHandlers.didBeginLoadingSoapbox.postMessage("started");
}
</script>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u="//trk.bonsa.net/";
_paq.push(['setTrackerUrl', u+'matomo.php']);
_paq.push(['setSiteId', '23231245']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
})();
</script>
</head>
<body class="theme-mode-light no-reduce-motion">
<div id="soapbox">

View file

@ -4,7 +4,7 @@ import { Link } from 'react-router-dom';
import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper';
import VerificationBadge from 'soapbox/components/verification_badge';
import ActionButton from 'soapbox/features/ui/components/action_button';
import { useAppSelector } from 'soapbox/hooks';
import { useAppSelector, useOnScreen } from 'soapbox/hooks';
import { getAcct } from 'soapbox/utils/accounts';
import { displayFqn } from 'soapbox/utils/state';
@ -52,8 +52,9 @@ const Account = ({
timestampUrl,
withRelationship = true,
}: IAccount) => {
const overflowRef = React.useRef(null);
const actionRef = React.useRef(null);
const overflowRef = React.useRef<HTMLDivElement>(null);
const actionRef = React.useRef<HTMLDivElement>(null);
const isOnScreen = useOnScreen(overflowRef);
const [style, setStyle] = React.useState<React.CSSProperties>({ visibility: 'hidden' });
@ -93,8 +94,8 @@ const Account = ({
};
React.useEffect(() => {
if (isOnScreen) {
const style: React.CSSProperties = {};
const actionWidth = actionRef.current?.clientWidth;
if (overflowRef.current) {
@ -104,7 +105,8 @@ const Account = ({
}
setStyle(style);
}, [overflowRef, actionRef]);
}
}, [isOnScreen, overflowRef, actionRef]);
if (!account) {
return null;
@ -161,8 +163,8 @@ const Account = ({
</LinkEl>
</ProfilePopper>
<HStack alignItems='center' space={1}>
<Text theme='muted' size='sm'>@{username}</Text>
<HStack alignItems='center' space={1} style={style}>
<Text theme='muted' size='sm' truncate>@{username}</Text>
{(timestamp) ? (
<>

View file

@ -8,7 +8,7 @@ import StillImage from 'soapbox/components/still_image';
export default class Avatar extends React.PureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
size: PropTypes.number,
style: PropTypes.object,
className: PropTypes.string,

View file

@ -6,7 +6,7 @@ import StillImage from 'soapbox/components/still_image';
export default class AvatarOverlay extends React.PureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
friend: ImmutablePropTypes.map.isRequired,
};

View file

@ -22,7 +22,7 @@ export default @connect(mapStateToProps)
class DisplayName extends React.PureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
displayFqn: PropTypes.bool,
others: ImmutablePropTypes.list,
children: PropTypes.node,

View file

@ -207,7 +207,7 @@ class Dropdown extends React.PureComponent {
pressed: PropTypes.bool,
title: PropTypes.string,
disabled: PropTypes.bool,
status: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
isUserTouching: PropTypes.func,
isModalOpen: PropTypes.bool.isRequired,
onOpen: PropTypes.func.isRequired,

View file

@ -17,15 +17,16 @@ export default class Icon extends React.PureComponent {
id: PropTypes.string,
src: PropTypes.string,
className: PropTypes.string,
fixedWidth: PropTypes.bool,
};
render() {
const { id, src, ...rest } = this.props;
const { id, src, fixedWidth, ...rest } = this.props;
if (src) {
return <SvgIcon src={src} {...rest} />;
} else {
return <ForkAwesomeIcon id={id} {...rest} />;
return <ForkAwesomeIcon id={id} fixedWidth={fixedWidth} {...rest} />;
}
}

View file

@ -45,7 +45,7 @@ const shouldLetterbox = attachment => {
class Item extends React.PureComponent {
static propTypes = {
attachment: ImmutablePropTypes.map.isRequired,
attachment: ImmutablePropTypes.record.isRequired,
standalone: PropTypes.bool,
index: PropTypes.number.isRequired,
size: PropTypes.number.isRequired,

View file

@ -1,39 +0,0 @@
import PropTypes from 'prop-types';
import React from 'react';
import { withRouter } from 'react-router-dom';
export default @withRouter
class Permalink extends React.PureComponent {
static propTypes = {
className: PropTypes.string,
href: PropTypes.string.isRequired,
to: PropTypes.string.isRequired,
children: PropTypes.node,
onInterceptClick: PropTypes.func,
history: PropTypes.object,
};
handleClick = e => {
if (this.props.onInterceptClick && this.props.onInterceptClick()) {
e.preventDefault();
return;
}
if (this.props.history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
e.preventDefault();
this.props.history.push(this.props.to);
}
}
render() {
const { href, children, className, onInterceptClick, ...other } = this.props;
return (
<a target='_blank' href={href} onClick={this.handleClick} {...other} className={`permalink${className ? ' ' + className : ''}`}>
{children}
</a>
);
}
}

View file

@ -0,0 +1,37 @@
import * as React from 'react';
import { useHistory } from 'react-router-dom';
interface IPermaLink extends Pick<React.HTMLAttributes<HTMLAnchorElement>, 'dangerouslySetInnerHTML'> {
className?: string,
href: string,
title?: string,
to: string,
}
const Permalink: React.FC<IPermaLink> = (props) => {
const history = useHistory();
const { className, href, title, to, children, ...filteredProps } = props;
const handleClick = (event: React.MouseEvent<HTMLAnchorElement>) => {
if (event.button === 0 && !(event.ctrlKey || event.metaKey)) {
event.preventDefault();
history.push(to);
}
};
return (
<a
target='_blank'
href={href}
onClick={handleClick}
title={title}
className={`permalink${className ? ' ' + className : ''}`}
{...filteredProps}
>
{children}
</a>
);
};
export default Permalink;

View file

@ -134,7 +134,7 @@ export const ProfileHoverCard = ({ visible }) => {
ProfileHoverCard.propTypes = {
visible: PropTypes.bool,
accountId: PropTypes.string,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
};
ProfileHoverCard.defaultProps = {

View file

@ -43,7 +43,7 @@ class ScrollableList extends PureComponent {
children: PropTypes.node,
onScrollToTop: PropTypes.func,
onScroll: PropTypes.func,
placeholderComponent: PropTypes.func,
placeholderComponent: PropTypes.object,
placeholderCount: PropTypes.number,
autoload: PropTypes.bool,
onRefresh: PropTypes.func,

View file

@ -55,8 +55,8 @@ export default @injectIntl @withRouter
class Status extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
account: ImmutablePropTypes.record,
otherAccounts: ImmutablePropTypes.list,
onClick: PropTypes.func,
onReply: PropTypes.func,

View file

@ -69,7 +69,7 @@ const messages = defineMessages({
class StatusActionBar extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.record.isRequired,
onOpenUnauthorizedModal: PropTypes.func.isRequired,
onOpenReblogsModal: PropTypes.func.isRequired,
onReply: PropTypes.func,

View file

@ -28,7 +28,7 @@ export default @connect(mapStateToProps)
class StatusContent extends React.PureComponent {
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.record.isRequired,
reblogContent: PropTypes.string,
expanded: PropTypes.bool,
onExpandedToggle: PropTypes.func,

View file

@ -223,7 +223,7 @@ export default class StatusList extends ImmutablePureComponent {
isLoading={isLoading}
showLoading={isLoading && statusIds.size === 0}
onLoadMore={onLoadMore && this.handleLoadOlder}
placeholderComponent={() => <PlaceholderStatus />}
placeholderComponent={PlaceholderStatus}
placeholderCount={20}
ref={this.setRef}
className={divideType === 'border' ? 'divide-y divide-solid divide-gray-200' : 'sm:space-y-3 divide-y divide-solid divide-gray-200 sm:divide-none'}

View file

@ -23,7 +23,7 @@ export default @connect(null, mapDispatchToProps)
class StatusReplyMentions extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.record.isRequired,
onOpenMentionsModal: PropTypes.func,
}

View file

@ -33,7 +33,7 @@ class ThumbNavigation extends React.PureComponent {
static propTypes = {
logo: PropTypes.string,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
dashboardCount: PropTypes.number,
notificationCount: PropTypes.number,
chatsCount: PropTypes.number,

View file

@ -29,6 +29,7 @@ interface IHStack {
justifyContent?: 'between' | 'center',
space?: 0.5 | 1 | 1.5 | 2 | 3 | 4 | 6,
grow?: boolean,
style?: React.CSSProperties
}
const HStack: React.FC<IHStack> = (props) => {

View file

@ -97,7 +97,7 @@ class SoapboxMount extends React.PureComponent {
static propTypes = {
showIntroduction: PropTypes.bool,
me: SoapboxPropTypes.me,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
instanceLoaded: PropTypes.bool,
reduceMotion: PropTypes.bool,
underlineLinks: PropTypes.bool,

View file

@ -86,8 +86,8 @@ export default @connect(mapStateToProps)
class Header extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
meAccount: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
meaccount: ImmutablePropTypes.record,
identity_props: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
username: PropTypes.string,

View file

@ -12,7 +12,7 @@ export default @withRouter
class Header extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
identity_proofs: ImmutablePropTypes.list,
onFollow: PropTypes.func.isRequired,
onBlock: PropTypes.func.isRequired,

View file

@ -22,7 +22,7 @@ export default @connect()
class ReportStatus extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.record.isRequired,
report: ImmutablePropTypes.map,
};

View file

@ -35,7 +35,7 @@ class UnapprovedAccount extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
};
handleApprove = () => {

View file

@ -50,7 +50,7 @@ class Dashboard extends ImmutablePureComponent {
intl: PropTypes.object.isRequired,
instance: ImmutablePropTypes.map.isRequired,
supportsEmailList: PropTypes.bool,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
};
handleSubscribersClick = e => {

View file

@ -49,7 +49,7 @@ export default @connect(makeMapStateToProps, mapDispatchToProps)
class Account extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
apId: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
onAdd: PropTypes.func.isRequired,

View file

@ -36,7 +36,7 @@ class Account extends ImmutablePureComponent {
static propTypes = {
accountId: PropTypes.string.isRequired,
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
};
static defaultProps = {

View file

@ -256,8 +256,6 @@ class PrivacyDropdown extends React.PureComponent {
className='text-gray-400 hover:text-gray-600'
src={valueOption.icon}
title={intl.formatMessage(messages.change_privacy)}
expanded={open}
active={open}
onClick={this.handleToggle}
onMouseDown={this.handleMouseDown}
onKeyDown={this.handleButtonKeyDown}

View file

@ -12,7 +12,7 @@ import { isRtl } from '../../../rtl';
export default class ReplyIndicator extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
onCancel: PropTypes.func.isRequired,
hideActions: PropTypes.bool,
};

View file

@ -40,7 +40,7 @@ class CreateApp extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
defaultScopes: PropTypes.string,
}

View file

@ -34,7 +34,7 @@ class AccountCard extends ImmutablePureComponent {
static propTypes = {
me: SoapboxPropTypes.me,
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
autoPlayGif: PropTypes.bool,
};

View file

@ -39,7 +39,7 @@ const ProfilePreview = ({ account, displayFqn }) => (
);
ProfilePreview.propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
displayFqn: PropTypes.bool,
};

View file

@ -88,7 +88,7 @@ class EditProfile extends ImmutablePureComponent {
static propTypes = {
dispatch: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
maxFields: PropTypes.number,
verifiedCanEditName: PropTypes.bool,
};

View file

@ -30,7 +30,7 @@ export default @connect(makeMapStateToProps)
class Account extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
intl: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
};

View file

@ -18,7 +18,7 @@ export default @injectIntl
class AccountAuthorize extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
onAuthorize: PropTypes.func.isRequired,
onReject: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,

View file

@ -35,7 +35,7 @@ class GroupTimeline extends React.PureComponent {
hasUnread: PropTypes.bool,
group: PropTypes.oneOfType([ImmutablePropTypes.map, PropTypes.bool]),
relationships: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
intl: PropTypes.object.isRequired,
};

View file

@ -24,7 +24,7 @@ export default @connect(makeMapStateToProps)
class Account extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
};
render() {

View file

@ -51,7 +51,7 @@ class ListAdder extends ImmutablePureComponent {
onInitialize: PropTypes.func.isRequired,
onReset: PropTypes.func.isRequired,
listIds: ImmutablePropTypes.list.isRequired,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
};
componentDidMount() {

View file

@ -37,7 +37,7 @@ export default @connect(makeMapStateToProps, mapDispatchToProps)
class Account extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
intl: PropTypes.object.isRequired,
onRemove: PropTypes.func.isRequired,
onAdd: PropTypes.func.isRequired,

View file

@ -18,7 +18,7 @@ export default @injectIntl
class FollowRequest extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
onAuthorize: PropTypes.func.isRequired,
onReject: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,

View file

@ -228,7 +228,7 @@ const Notification = (props) => {
Notification.propTypes = {
hidden: PropTypes.bool,
notification: ImmutablePropTypes.map.isRequired,
notification: ImmutablePropTypes.record.isRequired,
onMoveUp: PropTypes.func.isRequired,
onMoveDown: PropTypes.func.isRequired,
onMention: PropTypes.func.isRequired,

View file

@ -11,7 +11,7 @@ import { MediaGallery, Video, Audio } from '../../ui/util/async-components';
export default class StatusCheckBox extends React.PureComponent {
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.record.isRequired,
checked: PropTypes.bool,
onToggle: PropTypes.func.isRequired,
disabled: PropTypes.bool,

View file

@ -48,7 +48,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
class ScheduledStatusActionBar extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.record.isRequired,
intl: PropTypes.object.isRequired,
me: SoapboxPropTypes.me,
onCancelClick: PropTypes.func.isRequired,

View file

@ -84,7 +84,7 @@ const mapDispatchToProps = (dispatch, { status }) => ({
class ActionBar extends React.PureComponent {
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.record.isRequired,
onReply: PropTypes.func.isRequired,
onReblog: PropTypes.func.isRequired,
onQuote: PropTypes.func.isRequired,

View file

@ -61,7 +61,7 @@ const addAutoPlay = html => {
export default class Card extends React.PureComponent {
static propTypes = {
card: ImmutablePropTypes.map,
card: ImmutablePropTypes.record,
maxDescription: PropTypes.number,
onOpenMedia: PropTypes.func.isRequired,
compact: PropTypes.bool,

View file

@ -27,7 +27,7 @@ export default @injectIntl
class DetailedStatus extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
onOpenMedia: PropTypes.func.isRequired,
onOpenVideo: PropTypes.func.isRequired,
onToggleHidden: PropTypes.func.isRequired,

View file

@ -20,7 +20,7 @@ export default @injectIntl @withRouter
class QuotedStatus extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
onCancel: PropTypes.func,
intl: PropTypes.object.isRequired,
compose: PropTypes.bool,

View file

@ -55,7 +55,7 @@ export default @connect(mapStateToProps, mapDispatchToProps)
class StatusInteractionBar extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
me: SoapboxPropTypes.me,
allowedEmoji: ImmutablePropTypes.list,
features: PropTypes.object.isRequired,

View file

@ -165,7 +165,7 @@ class Status extends ImmutablePureComponent {
static propTypes = {
params: PropTypes.object.isRequired,
dispatch: PropTypes.func.isRequired,
status: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
ancestorsIds: ImmutablePropTypes.orderedSet,
descendantsIds: ImmutablePropTypes.orderedSet,
intl: PropTypes.object.isRequired,

View file

@ -68,7 +68,7 @@ export default @connect(mapStateToProps, mapDispatchToProps)
class ActionButton extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
onFollow: PropTypes.func.isRequired,
onBlock: PropTypes.func.isRequired,
onOpenUnauthorizedModal: PropTypes.func.isRequired,

View file

@ -74,7 +74,7 @@ const ActionsModal = ({ status, actions, onClick, onClose }) => {
};
ActionsModal.propTypes = {
status: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
actions: PropTypes.array,
onClick: PropTypes.func,
onClose: PropTypes.func.isRequired,

View file

@ -18,7 +18,7 @@ export default @injectIntl @withRouter
class BoostModal extends ImmutablePureComponent {
static propTypes = {
status: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.record.isRequired,
onReblog: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,

View file

@ -29,7 +29,7 @@ const mapStateToProps = state => {
class ComposeModal extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
intl: PropTypes.object.isRequired,
onClose: PropTypes.func.isRequired,
composeText: PropTypes.string,

View file

@ -6,10 +6,11 @@ import { connect } from 'react-redux';
import { Link } from 'react-router-dom';
import { logOut } from 'soapbox/actions/auth';
import { getSoapboxConfig } from 'soapbox/actions/soapbox';
import { Text } from 'soapbox/components/ui';
import emojify from 'soapbox/features/emoji/emoji';
import { getBaseURL } from 'soapbox/utils/accounts';
// import sourceCode from 'soapbox/utils/code';
import sourceCode from 'soapbox/utils/code';
import { getFeatures } from 'soapbox/utils/features';
import { openModal } from '../../../actions/modals';
@ -19,9 +20,11 @@ const mapStateToProps = state => {
const account = state.getIn(['accounts', me]);
const instance = state.get('instance');
const features = getFeatures(instance);
const soapboxConfig = getSoapboxConfig(state);
return {
account,
soapboxConfig,
profileDirectory: features.profileDirectory,
federating: features.federating,
showAliases: features.accountAliasesAPI,
@ -41,7 +44,7 @@ const mapDispatchToProps = (dispatch, { intl }) => ({
},
});
const LinkFooter = ({ onOpenHotkeys, account, profileDirectory, federating, showAliases, importAPI, onClickLogOut, baseURL }) => (
const LinkFooter = ({ onOpenHotkeys, account, profileDirectory, federating, showAliases, importAPI, onClickLogOut, baseURL, soapboxConfig }) => (
<div className='space-y-2'>
<ul className='flex flex-wrap items-center divide-x-dot'>
{account && <>
@ -68,7 +71,13 @@ const LinkFooter = ({ onOpenHotkeys, account, profileDirectory, federating, show
</ul>
<Text theme='muted' size='sm'>
{/*<FormattedMessage
{soapboxConfig.get('linkFooterMessage') ? (
<span
className='inline-block align-middle'
dangerouslySetInnerHTML={{ __html: emojify(soapboxConfig.get('linkFooterMessage')) }}
/>
) : (
<FormattedMessage
id='getting_started.open_source_notice'
defaultMessage='{code_name} is open source software. You can contribute or report issues at {code_link} (v{code_version}).'
values={{
@ -76,18 +85,15 @@ const LinkFooter = ({ onOpenHotkeys, account, profileDirectory, federating, show
code_link: <a href={sourceCode.url} rel='noopener' target='_blank'>{sourceCode.repository}</a>,
code_version: sourceCode.version,
}}
/>*/}
<FormattedMessage
id='link_footer.made_in_usa'
defaultMessage='Proudly made in the United States of America. {emoji}'
values={{ emoji: <span className='inline-block align-middle' dangerouslySetInnerHTML={{ __html: emojify('🇺🇸') }} /> }}
/>
)}
</Text>
</div>
);
LinkFooter.propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
soapboxConfig: ImmutablePropTypes.map,
profileDirectory: PropTypes.bool,
federating: PropTypes.bool,
showAliases: PropTypes.bool,

View file

@ -26,8 +26,8 @@ class MediaModal extends ImmutablePureComponent {
static propTypes = {
media: ImmutablePropTypes.list.isRequired,
status: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
account: ImmutablePropTypes.record,
index: PropTypes.number.isRequired,
onClose: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,

View file

@ -116,7 +116,7 @@ const ProfileDropdown: React.FC<IProfileDropdown> = ({ account, children }) => {
const itemProps = menuItem.action ? { onSelect: menuItem.action } : { to: menuItem.to, as: Link };
return (
<Comp key={idx} {...itemProps}>
<Comp key={idx} {...itemProps} className='truncate'>
{menuItem.text}
</Comp>
);

View file

@ -37,7 +37,7 @@ const messages = defineMessages({
class ProfileInfoPanel extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
identity_proofs: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired,
username: PropTypes.string,

View file

@ -16,7 +16,7 @@ import MediaItem from '../../account_gallery/components/media_item';
class ProfileMediaPanel extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
attachments: ImmutablePropTypes.list,
dispatch: PropTypes.func.isRequired,
};

View file

@ -18,7 +18,7 @@ class ProfileStats extends React.PureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
className: PropTypes.string,
onClickHandler: PropTypes.func,
}

View file

@ -53,7 +53,7 @@ class ReportModal extends ImmutablePureComponent {
static propTypes = {
isSubmitting: PropTypes.bool,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
statusIds: ImmutablePropTypes.orderedSet.isRequired,
comment: PropTypes.string.isRequired,
forward: PropTypes.bool,

View file

@ -49,7 +49,7 @@ export default @connect(mapStateToProps, mapDispatchToProps)
class SubscriptionButton extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
features: PropTypes.object.isRequired,
};

View file

@ -19,7 +19,7 @@ import { makeGetAccount } from '../../../selectors';
class UserPanel extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
displayFqn: PropTypes.bool,
intl: PropTypes.object.isRequired,
domain: PropTypes.string,

View file

@ -12,8 +12,8 @@ class VideoModal extends ImmutablePureComponent {
static propTypes = {
media: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.map,
account: ImmutablePropTypes.map,
status: ImmutablePropTypes.record,
account: ImmutablePropTypes.record,
time: PropTypes.number,
onClose: PropTypes.func.isRequired,
history: PropTypes.object,

View file

@ -40,7 +40,7 @@ class WelcomeButton extends ImmutablePureComponent {
static propTypes = {
intl: PropTypes.object.isRequired,
account: ImmutablePropTypes.map.isRequired,
account: ImmutablePropTypes.record.isRequired,
onClick: PropTypes.func.isRequired,
};

View file

@ -30,7 +30,7 @@ class WrappedRoute extends React.Component {
content: PropTypes.node,
componentParams: PropTypes.object,
layout: PropTypes.object,
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
settings: ImmutablePropTypes.map.isRequired,
publicRoute: PropTypes.bool,
staffOnly: PropTypes.bool,

View file

@ -1 +1,2 @@
export { useAppSelector } from './useAppSelector';
export { useOnScreen } from './useOnScreen';

View file

@ -0,0 +1,19 @@
import * as React from 'react';
export const useOnScreen = (ref: React.MutableRefObject<HTMLElement>) => {
const [isIntersecting, setIntersecting] = React.useState(false);
const observer = new IntersectionObserver(
([entry]) => setIntersecting(entry.isIntersecting),
);
React.useEffect(() => {
observer.observe(ref.current);
return () => {
observer.disconnect();
};
}, []);
return isIntersecting;
};

View file

@ -20,7 +20,7 @@ export default @connect(mapStateToProps)
class GroupsPage extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
};
render() {

View file

@ -68,7 +68,7 @@ export default @connect(mapStateToProps)
class ProfilePage extends ImmutablePureComponent {
static propTypes = {
account: ImmutablePropTypes.map,
account: ImmutablePropTypes.record,
accountUsername: PropTypes.string.isRequired,
displayFqn: PropTypes.bool,
features: PropTypes.object,

View file

@ -40,7 +40,7 @@
}
.notification-bar-wrapper {
@apply p-4 flex items-start;
@apply p-4 flex items-center justify-between w-full space-x-2;
}
.notification-bar-title {
@ -50,3 +50,10 @@
.notification-bar-message {
@apply text-sm text-gray-700;
}
.notification-bar-action a {
@apply inline-flex items-center px-2.5 py-1 border border-solid border-gray-300
shadow-sm text-xs font-medium rounded-full text-gray-700 bg-white
hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2
focus:ring-primary-500;
}