WIP pl-api migration
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
@@ -23,6 +23,7 @@ import type { Account as BaseAccount, BackendVersion, CreateStatusParams, Group,
|
||||
import type { AutoSuggestion } from 'soapbox/components/autosuggest-input';
|
||||
import type { Emoji } from 'soapbox/features/emoji';
|
||||
import type { Account, Status } from 'soapbox/normalizers';
|
||||
import type { ReducerStatus } from 'soapbox/reducers/statuses';
|
||||
import type { AppDispatch, RootState } from 'soapbox/store';
|
||||
import type { History } from 'soapbox/types/history';
|
||||
|
||||
@@ -110,8 +111,8 @@ const messages = defineMessages({
|
||||
interface ComposeSetStatusAction {
|
||||
type: typeof COMPOSE_SET_STATUS;
|
||||
composeId: string;
|
||||
status: Pick<BaseStatus, 'id' | 'account' | 'content' | 'group' | 'in_reply_to_id' | 'media_attachments' | 'mentions' | 'quote' | 'spoiler_text' | 'visibility'>;
|
||||
poll?: Poll;
|
||||
status: Pick<Status | ReducerStatus, 'id' | 'account' | 'content' | 'group' | 'in_reply_to_id' | 'media_attachments' | 'mentions' | 'quote' | 'spoiler_text' | 'visibility'>;
|
||||
poll?: Poll | null;
|
||||
rawText: string;
|
||||
explicitAddressing: boolean;
|
||||
spoilerText?: string;
|
||||
@@ -122,7 +123,7 @@ interface ComposeSetStatusAction {
|
||||
editorState?: string | null;
|
||||
}
|
||||
|
||||
const setComposeToStatus = (status: ComposeSetStatusAction['status'], poll: Poll, rawText: string, spoilerText?: string, contentType?: string | false, withRedraft?: boolean, draftId?: string, editorState?: string | null) =>
|
||||
const setComposeToStatus = (status: ComposeSetStatusAction['status'], poll: Poll | null, rawText: string, spoilerText?: string, contentType?: string | false, withRedraft?: boolean, draftId?: string, editorState?: string | null) =>
|
||||
(dispatch: AppDispatch, getState: () => RootState) => {
|
||||
const client = getClient(getState);
|
||||
const { createStatusExplicitAddressing: explicitAddressing, version: v } = client.features;
|
||||
@@ -154,7 +155,7 @@ const changeCompose = (composeId: string, text: string) => ({
|
||||
interface ComposeReplyAction {
|
||||
type: typeof COMPOSE_REPLY;
|
||||
composeId: string;
|
||||
status: Pick<Status, 'id' | 'account' | 'group' | 'mentions' | 'spoiler_text' | 'visibility'>;
|
||||
status: Pick<Status | ReducerStatus, 'id' | 'account' | 'group' | 'mentions' | 'spoiler_text' | 'visibility'>;
|
||||
account: Pick<Account, 'acct'>;
|
||||
explicitAddressing: boolean;
|
||||
preserveSpoilers: boolean;
|
||||
@@ -196,7 +197,7 @@ const cancelReplyCompose = () => ({
|
||||
interface ComposeQuoteAction {
|
||||
type: typeof COMPOSE_QUOTE;
|
||||
composeId: string;
|
||||
status: Pick<Status, 'id' | 'account' | 'visibility' | 'group'>;
|
||||
status: Pick<Status | ReducerStatus, 'id' | 'account' | 'visibility' | 'group'>;
|
||||
account: Pick<Account, 'acct'> | undefined;
|
||||
explicitAddressing: boolean;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { accountSchema, type Account as BaseAccount } from 'pl-api';
|
||||
import { accountSchema, mutedAccountSchema, type Account as BaseAccount } from 'pl-api';
|
||||
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { useEntities } from 'soapbox/entity-store/hooks';
|
||||
@@ -17,7 +17,7 @@ const useAccountList = (listKey: string[], entityFn: EntityFn<void>, opts: useAc
|
||||
const { entities, ...rest } = useEntities<BaseAccount, Account>(
|
||||
[Entities.ACCOUNTS, ...listKey],
|
||||
entityFn,
|
||||
{ schema: accountSchema, enabled: opts.enabled, transform: normalizeAccount },
|
||||
{ schema: listKey[0] === 'mutes' ? mutedAccountSchema : accountSchema, enabled: opts.enabled, transform: normalizeAccount },
|
||||
);
|
||||
|
||||
const { relationships } = useRelationships(
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import { groupMemberSchema, type Group, type GroupMember, type GroupRole } from 'pl-api';
|
||||
import { groupMemberSchema, type Group, type GroupMember as GroupMember, type GroupRole } from 'pl-api';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { useCreateEntity } from 'soapbox/entity-store/hooks';
|
||||
import { useClient } from 'soapbox/hooks';
|
||||
import { normalizeGroupMember } from 'soapbox/normalizers/group-member';
|
||||
|
||||
const useDemoteGroupMember = (group: Pick<Group, 'id'>, groupMember: Pick<GroupMember, 'id'>) => {
|
||||
const client = useClient();
|
||||
@@ -11,7 +12,7 @@ const useDemoteGroupMember = (group: Pick<Group, 'id'>, groupMember: Pick<GroupM
|
||||
const { createEntity } = useCreateEntity(
|
||||
[Entities.GROUP_MEMBERSHIPS, groupMember.id],
|
||||
({ account_ids, role }: { account_ids: string[]; role: GroupRole }) => client.experimental.groups.demoteGroupUsers(group.id, account_ids, role),
|
||||
{ schema: z.array(groupMemberSchema).transform((arr) => arr[0]) },
|
||||
{ schema: z.array(groupMemberSchema).transform((arr) => arr[0]), transform: normalizeGroupMember },
|
||||
);
|
||||
|
||||
return createEntity;
|
||||
|
||||
@@ -3,6 +3,7 @@ import { groupMemberSchema, type GroupMember, type GroupRoles } from 'pl-api';
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { useEntities } from 'soapbox/entity-store/hooks';
|
||||
import { useClient } from 'soapbox/hooks';
|
||||
import { normalizeGroupMember } from 'soapbox/normalizers/group-member';
|
||||
|
||||
const useGroupMembers = (groupId: string, role: GroupRoles) => {
|
||||
const client = useClient();
|
||||
@@ -10,7 +11,7 @@ const useGroupMembers = (groupId: string, role: GroupRoles) => {
|
||||
const { entities, ...result } = useEntities<GroupMember>(
|
||||
[Entities.GROUP_MEMBERSHIPS, groupId, role],
|
||||
() => client.experimental.groups.getGroupMemberships(groupId, role),
|
||||
{ schema: groupMemberSchema },
|
||||
{ schema: groupMemberSchema, transform: normalizeGroupMember },
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { groupSchema, type Group } from 'pl-api';
|
||||
import { groupSchema, type Group as BaseGroup } from 'pl-api';
|
||||
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { useEntities } from 'soapbox/entity-store/hooks';
|
||||
import { useClient } from 'soapbox/hooks';
|
||||
import { useFeatures } from 'soapbox/hooks/useFeatures';
|
||||
import { normalizeGroup } from 'soapbox/normalizers';
|
||||
import { normalizeGroup, type Group } from 'soapbox/normalizers';
|
||||
|
||||
import { useGroupRelationships } from './useGroupRelationships';
|
||||
|
||||
@@ -12,7 +12,7 @@ const useGroups = () => {
|
||||
const client = useClient();
|
||||
const features = useFeatures();
|
||||
|
||||
const { entities, ...result } = useEntities<Group>(
|
||||
const { entities, ...result } = useEntities<BaseGroup, Group>(
|
||||
[Entities.GROUPS, 'search', ''],
|
||||
() => client.experimental.groups.getGroups(),
|
||||
{ enabled: features.groups, schema: groupSchema, transform: normalizeGroup },
|
||||
|
||||
@@ -4,6 +4,7 @@ import { z } from 'zod';
|
||||
import { Entities } from 'soapbox/entity-store/entities';
|
||||
import { useCreateEntity } from 'soapbox/entity-store/hooks';
|
||||
import { useClient } from 'soapbox/hooks';
|
||||
import { normalizeGroupMember } from 'soapbox/normalizers/group-member';
|
||||
|
||||
import type { Group, GroupMember, GroupRole } from 'pl-api';
|
||||
|
||||
@@ -13,7 +14,7 @@ const usePromoteGroupMember = (group: Pick<Group, 'id'>, groupMember: Pick<Group
|
||||
const { createEntity } = useCreateEntity(
|
||||
[Entities.GROUP_MEMBERSHIPS, groupMember.id],
|
||||
({ account_ids, role }: { account_ids: string[]; role: GroupRole }) => client.experimental.groups.promoteGroupUsers(group.id, account_ids, role),
|
||||
{ schema: z.array(groupMemberSchema).transform((arr) => arr[0]) },
|
||||
{ schema: z.array(groupMemberSchema).transform((arr) => arr[0]), transform: normalizeGroupMember },
|
||||
);
|
||||
|
||||
return createEntity;
|
||||
|
||||
@@ -10,7 +10,7 @@ import Icon from './icon';
|
||||
import { Button, HStack, Stack, Text } from './ui';
|
||||
import VerificationBadge from './verification-badge';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
eventBanner: { id: 'event.banner', defaultMessage: 'Event banner' },
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import clsx from 'clsx';
|
||||
import { type MediaAttachment, mediaAttachmentSchema } from 'pl-api';
|
||||
import { type MediaAttachment, type PreviewCard as CardEntity, mediaAttachmentSchema } from 'pl-api';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
|
||||
import Blurhash from 'soapbox/components/blurhash';
|
||||
@@ -7,8 +7,6 @@ import { HStack, Stack, Text, Icon } from 'soapbox/components/ui';
|
||||
import { addAutoPlay } from 'soapbox/utils/media';
|
||||
import { getTextDirection } from 'soapbox/utils/rtl';
|
||||
|
||||
import type { Card as CardEntity } from 'soapbox/types/entities';
|
||||
|
||||
/** Props for `PreviewCard`. */
|
||||
interface IPreviewCard {
|
||||
card: CardEntity;
|
||||
|
||||
@@ -14,7 +14,7 @@ import StatusContent from './status-content';
|
||||
import StatusReplyMentions from './status-reply-mentions';
|
||||
import SensitiveContentOverlay from './statuses/sensitive-content-overlay';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { ReducerStatus as StatusEntity } from 'soapbox/reducers/statuses';
|
||||
|
||||
const messages = defineMessages({
|
||||
cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' },
|
||||
|
||||
@@ -15,7 +15,7 @@ import { useAppDispatch, useAppSelector, useFeatures, useInstance } from 'soapbo
|
||||
import { makeGetOtherAccounts } from 'soapbox/selectors';
|
||||
|
||||
import type { List as ImmutableList } from 'immutable';
|
||||
import type { Account as AccountEntity } from 'soapbox/types/entities';
|
||||
import type { Account as AccountEntity } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
profile: { id: 'account.profile', defaultMessage: 'Profile' },
|
||||
@@ -336,7 +336,7 @@ const SidebarMenu: React.FC = (): JSX.Element | null => {
|
||||
/>
|
||||
)}
|
||||
|
||||
{account.staff && (
|
||||
{(account.is_admin || account.is_moderator) && (
|
||||
<SidebarLink
|
||||
to='/dashboard'
|
||||
icon={require('@tabler/icons/outline/dashboard.svg')}
|
||||
|
||||
@@ -30,8 +30,7 @@ import { getReactForStatus, reduceEmoji } from 'soapbox/utils/emoji-reacts';
|
||||
import GroupPopover from './groups/popover/group-popover';
|
||||
|
||||
import type { Menu } from 'soapbox/components/dropdown-menu';
|
||||
import type { Account, Group } from 'soapbox/normalizers';
|
||||
import type { Status } from 'soapbox/types/entities';
|
||||
import type { Account, Group, Status } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
adminAccount: { id: 'status.admin_account', defaultMessage: 'Moderate @{name}' },
|
||||
|
||||
@@ -15,7 +15,7 @@ import Markup from './markup';
|
||||
import Poll from './polls/poll';
|
||||
|
||||
import type { Sizes } from 'soapbox/components/ui/text/text';
|
||||
import type { Status } from 'soapbox/types/entities';
|
||||
import type { Status } from 'soapbox/normalizers';
|
||||
|
||||
const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
|
||||
const BIG_EMOJI_LIMIT = 10;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { useAppDispatch } from 'soapbox/hooks';
|
||||
import DropdownMenu from './dropdown-menu';
|
||||
import { HStack, Icon, Text } from './ui';
|
||||
|
||||
import type { Status } from 'soapbox/types/entities';
|
||||
import type { Status } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
languageVersions: { id: 'status.language_versions', defaultMessage: 'The post has multiple language versions.' },
|
||||
|
||||
@@ -9,7 +9,7 @@ import { useAppDispatch, useSettings } from 'soapbox/hooks';
|
||||
import { defaultMediaVisibility } from 'soapbox/utils/status';
|
||||
|
||||
import type { MediaAttachment } from 'pl-api';
|
||||
import type { Status } from 'soapbox/types/entities';
|
||||
import type { Status } from 'soapbox/normalizers';
|
||||
|
||||
interface IStatusMedia {
|
||||
/** Status entity to render media for. */
|
||||
|
||||
@@ -24,7 +24,7 @@ import SensitiveContentOverlay from './statuses/sensitive-content-overlay';
|
||||
import StatusInfo from './statuses/status-info';
|
||||
import { Card, Icon, Stack, Text } from './ui';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
|
||||
// Defined in components/scrollable-list
|
||||
type ScrollPosition = { height: number; top: number };
|
||||
@@ -84,7 +84,7 @@ const Status: React.FC<IStatus> = (props) => {
|
||||
|
||||
const [minHeight, setMinHeight] = useState(208);
|
||||
|
||||
const actualStatus = getActualStatus(status);
|
||||
const actualStatus = getActualStatus<StatusEntity>(status);
|
||||
const isReblog = status.reblog && typeof status.reblog === 'object';
|
||||
const statusUrl = `/@${actualStatus.account.acct}/posts/${actualStatus.id}`;
|
||||
const group = actualStatus.group;
|
||||
|
||||
@@ -28,7 +28,7 @@ const useCreateEntity = <TEntity extends Entity = Entity, TTransformedEntity ext
|
||||
|
||||
const createEntity = async (
|
||||
data: Data,
|
||||
callbacks: EntityCallbacks<TEntity | TTransformedEntity, { response?: PlfeResponse }> = {},
|
||||
callbacks: EntityCallbacks<TTransformedEntity, { response?: PlfeResponse }> = {},
|
||||
): Promise<void> => {
|
||||
const result = await setPromise(entityFn(data));
|
||||
const schema = opts.schema || z.custom<TEntity>();
|
||||
@@ -39,7 +39,7 @@ const useCreateEntity = <TEntity extends Entity = Entity, TTransformedEntity ext
|
||||
dispatch(importEntities([entity], entityType, listKey, 'start'));
|
||||
|
||||
if (callbacks.onSuccess) {
|
||||
callbacks.onSuccess(entity);
|
||||
callbacks.onSuccess(entity as TTransformedEntity);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -14,8 +14,6 @@ import { type AccountGalleryAttachment, getAccountGallery } from 'soapbox/select
|
||||
|
||||
import MediaItem from './components/media-item';
|
||||
|
||||
import type { Status } from 'soapbox/types/entities';
|
||||
|
||||
interface ILoadMoreMedia {
|
||||
maxId: string | null;
|
||||
onLoadMore: (value: string | null) => void;
|
||||
@@ -68,7 +66,7 @@ const AccountGallery = () => {
|
||||
if (attachment.type === 'video') {
|
||||
dispatch(openModal('VIDEO', { media: attachment, status: attachment.status, account: attachment.account }));
|
||||
} else {
|
||||
const media = (attachment.status as Status).media_attachments;
|
||||
const media = attachment.status.media_attachments;
|
||||
const index = media.findIndex((x) => x.id === attachment.id);
|
||||
|
||||
dispatch(openModal('MEDIA', { media, index, status: attachment.status }));
|
||||
|
||||
@@ -8,7 +8,8 @@ import StatusMedia from 'soapbox/components/status-media';
|
||||
import { HStack, Stack } from 'soapbox/components/ui';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
|
||||
import type { AdminReport, Status } from 'soapbox/types/entities';
|
||||
import type { Status } from 'soapbox/normalizers';
|
||||
import type { AdminReport } from 'soapbox/types/entities';
|
||||
|
||||
const messages = defineMessages({
|
||||
viewStatus: { id: 'admin.reports.actions.view_status', defaultMessage: 'View post' },
|
||||
|
||||
@@ -5,7 +5,7 @@ import { openModal } from 'soapbox/actions/modals';
|
||||
import { useAppDispatch, useAppSelector, useCompose, useFeatures } from 'soapbox/hooks';
|
||||
import { makeGetStatus } from 'soapbox/selectors';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
|
||||
interface IReplyMentions {
|
||||
composeId: string;
|
||||
|
||||
@@ -46,7 +46,7 @@ const DraftStatusActionBar: React.FC<IDraftStatusActionBar> = ({ source, status
|
||||
};
|
||||
|
||||
const handleEditClick = () => {
|
||||
dispatch(setComposeToStatus(status, source.text, source.spoiler_text, source.content_type, false, source.draft_id, source.editorState));
|
||||
dispatch(setComposeToStatus(status, status.poll, source.text, source.spoiler_text, source.content_type, false, source.draft_id, source.editorState));
|
||||
dispatch(openModal('COMPOSE'));
|
||||
};
|
||||
|
||||
|
||||
@@ -15,8 +15,8 @@ import { buildStatus } from '../builder';
|
||||
|
||||
import DraftStatusActionBar from './draft-status-action-bar';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
import type { DraftStatus as DraftStatusType } from 'soapbox/reducers/draft-statuses';
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
|
||||
interface IDraftStatus {
|
||||
draftStatus: DraftStatusType;
|
||||
|
||||
@@ -12,7 +12,7 @@ import QuotedStatus from 'soapbox/features/status/containers/quoted-status-conta
|
||||
import { useAppDispatch, useAppSelector, useSoapboxConfig } from 'soapbox/hooks';
|
||||
import { makeGetStatus } from 'soapbox/selectors';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
|
||||
type RouteParams = { statusId: string };
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@ import { useAppDispatch } from 'soapbox/hooks';
|
||||
|
||||
import MediaItem from '../account-gallery/components/media-item';
|
||||
|
||||
import type { Status } from 'soapbox/normalizers';
|
||||
import type { AccountGalleryAttachment } from 'soapbox/selectors';
|
||||
import type { Status } from 'soapbox/types/entities';
|
||||
|
||||
interface IGroupGallery {
|
||||
params: { groupId: string };
|
||||
|
||||
@@ -9,6 +9,7 @@ import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
|
||||
import NewListForm from './components/new-list-form';
|
||||
|
||||
import type { List as ListEntity } from 'pl-api';
|
||||
import type { RootState } from 'soapbox/store';
|
||||
|
||||
const messages = defineMessages({
|
||||
@@ -21,7 +22,7 @@ const getOrderedLists = createSelector([(state: RootState) => state.lists], list
|
||||
return lists;
|
||||
}
|
||||
|
||||
return lists.toList().filter((item) => !!item).sort((a, b) => a.title.localeCompare(b.title));
|
||||
return lists.toList().filter((item): item is ListEntity => !!item).sort((a, b) => a.title.localeCompare(b.title));
|
||||
});
|
||||
|
||||
const Lists: React.FC = () => {
|
||||
|
||||
@@ -16,11 +16,10 @@ import { useAppDispatch, useAppSelector, useInstance } from 'soapbox/hooks';
|
||||
import { makeGetNotification } from 'soapbox/selectors';
|
||||
import { NotificationType } from 'soapbox/utils/notification';
|
||||
|
||||
import type { Account, Notification as BaseNotification } from 'pl-api';
|
||||
import type { Notification as BaseNotification } from 'pl-api';
|
||||
import type { ScrollPosition } from 'soapbox/components/status';
|
||||
import type { Notification as NotificationEntity } from 'soapbox/normalizers';
|
||||
import type { Account, Notification as NotificationEntity, Status as StatusEntity } from 'soapbox/normalizers';
|
||||
import type { MinifiedNotification } from 'soapbox/reducers/notifications';
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
|
||||
const notificationForScreenReader = (intl: IntlShape, message: string, timestamp: string) => {
|
||||
const output = [message];
|
||||
@@ -290,7 +289,7 @@ const Notification: React.FC<INotification> = (props) => {
|
||||
} else if (icons[type]) {
|
||||
return (
|
||||
<Icon
|
||||
src={icons[type]}
|
||||
src={icons[type]!}
|
||||
className='flex-none text-primary-600 dark:text-primary-400'
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { getSettings } from 'soapbox/actions/settings';
|
||||
import { Button, HStack } from 'soapbox/components/ui';
|
||||
import { useAppDispatch } from 'soapbox/hooks';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
cancel: { id: 'scheduled_status.cancel', defaultMessage: 'Cancel' },
|
||||
|
||||
@@ -34,11 +34,11 @@ const MfaForm: React.FC = () => {
|
||||
setDisplayOtpForm(true);
|
||||
};
|
||||
|
||||
const mfa = useAppSelector((state) => state.security.get('mfa'));
|
||||
const mfa = useAppSelector((state) => state.security.mfa);
|
||||
|
||||
return (
|
||||
<Column label={intl.formatMessage(messages.heading)}>
|
||||
{mfa.getIn(['settings', 'totp']) ? (
|
||||
{mfa.settings.totp ? (
|
||||
<DisableOtpForm />
|
||||
) : (
|
||||
<Stack space={4}>
|
||||
|
||||
@@ -16,7 +16,7 @@ import { getActualStatus } from 'soapbox/utils/status';
|
||||
|
||||
import StatusInteractionBar from './status-interaction-bar';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
|
||||
interface IDetailedStatus {
|
||||
status: StatusEntity;
|
||||
@@ -81,7 +81,7 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const actualStatus = getActualStatus(status);
|
||||
const actualStatus = getActualStatus<StatusEntity>(status);
|
||||
if (!actualStatus) return null;
|
||||
const { account } = actualStatus;
|
||||
if (!account || typeof account !== 'object') return null;
|
||||
|
||||
@@ -8,7 +8,7 @@ import { HStack, Text, Emoji } from 'soapbox/components/ui';
|
||||
import { useAppSelector, useSoapboxConfig, useFeatures, useAppDispatch } from 'soapbox/hooks';
|
||||
import { reduceEmoji } from 'soapbox/utils/emoji-reacts';
|
||||
|
||||
import type { Status } from 'soapbox/types/entities';
|
||||
import type { Status } from 'soapbox/normalizers';
|
||||
|
||||
interface IStatusInteractionBar {
|
||||
status: Status;
|
||||
|
||||
@@ -25,7 +25,7 @@ import { textForScreenReader } from 'soapbox/utils/status';
|
||||
import DetailedStatus from './detailed-status';
|
||||
import ThreadStatus from './thread-status';
|
||||
|
||||
import type { Account, Status } from 'soapbox/types/entities';
|
||||
import type { Account, Status } from 'soapbox/normalizers';
|
||||
|
||||
const getAncestorsIds = createSelector([
|
||||
(_: RootState, statusId: string | undefined) => statusId,
|
||||
|
||||
@@ -5,7 +5,7 @@ import Icon from 'soapbox/components/icon';
|
||||
import { Modal, Stack, Text } from 'soapbox/components/ui';
|
||||
import ReplyIndicator from 'soapbox/features/compose/components/reply-indicator';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
cancel_reblog: { id: 'status.cancel_reblog_private', defaultMessage: 'Un-repost' },
|
||||
@@ -14,7 +14,7 @@ const messages = defineMessages({
|
||||
|
||||
interface IBoostModal {
|
||||
status: StatusEntity;
|
||||
onReblog: (status: StatusEntity) => void;
|
||||
onReblog: (status: Pick<StatusEntity, 'id' | 'reblogged'>) => void;
|
||||
onClose: () => void;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ import { makeGetStatus } from 'soapbox/selectors';
|
||||
import ImageLoader from '../image-loader';
|
||||
|
||||
import type { MediaAttachment } from 'pl-api';
|
||||
import type { Status } from 'soapbox/types/entities';
|
||||
import type { Status } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
close: { id: 'lightbox.close', defaultMessage: 'Close' },
|
||||
|
||||
@@ -9,7 +9,7 @@ import NewFolderForm from 'soapbox/features/bookmark-folders/components/new-fold
|
||||
import { useAppDispatch, useAppSelector } from 'soapbox/hooks';
|
||||
import { makeGetStatus } from 'soapbox/selectors';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
|
||||
interface ISelectBookmarkFolderModal {
|
||||
statusId: string;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { useHistory } from 'react-router-dom';
|
||||
import Video from 'soapbox/features/video';
|
||||
|
||||
import type { MediaAttachment } from 'pl-api';
|
||||
import type { Status, Account } from 'soapbox/types/entities';
|
||||
import type { Account, Status } from 'soapbox/normalizers';
|
||||
|
||||
interface IVideoModal {
|
||||
media: MediaAttachment;
|
||||
|
||||
@@ -14,7 +14,7 @@ import { buildStatus } from '../util/pending-status-builder';
|
||||
|
||||
import PollPreview from './poll-preview';
|
||||
|
||||
import type { Status as StatusEntity } from 'soapbox/types/entities';
|
||||
import type { Status as StatusEntity } from 'soapbox/normalizers';
|
||||
|
||||
const shouldHaveCard = (pendingStatus: StatusEntity) => Boolean(pendingStatus.content.match(/https?:\/\/\S*/));
|
||||
|
||||
@@ -47,7 +47,7 @@ const PendingStatus: React.FC<IPendingStatus> = ({ idempotencyKey, className, mu
|
||||
const status = useAppSelector((state) => {
|
||||
const pendingStatus = state.pending_statuses.get(idempotencyKey);
|
||||
return pendingStatus ? buildStatus(state, pendingStatus, idempotencyKey) : null;
|
||||
}) as StatusEntity | null;
|
||||
});
|
||||
|
||||
if (!status) return null;
|
||||
if (!status.account) return null;
|
||||
@@ -89,7 +89,7 @@ const PendingStatus: React.FC<IPendingStatus> = ({ idempotencyKey, className, mu
|
||||
|
||||
{status.poll && <PollPreview poll={status.poll} />}
|
||||
|
||||
{status.quote && <QuotedStatus statusId={status.quote as string} />}
|
||||
{status.quote && <QuotedStatus statusId={status.quote.id} />}
|
||||
</Stack>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { makeGetAccount } from 'soapbox/selectors';
|
||||
|
||||
import ThemeToggle from './theme-toggle';
|
||||
|
||||
import type { Account as AccountEntity } from 'soapbox/types/entities';
|
||||
import type { Account as AccountEntity } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
add: { id: 'profile_dropdown.add_account', defaultMessage: 'Add an existing account' },
|
||||
|
||||
@@ -6,7 +6,7 @@ import { IconButton } from 'soapbox/components/ui';
|
||||
import { useFeatures } from 'soapbox/hooks';
|
||||
import toast from 'soapbox/toast';
|
||||
|
||||
import type { Account as AccountEntity } from 'soapbox/types/entities';
|
||||
import type { Account as AccountEntity } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
subscribe: { id: 'account.subscribe', defaultMessage: 'Subscribe to notifications from @{name}' },
|
||||
|
||||
@@ -7,7 +7,7 @@ import AccountContainer from 'soapbox/containers/account-container';
|
||||
import PlaceholderSidebarSuggestions from 'soapbox/features/placeholder/components/placeholder-sidebar-suggestions';
|
||||
import { useDismissSuggestion, useSuggestions } from 'soapbox/queries/suggestions';
|
||||
|
||||
import type { Account as AccountEntity } from 'soapbox/types/entities';
|
||||
import type { Account as AccountEntity } from 'soapbox/normalizers';
|
||||
|
||||
const messages = defineMessages({
|
||||
dismissSuggestion: { id: 'suggestions.dismiss', defaultMessage: 'Dismiss suggestion' },
|
||||
|
||||
@@ -41,7 +41,7 @@ const buildStatus = (state: RootState, pendingStatus: PendingStatus, idempotency
|
||||
media_attachments: (pendingStatus.media_ids || ImmutableList()).map((id: string) => ({ id })),
|
||||
mentions: buildMentions(pendingStatus),
|
||||
poll: buildPoll(pendingStatus),
|
||||
quote: pendingStatus.quote_id,
|
||||
quote: pendingStatus.quote_id ? state.statuses.get(pendingStatus.quote_id) : null,
|
||||
sensitive: pendingStatus.sensitive,
|
||||
visibility: pendingStatus.visibility,
|
||||
};
|
||||
|
||||
@@ -37,6 +37,7 @@ const normalizeAccount = (account: BaseAccount) => {
|
||||
const emojiMap = makeEmojiMap(account.emojis);
|
||||
|
||||
return {
|
||||
mute_expires_at: null,
|
||||
...account,
|
||||
avatar: account.avatar || account.avatar_static || missingAvatar,
|
||||
avatar_static: account.avatar_static || account.avatar || missingAvatar,
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
fromJS,
|
||||
} from 'immutable';
|
||||
|
||||
import type { Account, EmbeddedEntity } from 'soapbox/types/entities';
|
||||
import type { Account } from 'soapbox/normalizers';
|
||||
import type { EmbeddedEntity } from 'soapbox/types/entities';
|
||||
|
||||
const AdminAccountRecord = ImmutableRecord({
|
||||
account: null as EmbeddedEntity<Account>,
|
||||
|
||||
@@ -9,7 +9,8 @@ import {
|
||||
fromJS,
|
||||
} from 'immutable';
|
||||
|
||||
import type { Account, EmbeddedEntity, Status } from 'soapbox/types/entities';
|
||||
import type { Account, Status } from 'soapbox/normalizers';
|
||||
import type { EmbeddedEntity } from 'soapbox/types/entities';
|
||||
|
||||
const AdminReportRecord = ImmutableRecord({
|
||||
account: null as EmbeddedEntity<Account>,
|
||||
|
||||
@@ -331,7 +331,7 @@ const compose = (state = initialState, action: ComposeAction | EventsAction | Me
|
||||
? statusToMentionsArray(action.status, action.account, action.rebloggedBy)
|
||||
: ImmutableOrderedSet<string>();
|
||||
|
||||
map.set('group_id', action.status.group?.id as string);
|
||||
map.set('group_id', typeof action.status.group === 'string' ? action.status.group : action.status.group?.id || null);
|
||||
map.set('in_reply_to', action.status.id);
|
||||
map.set('to', to);
|
||||
map.set('parent_reblogged_by', action.rebloggedBy?.id || null);
|
||||
@@ -371,7 +371,7 @@ const compose = (state = initialState, action: ComposeAction | EventsAction | Me
|
||||
map.set('spoiler_text', '');
|
||||
|
||||
if (action.status.visibility === 'group') {
|
||||
map.set('group_id', action.status.group?.id as string);
|
||||
map.set('group_id', typeof action.status.group === 'string' ? action.status.group : action.status.group?.id || null);
|
||||
map.set('privacy', 'group');
|
||||
}
|
||||
}));
|
||||
@@ -474,8 +474,8 @@ const compose = (state = initialState, action: ComposeAction | EventsAction | Me
|
||||
map.set('caretPosition', null);
|
||||
map.set('idempotencyKey', uuid());
|
||||
map.set('content_type', action.contentType || 'text/plain');
|
||||
map.set('quote', action.status.quote?.id as string);
|
||||
map.set('group_id', action.status.group?.id as string);
|
||||
map.set('quote', typeof action.status.quote === 'string' ? action.status.quote : action.status.quote?.id || null);
|
||||
map.set('group_id', typeof action.status.group === 'string' ? action.status.group : action.status.group?.id || null);
|
||||
|
||||
if (action.v?.software === PLEROMA && action.withRedraft && hasIntegerMediaIds(action.status)) {
|
||||
map.set('media_attachments', ImmutableList());
|
||||
|
||||
Reference in New Issue
Block a user