Merge branch 'account-local' into 'main'
Add 'local' to account schema See merge request soapbox-pub/soapbox!2835
This commit is contained in:
commit
b25408a79f
18 changed files with 48 additions and 62 deletions
|
@ -9,7 +9,6 @@ import { Stack, Text } from 'soapbox/components/ui';
|
||||||
import AccountContainer from 'soapbox/containers/account-container';
|
import AccountContainer from 'soapbox/containers/account-container';
|
||||||
import { selectAccount } from 'soapbox/selectors';
|
import { selectAccount } from 'soapbox/selectors';
|
||||||
import toast from 'soapbox/toast';
|
import toast from 'soapbox/toast';
|
||||||
import { isLocal } from 'soapbox/utils/accounts';
|
|
||||||
|
|
||||||
import type { AppDispatch, RootState } from 'soapbox/store';
|
import type { AppDispatch, RootState } from 'soapbox/store';
|
||||||
|
|
||||||
|
@ -79,7 +78,7 @@ const deleteUserModal = (intl: IntlShape, accountId: string, afterConfirm = () =
|
||||||
const account = selectAccount(state, accountId)!;
|
const account = selectAccount(state, accountId)!;
|
||||||
const acct = account.acct;
|
const acct = account.acct;
|
||||||
const name = account.username;
|
const name = account.username;
|
||||||
const local = isLocal(account);
|
const local = account.local;
|
||||||
|
|
||||||
const message = (
|
const message = (
|
||||||
<Stack space={4}>
|
<Stack space={4}>
|
||||||
|
|
|
@ -10,7 +10,7 @@ import Icon from './icon';
|
||||||
import { Button, HStack, Stack, Text } from './ui';
|
import { Button, HStack, Stack, Text } from './ui';
|
||||||
import VerificationBadge from './verification-badge';
|
import VerificationBadge from './verification-badge';
|
||||||
|
|
||||||
import type { Account as AccountEntity, Status as StatusEntity } from 'soapbox/types/entities';
|
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
eventBanner: { id: 'event.banner', defaultMessage: 'Event banner' },
|
eventBanner: { id: 'event.banner', defaultMessage: 'Event banner' },
|
||||||
|
@ -30,7 +30,7 @@ const EventPreview: React.FC<IEventPreview> = ({ status, className, hideAction,
|
||||||
|
|
||||||
const me = useAppSelector((state) => state.me);
|
const me = useAppSelector((state) => state.me);
|
||||||
|
|
||||||
const account = status.account as AccountEntity;
|
const account = status.account;
|
||||||
const event = status.event!;
|
const event = status.event!;
|
||||||
|
|
||||||
const banner = event.banner;
|
const banner = event.banner;
|
||||||
|
|
|
@ -14,7 +14,6 @@ import Badge from 'soapbox/components/badge';
|
||||||
import ActionButton from 'soapbox/features/ui/components/action-button';
|
import ActionButton from 'soapbox/features/ui/components/action-button';
|
||||||
import { UserPanel } from 'soapbox/features/ui/util/async-components';
|
import { UserPanel } from 'soapbox/features/ui/util/async-components';
|
||||||
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
import { useAppSelector, useAppDispatch } from 'soapbox/hooks';
|
||||||
import { isLocal } from 'soapbox/utils/accounts';
|
|
||||||
|
|
||||||
import { showProfileHoverCard } from './hover-ref-wrapper';
|
import { showProfileHoverCard } from './hover-ref-wrapper';
|
||||||
import { dateFormatOptions } from './relative-timestamp';
|
import { dateFormatOptions } from './relative-timestamp';
|
||||||
|
@ -117,7 +116,7 @@ export const ProfileHoverCard: React.FC<IProfileHoverCard> = ({ visible = true }
|
||||||
badges={badges}
|
badges={badges}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{isLocal(account) ? (
|
{account.local ? (
|
||||||
<HStack alignItems='center' space={0.5}>
|
<HStack alignItems='center' space={0.5}>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/calendar.svg')}
|
src={require('@tabler/icons/calendar.svg')}
|
||||||
|
|
|
@ -15,7 +15,7 @@ import StatusContent from './status-content';
|
||||||
import StatusReplyMentions from './status-reply-mentions';
|
import StatusReplyMentions from './status-reply-mentions';
|
||||||
import SensitiveContentOverlay from './statuses/sensitive-content-overlay';
|
import SensitiveContentOverlay from './statuses/sensitive-content-overlay';
|
||||||
|
|
||||||
import type { Account as AccountEntity, Status as StatusEntity } from 'soapbox/types/entities';
|
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
|
cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
|
||||||
|
@ -51,7 +51,7 @@ const QuotedStatus: React.FC<IQuotedStatus> = ({ status, onCancel, compose }) =>
|
||||||
|
|
||||||
const handleExpandClick: MouseEventHandler<HTMLDivElement> = (e) => {
|
const handleExpandClick: MouseEventHandler<HTMLDivElement> = (e) => {
|
||||||
if (!status) return;
|
if (!status) return;
|
||||||
const account = status.account as AccountEntity;
|
const account = status.account;
|
||||||
|
|
||||||
if (!compose && e.button === 0) {
|
if (!compose && e.button === 0) {
|
||||||
const statusUrl = `/@${account.acct}/posts/${status.id}`;
|
const statusUrl = `/@${account.acct}/posts/${status.id}`;
|
||||||
|
@ -79,7 +79,7 @@ const QuotedStatus: React.FC<IQuotedStatus> = ({ status, onCancel, compose }) =>
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const account = status.account as AccountEntity;
|
const account = status.account;
|
||||||
|
|
||||||
let actions = {};
|
let actions = {};
|
||||||
if (onCancel) {
|
if (onCancel) {
|
||||||
|
|
|
@ -23,14 +23,13 @@ import { HStack } from 'soapbox/components/ui';
|
||||||
import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount, useSettings, useSoapboxConfig } from 'soapbox/hooks';
|
import { useAppDispatch, useAppSelector, useFeatures, useOwnAccount, useSettings, useSoapboxConfig } from 'soapbox/hooks';
|
||||||
import { GroupRoles } from 'soapbox/schemas/group-member';
|
import { GroupRoles } from 'soapbox/schemas/group-member';
|
||||||
import toast from 'soapbox/toast';
|
import toast from 'soapbox/toast';
|
||||||
import { isLocal, isRemote } from 'soapbox/utils/accounts';
|
|
||||||
import copy from 'soapbox/utils/copy';
|
import copy from 'soapbox/utils/copy';
|
||||||
import { getReactForStatus, reduceEmoji } from 'soapbox/utils/emoji-reacts';
|
import { getReactForStatus, reduceEmoji } from 'soapbox/utils/emoji-reacts';
|
||||||
|
|
||||||
import GroupPopover from './groups/popover/group-popover';
|
import GroupPopover from './groups/popover/group-popover';
|
||||||
|
|
||||||
import type { Menu } from 'soapbox/components/dropdown-menu';
|
import type { Menu } from 'soapbox/components/dropdown-menu';
|
||||||
import type { Account, Group, Status } from 'soapbox/types/entities';
|
import type { Group, Status } from 'soapbox/types/entities';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
adminAccount: { id: 'status.admin_account', defaultMessage: 'Moderate @{name}' },
|
adminAccount: { id: 'status.admin_account', defaultMessage: 'Moderate @{name}' },
|
||||||
|
@ -132,7 +131,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
const unmuteGroup = useUnmuteGroup(group as Group);
|
const unmuteGroup = useUnmuteGroup(group as Group);
|
||||||
const isMutingGroup = !!group?.relationship?.muting;
|
const isMutingGroup = !!group?.relationship?.muting;
|
||||||
const deleteGroupStatus = useDeleteGroupStatus(group as Group, status.id);
|
const deleteGroupStatus = useDeleteGroupStatus(group as Group, status.id);
|
||||||
const blockGroupMember = useBlockGroupMember(group as Group, status?.account as any);
|
const blockGroupMember = useBlockGroupMember(group as Group, status.account);
|
||||||
|
|
||||||
const me = useAppSelector(state => state.me);
|
const me = useAppSelector(state => state.me);
|
||||||
const { groupRelationship } = useGroupRelationship(status.group?.id);
|
const { groupRelationship } = useGroupRelationship(status.group?.id);
|
||||||
|
@ -267,20 +266,20 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMentionClick: React.EventHandler<React.MouseEvent> = (e) => {
|
const handleMentionClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
dispatch(mentionCompose(status.account as Account));
|
dispatch(mentionCompose(status.account));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDirectClick: React.EventHandler<React.MouseEvent> = (e) => {
|
const handleDirectClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
dispatch(directCompose(status.account as Account));
|
dispatch(directCompose(status.account));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleChatClick: React.EventHandler<React.MouseEvent> = (e) => {
|
const handleChatClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
const account = status.account as Account;
|
const account = status.account;
|
||||||
dispatch(launchChat(account.id, history));
|
dispatch(launchChat(account.id, history));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMuteClick: React.EventHandler<React.MouseEvent> = (e) => {
|
const handleMuteClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
dispatch(initMuteModal(status.account as Account));
|
dispatch(initMuteModal(status.account));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMuteGroupClick: React.EventHandler<React.MouseEvent> = () =>
|
const handleMuteGroupClick: React.EventHandler<React.MouseEvent> = () =>
|
||||||
|
@ -305,7 +304,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBlockClick: React.EventHandler<React.MouseEvent> = (e) => {
|
const handleBlockClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
const account = status.account as Account;
|
const account = status.account;
|
||||||
|
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
icon: require('@tabler/icons/ban.svg'),
|
icon: require('@tabler/icons/ban.svg'),
|
||||||
|
@ -333,7 +332,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReport: React.EventHandler<React.MouseEvent> = (e) => {
|
const handleReport: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
dispatch(initReport(ReportableEntities.STATUS, status.account as Account, { status }));
|
dispatch(initReport(ReportableEntities.STATUS, status.account, { status }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleConversationMuteClick: React.EventHandler<React.MouseEvent> = (e) => {
|
const handleConversationMuteClick: React.EventHandler<React.MouseEvent> = (e) => {
|
||||||
|
@ -347,7 +346,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const onModerate: React.MouseEventHandler = (e) => {
|
const onModerate: React.MouseEventHandler = (e) => {
|
||||||
const account = status.account as Account;
|
const account = status.account;
|
||||||
dispatch(openModal('ACCOUNT_MODERATION', { accountId: account.id }));
|
dispatch(openModal('ACCOUNT_MODERATION', { accountId: account.id }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -360,7 +359,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleDeleteFromGroup: React.EventHandler<React.MouseEvent> = () => {
|
const handleDeleteFromGroup: React.EventHandler<React.MouseEvent> = () => {
|
||||||
const account = status.account as Account;
|
const account = status.account;
|
||||||
|
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
heading: intl.formatMessage(messages.deleteHeading),
|
heading: intl.formatMessage(messages.deleteHeading),
|
||||||
|
@ -379,10 +378,10 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
const handleBlockFromGroup = () => {
|
const handleBlockFromGroup = () => {
|
||||||
dispatch(openModal('CONFIRM', {
|
dispatch(openModal('CONFIRM', {
|
||||||
heading: intl.formatMessage(messages.groupBlockFromGroupHeading),
|
heading: intl.formatMessage(messages.groupBlockFromGroupHeading),
|
||||||
message: intl.formatMessage(messages.groupBlockFromGroupMessage, { name: (status.account as any).username }),
|
message: intl.formatMessage(messages.groupBlockFromGroupMessage, { name: status.account.username }),
|
||||||
confirm: intl.formatMessage(messages.groupBlockConfirm),
|
confirm: intl.formatMessage(messages.groupBlockConfirm),
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
blockGroupMember({ account_ids: [(status.account as any).id] }, {
|
blockGroupMember({ account_ids: [status.account.id] }, {
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
toast.success(intl.formatMessage(messages.blocked, { name: account?.acct }));
|
toast.success(intl.formatMessage(messages.blocked, { name: account?.acct }));
|
||||||
},
|
},
|
||||||
|
@ -415,7 +414,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
icon: require('@tabler/icons/clipboard-copy.svg'),
|
icon: require('@tabler/icons/clipboard-copy.svg'),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (features.embeds && isLocal(account)) {
|
if (features.embeds && account.local) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.embed),
|
text: intl.formatMessage(messages.embed),
|
||||||
action: handleEmbed,
|
action: handleEmbed,
|
||||||
|
@ -449,7 +448,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (features.federating && isRemote(account)) {
|
if (features.federating && !account.local) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.external, { domain }),
|
text: intl.formatMessage(messages.external, { domain }),
|
||||||
action: handleExternalClick,
|
action: handleExternalClick,
|
||||||
|
@ -554,7 +553,7 @@ const StatusActionBar: React.FC<IStatusActionBar> = ({
|
||||||
|
|
||||||
if (isGroupStatus && !!status.group) {
|
if (isGroupStatus && !!status.group) {
|
||||||
const group = status.group as Group;
|
const group = status.group as Group;
|
||||||
const account = status.account as Account;
|
const account = status.account;
|
||||||
const isGroupOwner = groupRelationship?.role === GroupRoles.OWNER;
|
const isGroupOwner = groupRelationship?.role === GroupRoles.OWNER;
|
||||||
const isGroupAdmin = groupRelationship?.role === GroupRoles.ADMIN;
|
const isGroupAdmin = groupRelationship?.role === GroupRoles.ADMIN;
|
||||||
const isStatusFromOwner = group.owner.id === account.id;
|
const isStatusFromOwner = group.owner.id === account.id;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import HoverStatusWrapper from 'soapbox/components/hover-status-wrapper';
|
||||||
import { useAppDispatch } from 'soapbox/hooks';
|
import { useAppDispatch } from 'soapbox/hooks';
|
||||||
import { isPubkey } from 'soapbox/utils/nostr';
|
import { isPubkey } from 'soapbox/utils/nostr';
|
||||||
|
|
||||||
import type { Account, Status } from 'soapbox/types/entities';
|
import type { Status } from 'soapbox/types/entities';
|
||||||
|
|
||||||
interface IStatusReplyMentions {
|
interface IStatusReplyMentions {
|
||||||
status: Status;
|
status: Status;
|
||||||
|
@ -21,7 +21,7 @@ const StatusReplyMentions: React.FC<IStatusReplyMentions> = ({ status, hoverable
|
||||||
const handleOpenMentionsModal: React.MouseEventHandler<HTMLSpanElement> = (e) => {
|
const handleOpenMentionsModal: React.MouseEventHandler<HTMLSpanElement> = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
const account = status.account as Account;
|
const account = status.account;
|
||||||
|
|
||||||
dispatch(openModal('MENTIONS', {
|
dispatch(openModal('MENTIONS', {
|
||||||
username: account.acct,
|
username: account.acct,
|
||||||
|
|
|
@ -24,10 +24,7 @@ import StatusInfo from './statuses/status-info';
|
||||||
import Tombstone from './tombstone';
|
import Tombstone from './tombstone';
|
||||||
import { Card, Icon, Stack, Text } from './ui';
|
import { Card, Icon, Stack, Text } from './ui';
|
||||||
|
|
||||||
import type {
|
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||||
Account as AccountEntity,
|
|
||||||
Status as StatusEntity,
|
|
||||||
} from 'soapbox/types/entities';
|
|
||||||
|
|
||||||
// Defined in components/scrollable-list
|
// Defined in components/scrollable-list
|
||||||
export type ScrollPosition = { height: number; top: number };
|
export type ScrollPosition = { height: number; top: number };
|
||||||
|
@ -168,7 +165,7 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
|
|
||||||
const handleHotkeyMention = (e?: KeyboardEvent): void => {
|
const handleHotkeyMention = (e?: KeyboardEvent): void => {
|
||||||
e?.preventDefault();
|
e?.preventDefault();
|
||||||
dispatch(mentionCompose(actualStatus.account as AccountEntity));
|
dispatch(mentionCompose(actualStatus.account));
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleHotkeyOpen = (): void => {
|
const handleHotkeyOpen = (): void => {
|
||||||
|
|
|
@ -3,11 +3,10 @@ import { FormattedMessage, useIntl } from 'react-intl';
|
||||||
|
|
||||||
import { translateStatus, undoStatusTranslation } from 'soapbox/actions/statuses';
|
import { translateStatus, undoStatusTranslation } from 'soapbox/actions/statuses';
|
||||||
import { useAppDispatch, useAppSelector, useFeatures, useInstance } from 'soapbox/hooks';
|
import { useAppDispatch, useAppSelector, useFeatures, useInstance } from 'soapbox/hooks';
|
||||||
import { isLocal } from 'soapbox/utils/accounts';
|
|
||||||
|
|
||||||
import { Stack, Button, Text } from './ui';
|
import { Stack, Button, Text } from './ui';
|
||||||
|
|
||||||
import type { Account, Status } from 'soapbox/types/entities';
|
import type { Status } from 'soapbox/types/entities';
|
||||||
|
|
||||||
interface ITranslateButton {
|
interface ITranslateButton {
|
||||||
status: Status;
|
status: Status;
|
||||||
|
@ -28,7 +27,7 @@ const TranslateButton: React.FC<ITranslateButton> = ({ status }) => {
|
||||||
target_languages: targetLanguages,
|
target_languages: targetLanguages,
|
||||||
} = instance.pleroma.metadata.translation;
|
} = instance.pleroma.metadata.translation;
|
||||||
|
|
||||||
const renderTranslate = (me || allowUnauthenticated) && (allowRemote || isLocal(status.account as Account)) && ['public', 'unlisted'].includes(status.visibility) && status.contentHtml.length > 0 && status.language !== null && intl.locale !== status.language;
|
const renderTranslate = (me || allowUnauthenticated) && (allowRemote || status.account.local) && ['public', 'unlisted'].includes(status.visibility) && status.contentHtml.length > 0 && status.language !== null && intl.locale !== status.language;
|
||||||
|
|
||||||
const supportsLanguages = (!sourceLanguages || sourceLanguages.includes(status.language!)) && (!targetLanguages || targetLanguages.includes(intl.locale));
|
const supportsLanguages = (!sourceLanguages || sourceLanguages.includes(status.language!)) && (!targetLanguages || targetLanguages.includes(intl.locale));
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ import { ChatKeys, useChats } from 'soapbox/queries/chats';
|
||||||
import { queryClient } from 'soapbox/queries/client';
|
import { queryClient } from 'soapbox/queries/client';
|
||||||
import { Account } from 'soapbox/schemas';
|
import { Account } from 'soapbox/schemas';
|
||||||
import toast from 'soapbox/toast';
|
import toast from 'soapbox/toast';
|
||||||
import { isDefaultHeader, isLocal, isRemote } from 'soapbox/utils/accounts';
|
import { isDefaultHeader } from 'soapbox/utils/accounts';
|
||||||
import copy from 'soapbox/utils/copy';
|
import copy from 'soapbox/utils/copy';
|
||||||
import { MASTODON, parseVersion } from 'soapbox/utils/features';
|
import { MASTODON, parseVersion } from 'soapbox/utils/features';
|
||||||
|
|
||||||
|
@ -287,7 +287,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (features.rssFeeds && isLocal(account)) {
|
if (features.rssFeeds && account.local) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.subscribeFeed),
|
text: intl.formatMessage(messages.subscribeFeed),
|
||||||
action: handleRssFeedClick,
|
action: handleRssFeedClick,
|
||||||
|
@ -303,7 +303,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (features.federating && isRemote(account)) {
|
if (features.federating && !account.local) {
|
||||||
const domain = account.fqn.split('@')[1];
|
const domain = account.fqn.split('@')[1];
|
||||||
|
|
||||||
menu.push({
|
menu.push({
|
||||||
|
@ -453,7 +453,7 @@ const Header: React.FC<IHeader> = ({ account }) => {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isRemote(account)) {
|
if (!account.local) {
|
||||||
const domain = account.fqn.split('@')[1];
|
const domain = account.fqn.split('@')[1];
|
||||||
|
|
||||||
menu.push(null);
|
menu.push(null);
|
||||||
|
|
|
@ -19,7 +19,6 @@ import { Button, HStack, IconButton, Menu, MenuButton, MenuDivider, MenuItem, Me
|
||||||
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
|
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
|
||||||
import VerificationBadge from 'soapbox/components/verification-badge';
|
import VerificationBadge from 'soapbox/components/verification-badge';
|
||||||
import { useAppDispatch, useFeatures, useOwnAccount, useSettings } from 'soapbox/hooks';
|
import { useAppDispatch, useFeatures, useOwnAccount, useSettings } from 'soapbox/hooks';
|
||||||
import { isRemote } from 'soapbox/utils/accounts';
|
|
||||||
import copy from 'soapbox/utils/copy';
|
import copy from 'soapbox/utils/copy';
|
||||||
import { download } from 'soapbox/utils/download';
|
import { download } from 'soapbox/utils/download';
|
||||||
import { shortNumberFormat } from 'soapbox/utils/numbers';
|
import { shortNumberFormat } from 'soapbox/utils/numbers';
|
||||||
|
@ -29,7 +28,7 @@ import EventActionButton from '../components/event-action-button';
|
||||||
import EventDate from '../components/event-date';
|
import EventDate from '../components/event-date';
|
||||||
|
|
||||||
import type { Menu as MenuType } from 'soapbox/components/dropdown-menu';
|
import type { Menu as MenuType } from 'soapbox/components/dropdown-menu';
|
||||||
import type { Account as AccountEntity, Status as StatusEntity } from 'soapbox/types/entities';
|
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
bannerHeader: { id: 'event.banner', defaultMessage: 'Event banner' },
|
bannerHeader: { id: 'event.banner', defaultMessage: 'Event banner' },
|
||||||
|
@ -89,7 +88,7 @@ const EventHeader: React.FC<IEventHeader> = ({ status }) => {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const account = status.account as AccountEntity;
|
const account = status.account;
|
||||||
const event = status.event;
|
const event = status.event;
|
||||||
const banner = event.banner;
|
const banner = event.banner;
|
||||||
|
|
||||||
|
@ -217,7 +216,7 @@ const EventHeader: React.FC<IEventHeader> = ({ status }) => {
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
if (features.federating && isRemote(account)) {
|
if (features.federating && !account.local) {
|
||||||
menu.push({
|
menu.push({
|
||||||
text: intl.formatMessage(messages.external, { domain }),
|
text: intl.formatMessage(messages.external, { domain }),
|
||||||
action: handleExternalClick,
|
action: handleExternalClick,
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { buildStatus } from '../builder';
|
||||||
|
|
||||||
import ScheduledStatusActionBar from './scheduled-status-action-bar';
|
import ScheduledStatusActionBar from './scheduled-status-action-bar';
|
||||||
|
|
||||||
import type { Account as AccountEntity, Status as StatusEntity } from 'soapbox/types/entities';
|
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||||
|
|
||||||
interface IScheduledStatus {
|
interface IScheduledStatus {
|
||||||
statusId: string;
|
statusId: string;
|
||||||
|
@ -28,7 +28,7 @@ const ScheduledStatus: React.FC<IScheduledStatus> = ({ statusId, ...other }) =>
|
||||||
|
|
||||||
if (!status) return null;
|
if (!status) return null;
|
||||||
|
|
||||||
const account = status.account as AccountEntity;
|
const account = status.account;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx('status__wrapper', `status__wrapper-${status.visibility}`, { 'status__wrapper-reply': !!status.in_reply_to_id })} tabIndex={0}>
|
<div className={clsx('status__wrapper', `status__wrapper-${status.visibility}`, { 'status__wrapper-reply': !!status.in_reply_to_id })} tabIndex={0}>
|
||||||
|
|
|
@ -12,7 +12,6 @@ import OutlineBox from 'soapbox/components/outline-box';
|
||||||
import { Button, Text, HStack, Modal, Stack, Toggle } from 'soapbox/components/ui';
|
import { Button, Text, HStack, Modal, Stack, Toggle } from 'soapbox/components/ui';
|
||||||
import { useAppDispatch, useFeatures, useOwnAccount } from 'soapbox/hooks';
|
import { useAppDispatch, useFeatures, useOwnAccount } from 'soapbox/hooks';
|
||||||
import toast from 'soapbox/toast';
|
import toast from 'soapbox/toast';
|
||||||
import { isLocal } from 'soapbox/utils/accounts';
|
|
||||||
import { getBadges } from 'soapbox/utils/badges';
|
import { getBadges } from 'soapbox/utils/badges';
|
||||||
|
|
||||||
import BadgeInput from './badge-input';
|
import BadgeInput from './badge-input';
|
||||||
|
@ -115,7 +114,7 @@ const AccountModerationModal: React.FC<IAccountModerationModal> = ({ onClose, ac
|
||||||
</OutlineBox>
|
</OutlineBox>
|
||||||
|
|
||||||
<List>
|
<List>
|
||||||
{(ownAccount.admin && isLocal(account)) && (
|
{(ownAccount.admin && account.local) && (
|
||||||
<ListItem label={<FormattedMessage id='account_moderation_modal.fields.account_role' defaultMessage='Staff level' />}>
|
<ListItem label={<FormattedMessage id='account_moderation_modal.fields.account_role' defaultMessage='Staff level' />}>
|
||||||
<div className='w-auto'>
|
<div className='w-auto'>
|
||||||
<StaffRolePicker account={account} />
|
<StaffRolePicker account={account} />
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { fetchRules } from 'soapbox/actions/rules';
|
||||||
import { Button, FormGroup, HStack, Stack, Text, Toggle } from 'soapbox/components/ui';
|
import { Button, FormGroup, HStack, Stack, Text, Toggle } from 'soapbox/components/ui';
|
||||||
import StatusCheckBox from 'soapbox/features/report/components/status-check-box';
|
import StatusCheckBox from 'soapbox/features/report/components/status-check-box';
|
||||||
import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks';
|
import { useAppDispatch, useAppSelector, useFeatures } from 'soapbox/hooks';
|
||||||
import { isRemote, getDomain } from 'soapbox/utils/accounts';
|
import { getDomain } from 'soapbox/utils/accounts';
|
||||||
|
|
||||||
import type { Account } from 'soapbox/schemas';
|
import type { Account } from 'soapbox/schemas';
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ const OtherActionsStep = ({ account }: IOtherActionsStep) => {
|
||||||
const statusIds = useAppSelector((state) => OrderedSet(state.timelines.get(`account:${account.id}:with_replies`)!.items).union(state.reports.new.status_ids) as OrderedSet<string>);
|
const statusIds = useAppSelector((state) => OrderedSet(state.timelines.get(`account:${account.id}:with_replies`)!.items).union(state.reports.new.status_ids) as OrderedSet<string>);
|
||||||
const isBlocked = useAppSelector((state) => state.reports.new.block);
|
const isBlocked = useAppSelector((state) => state.reports.new.block);
|
||||||
const isForward = useAppSelector((state) => state.reports.new.forward);
|
const isForward = useAppSelector((state) => state.reports.new.forward);
|
||||||
const canForward = isRemote(account) && features.federating;
|
const canForward = !account.local && features.federating;
|
||||||
const isSubmitting = useAppSelector((state) => state.reports.new.isSubmitting);
|
const isSubmitting = useAppSelector((state) => state.reports.new.isSubmitting);
|
||||||
|
|
||||||
const [showAdditionalStatuses, setShowAdditionalStatuses] = useState<boolean>(false);
|
const [showAdditionalStatuses, setShowAdditionalStatuses] = useState<boolean>(false);
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { buildStatus } from '../util/pending-status-builder';
|
||||||
|
|
||||||
import PollPreview from './poll-preview';
|
import PollPreview from './poll-preview';
|
||||||
|
|
||||||
import type { Account as AccountEntity, Status as StatusEntity } from 'soapbox/types/entities';
|
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||||
|
|
||||||
const shouldHaveCard = (pendingStatus: StatusEntity) => {
|
const shouldHaveCard = (pendingStatus: StatusEntity) => {
|
||||||
return Boolean(pendingStatus.content.match(/https?:\/\/\S*/));
|
return Boolean(pendingStatus.content.match(/https?:\/\/\S*/));
|
||||||
|
@ -54,7 +54,7 @@ const PendingStatus: React.FC<IPendingStatus> = ({ idempotencyKey, className, mu
|
||||||
if (!status) return null;
|
if (!status) return null;
|
||||||
if (!status.account) return null;
|
if (!status.account) return null;
|
||||||
|
|
||||||
const account = status.account as AccountEntity;
|
const account = status.account;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={clsx('opacity-50', className)}>
|
<div className={clsx('opacity-50', className)}>
|
||||||
|
|
|
@ -7,7 +7,6 @@ import Markup from 'soapbox/components/markup';
|
||||||
import { dateFormatOptions } from 'soapbox/components/relative-timestamp';
|
import { dateFormatOptions } from 'soapbox/components/relative-timestamp';
|
||||||
import { Icon, HStack, Stack, Text } from 'soapbox/components/ui';
|
import { Icon, HStack, Stack, Text } from 'soapbox/components/ui';
|
||||||
import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks';
|
import { useAppSelector, useSoapboxConfig } from 'soapbox/hooks';
|
||||||
import { isLocal } from 'soapbox/utils/accounts';
|
|
||||||
import { badgeToTag, getBadges as getAccountBadges } from 'soapbox/utils/badges';
|
import { badgeToTag, getBadges as getAccountBadges } from 'soapbox/utils/badges';
|
||||||
import { capitalize } from 'soapbox/utils/strings';
|
import { capitalize } from 'soapbox/utils/strings';
|
||||||
|
|
||||||
|
@ -176,7 +175,7 @@ const ProfileInfoPanel: React.FC<IProfileInfoPanel> = ({ account, username }) =>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className='flex flex-col items-start gap-2 md:flex-row md:flex-wrap md:items-center'>
|
<div className='flex flex-col items-start gap-2 md:flex-row md:flex-wrap md:items-center'>
|
||||||
{isLocal(account) ? (
|
{account.local ? (
|
||||||
<HStack alignItems='center' space={0.5}>
|
<HStack alignItems='center' space={0.5}>
|
||||||
<Icon
|
<Icon
|
||||||
src={require('@tabler/icons/calendar.svg')}
|
src={require('@tabler/icons/calendar.svg')}
|
||||||
|
|
|
@ -17,7 +17,7 @@ import {
|
||||||
AccountNotePanel,
|
AccountNotePanel,
|
||||||
} from 'soapbox/features/ui/util/async-components';
|
} from 'soapbox/features/ui/util/async-components';
|
||||||
import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks';
|
import { useAppSelector, useFeatures, useSoapboxConfig } from 'soapbox/hooks';
|
||||||
import { getAcct, isLocal } from 'soapbox/utils/accounts';
|
import { getAcct } from 'soapbox/utils/accounts';
|
||||||
|
|
||||||
interface IProfilePage {
|
interface IProfilePage {
|
||||||
params?: {
|
params?: {
|
||||||
|
@ -118,7 +118,7 @@ const ProfilePage: React.FC<IProfilePage> = ({ params, children }) => {
|
||||||
{(account && account.fields.length > 0) && (
|
{(account && account.fields.length > 0) && (
|
||||||
<ProfileFieldsPanel account={account} />
|
<ProfileFieldsPanel account={account} />
|
||||||
)}
|
)}
|
||||||
{(features.accountEndorsements && account && isLocal(account)) ? (
|
{(features.accountEndorsements && account && account.local) ? (
|
||||||
<PinnedAccountsPanel account={account} limit={5} />
|
<PinnedAccountsPanel account={account} limit={5} />
|
||||||
) : me && features.suggestions && (
|
) : me && features.suggestions && (
|
||||||
<WhoToFollowPanel limit={3} />
|
<WhoToFollowPanel limit={3} />
|
||||||
|
|
|
@ -38,6 +38,7 @@ const baseAccountSchema = z.object({
|
||||||
header_static: z.string().url().optional().catch(undefined),
|
header_static: z.string().url().optional().catch(undefined),
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
last_status_at: z.string().datetime().optional().catch(undefined),
|
last_status_at: z.string().datetime().optional().catch(undefined),
|
||||||
|
local: z.boolean().catch(false),
|
||||||
location: z.string().optional().catch(undefined),
|
location: z.string().optional().catch(undefined),
|
||||||
locked: z.boolean().catch(false),
|
locked: z.boolean().catch(false),
|
||||||
moved: z.literal(null).catch(null),
|
moved: z.literal(null).catch(null),
|
||||||
|
@ -65,6 +66,7 @@ const baseAccountSchema = z.object({
|
||||||
hide_follows: z.boolean().catch(false),
|
hide_follows: z.boolean().catch(false),
|
||||||
hide_follows_count: z.boolean().catch(false),
|
hide_follows_count: z.boolean().catch(false),
|
||||||
is_admin: z.boolean().catch(false),
|
is_admin: z.boolean().catch(false),
|
||||||
|
is_local: z.boolean().optional().catch(undefined),
|
||||||
is_moderator: z.boolean().catch(false),
|
is_moderator: z.boolean().catch(false),
|
||||||
is_suggested: z.boolean().catch(false),
|
is_suggested: z.boolean().catch(false),
|
||||||
location: z.string().optional().catch(undefined),
|
location: z.string().optional().catch(undefined),
|
||||||
|
@ -134,6 +136,7 @@ const transformAccount = <T extends TransformableAccount>({ pleroma, other_setti
|
||||||
fqn: account.fqn || (account.acct.includes('@') ? account.acct : `${account.acct}@${domain}`),
|
fqn: account.fqn || (account.acct.includes('@') ? account.acct : `${account.acct}@${domain}`),
|
||||||
header_static: account.header_static || account.header,
|
header_static: account.header_static || account.header,
|
||||||
moderator: pleroma?.is_moderator || false,
|
moderator: pleroma?.is_moderator || false,
|
||||||
|
local: pleroma?.is_local !== undefined ? pleroma.is_local : account.acct.split('@')[1] === undefined,
|
||||||
location: account.location || pleroma?.location || other_settings?.location || '',
|
location: account.location || pleroma?.location || other_settings?.location || '',
|
||||||
note_emojified: emojify(account.note, customEmojiMap),
|
note_emojified: emojify(account.note, customEmojiMap),
|
||||||
pleroma: (() => {
|
pleroma: (() => {
|
||||||
|
|
|
@ -26,13 +26,6 @@ export const getAcct = (account: Pick<Account, 'fqn' | 'acct'>, displayFqn: bool
|
||||||
displayFqn === true ? account.fqn : account.acct
|
displayFqn === true ? account.fqn : account.acct
|
||||||
);
|
);
|
||||||
|
|
||||||
export const isLocal = (account: Pick<Account, 'acct'>): boolean => {
|
|
||||||
const domain: string = account.acct.split('@')[1];
|
|
||||||
return domain === undefined ? true : false;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const isRemote = (account: Pick<Account, 'acct'>): boolean => !isLocal(account);
|
|
||||||
|
|
||||||
/** Default header filenames from various backends */
|
/** Default header filenames from various backends */
|
||||||
const DEFAULT_HEADERS: string[] = [
|
const DEFAULT_HEADERS: string[] = [
|
||||||
'/headers/original/missing.png', // Mastodon
|
'/headers/original/missing.png', // Mastodon
|
||||||
|
|
Loading…
Reference in a new issue