Merge commit 'cfb473c204
' into upstream-20250228
This commit is contained in:
commit
795561f5a7
78 changed files with 1684 additions and 1081 deletions
|
@ -14,6 +14,9 @@ const isHashtagClick = (element: HTMLAnchorElement) =>
|
|||
element.textContent?.[0] === '#' ||
|
||||
element.previousSibling?.textContent?.endsWith('#');
|
||||
|
||||
const isFeaturedHashtagClick = (element: HTMLAnchorElement) =>
|
||||
isHashtagClick(element) && element.href.includes('/tagged/');
|
||||
|
||||
export const useLinks = () => {
|
||||
const history = useHistory();
|
||||
const dispatch = useAppDispatch();
|
||||
|
@ -29,6 +32,19 @@ export const useLinks = () => {
|
|||
[history],
|
||||
);
|
||||
|
||||
const handleFeaturedHashtagClick = useCallback(
|
||||
(element: HTMLAnchorElement) => {
|
||||
const { textContent, href } = element;
|
||||
|
||||
if (!textContent) return;
|
||||
|
||||
const url = new URL(href);
|
||||
|
||||
history.push(url.pathname);
|
||||
},
|
||||
[history],
|
||||
);
|
||||
|
||||
const handleMentionClick = useCallback(
|
||||
async (element: HTMLAnchorElement) => {
|
||||
const result = await dispatch(openURL({ url: element.href }));
|
||||
|
@ -61,12 +77,15 @@ export const useLinks = () => {
|
|||
if (isMentionClick(target)) {
|
||||
e.preventDefault();
|
||||
void handleMentionClick(target);
|
||||
} else if (isFeaturedHashtagClick(target)) {
|
||||
e.preventDefault();
|
||||
handleFeaturedHashtagClick(target);
|
||||
} else if (isHashtagClick(target)) {
|
||||
e.preventDefault();
|
||||
handleHashtagClick(target);
|
||||
}
|
||||
},
|
||||
[handleMentionClick, handleHashtagClick],
|
||||
[handleMentionClick, handleFeaturedHashtagClick, handleHashtagClick],
|
||||
);
|
||||
|
||||
return handleClick;
|
||||
|
|
|
@ -142,6 +142,13 @@ export function fetchAccountFail(id, error) {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} id
|
||||
* @param {Object} options
|
||||
* @param {boolean} [options.reblogs]
|
||||
* @param {boolean} [options.notify]
|
||||
* @returns {function(): void}
|
||||
*/
|
||||
export function followAccount(id, options = { reblogs: true }) {
|
||||
return (dispatch, getState) => {
|
||||
const alreadyFollowing = getState().getIn(['relationships', id, 'following']);
|
||||
|
|
|
@ -55,7 +55,7 @@ export const FollowButton: React.FC<{
|
|||
);
|
||||
}
|
||||
|
||||
if (!relationship) return;
|
||||
if (!relationship || !accountId) return;
|
||||
|
||||
if (accountId === me) {
|
||||
return;
|
||||
|
|
|
@ -1,566 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { NavLink, withRouter } from 'react-router-dom';
|
||||
|
||||
import { isFulfilled, isRejected } from '@reduxjs/toolkit';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
import CheckIcon from '@/material-icons/400-24px/check.svg?react';
|
||||
import LockIcon from '@/material-icons/400-24px/lock.svg?react';
|
||||
import MoreHorizIcon from '@/material-icons/400-24px/more_horiz.svg?react';
|
||||
import NotificationsIcon from '@/material-icons/400-24px/notifications.svg?react';
|
||||
import NotificationsActiveIcon from '@/material-icons/400-24px/notifications_active-fill.svg?react';
|
||||
import ShareIcon from '@/material-icons/400-24px/share.svg?react';
|
||||
import { Avatar } from 'mastodon/components/avatar';
|
||||
import { Badge, AutomatedBadge, GroupBadge } from 'mastodon/components/badge';
|
||||
import { Button } from 'mastodon/components/button';
|
||||
import { CopyIconButton } from 'mastodon/components/copy_icon_button';
|
||||
import { FollowersCounter, FollowingCounter, StatusesCounter } from 'mastodon/components/counters';
|
||||
import { getFeaturedHashtagBar } from 'mastodon/components/hashtag_bar';
|
||||
import { Icon } from 'mastodon/components/icon';
|
||||
import { IconButton } from 'mastodon/components/icon_button';
|
||||
import { LoadingIndicator } from 'mastodon/components/loading_indicator';
|
||||
import { ShortNumber } from 'mastodon/components/short_number';
|
||||
import DropdownMenuContainer from 'mastodon/containers/dropdown_menu_container';
|
||||
import { identityContextPropShape, withIdentity } from 'mastodon/identity_context';
|
||||
import { autoPlayGif, me, domain as localDomain, isShowItem } from 'mastodon/initial_state';
|
||||
import { PERMISSION_MANAGE_USERS, PERMISSION_MANAGE_FEDERATION } from 'mastodon/permissions';
|
||||
import { WithRouterPropTypes } from 'mastodon/utils/react_router';
|
||||
|
||||
import AccountNoteContainer from '../containers/account_note_container';
|
||||
import FollowRequestNoteContainer from '../containers/follow_request_note_container';
|
||||
|
||||
import { DomainPill } from './domain_pill';
|
||||
|
||||
const messages = defineMessages({
|
||||
unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
|
||||
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
||||
followBack: { id: 'account.follow_back', defaultMessage: 'Follow back' },
|
||||
mutual: { id: 'account.mutual', defaultMessage: 'Mutual' },
|
||||
cancel_follow_request: { id: 'account.cancel_follow_request', defaultMessage: 'Withdraw follow request' },
|
||||
requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' },
|
||||
unblock: { id: 'account.unblock', defaultMessage: 'Unblock @{name}' },
|
||||
edit_profile: { id: 'account.edit_profile', defaultMessage: 'Edit profile' },
|
||||
linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
|
||||
account_locked: { id: 'account.locked_info', defaultMessage: 'This account privacy status is set to locked. The owner manually reviews who can follow them.' },
|
||||
mention: { id: 'account.mention', defaultMessage: 'Mention @{name}' },
|
||||
direct: { id: 'account.direct', defaultMessage: 'Privately mention @{name}' },
|
||||
unmute: { id: 'account.unmute', defaultMessage: 'Unmute @{name}' },
|
||||
block: { id: 'account.block', defaultMessage: 'Block @{name}' },
|
||||
mute: { id: 'account.mute', defaultMessage: 'Mute @{name}' },
|
||||
report: { id: 'account.report', defaultMessage: 'Report @{name}' },
|
||||
share: { id: 'account.share', defaultMessage: 'Share @{name}\'s profile' },
|
||||
copy: { id: 'account.copy', defaultMessage: 'Copy link to profile' },
|
||||
media: { id: 'account.media', defaultMessage: 'Media' },
|
||||
blockDomain: { id: 'account.block_domain', defaultMessage: 'Block domain {domain}' },
|
||||
unblockDomain: { id: 'account.unblock_domain', defaultMessage: 'Unblock domain {domain}' },
|
||||
hideReblogs: { id: 'account.hide_reblogs', defaultMessage: 'Hide boosts from @{name}' },
|
||||
showReblogs: { id: 'account.show_reblogs', defaultMessage: 'Show boosts from @{name}' },
|
||||
enableNotifications: { id: 'account.enable_notifications', defaultMessage: 'Notify me when @{name} posts' },
|
||||
disableNotifications: { id: 'account.disable_notifications', defaultMessage: 'Stop notifying me when @{name} posts' },
|
||||
pins: { id: 'navigation_bar.pins', defaultMessage: 'Pinned posts' },
|
||||
preferences: { id: 'navigation_bar.preferences', defaultMessage: 'Preferences' },
|
||||
follow_requests: { id: 'navigation_bar.follow_requests', defaultMessage: 'Follow requests' },
|
||||
favourites: { id: 'navigation_bar.favourites', defaultMessage: 'Favorites' },
|
||||
lists: { id: 'navigation_bar.lists', defaultMessage: 'Lists' },
|
||||
followed_tags: { id: 'navigation_bar.followed_tags', defaultMessage: 'Followed hashtags' },
|
||||
blocks: { id: 'navigation_bar.blocks', defaultMessage: 'Blocked users' },
|
||||
domain_blocks: { id: 'navigation_bar.domain_blocks', defaultMessage: 'Blocked domains' },
|
||||
mutes: { id: 'navigation_bar.mutes', defaultMessage: 'Muted users' },
|
||||
endorse: { id: 'account.endorse', defaultMessage: 'Feature on profile' },
|
||||
unendorse: { id: 'account.unendorse', defaultMessage: 'Don\'t feature on profile' },
|
||||
add_or_remove_from_list: { id: 'account.add_or_remove_from_list', defaultMessage: 'Add or Remove from lists' },
|
||||
add_or_remove_from_antenna: { id: 'account.add_or_remove_from_antenna', defaultMessage: 'Add or Remove from antennas' },
|
||||
add_or_remove_from_exclude_antenna: { id: 'account.add_or_remove_from_exclude_antenna', defaultMessage: 'Add or Remove from antennas as exclusion' },
|
||||
add_or_remove_from_circle: { id: 'account.add_or_remove_from_circle', defaultMessage: 'Add or Remove from circles' },
|
||||
admin_account: { id: 'status.admin_account', defaultMessage: 'Open moderation interface for @{name}' },
|
||||
admin_domain: { id: 'status.admin_domain', defaultMessage: 'Open moderation interface for {domain}' },
|
||||
languages: { id: 'account.languages', defaultMessage: 'Change subscribed languages' },
|
||||
openOriginalPage: { id: 'account.open_original_page', defaultMessage: 'Open original page' },
|
||||
});
|
||||
|
||||
const titleFromAccount = account => {
|
||||
const displayName = account.get('display_name');
|
||||
const acct = account.get('acct') === account.get('username') ? `${account.get('username')}@${localDomain}` : account.get('acct');
|
||||
const prefix = displayName.trim().length === 0 ? account.get('username') : displayName;
|
||||
|
||||
return `${prefix} (@${acct})`;
|
||||
};
|
||||
|
||||
const messageForFollowButton = relationship => {
|
||||
if(!relationship) return messages.follow;
|
||||
|
||||
if (relationship.get('following') && relationship.get('followed_by') && isShowItem('relationships')) {
|
||||
return messages.mutual;
|
||||
} else if (relationship.get('following') || relationship.get('requested')) {
|
||||
return messages.unfollow;
|
||||
} else if (relationship.get('followed_by') && isShowItem('relationships')) {
|
||||
return messages.followBack;
|
||||
} else {
|
||||
return messages.follow;
|
||||
}
|
||||
};
|
||||
|
||||
const dateFormatOptions = {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
};
|
||||
|
||||
class Header extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
identity: identityContextPropShape,
|
||||
account: ImmutablePropTypes.record,
|
||||
featuredTags: PropTypes.array,
|
||||
identity_props: ImmutablePropTypes.list,
|
||||
onFollow: PropTypes.func.isRequired,
|
||||
onBlock: PropTypes.func.isRequired,
|
||||
onMention: PropTypes.func.isRequired,
|
||||
onDirect: PropTypes.func.isRequired,
|
||||
onReblogToggle: PropTypes.func.isRequired,
|
||||
onNotifyToggle: PropTypes.func.isRequired,
|
||||
onReport: PropTypes.func.isRequired,
|
||||
onMute: PropTypes.func.isRequired,
|
||||
onBlockDomain: PropTypes.func.isRequired,
|
||||
onUnblockDomain: PropTypes.func.isRequired,
|
||||
onEndorseToggle: PropTypes.func.isRequired,
|
||||
onAddToList: PropTypes.func.isRequired,
|
||||
onAddToAntenna: PropTypes.func.isRequired,
|
||||
onAddToExcludeAntenna: PropTypes.func.isRequired,
|
||||
onAddToCircle: PropTypes.func.isRequired,
|
||||
onEditAccountNote: PropTypes.func.isRequired,
|
||||
onChangeLanguages: PropTypes.func.isRequired,
|
||||
onInteractionModal: PropTypes.func.isRequired,
|
||||
onOpenAvatar: PropTypes.func.isRequired,
|
||||
onOpenURL: PropTypes.func.isRequired,
|
||||
intl: PropTypes.object.isRequired,
|
||||
domain: PropTypes.string.isRequired,
|
||||
hidden: PropTypes.bool,
|
||||
...WithRouterPropTypes,
|
||||
};
|
||||
|
||||
setRef = c => {
|
||||
this.node = c;
|
||||
};
|
||||
|
||||
openEditProfile = () => {
|
||||
window.open('/settings/profile', '_blank');
|
||||
};
|
||||
|
||||
isStatusesPageActive = (match, location) => {
|
||||
if (!match) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !location.pathname.match(/\/(followers|following)\/?$/);
|
||||
};
|
||||
|
||||
handleMouseEnter = ({ currentTarget }) => {
|
||||
if (autoPlayGif) {
|
||||
return;
|
||||
}
|
||||
|
||||
const emojis = currentTarget.querySelectorAll('.custom-emoji');
|
||||
|
||||
for (var i = 0; i < emojis.length; i++) {
|
||||
let emoji = emojis[i];
|
||||
emoji.src = emoji.getAttribute('data-original');
|
||||
}
|
||||
};
|
||||
|
||||
handleMouseLeave = ({ currentTarget }) => {
|
||||
if (autoPlayGif) {
|
||||
return;
|
||||
}
|
||||
|
||||
const emojis = currentTarget.querySelectorAll('.custom-emoji');
|
||||
|
||||
for (var i = 0; i < emojis.length; i++) {
|
||||
let emoji = emojis[i];
|
||||
emoji.src = emoji.getAttribute('data-static');
|
||||
}
|
||||
};
|
||||
|
||||
handleAvatarClick = e => {
|
||||
if (e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
this.props.onOpenAvatar();
|
||||
}
|
||||
};
|
||||
|
||||
handleShare = () => {
|
||||
const { account } = this.props;
|
||||
|
||||
navigator.share({
|
||||
url: account.get('url'),
|
||||
}).catch((e) => {
|
||||
if (e.name !== 'AbortError') console.error(e);
|
||||
});
|
||||
};
|
||||
|
||||
handleHashtagClick = e => {
|
||||
const { history } = this.props;
|
||||
const value = e.currentTarget.textContent.replace(/^#/, '');
|
||||
|
||||
if (history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
history.push(`/tags/${value}`);
|
||||
}
|
||||
};
|
||||
|
||||
handleFeaturedHashtagClick = e => {
|
||||
const { history, account } = this.props;
|
||||
const value = e.currentTarget.textContent.replace(/^#/, '');
|
||||
|
||||
if (history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
history.push(`/@${account.get('acct')}/tagged/${value}`);
|
||||
}
|
||||
};
|
||||
|
||||
handleMentionClick = e => {
|
||||
const { history, onOpenURL } = this.props;
|
||||
|
||||
if (history && e.button === 0 && !(e.ctrlKey || e.metaKey)) {
|
||||
e.preventDefault();
|
||||
|
||||
const link = e.currentTarget;
|
||||
|
||||
onOpenURL(link.href).then((result) => {
|
||||
if (isFulfilled(result)) {
|
||||
if (result.payload.accounts[0]) {
|
||||
history.push(`/@${result.payload.accounts[0].acct}`);
|
||||
} else if (result.payload.statuses[0]) {
|
||||
history.push(`/@${result.payload.statuses[0].account.acct}/${result.payload.statuses[0].id}`);
|
||||
} else {
|
||||
window.location = link.href;
|
||||
}
|
||||
} else if (isRejected(result)) {
|
||||
window.location = link.href;
|
||||
}
|
||||
}).catch(() => {
|
||||
// Nothing
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
_attachLinkEvents () {
|
||||
const node = this.node;
|
||||
|
||||
if (!node) {
|
||||
return;
|
||||
}
|
||||
|
||||
const links = node.querySelectorAll('a');
|
||||
|
||||
let link;
|
||||
|
||||
for (var i = 0; i < links.length; ++i) {
|
||||
link = links[i];
|
||||
|
||||
if (link.textContent[0] === '#' || (link.previousSibling && link.previousSibling.textContent && link.previousSibling.textContent[link.previousSibling.textContent.length - 1] === '#')) {
|
||||
if (link.href && link.href.includes('/tagged/')) {
|
||||
link.addEventListener('click', this.handleFeaturedHashtagClick, false);
|
||||
} else {
|
||||
link.addEventListener('click', this.handleHashtagClick, false);
|
||||
}
|
||||
} else if (link.classList.contains('mention')) {
|
||||
link.addEventListener('click', this.handleMentionClick, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount () {
|
||||
this._attachLinkEvents();
|
||||
}
|
||||
|
||||
componentDidUpdate () {
|
||||
this._attachLinkEvents();
|
||||
}
|
||||
|
||||
render () {
|
||||
const { account, hidden, intl } = this.props;
|
||||
const { signedIn, permissions } = this.props.identity;
|
||||
|
||||
if (!account) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const suspended = account.get('suspended');
|
||||
const isRemote = account.get('acct') !== account.get('username');
|
||||
const remoteDomain = isRemote ? account.get('acct').split('@')[1] : null;
|
||||
|
||||
let actionBtn, bellBtn, lockedIcon, shareBtn;
|
||||
|
||||
let info = [];
|
||||
let menu = [];
|
||||
|
||||
if (me !== account.get('id') && account.getIn(['relationship', 'blocking'])) {
|
||||
info.push(<span key='blocked' className='relationship-tag'><FormattedMessage id='account.blocked' defaultMessage='Blocked' /></span>);
|
||||
}
|
||||
|
||||
if (me !== account.get('id') && account.getIn(['relationship', 'muting'])) {
|
||||
info.push(<span key='muted' className='relationship-tag'><FormattedMessage id='account.muted' defaultMessage='Muted' /></span>);
|
||||
} else if (me !== account.get('id') && account.getIn(['relationship', 'domain_blocking'])) {
|
||||
info.push(<span key='domain_blocked' className='relationship-tag'><FormattedMessage id='account.domain_blocked' defaultMessage='Domain blocked' /></span>);
|
||||
}
|
||||
|
||||
if (account.getIn(['relationship', 'requested']) || account.getIn(['relationship', 'following'])) {
|
||||
bellBtn = <IconButton icon={account.getIn(['relationship', 'notifying']) ? 'bell' : 'bell-o'} iconComponent={account.getIn(['relationship', 'notifying']) ? NotificationsActiveIcon : NotificationsIcon} active={account.getIn(['relationship', 'notifying'])} title={intl.formatMessage(account.getIn(['relationship', 'notifying']) ? messages.disableNotifications : messages.enableNotifications, { name: account.get('username') })} onClick={this.props.onNotifyToggle} />;
|
||||
}
|
||||
|
||||
if ('share' in navigator) {
|
||||
shareBtn = <IconButton className='optional' iconComponent={ShareIcon} title={intl.formatMessage(messages.share, { name: account.get('username') })} onClick={this.handleShare} />;
|
||||
} else {
|
||||
shareBtn = <CopyIconButton className='optional' title={intl.formatMessage(messages.copy)} value={account.get('url')} />;
|
||||
}
|
||||
|
||||
if (me !== account.get('id')) {
|
||||
if (signedIn && !account.get('relationship')) { // Wait until the relationship is loaded
|
||||
actionBtn = <Button disabled><LoadingIndicator /></Button>;
|
||||
} else if (!account.getIn(['relationship', 'blocking'])) {
|
||||
actionBtn = <Button disabled={account.getIn(['relationship', 'blocked_by'])} className={classNames({ 'button--destructive': (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) })} text={intl.formatMessage(messageForFollowButton(account.get('relationship')))} onClick={signedIn ? this.props.onFollow : this.props.onInteractionModal} />;
|
||||
} else if (account.getIn(['relationship', 'blocking'])) {
|
||||
actionBtn = <Button text={intl.formatMessage(messages.unblock, { name: account.get('username') })} onClick={this.props.onBlock} />;
|
||||
}
|
||||
} else {
|
||||
actionBtn = <Button text={intl.formatMessage(messages.edit_profile)} onClick={this.openEditProfile} />;
|
||||
}
|
||||
|
||||
if (account.get('moved') && !account.getIn(['relationship', 'following'])) {
|
||||
actionBtn = '';
|
||||
}
|
||||
|
||||
if (account.get('locked')) {
|
||||
lockedIcon = <Icon id='lock' icon={LockIcon} title={intl.formatMessage(messages.account_locked)} />;
|
||||
}
|
||||
|
||||
if (signedIn && account.get('id') !== me && !account.get('suspended')) {
|
||||
menu.push({ text: intl.formatMessage(messages.mention, { name: account.get('username') }), action: this.props.onMention });
|
||||
menu.push({ text: intl.formatMessage(messages.direct, { name: account.get('username') }), action: this.props.onDirect });
|
||||
menu.push(null);
|
||||
}
|
||||
|
||||
if (isRemote) {
|
||||
menu.push({ text: intl.formatMessage(messages.openOriginalPage), href: account.get('url') });
|
||||
menu.push(null);
|
||||
}
|
||||
|
||||
if (account.get('id') === me) {
|
||||
menu.push({ text: intl.formatMessage(messages.edit_profile), href: '/settings/profile' });
|
||||
menu.push({ text: intl.formatMessage(messages.preferences), href: '/settings/preferences' });
|
||||
menu.push({ text: intl.formatMessage(messages.pins), to: '/pinned' });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.follow_requests), to: '/follow_requests' });
|
||||
menu.push({ text: intl.formatMessage(messages.favourites), to: '/favourites' });
|
||||
menu.push({ text: intl.formatMessage(messages.lists), to: '/lists' });
|
||||
menu.push({ text: intl.formatMessage(messages.followed_tags), to: '/followed_tags' });
|
||||
menu.push(null);
|
||||
menu.push({ text: intl.formatMessage(messages.mutes), to: '/mutes' });
|
||||
menu.push({ text: intl.formatMessage(messages.blocks), to: '/blocks' });
|
||||
menu.push({ text: intl.formatMessage(messages.domain_blocks), to: '/domain_blocks' });
|
||||
} else if (signedIn) {
|
||||
if (account.getIn(['relationship', 'following'])) {
|
||||
if (!account.getIn(['relationship', 'muting'])) {
|
||||
if (account.getIn(['relationship', 'showing_reblogs'])) {
|
||||
menu.push({ text: intl.formatMessage(messages.hideReblogs, { name: account.get('username') }), action: this.props.onReblogToggle });
|
||||
} else {
|
||||
menu.push({ text: intl.formatMessage(messages.showReblogs, { name: account.get('username') }), action: this.props.onReblogToggle });
|
||||
}
|
||||
|
||||
menu.push({ text: intl.formatMessage(messages.languages), action: this.props.onChangeLanguages });
|
||||
menu.push(null);
|
||||
}
|
||||
|
||||
menu.push({ text: intl.formatMessage(account.getIn(['relationship', 'endorsed']) ? messages.unendorse : messages.endorse), action: this.props.onEndorseToggle });
|
||||
menu.push({ text: intl.formatMessage(messages.add_or_remove_from_list), action: this.props.onAddToList });
|
||||
}
|
||||
menu.push({ text: intl.formatMessage(messages.add_or_remove_from_antenna), action: this.props.onAddToAntenna });
|
||||
menu.push({ text: intl.formatMessage(messages.add_or_remove_from_exclude_antenna), action: this.props.onAddToExcludeAntenna });
|
||||
if (account.getIn(['relationship', 'followed_by'])) {
|
||||
menu.push({ text: intl.formatMessage(messages.add_or_remove_from_circle), action: this.props.onAddToCircle });
|
||||
}
|
||||
menu.push(null);
|
||||
|
||||
if (account.getIn(['relationship', 'muting'])) {
|
||||
menu.push({ text: intl.formatMessage(messages.unmute, { name: account.get('username') }), action: this.props.onMute });
|
||||
} else {
|
||||
menu.push({ text: intl.formatMessage(messages.mute, { name: account.get('username') }), action: this.props.onMute, dangerous: true });
|
||||
}
|
||||
|
||||
if (account.getIn(['relationship', 'blocking'])) {
|
||||
menu.push({ text: intl.formatMessage(messages.unblock, { name: account.get('username') }), action: this.props.onBlock });
|
||||
} else {
|
||||
menu.push({ text: intl.formatMessage(messages.block, { name: account.get('username') }), action: this.props.onBlock, dangerous: true });
|
||||
}
|
||||
|
||||
if (!account.get('suspended')) {
|
||||
menu.push({ text: intl.formatMessage(messages.report, { name: account.get('username') }), action: this.props.onReport, dangerous: true });
|
||||
}
|
||||
}
|
||||
|
||||
if (signedIn && isRemote) {
|
||||
menu.push(null);
|
||||
|
||||
if (account.getIn(['relationship', 'domain_blocking'])) {
|
||||
menu.push({ text: intl.formatMessage(messages.unblockDomain, { domain: remoteDomain }), action: this.props.onUnblockDomain });
|
||||
} else {
|
||||
menu.push({ text: intl.formatMessage(messages.blockDomain, { domain: remoteDomain }), action: this.props.onBlockDomain, dangerous: true });
|
||||
}
|
||||
}
|
||||
|
||||
if ((account.get('id') !== me && (permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) || (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION)) {
|
||||
menu.push(null);
|
||||
if ((permissions & PERMISSION_MANAGE_USERS) === PERMISSION_MANAGE_USERS) {
|
||||
menu.push({ text: intl.formatMessage(messages.admin_account, { name: account.get('username') }), href: `/admin/accounts/${account.get('id')}` });
|
||||
}
|
||||
if (isRemote && (permissions & PERMISSION_MANAGE_FEDERATION) === PERMISSION_MANAGE_FEDERATION) {
|
||||
menu.push({ text: intl.formatMessage(messages.admin_domain, { domain: remoteDomain }), href: `/admin/instances/${remoteDomain}` });
|
||||
}
|
||||
}
|
||||
|
||||
const content = { __html: account.get('note_emojified') };
|
||||
const displayNameHtml = { __html: account.get('display_name_html') };
|
||||
const fields = account.get('fields');
|
||||
const isLocal = account.get('acct').indexOf('@') === -1;
|
||||
const username = account.get('acct').split('@')[0];
|
||||
const domain = isLocal ? localDomain : account.get('acct').split('@')[1];
|
||||
const isIndexable = !account.get('noindex');
|
||||
const featuredTagsArr = this.props.featuredTags?.map((tag) => tag.get('name')).toArray() || [];
|
||||
const featuredTags = getFeaturedHashtagBar(account.get('acct'), featuredTagsArr);
|
||||
|
||||
const badges = [];
|
||||
|
||||
if (account.get('bot')) {
|
||||
badges.push(<AutomatedBadge key='bot-badge' />);
|
||||
} else if (account.get('group')) {
|
||||
badges.push(<GroupBadge key='group-badge' />);
|
||||
}
|
||||
|
||||
account.get('roles', []).forEach((role) => {
|
||||
badges.push(<Badge key={`role-badge-${role.get('id')}`} label={<span>{role.get('name')}</span>} domain={domain} roleId={role.get('id')} />);
|
||||
});
|
||||
|
||||
return (
|
||||
<div className={classNames('account__header', { inactive: !!account.get('moved') })} onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave}>
|
||||
{!(suspended || hidden || account.get('moved')) && account.getIn(['relationship', 'requested_by']) && <FollowRequestNoteContainer account={account} />}
|
||||
|
||||
<div className='account__header__image'>
|
||||
<div className='account__header__info'>
|
||||
{info}
|
||||
</div>
|
||||
|
||||
{!(suspended || hidden) && <img src={autoPlayGif ? account.get('header') : account.get('header_static')} alt='' className='parallax' />}
|
||||
</div>
|
||||
|
||||
<div className='account__header__bar'>
|
||||
<div className='account__header__tabs'>
|
||||
<a className='avatar' href={account.get('avatar')} rel='noopener' target='_blank' onClick={this.handleAvatarClick}>
|
||||
<Avatar account={suspended || hidden ? undefined : account} size={90} />
|
||||
</a>
|
||||
|
||||
<div className='account__header__tabs__buttons'>
|
||||
{!hidden && bellBtn}
|
||||
{!hidden && shareBtn}
|
||||
<DropdownMenuContainer disabled={menu.length === 0} items={menu} icon='ellipsis-v' iconComponent={MoreHorizIcon} size={24} direction='right' />
|
||||
{!hidden && actionBtn}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='account__header__tabs__name'>
|
||||
<h1>
|
||||
<span dangerouslySetInnerHTML={displayNameHtml} />
|
||||
<small>
|
||||
<span>@{username}<span className='invisible'>@{domain}</span></span>
|
||||
<DomainPill username={username} domain={domain} isSelf={me === account.get('id')} />
|
||||
{lockedIcon}
|
||||
</small>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{badges.length > 0 && (
|
||||
<div className='account__header__badges'>
|
||||
{badges}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!(suspended || hidden) && (
|
||||
<div className='account__header__extra'>
|
||||
<div className='account__header__bio' ref={this.setRef}>
|
||||
{(account.get('id') !== me && signedIn) && <AccountNoteContainer account={account} />}
|
||||
|
||||
{account.get('note').length > 0 && account.get('note') !== '<p></p>' && <div className='account__header__content translate' dangerouslySetInnerHTML={content} />}
|
||||
|
||||
{featuredTagsArr.length > 0 && (
|
||||
<div className='account__header__featured-tags'>
|
||||
{featuredTags}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='account__header__fields'>
|
||||
<dl>
|
||||
<dt><FormattedMessage id='account.joined_short' defaultMessage='Joined' /></dt>
|
||||
<dd>{intl.formatDate(account.get('created_at'), { year: 'numeric', month: 'short', day: '2-digit' })}</dd>
|
||||
</dl>
|
||||
|
||||
{fields.map((pair, i) => (
|
||||
<dl key={i} className={classNames({ verified: pair.get('verified_at') })}>
|
||||
<dt dangerouslySetInnerHTML={{ __html: pair.get('name_emojified') }} title={pair.get('name')} className='translate' />
|
||||
|
||||
<dd className='translate' title={pair.get('value_plain')}>
|
||||
{pair.get('verified_at') && <span title={intl.formatMessage(messages.linkVerifiedOn, { date: intl.formatDate(pair.get('verified_at'), dateFormatOptions) })}><Icon id='check' icon={CheckIcon} className='verified__mark' /></span>} <span dangerouslySetInnerHTML={{ __html: pair.get('value_emojified') }} />
|
||||
</dd>
|
||||
</dl>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='account__header__extra__links'>
|
||||
<NavLink isActive={this.isStatusesPageActive} activeClassName='active' to={`/@${account.get('acct')}`} title={intl.formatNumber(account.get('statuses_count'))}>
|
||||
<ShortNumber
|
||||
value={account.get('statuses_count')}
|
||||
isHide={account.getIn(['other_settings', 'hide_statuses_count']) || false}
|
||||
renderer={StatusesCounter}
|
||||
/>
|
||||
</NavLink>
|
||||
|
||||
<NavLink exact activeClassName='active' to={`/@${account.get('acct')}/following`} title={intl.formatNumber(account.get('following_count'))}>
|
||||
<ShortNumber
|
||||
value={account.get('following_count')}
|
||||
isHide={account.getIn(['other_settings', 'hide_following_count']) || false}
|
||||
renderer={FollowingCounter}
|
||||
/>
|
||||
</NavLink>
|
||||
|
||||
<NavLink exact activeClassName='active' to={`/@${account.get('acct')}/followers`} title={intl.formatNumber(account.get('followers_count'))}>
|
||||
<ShortNumber
|
||||
value={account.get('followers_count')}
|
||||
isHide={account.getIn(['other_settings', 'hide_followers_count']) || false}
|
||||
renderer={FollowersCounter}
|
||||
/>
|
||||
</NavLink>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Helmet>
|
||||
<title>{titleFromAccount(account)}</title>
|
||||
<meta name='robots' content={(isLocal && isIndexable) ? 'all' : 'noindex'} />
|
||||
<link rel='canonical' href={account.get('url')} />
|
||||
</Helmet>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default withRouter(withIdentity(injectIntl(Header)));
|
|
@ -17,7 +17,7 @@ import { normalizeForLookup } from 'mastodon/reducers/accounts_map';
|
|||
import { getAccountGallery } from 'mastodon/selectors';
|
||||
|
||||
import { expandAccountMediaTimeline } from '../../actions/timelines';
|
||||
import HeaderContainer from '../account_timeline/containers/header_container';
|
||||
import { AccountHeader } from '../account_timeline/components/account_header';
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
import { MediaItem } from './components/media_item';
|
||||
|
@ -207,7 +207,7 @@ class AccountGallery extends ImmutablePureComponent {
|
|||
|
||||
<ScrollContainer scrollKey='account_gallery'>
|
||||
<div className='scrollable scrollable--flex' onScroll={this.handleScroll}>
|
||||
<HeaderContainer accountId={this.props.accountId} />
|
||||
<AccountHeader accountId={this.props.accountId} />
|
||||
|
||||
{(suspended || blockedBy) ? (
|
||||
<div className='empty-column-indicator'>
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,175 +0,0 @@
|
|||
import PropTypes from 'prop-types';
|
||||
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { NavLink } from 'react-router-dom';
|
||||
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import ImmutablePureComponent from 'react-immutable-pure-component';
|
||||
|
||||
import InnerHeader from '../../account/components/header';
|
||||
|
||||
import MemorialNote from './memorial_note';
|
||||
import MovedNote from './moved_note';
|
||||
|
||||
class Header extends ImmutablePureComponent {
|
||||
|
||||
static propTypes = {
|
||||
account: ImmutablePropTypes.record,
|
||||
featuredTags: PropTypes.array,
|
||||
onFollow: PropTypes.func.isRequired,
|
||||
onBlock: PropTypes.func.isRequired,
|
||||
onMention: PropTypes.func.isRequired,
|
||||
onDirect: PropTypes.func.isRequired,
|
||||
onReblogToggle: PropTypes.func.isRequired,
|
||||
onReport: PropTypes.func.isRequired,
|
||||
onMute: PropTypes.func.isRequired,
|
||||
onBlockDomain: PropTypes.func.isRequired,
|
||||
onUnblockDomain: PropTypes.func.isRequired,
|
||||
onEndorseToggle: PropTypes.func.isRequired,
|
||||
onAddToList: PropTypes.func.isRequired,
|
||||
onAddToAntenna: PropTypes.func.isRequired,
|
||||
onAddToExcludeAntenna: PropTypes.func.isRequired,
|
||||
onAddToCircle: PropTypes.func.isRequired,
|
||||
onChangeLanguages: PropTypes.func.isRequired,
|
||||
onInteractionModal: PropTypes.func.isRequired,
|
||||
onOpenAvatar: PropTypes.func.isRequired,
|
||||
onOpenURL: PropTypes.func.isRequired,
|
||||
hideTabs: PropTypes.bool,
|
||||
domain: PropTypes.string.isRequired,
|
||||
hidden: PropTypes.bool,
|
||||
};
|
||||
|
||||
handleFollow = () => {
|
||||
this.props.onFollow(this.props.account);
|
||||
};
|
||||
|
||||
handleBlock = () => {
|
||||
this.props.onBlock(this.props.account);
|
||||
};
|
||||
|
||||
handleMention = () => {
|
||||
this.props.onMention(this.props.account);
|
||||
};
|
||||
|
||||
handleDirect = () => {
|
||||
this.props.onDirect(this.props.account);
|
||||
};
|
||||
|
||||
handleReport = () => {
|
||||
this.props.onReport(this.props.account);
|
||||
};
|
||||
|
||||
handleReblogToggle = () => {
|
||||
this.props.onReblogToggle(this.props.account);
|
||||
};
|
||||
|
||||
handleNotifyToggle = () => {
|
||||
this.props.onNotifyToggle(this.props.account);
|
||||
};
|
||||
|
||||
handleMute = () => {
|
||||
this.props.onMute(this.props.account);
|
||||
};
|
||||
|
||||
handleBlockDomain = () => {
|
||||
this.props.onBlockDomain(this.props.account);
|
||||
};
|
||||
|
||||
handleUnblockDomain = () => {
|
||||
const domain = this.props.account.get('acct').split('@')[1];
|
||||
|
||||
if (!domain) return;
|
||||
|
||||
this.props.onUnblockDomain(domain);
|
||||
};
|
||||
|
||||
handleEndorseToggle = () => {
|
||||
this.props.onEndorseToggle(this.props.account);
|
||||
};
|
||||
|
||||
handleAddToList = () => {
|
||||
this.props.onAddToList(this.props.account);
|
||||
};
|
||||
|
||||
handleAddToAntenna = () => {
|
||||
this.props.onAddToAntenna(this.props.account);
|
||||
};
|
||||
|
||||
handleAddToExcludeAntenna = () => {
|
||||
this.props.onAddToExcludeAntenna(this.props.account);
|
||||
};
|
||||
|
||||
handleAddToCircle = () => {
|
||||
this.props.onAddToCircle(this.props.account);
|
||||
};
|
||||
|
||||
handleEditAccountNote = () => {
|
||||
this.props.onEditAccountNote(this.props.account);
|
||||
};
|
||||
|
||||
handleChangeLanguages = () => {
|
||||
this.props.onChangeLanguages(this.props.account);
|
||||
};
|
||||
|
||||
handleInteractionModal = () => {
|
||||
this.props.onInteractionModal(this.props.account);
|
||||
};
|
||||
|
||||
handleOpenAvatar = () => {
|
||||
this.props.onOpenAvatar(this.props.account);
|
||||
};
|
||||
|
||||
render () {
|
||||
const { account, featuredTags, hidden, hideTabs } = this.props;
|
||||
|
||||
if (account === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='account-timeline__header'>
|
||||
{(!hidden && account.get('memorial')) && <MemorialNote />}
|
||||
{(!hidden && account.get('moved')) && <MovedNote from={account} to={account.get('moved')} />}
|
||||
|
||||
<InnerHeader
|
||||
account={account}
|
||||
featuredTags={featuredTags}
|
||||
onFollow={this.handleFollow}
|
||||
onBlock={this.handleBlock}
|
||||
onMention={this.handleMention}
|
||||
onDirect={this.handleDirect}
|
||||
onReblogToggle={this.handleReblogToggle}
|
||||
onNotifyToggle={this.handleNotifyToggle}
|
||||
onReport={this.handleReport}
|
||||
onMute={this.handleMute}
|
||||
onBlockDomain={this.handleBlockDomain}
|
||||
onUnblockDomain={this.handleUnblockDomain}
|
||||
onEndorseToggle={this.handleEndorseToggle}
|
||||
onAddToList={this.handleAddToList}
|
||||
onAddToAntenna={this.handleAddToAntenna}
|
||||
onAddToExcludeAntenna={this.handleAddToExcludeAntenna}
|
||||
onAddToCircle={this.handleAddToCircle}
|
||||
onEditAccountNote={this.handleEditAccountNote}
|
||||
onChangeLanguages={this.handleChangeLanguages}
|
||||
onInteractionModal={this.handleInteractionModal}
|
||||
onOpenAvatar={this.handleOpenAvatar}
|
||||
onOpenURL={this.props.onOpenURL}
|
||||
domain={this.props.domain}
|
||||
hidden={hidden}
|
||||
/>
|
||||
|
||||
{!(hideTabs || hidden) && (
|
||||
<div className='account__section-headline'>
|
||||
<NavLink exact to={`/@${account.get('acct')}`}><FormattedMessage id='account.posts' defaultMessage='Posts' /></NavLink>
|
||||
<NavLink exact to={`/@${account.get('acct')}/with_replies`}><FormattedMessage id='account.posts_with_replies' defaultMessage='Posts and replies' /></NavLink>
|
||||
<NavLink exact to={`/@${account.get('acct')}/media`}><FormattedMessage id='account.media' defaultMessage='Media' /></NavLink>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Header;
|
|
@ -1,183 +0,0 @@
|
|||
import { injectIntl } from 'react-intl';
|
||||
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { openURL } from 'mastodon/actions/search';
|
||||
|
||||
import {
|
||||
followAccount,
|
||||
unblockAccount,
|
||||
unmuteAccount,
|
||||
pinAccount,
|
||||
unpinAccount,
|
||||
} from '../../../actions/accounts';
|
||||
import { initBlockModal } from '../../../actions/blocks';
|
||||
import {
|
||||
mentionCompose,
|
||||
directCompose,
|
||||
} from '../../../actions/compose';
|
||||
import { initDomainBlockModal, unblockDomain } from '../../../actions/domain_blocks';
|
||||
import { openModal } from '../../../actions/modal';
|
||||
import { initMuteModal } from '../../../actions/mutes';
|
||||
import { initReport } from '../../../actions/reports';
|
||||
import { makeGetAccount, getAccountHidden } from '../../../selectors';
|
||||
import Header from '../components/header';
|
||||
|
||||
const makeMapStateToProps = () => {
|
||||
const getAccount = makeGetAccount();
|
||||
|
||||
const mapStateToProps = (state, { accountId }) => ({
|
||||
account: getAccount(state, accountId),
|
||||
domain: state.getIn(['meta', 'domain']),
|
||||
hidden: getAccountHidden(state, accountId),
|
||||
featuredTags: state.getIn(['user_lists', 'featured_tags', accountId, 'items']),
|
||||
});
|
||||
|
||||
return mapStateToProps;
|
||||
};
|
||||
|
||||
const mapDispatchToProps = (dispatch) => ({
|
||||
|
||||
onFollow (account) {
|
||||
if (account.getIn(['relationship', 'following']) || account.getIn(['relationship', 'requested'])) {
|
||||
dispatch(openModal({ modalType: 'CONFIRM_UNFOLLOW', modalProps: { account } }));
|
||||
} else {
|
||||
dispatch(followAccount(account.get('id')));
|
||||
}
|
||||
},
|
||||
|
||||
onInteractionModal (account) {
|
||||
dispatch(openModal({
|
||||
modalType: 'INTERACTION',
|
||||
modalProps: {
|
||||
type: 'follow',
|
||||
accountId: account.get('id'),
|
||||
url: account.get('uri'),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
onBlock (account) {
|
||||
if (account.getIn(['relationship', 'blocking'])) {
|
||||
dispatch(unblockAccount(account.get('id')));
|
||||
} else {
|
||||
dispatch(initBlockModal(account));
|
||||
}
|
||||
},
|
||||
|
||||
onMention (account) {
|
||||
dispatch(mentionCompose(account));
|
||||
},
|
||||
|
||||
onDirect (account) {
|
||||
dispatch(directCompose(account));
|
||||
},
|
||||
|
||||
onReblogToggle (account) {
|
||||
if (account.getIn(['relationship', 'showing_reblogs'])) {
|
||||
dispatch(followAccount(account.get('id'), { reblogs: false }));
|
||||
} else {
|
||||
dispatch(followAccount(account.get('id'), { reblogs: true }));
|
||||
}
|
||||
},
|
||||
|
||||
onEndorseToggle (account) {
|
||||
if (account.getIn(['relationship', 'endorsed'])) {
|
||||
dispatch(unpinAccount(account.get('id')));
|
||||
} else {
|
||||
dispatch(pinAccount(account.get('id')));
|
||||
}
|
||||
},
|
||||
|
||||
onNotifyToggle (account) {
|
||||
if (account.getIn(['relationship', 'notifying'])) {
|
||||
dispatch(followAccount(account.get('id'), { notify: false }));
|
||||
} else {
|
||||
dispatch(followAccount(account.get('id'), { notify: true }));
|
||||
}
|
||||
},
|
||||
|
||||
onReport (account) {
|
||||
dispatch(initReport(account));
|
||||
},
|
||||
|
||||
onMute (account) {
|
||||
if (account.getIn(['relationship', 'muting'])) {
|
||||
dispatch(unmuteAccount(account.get('id')));
|
||||
} else {
|
||||
dispatch(initMuteModal(account));
|
||||
}
|
||||
},
|
||||
|
||||
onBlockDomain (account) {
|
||||
dispatch(initDomainBlockModal(account));
|
||||
},
|
||||
|
||||
onUnblockDomain (domain) {
|
||||
dispatch(unblockDomain(domain));
|
||||
},
|
||||
|
||||
onAddToList (account) {
|
||||
dispatch(openModal({
|
||||
modalType: 'LIST_ADDER',
|
||||
modalProps: {
|
||||
accountId: account.get('id'),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
onAddToAntenna (account) {
|
||||
dispatch(openModal({
|
||||
modalType: 'ANTENNA_ADDER',
|
||||
modalProps: {
|
||||
accountId: account.get('id'),
|
||||
isExclude: false,
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
onAddToExcludeAntenna (account) {
|
||||
dispatch(openModal({
|
||||
modalType: 'ANTENNA_ADDER',
|
||||
modalProps: {
|
||||
accountId: account.get('id'),
|
||||
isExclude: true,
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
onAddToCircle (account) {
|
||||
dispatch(openModal({
|
||||
modalType: 'CIRCLE_ADDER',
|
||||
modalProps: {
|
||||
accountId: account.get('id'),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
onChangeLanguages (account) {
|
||||
dispatch(openModal({
|
||||
modalType: 'SUBSCRIBED_LANGUAGES',
|
||||
modalProps: {
|
||||
accountId: account.get('id'),
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
onOpenAvatar (account) {
|
||||
dispatch(openModal({
|
||||
modalType: 'IMAGE',
|
||||
modalProps: {
|
||||
src: account.get('avatar'),
|
||||
alt: '',
|
||||
},
|
||||
}));
|
||||
},
|
||||
|
||||
onOpenURL (url) {
|
||||
return dispatch(openURL({ url }));
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
export default injectIntl(connect(makeMapStateToProps, mapDispatchToProps)(Header));
|
|
@ -11,7 +11,7 @@ import { TimelineHint } from 'mastodon/components/timeline_hint';
|
|||
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
|
||||
import { me } from 'mastodon/initial_state';
|
||||
import { normalizeForLookup } from 'mastodon/reducers/accounts_map';
|
||||
import { getAccountHidden } from 'mastodon/selectors';
|
||||
import { getAccountHidden } from 'mastodon/selectors/accounts';
|
||||
import { useAppSelector } from 'mastodon/store';
|
||||
|
||||
import { lookupAccount, fetchAccount } from '../../actions/accounts';
|
||||
|
@ -22,8 +22,8 @@ import { LoadingIndicator } from '../../components/loading_indicator';
|
|||
import StatusList from '../../components/status_list';
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
import { AccountHeader } from './components/account_header';
|
||||
import { LimitedAccountHint } from './components/limited_account_hint';
|
||||
import HeaderContainer from './containers/header_container';
|
||||
|
||||
const emptyList = ImmutableList();
|
||||
|
||||
|
@ -198,7 +198,7 @@ class AccountTimeline extends ImmutablePureComponent {
|
|||
<ColumnBackButton />
|
||||
|
||||
<StatusList
|
||||
prepend={<HeaderContainer accountId={this.props.accountId} hideTabs={forceEmptyState} tagged={this.props.params.tagged} />}
|
||||
prepend={<AccountHeader accountId={this.props.accountId} hideTabs={forceEmptyState} tagged={this.props.params.tagged} />}
|
||||
alwaysPrepend
|
||||
append={remoteMessage}
|
||||
scrollKey='account_timeline'
|
||||
|
|
|
@ -10,10 +10,11 @@ import { debounce } from 'lodash';
|
|||
|
||||
import { Account } from 'mastodon/components/account';
|
||||
import { TimelineHint } from 'mastodon/components/timeline_hint';
|
||||
import { AccountHeader } from 'mastodon/features/account_timeline/components/account_header';
|
||||
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
|
||||
import { isHideItem, me } from 'mastodon/initial_state';
|
||||
import { normalizeForLookup } from 'mastodon/reducers/accounts_map';
|
||||
import { getAccountHidden } from 'mastodon/selectors';
|
||||
import { getAccountHidden } from 'mastodon/selectors/accounts';
|
||||
import { useAppSelector } from 'mastodon/store';
|
||||
|
||||
import {
|
||||
|
@ -26,7 +27,6 @@ import { ColumnBackButton } from '../../components/column_back_button';
|
|||
import { LoadingIndicator } from '../../components/loading_indicator';
|
||||
import ScrollableList from '../../components/scrollable_list';
|
||||
import { LimitedAccountHint } from '../account_timeline/components/limited_account_hint';
|
||||
import HeaderContainer from '../account_timeline/containers/header_container';
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
const mapStateToProps = (state, { params: { acct, id } }) => {
|
||||
|
@ -172,7 +172,7 @@ class Followers extends ImmutablePureComponent {
|
|||
hasMore={!forceEmptyState && hasMore}
|
||||
isLoading={isLoading}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
prepend={<HeaderContainer accountId={this.props.accountId} hideTabs />}
|
||||
prepend={<AccountHeader accountId={this.props.accountId} hideTabs />}
|
||||
alwaysPrepend
|
||||
append={remoteMessage}
|
||||
emptyMessage={emptyMessage}
|
||||
|
|
|
@ -10,10 +10,11 @@ import { debounce } from 'lodash';
|
|||
|
||||
import { Account } from 'mastodon/components/account';
|
||||
import { TimelineHint } from 'mastodon/components/timeline_hint';
|
||||
import { AccountHeader } from 'mastodon/features/account_timeline/components/account_header';
|
||||
import BundleColumnError from 'mastodon/features/ui/components/bundle_column_error';
|
||||
import { isHideItem, me } from 'mastodon/initial_state';
|
||||
import { normalizeForLookup } from 'mastodon/reducers/accounts_map';
|
||||
import { getAccountHidden } from 'mastodon/selectors';
|
||||
import { getAccountHidden } from 'mastodon/selectors/accounts';
|
||||
import { useAppSelector } from 'mastodon/store';
|
||||
|
||||
import {
|
||||
|
@ -26,7 +27,6 @@ import { ColumnBackButton } from '../../components/column_back_button';
|
|||
import { LoadingIndicator } from '../../components/loading_indicator';
|
||||
import ScrollableList from '../../components/scrollable_list';
|
||||
import { LimitedAccountHint } from '../account_timeline/components/limited_account_hint';
|
||||
import HeaderContainer from '../account_timeline/containers/header_container';
|
||||
import Column from '../ui/components/column';
|
||||
|
||||
const mapStateToProps = (state, { params: { acct, id } }) => {
|
||||
|
@ -170,7 +170,7 @@ class Following extends ImmutablePureComponent {
|
|||
hasMore={!forceEmptyState && hasMore}
|
||||
isLoading={isLoading}
|
||||
onLoadMore={this.handleLoadMore}
|
||||
prepend={<HeaderContainer accountId={this.props.accountId} hideTabs />}
|
||||
prepend={<AccountHeader accountId={this.props.accountId} hideTabs />}
|
||||
alwaysPrepend
|
||||
append={remoteMessage}
|
||||
emptyMessage={emptyMessage}
|
||||
|
|
|
@ -4,15 +4,16 @@
|
|||
"about.disclaimer": "Mastodon ye software gratuito y de códigu llibre, y una marca rexistrada de Mastodon gGmbH.",
|
||||
"about.domain_blocks.no_reason_available": "El motivu nun ta disponible",
|
||||
"about.domain_blocks.preamble": "Polo xeneral, Mastodon permítete ver el conteníu ya interactuar colos perfiles d'otros sirvidores nel fediversu. Estes son les esceiciones que se ficieron nesti sirvidor.",
|
||||
"about.domain_blocks.silenced.explanation": "Polo xeneral, nun ves los perfiles ya'l conteníu d'esti sirvidor sacante que los busques o decidas siguilos.",
|
||||
"about.domain_blocks.silenced.explanation": "Polo xeneral, nun ves los perfiles y el conteníu d'esti sirvidor sacante que los busques o decidas siguilos.",
|
||||
"about.domain_blocks.silenced.title": "Llendóse",
|
||||
"about.domain_blocks.suspended.explanation": "Nun se procesa, atroxa nin intercambia nengún datu d'esti sirvidor, lo que fai que cualesquier interaición o comunicación colos sos perfiles seya imposible.",
|
||||
"about.domain_blocks.suspended.explanation": "Nun se procesa, atroxa nin intercambia nengún datu d'esti sirvidor, lo que fai imposible cualesquier interaición o comunicación colos sos perfiles.",
|
||||
"about.domain_blocks.suspended.title": "Suspendióse",
|
||||
"about.not_available": "Esta información nun ta disponible nesti sirvidor.",
|
||||
"about.powered_by": "Una rede social descentralizada que tien la teunoloxía de {mastodon}",
|
||||
"about.rules": "Normes del sirvidor",
|
||||
"account.account_note_header": "Nota personal",
|
||||
"account.add_or_remove_from_list": "Amestar o quitar de les llistes",
|
||||
"account.badges.bot": "Automatizóse",
|
||||
"account.badges.group": "Grupu",
|
||||
"account.block": "Bloquiar a @{name}",
|
||||
"account.block_domain": "Bloquiar el dominiu {domain}",
|
||||
|
@ -25,7 +26,7 @@
|
|||
"account.edit_profile": "Editar el perfil",
|
||||
"account.enable_notifications": "Avisame cuando @{name} espublice artículos",
|
||||
"account.endorse": "Destacar nel perfil",
|
||||
"account.featured_tags.last_status_never": "Nun hai nengún artículu",
|
||||
"account.featured_tags.last_status_never": "Nun hai nenguna publicación",
|
||||
"account.featured_tags.title": "Etiquetes destacaes de: {name}",
|
||||
"account.follow": "Siguir",
|
||||
"account.follow_back": "Siguir tamién",
|
||||
|
@ -107,6 +108,7 @@
|
|||
"column.domain_blocks": "Dominios bloquiaos",
|
||||
"column.edit_list": "Editar la llista",
|
||||
"column.favourites": "Favoritos",
|
||||
"column.firehose": "Feed en direuto",
|
||||
"column.follow_requests": "Solicitúes de siguimientu",
|
||||
"column.home": "Aniciu",
|
||||
"column.lists": "Llistes",
|
||||
|
@ -126,9 +128,9 @@
|
|||
"community.column_settings.remote_only": "Namás lo remoto",
|
||||
"compose.language.change": "Camudar la llingua",
|
||||
"compose.language.search": "Buscar llingües…",
|
||||
"compose.published.body": "Espublizóse l'artículu.",
|
||||
"compose.published.body": "Publicóse la publicación.",
|
||||
"compose.published.open": "Abrir",
|
||||
"compose.saved.body": "Post guardáu.",
|
||||
"compose.saved.body": "Guardóse la publicación.",
|
||||
"compose_form.direct_message_warning_learn_more": "Saber más",
|
||||
"compose_form.encryption_warning": "Los artículos de Mastodon nun tán cifraos de puntu a puntu. Nun compartas nengún tipu d'información sensible per Mastodon.",
|
||||
"compose_form.lock_disclaimer": "La to cuenta nun ye {locked}. Cualesquier perfil pue siguite pa ver los artículos que son namás pa siguidores.",
|
||||
|
@ -137,34 +139,33 @@
|
|||
"compose_form.poll.option_placeholder": "Opción {number}",
|
||||
"compose_form.poll.type": "Tipu",
|
||||
"compose_form.publish": "Espublizar",
|
||||
"compose_form.publish_form": "Artículu nuevu",
|
||||
"compose_form.publish_form": "Publicación nueva",
|
||||
"compose_form.reply": "Responder",
|
||||
"confirmation_modal.cancel": "Encaboxar",
|
||||
"confirmations.block.confirm": "Bloquiar",
|
||||
"confirmations.delete.confirm": "Desaniciar",
|
||||
"confirmations.delete.message": "¿De xuru que quies desaniciar esti artículu?",
|
||||
"confirmations.delete.title": "¿Desaniciar l'artículu?",
|
||||
"confirmations.delete.message": "¿De xuru que quies desaniciar esta publicación?",
|
||||
"confirmations.delete.title": "¿Quies desaniciar esta publicación?",
|
||||
"confirmations.delete_list.confirm": "Desaniciar",
|
||||
"confirmations.delete_list.message": "¿De xuru que quies desaniciar permanentemente esta llista?",
|
||||
"confirmations.delete_list.title": "¿Desaniciar la llista?",
|
||||
"confirmations.delete_list.title": "¿Quies desaniciar la llista?",
|
||||
"confirmations.discard_edit_media.confirm": "Escartar",
|
||||
"confirmations.edit.confirm": "Editar",
|
||||
"confirmations.edit.message": "La edición va sobrescribir el mensaxe que tas escribiendo. ¿De xuru que quies siguir?",
|
||||
"confirmations.follow_to_list.title": "¿Siguir al usuariu?",
|
||||
"confirmations.logout.confirm": "Zarrar la sesión",
|
||||
"confirmations.logout.message": "¿De xuru que quies zarrar la sesión?",
|
||||
"confirmations.logout.title": "¿Zarrar la sesión?",
|
||||
"confirmations.logout.title": "¿Quies zarrar la sesión?",
|
||||
"confirmations.missing_alt_text.confirm": "Amestar testu alternativu",
|
||||
"confirmations.missing_alt_text.title": "¿Quies amestar testu alternativu?",
|
||||
"confirmations.redraft.confirm": "Desaniciar y reeditar",
|
||||
"confirmations.redraft.message": "¿De xuru que quies desaniciar esti artículu y reeditalu? Van perdese los favoritos y comparticiones, y les rempuestes al artículu orixinal van quedar güérfanes.",
|
||||
"confirmations.redraft.title": "¿Desaniciar ya reeditar l'artículu?",
|
||||
"confirmations.redraft.title": "¿Desaniciar y reeditar la publicación?",
|
||||
"confirmations.reply.confirm": "Responder",
|
||||
"confirmations.reply.message": "Responder agora va sobrescribir el mensaxe que tas componiendo anguaño. ¿De xuru que quies siguir?",
|
||||
"confirmations.unfollow.confirm": "Dexar de siguir",
|
||||
"confirmations.unfollow.message": "¿De xuru que quies dexar de siguir a {name}?",
|
||||
"confirmations.unfollow.title": "¿Dexar de siguir al usuariu?",
|
||||
"content_warning.hide": "Anubrir l'artículu",
|
||||
"content_warning.hide": "Esconder la publicación",
|
||||
"content_warning.show": "Amosar de toes toes",
|
||||
"content_warning.show_more": "Amosar más",
|
||||
"conversation.delete": "Desaniciar la conversación",
|
||||
|
@ -186,7 +187,7 @@
|
|||
"domain_block_modal.title": "Bloquiar el dominiu?",
|
||||
"domain_pill.server": "Sirvidor",
|
||||
"domain_pill.username": "Nome d'usuariu",
|
||||
"embed.instructions": "Empotra esti artículu nel to sitiu web copiando'l códigu d'abaxo.",
|
||||
"embed.instructions": "Empotra esta publicación nel to sitiu web copiando'l códigu d'abaxo.",
|
||||
"embed.preview": "Va apaecer asina:",
|
||||
"emoji_button.activity": "Actividá",
|
||||
"emoji_button.flags": "Banderes",
|
||||
|
@ -201,9 +202,9 @@
|
|||
"emoji_button.symbols": "Símbolos",
|
||||
"emoji_button.travel": "Viaxes y llugares",
|
||||
"empty_column.account_suspended": "Cuenta suspendida",
|
||||
"empty_column.account_timeline": "¡Equí nun hai nengún artículu!",
|
||||
"empty_column.account_timeline": "¡Equí nun hai nenguna publicación!",
|
||||
"empty_column.blocks": "Nun bloquiesti a nengún perfil.",
|
||||
"empty_column.bookmarked_statuses": "Nun tienes nengún artículu en Marcadores. Cuando amiestes dalgún, apaez equí.",
|
||||
"empty_column.bookmarked_statuses": "Nun tienes nenguna publicación en Marcadores. Cuando amiestes dalguna, va apaecer equí.",
|
||||
"empty_column.direct": "Nun tienes nenguna mención privada. Cuando unvies o recibas dalguna, apaez equí.",
|
||||
"empty_column.domain_blocks": "Nun hai nengún dominiu bloquiáu.",
|
||||
"empty_column.explore_statuses": "Agora nun hai nada en tendencia. ¡Volvi equí dempués!",
|
||||
|
@ -223,21 +224,21 @@
|
|||
"explore.trending_links": "Noticies",
|
||||
"explore.trending_statuses": "Artículos",
|
||||
"explore.trending_tags": "Etiquetes",
|
||||
"filter_modal.added.context_mismatch_explanation": "Esta categoría de peñera nun s'aplica al contestu nel qu'accediesti a esti artículu. Si tamién quies que se peñere l'artículu nesti contestu, tienes d'editar la peñera.",
|
||||
"filter_modal.added.context_mismatch_explanation": "Esta categoría de peñera nun s'aplica al contestu nel qu'accediesti a esta publicación. Si tamién quies que se peñere la publicación nesti contestu, tienes d'editar la peñera.",
|
||||
"filter_modal.added.context_mismatch_title": "¡El contestu nun coincide!",
|
||||
"filter_modal.added.expired_explanation": "Esta categoría de peñera caducó, tienes de camudar la so data de caducidá p'aplicala.",
|
||||
"filter_modal.added.expired_title": "¡La peñera caducó!",
|
||||
"filter_modal.added.review_and_configure": "Pa revisar y configurar a fondu esta categoría de peñera, vete a la {settings_link}.",
|
||||
"filter_modal.added.review_and_configure_title": "Configuración de la peñera",
|
||||
"filter_modal.added.settings_link": "páxina de configuración",
|
||||
"filter_modal.added.short_explanation": "Esti artículu amestóse a la categoría de peñera siguiente: {title}.",
|
||||
"filter_modal.added.short_explanation": "Esta publicación amestóse a la categoría de peñera siguiente: {title}.",
|
||||
"filter_modal.added.title": "¡Amestóse la peñera!",
|
||||
"filter_modal.select_filter.expired": "caducó",
|
||||
"filter_modal.select_filter.prompt_new": "Categoría nueva: {name}",
|
||||
"filter_modal.select_filter.search": "Buscar o crear",
|
||||
"filter_modal.select_filter.subtitle": "Usa una categoría esistente o créala",
|
||||
"filter_modal.select_filter.title": "Peñerar esti artículu",
|
||||
"filter_modal.title.status": "Peñera d'un artículu",
|
||||
"filter_modal.select_filter.title": "Peñerar esta publicación",
|
||||
"filter_modal.title.status": "Peñera d'una publicación",
|
||||
"firehose.all": "Tolos sirvidores",
|
||||
"firehose.local": "Esti sirvidor",
|
||||
"firehose.remote": "Otros sirvidores",
|
||||
|
@ -285,20 +286,20 @@
|
|||
"interaction_modal.on_another_server": "N'otru sirvidor",
|
||||
"interaction_modal.on_this_server": "Nesti sirvidor",
|
||||
"interaction_modal.title.follow": "Siguir a {name}",
|
||||
"interaction_modal.title.reply": "Rempuesta al artículu de: {name}",
|
||||
"interaction_modal.title.reply": "Rempuesta a la publicación de: {name}",
|
||||
"interaction_modal.title.vote": "Vota na encuesta de {name}",
|
||||
"intervals.full.days": "{number, plural, one {# día} other {# díes}}",
|
||||
"intervals.full.hours": "{number, plural, one {# hora} other {# hores}}",
|
||||
"intervals.full.minutes": "{number, plural, one {# minutu} other {# minutos}}",
|
||||
"keyboard_shortcuts.back": "Dir p'atrás",
|
||||
"keyboard_shortcuts.blocked": "Abrir la llista de perfiles bloquiaos",
|
||||
"keyboard_shortcuts.boost": "Compartir un artículu",
|
||||
"keyboard_shortcuts.boost": "Compartir una publicación",
|
||||
"keyboard_shortcuts.column": "Enfocar una columna",
|
||||
"keyboard_shortcuts.compose": "Enfocar l'área de composición",
|
||||
"keyboard_shortcuts.description": "Descripción",
|
||||
"keyboard_shortcuts.direct": "p'abrir la columna de les menciones privaes",
|
||||
"keyboard_shortcuts.down": "Baxar na llista",
|
||||
"keyboard_shortcuts.enter": "Abrir un artículu",
|
||||
"keyboard_shortcuts.enter": "Abrir una publicación",
|
||||
"keyboard_shortcuts.federated": "Abrir la llinia de tiempu federada",
|
||||
"keyboard_shortcuts.heading": "Atayos del tecláu",
|
||||
"keyboard_shortcuts.home": "Abrir la llinia de tiempu del aniciu",
|
||||
|
@ -312,12 +313,12 @@
|
|||
"keyboard_shortcuts.open_media": "Abrir el conteníu mutimedia",
|
||||
"keyboard_shortcuts.pinned": "Abrir la llista d'artículos fixaos",
|
||||
"keyboard_shortcuts.profile": "Abrir el perfil del autor/a",
|
||||
"keyboard_shortcuts.reply": "Responder a un artículu",
|
||||
"keyboard_shortcuts.reply": "Responder a una publicación",
|
||||
"keyboard_shortcuts.requests": "Abrir la llista de solicitúes de siguimientu",
|
||||
"keyboard_shortcuts.search": "Enfocar la barra de busca",
|
||||
"keyboard_shortcuts.start": "Abrir la columna «Entamar»",
|
||||
"keyboard_shortcuts.toggle_sensitivity": "Amosar/esconder el conteníu multimedia",
|
||||
"keyboard_shortcuts.toot": "Comenzar un artículu nuevu",
|
||||
"keyboard_shortcuts.toot": "Escribir una publicación nueva",
|
||||
"keyboard_shortcuts.unfocus": "Desenfocar l'área de composición/busca",
|
||||
"keyboard_shortcuts.up": "Xubir na llista",
|
||||
"lightbox.close": "Zarrar",
|
||||
|
@ -377,9 +378,9 @@
|
|||
"notification.mentioned_you": "{name} mentóte",
|
||||
"notification.moderation-warning.learn_more": "Deprender más",
|
||||
"notification.poll": "Finó una encuesta na que votesti",
|
||||
"notification.reblog": "{name} compartió'l to artículu",
|
||||
"notification.reblog": "{name} compartió la to publicación",
|
||||
"notification.status": "{name} ta acabante d'espublizar",
|
||||
"notification.update": "{name} editó un artículu",
|
||||
"notification.update": "{name} editó una publicación",
|
||||
"notification_requests.edit_selection": "Editar",
|
||||
"notification_requests.exit_selection": "Fecho",
|
||||
"notifications.clear": "Borrar los avisos",
|
||||
|
@ -421,9 +422,10 @@
|
|||
"poll.votes": "{votes, plural, one {# votu} other {# votos}}",
|
||||
"poll_button.add_poll": "Amestar una encuesta",
|
||||
"poll_button.remove_poll": "Quitar la encuesta",
|
||||
"privacy.change": "Configurar la privacidá del artículu",
|
||||
"privacy.change": "Configurar la privacidá de la publicación",
|
||||
"privacy.direct.short": "Mención privada",
|
||||
"privacy.private.short": "Siguidores",
|
||||
"privacy.public.short": "Artículu públicu",
|
||||
"privacy.public.short": "Publicación pública",
|
||||
"privacy_policy.last_updated": "Data del últimu anovamientu: {date}",
|
||||
"privacy_policy.title": "Política de privacidá",
|
||||
"refresh": "Anovar",
|
||||
|
@ -447,7 +449,7 @@
|
|||
"report.category.subtitle": "Escueyi la meyor opción",
|
||||
"report.category.title": "Dinos qué pasa con esti {type}",
|
||||
"report.category.title_account": "perfil",
|
||||
"report.category.title_status": "artículu",
|
||||
"report.category.title_status": "publicación",
|
||||
"report.close": "Fecho",
|
||||
"report.comment.title": "¿Hai daqué más qu'habríemos saber?",
|
||||
"report.forward": "Reunviar a {target}",
|
||||
|
@ -467,7 +469,7 @@
|
|||
"report.rules.subtitle": "Seleiciona tolo que s'axuste",
|
||||
"report.rules.title": "¿Qué normes s'incumplen?",
|
||||
"report.statuses.subtitle": "Seleiciona tolo que s'axuste",
|
||||
"report.statuses.title": "¿Hai dalgún artículu qu'apoye esti informe?",
|
||||
"report.statuses.title": "¿Hai dalguna publicación qu'apoye esti informe?",
|
||||
"report.submit": "Unviar",
|
||||
"report.target": "Informe de: {target}",
|
||||
"report.thanks.take_action": "Equí tienes les opciones pa controlar qué ves en Mastodon:",
|
||||
|
@ -476,7 +478,7 @@
|
|||
"report.thanks.title_actionable": "Gracies pol informe, el casu yá ta n'investigación.",
|
||||
"report.unfollow": "Dexar de siguir a @{name}",
|
||||
"report.unfollow_explanation": "Sigues a esta cuenta. Pa dexar de ver los sos artículos nel to feed d'aniciu, dexa de siguila.",
|
||||
"report_notification.attached_statuses": "{count, plural, one {Axuntóse {count} artículu} other {Axuntáronse {count} artículos}}",
|
||||
"report_notification.attached_statuses": "{count, plural, one {Axuntóse {count} publicación} other {Axuntáronse {count} publicaciones}}",
|
||||
"report_notification.categories.legal": "Llegal",
|
||||
"report_notification.categories.legal_sentence": "conteníu illegal",
|
||||
"report_notification.categories.spam": "Spam",
|
||||
|
@ -489,6 +491,7 @@
|
|||
"search.quick_action.go_to_hashtag": "Dir a la etiqueta {x}",
|
||||
"search.quick_action.status_search": "Artículos que concasen con {x}",
|
||||
"search.search_or_paste": "Busca o apiega una URL",
|
||||
"search_popout.full_text_search_disabled_message": "Nun ta disponible nel dominiu {domain}.",
|
||||
"search_popout.language_code": "códigu de llingua ISO",
|
||||
"search_popout.options": "Opciones de busca",
|
||||
"search_popout.quick_actions": "Aiciones rápides",
|
||||
|
@ -500,22 +503,25 @@
|
|||
"search_results.hashtags": "Etiquetes",
|
||||
"search_results.see_all": "Ver too",
|
||||
"search_results.statuses": "Artículos",
|
||||
"server_banner.is_one_of_many": "{domain} ye unu de los munchos sirvidores independientes de Mastodon que pues usar pa participar nel fediversu.",
|
||||
"server_banner.server_stats": "Estadístiques del sirvidor:",
|
||||
"sign_in_banner.create_account": "Crear una cuenta",
|
||||
"sign_in_banner.mastodon_is": "Mastodon ye la meyor manera de siguir al momentu qué pasa.",
|
||||
"sign_in_banner.sign_in": "Aniciar la sesión",
|
||||
"sign_in_banner.sso_redirect": "Aniciar la sesión o rexistrase",
|
||||
"status.admin_account": "Abrir la interfaz de moderación pa @{name}",
|
||||
"status.admin_domain": "Abrir la interfaz de moderación pa «{domain}»",
|
||||
"status.admin_status": "Abrir esti artículu na interfaz de moderación",
|
||||
"status.admin_status": "Abrir esta publicación na interfaz de moderación",
|
||||
"status.block": "Bloquiar a @{name}",
|
||||
"status.bookmark": "Meter en Marcadores",
|
||||
"status.cannot_reblog": "Esti artículu nun se pue compartir",
|
||||
"status.copy": "Copiar l'enllaz al artículu",
|
||||
"status.cannot_reblog": "Esta publicación nun se pue compartir",
|
||||
"status.copy": "Copiar l'enllaz a la publicación",
|
||||
"status.delete": "Desaniciar",
|
||||
"status.direct": "Mentar a @{name} per privao",
|
||||
"status.direct_indicator": "Mención privada",
|
||||
"status.edited_x_times": "Editóse {count, plural, one {{count} vegada} other {{count} vegaes}}",
|
||||
"status.embed": "Consiguir el códigu pa empotrar",
|
||||
"status.filter": "Peñerar esti artículu",
|
||||
"status.filter": "Peñerar esta publicación",
|
||||
"status.history.created": "{name} creó {date}",
|
||||
"status.history.edited": "{name} editó {date}",
|
||||
"status.load_more": "Cargar más",
|
||||
|
@ -524,13 +530,13 @@
|
|||
"status.more": "Más",
|
||||
"status.mute": "Desactivar los avisos de @{name}",
|
||||
"status.mute_conversation": "Desactivar los avisos de la conversación",
|
||||
"status.open": "Espander esti artículu",
|
||||
"status.open": "Espander esta publicación",
|
||||
"status.pin": "Fixar nel perfil",
|
||||
"status.pinned": "Artículu fixáu",
|
||||
"status.pinned": "Publicación fixada",
|
||||
"status.read_more": "Lleer más",
|
||||
"status.reblog": "Compartir",
|
||||
"status.reblogged_by": "{name} compartió",
|
||||
"status.reblogs.empty": "Naide nun compartió esti artículu. Cuando daquién lo faiga, apaez equí.",
|
||||
"status.reblogs.empty": "Naide nun compartió esta publicación. Cuando daquién lo faiga, va apaecer equí.",
|
||||
"status.redraft": "Desaniciar y reeditar",
|
||||
"status.remove_bookmark": "Desaniciar el marcador",
|
||||
"status.replied_to": "En rempuesta a {name}",
|
||||
|
|
|
@ -696,6 +696,7 @@
|
|||
"poll_button.remove_poll": "Elimina l'enquesta",
|
||||
"privacy.change": "Canvia la privacitat del tut",
|
||||
"privacy.direct.long": "Tothom mencionat a la publicació",
|
||||
"privacy.direct.short": "Menció privada",
|
||||
"privacy.private.long": "Només els vostres seguidors",
|
||||
"privacy.private.short": "Seguidors",
|
||||
"privacy.public.long": "Tothom dins o fora Mastodon",
|
||||
|
|
|
@ -697,6 +697,7 @@
|
|||
"poll_button.remove_poll": "Remove poll",
|
||||
"privacy.change": "Change post privacy",
|
||||
"privacy.direct.long": "Everyone mentioned in the post",
|
||||
"privacy.direct.short": "Private mention",
|
||||
"privacy.private.long": "Only your followers",
|
||||
"privacy.private.short": "Followers",
|
||||
"privacy.public.long": "Anyone on and off Mastodon",
|
||||
|
|
|
@ -192,7 +192,7 @@
|
|||
"compose_form.poll.switch_to_multiple": "Cambiar la encuesta para permitir múltiples opciones",
|
||||
"compose_form.poll.switch_to_single": "Cambiar la encuesta para permitir una única opción",
|
||||
"compose_form.poll.type": "Estilo",
|
||||
"compose_form.publish": "Publicación",
|
||||
"compose_form.publish": "Publicar",
|
||||
"compose_form.publish_form": "Nueva publicación",
|
||||
"compose_form.reply": "Respuesta",
|
||||
"compose_form.save_changes": "Actualización",
|
||||
|
|
|
@ -697,6 +697,7 @@
|
|||
"poll_button.remove_poll": "Bain suirbhé",
|
||||
"privacy.change": "Athraigh príobháideacht postála",
|
||||
"privacy.direct.long": "Luaigh gach duine sa phost",
|
||||
"privacy.direct.short": "Tagairt phríobháideach",
|
||||
"privacy.private.long": "Do leanúna amháin",
|
||||
"privacy.private.short": "Leantóirí",
|
||||
"privacy.public.long": "Duine ar bith ar agus amach Mastodon",
|
||||
|
|
|
@ -702,7 +702,7 @@
|
|||
"privacy.private.short": "Follower",
|
||||
"privacy.public.long": "Chiunque dentro e fuori Mastodon",
|
||||
"privacy.public.short": "Pubblico",
|
||||
"privacy.unlisted.additional": "",
|
||||
"privacy.unlisted.additional": "Si comporta esattamente come pubblico, tranne per il fatto che il post non verrà visualizzato nei feed live o negli hashtag, nell'esplorazione o nella ricerca Mastodon, anche se hai attivato l'attivazione a livello di account.",
|
||||
"privacy.unlisted.long": "Meno fanfare algoritmiche",
|
||||
"privacy.unlisted.short": "Pubblico silenzioso",
|
||||
"privacy_policy.last_updated": "Ultimo aggiornamento {date}",
|
||||
|
|
|
@ -86,6 +86,12 @@
|
|||
"alert.unexpected.message": "Radās negaidīta kļūda.",
|
||||
"alert.unexpected.title": "Ups!",
|
||||
"alt_text_badge.title": "Alt teksts",
|
||||
"alt_text_modal.add_text_from_image": "Pievienot tekstu no attēla",
|
||||
"alt_text_modal.cancel": "Atcelt",
|
||||
"alt_text_modal.change_thumbnail": "Nomainīt sīktēlu",
|
||||
"alt_text_modal.describe_for_people_with_hearing_impairments": "Aprakstīt šo cilvēkiem ar dzirdes traucējumiem…",
|
||||
"alt_text_modal.describe_for_people_with_visual_impairments": "Aprakstīt šo cilvēkiem ar redzes traucējumiem…",
|
||||
"alt_text_modal.done": "Gatavs",
|
||||
"announcement.announcement": "Paziņojums",
|
||||
"annual_report.summary.archetype.oracle": "Orākuls",
|
||||
"annual_report.summary.archetype.replier": "Sabiedriskais tauriņš",
|
||||
|
@ -205,6 +211,7 @@
|
|||
"confirmations.logout.confirm": "Iziet",
|
||||
"confirmations.logout.message": "Vai tiešām vēlies izrakstīties?",
|
||||
"confirmations.logout.title": "Atteikties?",
|
||||
"confirmations.missing_alt_text.secondary": "Vienalga iesūtīt",
|
||||
"confirmations.mute.confirm": "Apklusināt",
|
||||
"confirmations.redraft.confirm": "Dzēst un pārrakstīt",
|
||||
"confirmations.redraft.message": "Vai tiešām vēlies dzēst šo ziņu un no jauna noformēt to? Izlase un pastiprinājumi tiks zaudēti, un atbildes uz sākotnējo ziņu tiks atstātas bez autoratlīdzības.",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"about.contact": "Hubungi:",
|
||||
"about.disclaimer": "Mastodon ialah perisian sumber terbuka percuma, dan merupakan tanda dagangan Mastodon gGmbH.",
|
||||
"about.domain_blocks.no_reason_available": "Sebab tidak tersedia",
|
||||
"about.domain_blocks.preamble": "Secara amnya, Mastodon membenarkan anda melihat kandungan daripada dan berinteraksi dengan pengguna daripada mana-mana pelayan dalam dunia persekutuan. Berikut ialah pengecualian yang telah dibuat pada pelayan ini secara khususnya.",
|
||||
"about.domain_blocks.preamble": "Secara amnya, Mastodon membenarkan anda melihat kandungan pengguna daripada mana-mana pelayan dalam alam bersekutu dan berinteraksi dengan mereka. Berikut ialah pengecualian yang khusus pada pelayan ini.",
|
||||
"about.domain_blocks.silenced.explanation": "Secara amnya, anda tidak akan melihat profil dan kandungan daripada pelayan ini, kecuali anda mencarinya secara khusus atau ikut serta dengan mengikutinya.",
|
||||
"about.domain_blocks.silenced.title": "Terhad",
|
||||
"about.domain_blocks.suspended.explanation": "Tiada data daripada pelayan ini yang akan diproses, disimpan atau ditukar, menjadikan sebarang interaksi atau perhubungan dengan pengguna daripada pelayan ini adalah mustahil.",
|
||||
|
@ -19,7 +19,7 @@
|
|||
"account.block_domain": "Sekat domain {domain}",
|
||||
"account.block_short": "Malay",
|
||||
"account.blocked": "Disekat",
|
||||
"account.cancel_follow_request": "Menarik balik permintaan mengikut",
|
||||
"account.cancel_follow_request": "Batalkan permintaan ikut",
|
||||
"account.copy": "Salin pautan ke profil",
|
||||
"account.direct": "Sebut secara persendirian @{name}",
|
||||
"account.disable_notifications": "Berhenti maklumkan saya apabila @{name} mengirim hantaran",
|
||||
|
@ -85,10 +85,45 @@
|
|||
"alert.rate_limited.title": "Kadar terhad",
|
||||
"alert.unexpected.message": "Berlaku ralat di luar jangkaan.",
|
||||
"alert.unexpected.title": "Alamak!",
|
||||
"alt_text_badge.title": "Teks alternatif",
|
||||
"alt_text_modal.add_alt_text": "Tambah teks alternatif",
|
||||
"alt_text_modal.add_text_from_image": "Tambah teks dari imej",
|
||||
"alt_text_modal.cancel": "Batal",
|
||||
"alt_text_modal.change_thumbnail": "Ubah imej kecil",
|
||||
"alt_text_modal.describe_for_people_with_hearing_impairments": "Terangkan untuk OKU pendengaran…vorite\n",
|
||||
"alt_text_modal.describe_for_people_with_visual_impairments": "Terangkan untuk OKU penglihatan…",
|
||||
"alt_text_modal.done": "Selesai",
|
||||
"announcement.announcement": "Pengumuman",
|
||||
"annual_report.summary.archetype.booster": "Si pencapap",
|
||||
"annual_report.summary.archetype.lurker": "Si penghendap",
|
||||
"annual_report.summary.archetype.oracle": "Si penilik",
|
||||
"annual_report.summary.archetype.pollster": "Si peninjau",
|
||||
"annual_report.summary.archetype.replier": "Si peramah",
|
||||
"annual_report.summary.followers.followers": "pengikut",
|
||||
"annual_report.summary.followers.total": "sebanyak {count}",
|
||||
"annual_report.summary.here_it_is": "Ini ulasan {year} anda:",
|
||||
"annual_report.summary.highlighted_post.by_favourites": "hantaran paling disukai ramai",
|
||||
"annual_report.summary.highlighted_post.by_reblogs": "hantaran paling digalak ramai",
|
||||
"annual_report.summary.highlighted_post.by_replies": "hantaran paling dibalas ramai",
|
||||
"annual_report.summary.highlighted_post.possessive": "oleh",
|
||||
"annual_report.summary.most_used_app.most_used_app": "aplikasi paling banyak digunakan",
|
||||
"annual_report.summary.most_used_hashtag.most_used_hashtag": "tanda pagar paling banyak digunakan",
|
||||
"annual_report.summary.most_used_hashtag.none": "Tiada",
|
||||
"annual_report.summary.new_posts.new_posts": "hantaran baharu",
|
||||
"annual_report.summary.percentile.text": "<topLabel>Anda berkedudukan</topLabel><percentage></percentage><bottomLabel> pengguna {domain}.</bottomLabel>",
|
||||
"annual_report.summary.percentile.we_wont_tell_bernie": "Rahsia anda selamat bersama kami. ;)",
|
||||
"annual_report.summary.thanks": "Terima kasih kerana setia bersama Mastodon!",
|
||||
"attachments_list.unprocessed": "(belum diproses)",
|
||||
"audio.hide": "Sembunyikan audio",
|
||||
"block_modal.remote_users_caveat": "Kami akan meminta pelayan {domain} untuk menghormati keputusan anda. Bagaimanapun, pematuhan tidak dijamin kerana ada pelayan yang mungkin menangani sekatan dengan cara berbeza. Hantaran awam mungkin masih tampak kepada pengguna yang tidak log masuk.",
|
||||
"block_modal.they_cant_mention": "Dia tidak boleh menyebut tentang anda atau mengikut anda.",
|
||||
"block_modal.they_cant_see_posts": "Dia tidak boleh melihat hantaran anda dan sebaliknya.",
|
||||
"block_modal.they_will_know": "Dia boleh lihat bahawa dia disekat.",
|
||||
"block_modal.title": "Sekat pengguna?",
|
||||
"block_modal.you_wont_see_mentions": "Anda tidak akan melihat hantaran yang menyebut tentangnya.",
|
||||
"boost_modal.combo": "Anda boleh tekan {combo} untuk melangkauinya pada waktu lain",
|
||||
"boost_modal.reblog": "Galakkan hantaran?",
|
||||
"boost_modal.undo_reblog": "Nyahgalakkan hantaran?",
|
||||
"bundle_column_error.copy_stacktrace": "Salin laporan ralat",
|
||||
"bundle_column_error.error.body": "Halaman yang diminta gagal dipaparkan. Ini mungkin disebabkan oleh pepijat dalam kod kami, atau masalah keserasian pelayar.",
|
||||
"bundle_column_error.error.title": "Alamak!",
|
||||
|
@ -99,6 +134,7 @@
|
|||
"bundle_column_error.routing.body": "Halaman tersebut tidak dapat ditemui. Adakah anda pasti URL dalam bar alamat adalah betul?",
|
||||
"bundle_column_error.routing.title": "404",
|
||||
"bundle_modal_error.close": "Tutup",
|
||||
"bundle_modal_error.message": "Terdapat masalah yang dihadapi ketika memuat layar ini.",
|
||||
"bundle_modal_error.retry": "Cuba lagi",
|
||||
"closed_registrations.other_server_instructions": "Oleh sebab Mastodon terpencar, anda boleh mencipta akaun pada pelayan lain dan masih berinteraksi dengan pelayan ini.",
|
||||
"closed_registrations_modal.description": "Mencipta akaun pada {domain} tidak dapat dibuat sekarang, tetapi sila ingat bahawa anda tidak memerlukan akaun khususnya pada {domain} untuk menggunakan Mastodon.",
|
||||
|
@ -109,13 +145,16 @@
|
|||
"column.blocks": "Pengguna yang disekat",
|
||||
"column.bookmarks": "Tanda buku",
|
||||
"column.community": "Garis masa tempatan",
|
||||
"column.create_list": "Cipta senarai",
|
||||
"column.direct": "Sebutan peribadi",
|
||||
"column.directory": "Layari profil",
|
||||
"column.domain_blocks": "Domain disekat",
|
||||
"column.favourites": "Kegemaran",
|
||||
"column.edit_list": "Sunting senarai",
|
||||
"column.favourites": "Sukaan",
|
||||
"column.firehose": "Suapan langsung",
|
||||
"column.follow_requests": "Permintaan ikutan",
|
||||
"column.home": "Laman Utama",
|
||||
"column.list_members": "Urus ahli senarai",
|
||||
"column.lists": "Senarai",
|
||||
"column.mutes": "Pengguna yang dibisukan",
|
||||
"column.notifications": "Pemberitahuan",
|
||||
|
@ -128,6 +167,7 @@
|
|||
"column_header.pin": "Sematkan",
|
||||
"column_header.show_settings": "Tunjukkan tetapan",
|
||||
"column_header.unpin": "Nyahsemat",
|
||||
"column_search.cancel": "Batal",
|
||||
"column_subheading.settings": "Tetapan",
|
||||
"community.column_settings.local_only": "Tempatan sahaja",
|
||||
"community.column_settings.media_only": "Media sahaja",
|
||||
|
@ -146,6 +186,7 @@
|
|||
"compose_form.poll.duration": "Tempoh undian",
|
||||
"compose_form.poll.multiple": "Pelbagai pilihan",
|
||||
"compose_form.poll.option_placeholder": "Pilihan {number}",
|
||||
"compose_form.poll.single": "Satu pilihan",
|
||||
"compose_form.poll.switch_to_multiple": "Ubah kepada membenarkan aneka undian",
|
||||
"compose_form.poll.switch_to_single": "Ubah kepada undian pilihan tunggal",
|
||||
"compose_form.poll.type": "Gaya",
|
||||
|
@ -160,17 +201,26 @@
|
|||
"confirmations.block.confirm": "Sekat",
|
||||
"confirmations.delete.confirm": "Padam",
|
||||
"confirmations.delete.message": "Adakah anda pasti anda ingin memadam hantaran ini?",
|
||||
"confirmations.delete.title": "Padam hantaran?",
|
||||
"confirmations.delete_list.confirm": "Padam",
|
||||
"confirmations.delete_list.message": "Adakah anda pasti anda ingin memadam senarai ini secara kekal?",
|
||||
"confirmations.delete_list.title": "Padam senarai?",
|
||||
"confirmations.discard_edit_media.confirm": "Singkir",
|
||||
"confirmations.discard_edit_media.message": "Anda belum menyimpan perubahan pada penerangan atau pratonton media. Anda ingin membuangnya?",
|
||||
"confirmations.edit.confirm": "Sunting",
|
||||
"confirmations.edit.message": "Mengedit sekarang akan menimpa mesej yang sedang anda karang. Adakah anda pasti mahu meneruskan?",
|
||||
"confirmations.edit.title": "Tulis ganti hantaran?",
|
||||
"confirmations.follow_to_list.confirm": "Ikut dan tambah ke senarai",
|
||||
"confirmations.follow_to_list.message": "Anda mesti mengikuti {name} untuk tambahkannya ke senarai.",
|
||||
"confirmations.follow_to_list.title": "Ikut pengguna?",
|
||||
"confirmations.logout.confirm": "Log keluar",
|
||||
"confirmations.logout.message": "Adakah anda pasti anda ingin log keluar?",
|
||||
"confirmations.logout.title": "Log keluar?",
|
||||
"confirmations.missing_alt_text.confirm": "Tambah teks alternatif",
|
||||
"confirmations.missing_alt_text.message": "Hantaran anda mempunyai media tanpa teks alternatif. Kandungan anda akan lebih mudah tercapai jika anda menambah keterangan.",
|
||||
"confirmations.mute.confirm": "Bisukan",
|
||||
"confirmations.redraft.confirm": "Padam & rangka semula",
|
||||
"confirmations.redraft.message": "Adakah anda pasti anda ingin memadam pos ini dan merangkanya semula? Kegemaran dan galakan akan hilang, dan balasan ke pos asal akan menjadi yatim.",
|
||||
"confirmations.redraft.message": "Adakah anda pasti anda ingin memadam hantaran ini dan gubal semula? Sukaan dan galakan akan hilang, dan balasan ke hantaran asal akan menjadi yatim.",
|
||||
"confirmations.reply.confirm": "Balas",
|
||||
"confirmations.reply.message": "Membalas sekarang akan menulis ganti mesej yang anda sedang karang. Adakah anda pasti anda ingin teruskan?",
|
||||
"confirmations.unfollow.confirm": "Nyahikut",
|
||||
|
@ -182,7 +232,7 @@
|
|||
"copy_icon_button.copied": "Disalin ke papan klip",
|
||||
"copypaste.copied": "Disalin",
|
||||
"copypaste.copy_to_clipboard": "Salin ke papan klip",
|
||||
"directory.federated": "Dari fediverse yang diketahui",
|
||||
"directory.federated": "Dari alam bersekutu yang diketahui",
|
||||
"directory.local": "Dari {domain} sahaja",
|
||||
"directory.new_arrivals": "Ketibaan baharu",
|
||||
"directory.recently_active": "Aktif baru-baru ini",
|
||||
|
@ -190,6 +240,7 @@
|
|||
"disabled_account_banner.text": "Akaun anda {disabledAccount} telah dinyahaktif.",
|
||||
"dismissable_banner.community_timeline": "Inilah hantaran awam terkini daripada orang yang akaun dihos oleh {domain}.",
|
||||
"dismissable_banner.dismiss": "Ketepikan",
|
||||
"dismissable_banner.explore_statuses": "Hantaran-hantaran dari seluruh alam bersekutu ini sedang sohor. Hantaran terbaharu dengan lebih banyak galakan dan sukaan diberi kedudukan lebih tinggi.",
|
||||
"embed.instructions": "Benam hantaran ini di laman sesawang anda dengan menyalin kod berikut.",
|
||||
"embed.preview": "Begini rupanya nanti:",
|
||||
"emoji_button.activity": "Aktiviti",
|
||||
|
@ -217,8 +268,8 @@
|
|||
"empty_column.direct": "Anda belum mempunyai sebarang sebutan peribadi lagi. Apabila anda menghantar atau menerima satu, ia akan dipaparkan di sini.",
|
||||
"empty_column.domain_blocks": "Belum ada domain yang disekat.",
|
||||
"empty_column.explore_statuses": "Tiada apa-apa yang sohor kini sekarang. Semaklah kemudian!",
|
||||
"empty_column.favourited_statuses": "Anda belum mempunyai sebarang pos kegemaran. Apabila anda kegemaran, ia akan dipaparkan di sini.",
|
||||
"empty_column.favourites": "Tiada siapa yang menggemari pos ini lagi. Apabila seseorang melakukannya, mereka akan muncul di sini.",
|
||||
"empty_column.favourited_statuses": "Anda belum mempunyai sebarang hantaran sukaan lagi. Hantaran akan muncul di sini apabila disukai oleh anda.",
|
||||
"empty_column.favourites": "Hantaran ini belum disukai mana-mana pengguna lagi. Pengguna yang menyukai akan muncul di sini.",
|
||||
"empty_column.follow_requests": "Anda belum mempunyai permintaan ikutan. Ia akan terpapar di sini apabila ada nanti.",
|
||||
"empty_column.followed_tags": "You have not followed any hashtags yet. When you do, they will show up here.",
|
||||
"empty_column.hashtag": "Belum ada apa-apa dengan tanda pagar ini.",
|
||||
|
@ -300,9 +351,10 @@
|
|||
"home.pending_critical_update.link": "Lihat pengemaskinian",
|
||||
"home.pending_critical_update.title": "Kemas kini keselamatan kritikal tersedia!",
|
||||
"home.show_announcements": "Tunjukkan pengumuman",
|
||||
"interaction_modal.action.favourite": "Untuk sambung, anda perlu suka dari akaun anda.",
|
||||
"interaction_modal.on_another_server": "Di pelayan lain",
|
||||
"interaction_modal.on_this_server": "Pada pelayan ini",
|
||||
"interaction_modal.title.favourite": "Pos {name} kegemaran",
|
||||
"interaction_modal.title.favourite": "Suka hantaran {name}",
|
||||
"interaction_modal.title.follow": "Ikuti {name}",
|
||||
"interaction_modal.title.reblog": "Galak hantaran {name}",
|
||||
"interaction_modal.title.reply": "Balas siaran {name}",
|
||||
|
@ -318,8 +370,8 @@
|
|||
"keyboard_shortcuts.direct": "to open direct messages column",
|
||||
"keyboard_shortcuts.down": "to move down in the list",
|
||||
"keyboard_shortcuts.enter": "Buka hantaran",
|
||||
"keyboard_shortcuts.favourite": "Pos kegemaran",
|
||||
"keyboard_shortcuts.favourites": "Buka senarai kegemaran",
|
||||
"keyboard_shortcuts.favourite": "Suka hantaran",
|
||||
"keyboard_shortcuts.favourites": "Buka senarai sukaan",
|
||||
"keyboard_shortcuts.federated": "to open federated timeline",
|
||||
"keyboard_shortcuts.heading": "Pintasan papan kekunci",
|
||||
"keyboard_shortcuts.home": "to open home timeline",
|
||||
|
@ -367,7 +419,7 @@
|
|||
"navigation_bar.discover": "Teroka",
|
||||
"navigation_bar.domain_blocks": "Domain disekat",
|
||||
"navigation_bar.explore": "Teroka",
|
||||
"navigation_bar.favourites": "Kegemaran",
|
||||
"navigation_bar.favourites": "Sukaan",
|
||||
"navigation_bar.filters": "Perkataan yang dibisukan",
|
||||
"navigation_bar.follow_requests": "Permintaan ikutan",
|
||||
"navigation_bar.followed_tags": "Ikuti hashtag",
|
||||
|
@ -385,11 +437,15 @@
|
|||
"not_signed_in_indicator.not_signed_in": "Anda perlu daftar masuk untuk mencapai sumber ini.",
|
||||
"notification.admin.report": "{name} melaporkan {target}",
|
||||
"notification.admin.sign_up": "{name} mendaftar",
|
||||
"notification.favourite": "{name} menggemari pos anda",
|
||||
"notification.favourite": "{name} menyukai hantaran anda",
|
||||
"notification.favourite.name_and_others_with_link": "{name} dan <a>{count, plural, other {# orang lain}}</a> telah suka hantaran anda",
|
||||
"notification.favourite_pm": "{name} menyukai sebutan persendirian anda",
|
||||
"notification.favourite_pm.name_and_others_with_link": "{name} dan <a>{count, plural, other {# orang lain}}</a> telah suka sebutan persendirian anda",
|
||||
"notification.follow": "{name} mengikuti anda",
|
||||
"notification.follow_request": "{name} meminta untuk mengikuti anda",
|
||||
"notification.own_poll": "Undian anda telah tamat",
|
||||
"notification.reblog": "{name} menggalak hantaran anda",
|
||||
"notification.reblog.name_and_others_with_link": "{name} dan <a>{count, plural, other {# orang lain}}</a> telah galakkan hantaran anda",
|
||||
"notification.status": "{name} baru sahaja mengirim hantaran",
|
||||
"notification.update": "{name} menyunting hantaran",
|
||||
"notifications.clear": "Buang pemberitahuan",
|
||||
|
@ -397,7 +453,7 @@
|
|||
"notifications.column_settings.admin.report": "Laporan baru:",
|
||||
"notifications.column_settings.admin.sign_up": "Pendaftaran baru:",
|
||||
"notifications.column_settings.alert": "Pemberitahuan atas meja",
|
||||
"notifications.column_settings.favourite": "Kegemaran:",
|
||||
"notifications.column_settings.favourite": "Sukaan:",
|
||||
"notifications.column_settings.follow": "Pengikut baharu:",
|
||||
"notifications.column_settings.follow_request": "Permintaan ikutan baharu:",
|
||||
"notifications.column_settings.mention": "Sebutan:",
|
||||
|
@ -412,7 +468,7 @@
|
|||
"notifications.column_settings.update": "Suntingan:",
|
||||
"notifications.filter.all": "Semua",
|
||||
"notifications.filter.boosts": "Galakan",
|
||||
"notifications.filter.favourites": "Kegemaran",
|
||||
"notifications.filter.favourites": "Sukaan",
|
||||
"notifications.filter.follows": "Ikutan",
|
||||
"notifications.filter.mentions": "Sebutan",
|
||||
"notifications.filter.polls": "Keputusan undian",
|
||||
|
@ -546,7 +602,7 @@
|
|||
"status.admin_status": "Buka hantaran ini dalam antara muka penyederhanaan",
|
||||
"status.block": "Sekat @{name}",
|
||||
"status.bookmark": "Tanda buku",
|
||||
"status.cancel_reblog_private": "Nyahgalak",
|
||||
"status.cancel_reblog_private": "Nyahgalakkan",
|
||||
"status.cannot_reblog": "Hantaran ini tidak boleh digalakkan",
|
||||
"status.copy": "Salin pautan ke hantaran",
|
||||
"status.delete": "Padam",
|
||||
|
@ -555,7 +611,8 @@
|
|||
"status.direct_indicator": "Sebutan peribadi",
|
||||
"status.edit": "Sunting",
|
||||
"status.edited_x_times": "Disunting {count, plural, other {{count} kali}}",
|
||||
"status.favourite": "Kegemaran",
|
||||
"status.favourite": "Suka",
|
||||
"status.favourites": "{count, plural, other {sukaan}}",
|
||||
"status.filter": "Tapiskan hantaran ini",
|
||||
"status.history.created": "{name} mencipta pada {date}",
|
||||
"status.history.edited": "{name} menyunting pada {date}",
|
||||
|
@ -572,11 +629,13 @@
|
|||
"status.pinned": "Hantaran disemat",
|
||||
"status.read_more": "Baca lagi",
|
||||
"status.reblog": "Galakkan",
|
||||
"status.reblog_private": "Galakkan dengan kebolehlihatan asal",
|
||||
"status.reblogged_by": "{name} telah menggalakkan",
|
||||
"status.reblogs.empty": "Tiada sesiapa yang menggalak hantaran ini. Apabila ada yang menggalak, ia akan muncul di sini.",
|
||||
"status.reblog_private": "Galakkan dengan ketampakan asal",
|
||||
"status.reblogged_by": "{name} galakkan",
|
||||
"status.reblogs": "{count, plural, other {galakan}}",
|
||||
"status.reblogs.empty": "Tiada sesiapa yang galakkan hantaran ini. Apabila ada yang galakkan, hantaran akan muncul di sini.",
|
||||
"status.redraft": "Padam & rangka semula",
|
||||
"status.remove_bookmark": "Buang tanda buku",
|
||||
"status.remove_favourite": "Padam dari sukaan",
|
||||
"status.replied_to": "Menjawab kepada {name}",
|
||||
"status.reply": "Balas",
|
||||
"status.replyAll": "Balas ke bebenang",
|
||||
|
@ -612,6 +671,8 @@
|
|||
"upload_button.label": "Tambah fail imej, video atau audio",
|
||||
"upload_error.limit": "Sudah melebihi had muat naik.",
|
||||
"upload_error.poll": "Tidak boleh memuat naik fail bersama undian.",
|
||||
"upload_form.drag_and_drop.instructions": "Untuk mengangkat lampiran media, tekan jarak atau enter. Ketika menarik, gunakan kekunci anak panah untuk menggerakkan lampiran media pada mana-mana arah. Tekan jarak atau enter untuk melepaskan lampiran media pada kedudukan baharunya, atau tekan keluar untuk batalkan.",
|
||||
"upload_form.drag_and_drop.on_drag_cancel": "Seretan dibatalkan. Lampiran media {item} dilepaskan.",
|
||||
"upload_form.edit": "Sunting",
|
||||
"upload_progress.label": "Memuat naik...",
|
||||
"upload_progress.processing": "Memproses…",
|
||||
|
|
|
@ -697,6 +697,7 @@
|
|||
"poll_button.remove_poll": "Fjern rundspørjing",
|
||||
"privacy.change": "Endre personvernet på innlegg",
|
||||
"privacy.direct.long": "Alle nemnde i innlegget",
|
||||
"privacy.direct.short": "Privat omtale",
|
||||
"privacy.private.long": "Berre dei som fylgjer deg",
|
||||
"privacy.private.short": "Fylgjarar",
|
||||
"privacy.public.long": "Kven som helst på og av Mastodon",
|
||||
|
|
|
@ -697,6 +697,7 @@
|
|||
"poll_button.remove_poll": "Usuń ankietę",
|
||||
"privacy.change": "Dostosuj widoczność wpisów",
|
||||
"privacy.direct.long": "Wszyscy wzmiankowani w tym wpisie",
|
||||
"privacy.direct.short": "Wzmianka bezpośrednia",
|
||||
"privacy.private.long": "Tylko obserwujący",
|
||||
"privacy.private.short": "Obserwujący",
|
||||
"privacy.public.long": "Każdy na i poza Mastodon",
|
||||
|
|
|
@ -697,6 +697,7 @@
|
|||
"poll_button.remove_poll": "Remover sondagem",
|
||||
"privacy.change": "Alterar a privacidade da publicação",
|
||||
"privacy.direct.long": "Todos os mencionados na publicação",
|
||||
"privacy.direct.short": "Menção privada",
|
||||
"privacy.private.long": "Apenas os teus seguidores",
|
||||
"privacy.private.short": "Seguidores",
|
||||
"privacy.public.long": "Qualquer pessoa no Mastodon ou não",
|
||||
|
|
|
@ -697,6 +697,7 @@
|
|||
"poll_button.remove_poll": "Удалить опрос",
|
||||
"privacy.change": "Изменить видимость поста",
|
||||
"privacy.direct.long": "Все упомянутые в посте",
|
||||
"privacy.direct.short": "Личное упоминание",
|
||||
"privacy.private.long": "Только ваши подписчики",
|
||||
"privacy.private.short": "Подписчики",
|
||||
"privacy.public.long": "Любой, находящийся на Mastodon и вне его",
|
||||
|
|
|
@ -700,7 +700,7 @@
|
|||
"privacy.direct.short": "私下提及",
|
||||
"privacy.private.long": "仅限你的关注者",
|
||||
"privacy.private.short": "关注者",
|
||||
"privacy.public.long": "",
|
||||
"privacy.public.long": "所有 Mastodon 内外的人",
|
||||
"privacy.public.short": "公开",
|
||||
"privacy.unlisted.additional": "此模式的行为与“公开”类似,只是嘟文不会出现在实时动态、话题、探索或 Mastodon 搜索页面中,即使您已全局开启了对应的发现设置。",
|
||||
"privacy.unlisted.long": "减少算法影响",
|
||||
|
|
24
app/javascript/mastodon/models/dropdown_menu.ts
Normal file
24
app/javascript/mastodon/models/dropdown_menu.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
interface BaseMenuItem {
|
||||
text: string;
|
||||
dangerous?: boolean;
|
||||
}
|
||||
|
||||
interface ActionMenuItem extends BaseMenuItem {
|
||||
action: () => void;
|
||||
}
|
||||
|
||||
interface LinkMenuItem extends BaseMenuItem {
|
||||
to: string;
|
||||
}
|
||||
|
||||
interface ExternalLinkMenuItem extends BaseMenuItem {
|
||||
href: string;
|
||||
}
|
||||
|
||||
export type MenuItem =
|
||||
| ActionMenuItem
|
||||
| LinkMenuItem
|
||||
| ExternalLinkMenuItem
|
||||
| null;
|
||||
|
||||
export type DropdownMenu = MenuItem[];
|
|
@ -1,6 +1,7 @@
|
|||
import { createSelector } from '@reduxjs/toolkit';
|
||||
import { Record as ImmutableRecord } from 'immutable';
|
||||
|
||||
import { me } from 'mastodon/initial_state';
|
||||
import { accountDefaultValues } from 'mastodon/models/account';
|
||||
import type { Account, AccountShape } from 'mastodon/models/account';
|
||||
import type { Relationship } from 'mastodon/models/relationship';
|
||||
|
@ -45,3 +46,16 @@ export function makeGetAccount() {
|
|||
},
|
||||
);
|
||||
}
|
||||
|
||||
export const getAccountHidden = createSelector(
|
||||
[
|
||||
(state: RootState, id: string) => state.accounts.get(id)?.hidden,
|
||||
(state: RootState, id: string) =>
|
||||
state.relationships.get(id)?.following ||
|
||||
state.relationships.get(id)?.requested,
|
||||
(state: RootState, id: string) => id === me,
|
||||
],
|
||||
(hidden, followingOrRequested, isSelf) => {
|
||||
return hidden && !(isSelf || followingOrRequested);
|
||||
},
|
||||
);
|
||||
|
|
|
@ -109,27 +109,23 @@ export const makeGetReport = () => createSelector([
|
|||
|
||||
export const getAccountGallery = createSelector([
|
||||
(state, id) => state.getIn(['timelines', `account:${id}:media`, 'items'], ImmutableList()),
|
||||
state => state.get('statuses'),
|
||||
state => state.get('statuses'),
|
||||
(state, id) => state.getIn(['accounts', id]),
|
||||
], (statusIds, statuses, account) => {
|
||||
let medias = ImmutableList();
|
||||
|
||||
statusIds.forEach(statusId => {
|
||||
const status = statuses.get(statusId).set('account', account);
|
||||
medias = medias.concat(status.get('media_attachments').map(media => media.set('status', status)));
|
||||
let status = statuses.get(statusId);
|
||||
|
||||
if (status) {
|
||||
status = status.set('account', account);
|
||||
medias = medias.concat(status.get('media_attachments').map(media => media.set('status', status)));
|
||||
}
|
||||
});
|
||||
|
||||
return medias;
|
||||
});
|
||||
|
||||
export const getAccountHidden = createSelector([
|
||||
(state, id) => state.getIn(['accounts', id, 'hidden']),
|
||||
(state, id) => state.getIn(['relationships', id, 'following']) || state.getIn(['relationships', id, 'requested']),
|
||||
(state, id) => id === me,
|
||||
], (hidden, followingOrRequested, isSelf) => {
|
||||
return hidden && !(isSelf || followingOrRequested);
|
||||
});
|
||||
|
||||
export const getStatusList = createSelector([
|
||||
(state, type) => state.getIn(['status_lists', type, 'items']),
|
||||
], (items) => items.toList());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue