Focus on selected status in status list, add moveUp/moveDown hotkeys to tombstone
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
666c2dd0ce
commit
d4cc2ab29b
3 changed files with 38 additions and 16 deletions
|
@ -1,4 +1,3 @@
|
||||||
import { List as ImmutableList } from 'immutable';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { FormattedList, FormattedMessage } from 'react-intl';
|
import { FormattedList, FormattedMessage } from 'react-intl';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
@ -7,7 +6,7 @@ import { openModal } from 'soapbox/actions/modals';
|
||||||
import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper';
|
import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper';
|
||||||
import { useAppDispatch } from 'soapbox/hooks';
|
import { useAppDispatch } from 'soapbox/hooks';
|
||||||
|
|
||||||
import type { Status } from 'soapbox/types/entities';
|
import type { Account, Status } from 'soapbox/types/entities';
|
||||||
|
|
||||||
interface IStatusReplyMentions {
|
interface IStatusReplyMentions {
|
||||||
status: Status,
|
status: Status,
|
||||||
|
@ -19,17 +18,19 @@ const StatusReplyMentions: React.FC<IStatusReplyMentions> = ({ status }) => {
|
||||||
const handleOpenMentionsModal: React.MouseEventHandler<HTMLSpanElement> = (e) => {
|
const handleOpenMentionsModal: React.MouseEventHandler<HTMLSpanElement> = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
|
const account = status.account as Account;
|
||||||
|
|
||||||
dispatch(openModal('MENTIONS', {
|
dispatch(openModal('MENTIONS', {
|
||||||
username: status.getIn(['account', 'acct']),
|
username: account.acct,
|
||||||
statusId: status.get('id'),
|
statusId: status.id,
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!status.get('in_reply_to_id')) {
|
if (!status.in_reply_to_id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const to = status.get('mentions', ImmutableList());
|
const to = status.mentions;
|
||||||
|
|
||||||
// The post is a reply, but it has no mentions.
|
// The post is a reply, but it has no mentions.
|
||||||
// Rare, but it can happen.
|
// Rare, but it can happen.
|
||||||
|
@ -46,14 +47,14 @@ const StatusReplyMentions: React.FC<IStatusReplyMentions> = ({ status }) => {
|
||||||
|
|
||||||
// The typical case with a reply-to and a list of mentions.
|
// The typical case with a reply-to and a list of mentions.
|
||||||
const accounts = to.slice(0, 2).map(account => (
|
const accounts = to.slice(0, 2).map(account => (
|
||||||
<HoverRefWrapper accountId={account.get('id')} inline>
|
<HoverRefWrapper key={account.id} accountId={account.id} inline>
|
||||||
<Link to={`/@${account.get('acct')}`} className='reply-mentions__account'>@{account.get('username')}</Link>
|
<Link to={`/@${account.acct}`} className='reply-mentions__account'>@{account.username}</Link>
|
||||||
</HoverRefWrapper>
|
</HoverRefWrapper>
|
||||||
)).toArray();
|
)).toArray();
|
||||||
|
|
||||||
if (to.size > 2) {
|
if (to.size > 2) {
|
||||||
accounts.push(
|
accounts.push(
|
||||||
<span className='hover:underline cursor-pointer' role='presentation' onClick={handleOpenMentionsModal}>
|
<span key='more' className='hover:underline cursor-pointer' role='presentation' onClick={handleOpenMentionsModal}>
|
||||||
<FormattedMessage id='reply_mentions.more' defaultMessage='{count} more' values={{ count: to.size - 2 }} />
|
<FormattedMessage id='reply_mentions.more' defaultMessage='{count} more' values={{ count: to.size - 2 }} />
|
||||||
</span>,
|
</span>,
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,16 +1,30 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { HotKeys } from 'react-hotkeys';
|
||||||
import { FormattedMessage } from 'react-intl';
|
import { FormattedMessage } from 'react-intl';
|
||||||
|
|
||||||
import { Text } from 'soapbox/components/ui';
|
import { Text } from 'soapbox/components/ui';
|
||||||
|
|
||||||
|
interface ITombstone {
|
||||||
|
id: string,
|
||||||
|
onMoveUp: (statusId: string) => void,
|
||||||
|
onMoveDown: (statusId: string) => void,
|
||||||
|
}
|
||||||
|
|
||||||
/** Represents a deleted item. */
|
/** Represents a deleted item. */
|
||||||
const Tombstone: React.FC = () => {
|
const Tombstone: React.FC<ITombstone> = ({ id, onMoveUp, onMoveDown }) => {
|
||||||
|
const handlers = {
|
||||||
|
moveUp: () => onMoveUp(id),
|
||||||
|
moveDown: () => onMoveDown(id),
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='p-9 flex items-center justify-center sm:rounded-xl bg-gray-100 border border-solid border-gray-200 dark:bg-slate-900 dark:border-slate-700'>
|
<HotKeys handlers={handlers}>
|
||||||
|
<div className='p-9 flex items-center justify-center sm:rounded-xl bg-gray-100 border border-solid border-gray-200 dark:bg-slate-900 dark:border-slate-700 focusable' tabIndex={0}>
|
||||||
<Text>
|
<Text>
|
||||||
<FormattedMessage id='statuses.tombstone' defaultMessage='One or more posts is unavailable.' />
|
<FormattedMessage id='statuses.tombstone' defaultMessage='One or more posts is unavailable.' />
|
||||||
</Text>
|
</Text>
|
||||||
</div>
|
</div>
|
||||||
|
</HotKeys>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -561,7 +561,12 @@ class Status extends ImmutablePureComponent<IStatus, IStatusState> {
|
||||||
renderTombstone(id: string) {
|
renderTombstone(id: string) {
|
||||||
return (
|
return (
|
||||||
<div className='py-4 pb-8'>
|
<div className='py-4 pb-8'>
|
||||||
<Tombstone key={id} />
|
<Tombstone
|
||||||
|
key={id}
|
||||||
|
id={id}
|
||||||
|
onMoveUp={this.handleMoveUp}
|
||||||
|
onMoveDown={this.handleMoveDown}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -635,6 +640,8 @@ class Status extends ImmutablePureComponent<IStatus, IStatusState> {
|
||||||
index: this.props.ancestorsIds.size,
|
index: this.props.ancestorsIds.size,
|
||||||
offset: -80,
|
offset: -80,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
setImmediate(() => this.status?.querySelector('a')?.focus());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue