Migrate most types to pl-hooks
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
parent
34ee036168
commit
832d0dff2e
33 changed files with 74 additions and 70 deletions
|
@ -16,7 +16,7 @@ import { useAccountHoverCardStore } from 'bigbuffet/stores/account-hover-card';
|
||||||
|
|
||||||
import { ParsedContent } from './parsed-content';
|
import { ParsedContent } from './parsed-content';
|
||||||
|
|
||||||
import type { Account } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as Account } from 'pl-hooks';
|
||||||
|
|
||||||
const showAccountHoverCard = debounce((openAccountHoverCard, ref, accountId) => {
|
const showAccountHoverCard = debounce((openAccountHoverCard, ref, accountId) => {
|
||||||
openAccountHoverCard(ref, accountId);
|
openAccountHoverCard(ref, accountId);
|
||||||
|
|
|
@ -11,7 +11,7 @@ import Emojify from 'bigbuffet/features/emoji';
|
||||||
import ActionButton from 'bigbuffet/features/ui/components/action-button';
|
import ActionButton from 'bigbuffet/features/ui/components/action-button';
|
||||||
import { getAcct } from 'bigbuffet/utils/accounts';
|
import { getAcct } from 'bigbuffet/utils/accounts';
|
||||||
|
|
||||||
import type { Account as AccountSchema } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as AccountEntity } from 'pl-hooks';
|
||||||
|
|
||||||
interface IProfilePopper {
|
interface IProfilePopper {
|
||||||
condition: boolean;
|
condition: boolean;
|
||||||
|
@ -26,7 +26,7 @@ const ProfilePopper: React.FC<IProfilePopper> = ({ condition, wrapper, children
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface IAccount {
|
export interface IAccount {
|
||||||
account: AccountSchema;
|
account: AccountEntity;
|
||||||
action?: React.ReactElement;
|
action?: React.ReactElement;
|
||||||
/** Override other actions for specificity like mute/unmute. */
|
/** Override other actions for specificity like mute/unmute. */
|
||||||
hidden?: boolean;
|
hidden?: boolean;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { getAcct } from '../utils/accounts';
|
||||||
|
|
||||||
import VerificationBadge from './verification-badge';
|
import VerificationBadge from './verification-badge';
|
||||||
|
|
||||||
import type { Account } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as Account } from 'pl-hooks';
|
||||||
|
|
||||||
interface IDisplayName {
|
interface IDisplayName {
|
||||||
account: Pick<Account, 'id' | 'acct' | 'fqn' | 'verified' | 'display_name' | 'emojis'>;
|
account: Pick<Account, 'id' | 'acct' | 'fqn' | 'verified' | 'display_name' | 'emojis'>;
|
||||||
|
|
|
@ -8,14 +8,14 @@ import Emojify from 'bigbuffet/features/emoji';
|
||||||
import EventActionButton from 'bigbuffet/features/event/components/event-action-button';
|
import EventActionButton from 'bigbuffet/features/event/components/event-action-button';
|
||||||
import EventDate from 'bigbuffet/features/event/components/event-date';
|
import EventDate from 'bigbuffet/features/event/components/event-date';
|
||||||
|
|
||||||
import type { Status as StatusEntity } from 'bigbuffet/normalizers/status';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
eventBanner: { id: 'event.banner', defaultMessage: 'Event banner' },
|
eventBanner: { id: 'event.banner', defaultMessage: 'Event banner' },
|
||||||
});
|
});
|
||||||
|
|
||||||
interface IEventPreview {
|
interface IEventPreview {
|
||||||
status: Pick<StatusEntity, 'id' | 'account' | 'event' | 'url'>;
|
status: Pick<Status, 'id' | 'account' | 'event' | 'url'>;
|
||||||
className?: string;
|
className?: string;
|
||||||
hideAction?: boolean;
|
hideAction?: boolean;
|
||||||
floatingAction?: boolean;
|
floatingAction?: boolean;
|
||||||
|
|
|
@ -8,8 +8,8 @@ import { isMobile } from 'bigbuffet/is-mobile';
|
||||||
import { useAccountHoverCardStore } from 'bigbuffet/stores/account-hover-card';
|
import { useAccountHoverCardStore } from 'bigbuffet/stores/account-hover-card';
|
||||||
|
|
||||||
const showAccountHoverCard = debounce((
|
const showAccountHoverCard = debounce((
|
||||||
openAccountHoverCard: (ref: React.MutableRefObject<HTMLDivElement>, accountId: string) => void,
|
openAccountHoverCard: (ref: React.MutableRefObject<HTMLDivElement | null>, accountId: string) => void,
|
||||||
ref: React.MutableRefObject<HTMLDivElement>,
|
ref: React.MutableRefObject<HTMLDivElement | null>,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
) => {
|
) => {
|
||||||
if (ref.current) openAccountHoverCard(ref, accountId);
|
if (ref.current) openAccountHoverCard(ref, accountId);
|
||||||
|
|
|
@ -6,8 +6,8 @@ import { isMobile } from 'bigbuffet/is-mobile';
|
||||||
import { useStatusHoverCardStore } from 'bigbuffet/stores/status-hover-card';
|
import { useStatusHoverCardStore } from 'bigbuffet/stores/status-hover-card';
|
||||||
|
|
||||||
const showStatusHoverCard = debounce((
|
const showStatusHoverCard = debounce((
|
||||||
openStatusHoverCard: (ref: React.MutableRefObject<HTMLDivElement>, accountId: string) => void,
|
openStatusHoverCard: (ref: React.MutableRefObject<HTMLDivElement | null>, accountId: string) => void,
|
||||||
ref: React.MutableRefObject<HTMLDivElement>,
|
ref: React.MutableRefObject<HTMLDivElement | null>,
|
||||||
statusId: string,
|
statusId: string,
|
||||||
) => {
|
) => {
|
||||||
openStatusHoverCard(ref, statusId);
|
openStatusHoverCard(ref, statusId);
|
||||||
|
|
|
@ -3,7 +3,7 @@ import { useHistory } from 'react-router-dom';
|
||||||
|
|
||||||
import StatusMedia from 'bigbuffet/components/status-media';
|
import StatusMedia from 'bigbuffet/components/status-media';
|
||||||
import AccountContainer from 'bigbuffet/containers/account-container';
|
import AccountContainer from 'bigbuffet/containers/account-container';
|
||||||
import { useShowMedia } from 'bigbuffet/hooks/useShowMedia';
|
import { useStatusMetaStore } from 'bigbuffet/stores/status-meta';
|
||||||
|
|
||||||
import EventPreview from './event-preview';
|
import EventPreview from './event-preview';
|
||||||
import OutlineBox from './outline-box';
|
import OutlineBox from './outline-box';
|
||||||
|
@ -11,20 +11,21 @@ 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 { SelectedStatus } from 'bigbuffet/selectors';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
interface IQuotedStatus {
|
interface IQuotedStatus {
|
||||||
/** The quoted status entity. */
|
/** The quoted status entity. */
|
||||||
status?: SelectedStatus;
|
status: Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Status embedded in a quote post. */
|
/** Status embedded in a quote post. */
|
||||||
const QuotedStatus: React.FC<IQuotedStatus> = ({ status }) => {
|
const QuotedStatus: React.FC<IQuotedStatus> = ({ status }) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
const { statuses: statusesMeta, hideStatus, revealStatus } = useStatusMetaStore();
|
||||||
|
|
||||||
const overlay = useRef<HTMLDivElement>(null);
|
const overlay = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const showMedia = useShowMedia(status);
|
const showMedia = statusesMeta[status.id]?.visible ?? !status.sensitive;
|
||||||
const [minHeight, setMinHeight] = useState(208);
|
const [minHeight, setMinHeight] = useState(208);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -50,7 +51,11 @@ const QuotedStatus: React.FC<IQuotedStatus> = ({ status }) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleToggleMediaVisibility = () => {
|
const handleToggleMediaVisibility = () => {
|
||||||
setShowMedia(!showMedia);
|
if (showMedia) {
|
||||||
|
hideStatus(status.id);
|
||||||
|
} else {
|
||||||
|
revealStatus(status.id);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!status) {
|
if (!status) {
|
||||||
|
|
|
@ -10,8 +10,8 @@ import { onlyEmoji as isOnlyEmoji } from 'bigbuffet/utils/rich-content';
|
||||||
import { ParsedContent } from './parsed-content';
|
import { ParsedContent } from './parsed-content';
|
||||||
import Poll from './polls/poll';
|
import Poll from './polls/poll';
|
||||||
|
|
||||||
import type { MinifiedStatus } from 'bigbuffet/reducers/statuses';
|
|
||||||
import type { Mention } from 'pl-api';
|
import type { Mention } from 'pl-api';
|
||||||
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
const MAX_HEIGHT = 642; // 20px * 16 (+ 2px padding at the top)
|
const MAX_HEIGHT = 642; // 20px * 16 (+ 2px padding at the top)
|
||||||
const BIG_EMOJI_LIMIT = 10;
|
const BIG_EMOJI_LIMIT = 10;
|
||||||
|
@ -29,7 +29,7 @@ const ReadMoreButton: React.FC<IReadMoreButton> = ({ to }) => (
|
||||||
);
|
);
|
||||||
|
|
||||||
interface IStatusContent {
|
interface IStatusContent {
|
||||||
status: MinifiedStatus;
|
status: Status;
|
||||||
collapsable?: boolean;
|
collapsable?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ import PreviewCard from 'bigbuffet/components/preview-card';
|
||||||
import { MediaGallery, Video, Audio } from 'bigbuffet/features/ui/util/async-components';
|
import { MediaGallery, Video, Audio } from 'bigbuffet/features/ui/util/async-components';
|
||||||
import { useModalsStore } from 'bigbuffet/stores/modals';
|
import { useModalsStore } from 'bigbuffet/stores/modals';
|
||||||
|
|
||||||
import type { Status } from 'bigbuffet/normalizers/status';
|
|
||||||
import type { MediaAttachment } from 'pl-api';
|
import type { MediaAttachment } from 'pl-api';
|
||||||
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
interface IStatusMedia {
|
interface IStatusMedia {
|
||||||
/** Status entity to render media for. */
|
/** Status entity to render media for. */
|
||||||
|
|
|
@ -6,7 +6,7 @@ import HoverAccountWrapper from 'bigbuffet/components/hover-account-wrapper';
|
||||||
import HoverStatusWrapper from 'bigbuffet/components/hover-status-wrapper';
|
import HoverStatusWrapper from 'bigbuffet/components/hover-status-wrapper';
|
||||||
import { useModalsStore } from 'bigbuffet/stores/modals';
|
import { useModalsStore } from 'bigbuffet/stores/modals';
|
||||||
|
|
||||||
import type { Status } from 'bigbuffet/normalizers/status';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
interface IStatusReplyMentions {
|
interface IStatusReplyMentions {
|
||||||
status: Pick<Status, 'in_reply_to_id' | 'id' | 'mentions'>;
|
status: Pick<Status, 'in_reply_to_id' | 'id' | 'mentions'>;
|
||||||
|
|
|
@ -22,7 +22,7 @@ import StatusReplyMentions from './status-reply-mentions';
|
||||||
import SensitiveContentOverlay from './statuses/sensitive-content-overlay';
|
import SensitiveContentOverlay from './statuses/sensitive-content-overlay';
|
||||||
import Card from './ui/card';
|
import Card from './ui/card';
|
||||||
|
|
||||||
import type { SelectedStatus } from 'bigbuffet/selectors';
|
import type { UseStatusData as StatusEntity } from 'pl-hooks';
|
||||||
|
|
||||||
// Defined in components/scrollable-list
|
// Defined in components/scrollable-list
|
||||||
export type ScrollPosition = { height: number; top: number };
|
export type ScrollPosition = { height: number; top: number };
|
||||||
|
@ -33,7 +33,7 @@ const messages = defineMessages({
|
||||||
|
|
||||||
export interface IStatus {
|
export interface IStatus {
|
||||||
id?: string;
|
id?: string;
|
||||||
status: SelectedStatus;
|
status: StatusEntity;
|
||||||
onMoveUp?: (statusId: string, featured?: boolean) => void;
|
onMoveUp?: (statusId: string, featured?: boolean) => void;
|
||||||
onMoveDown?: (statusId: string, featured?: boolean) => void;
|
onMoveDown?: (statusId: string, featured?: boolean) => void;
|
||||||
focusable?: boolean;
|
focusable?: boolean;
|
||||||
|
@ -75,20 +75,12 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
didShowCard.current = Boolean(status?.card);
|
didShowCard.current = Boolean(status?.card);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
setShowMedia(!status.sensitive);
|
|
||||||
}, [status.id]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (overlay.current) {
|
if (overlay.current) {
|
||||||
setMinHeight(overlay.current.getBoundingClientRect().height);
|
setMinHeight(overlay.current.getBoundingClientRect().height);
|
||||||
}
|
}
|
||||||
}, [overlay.current]);
|
}, [overlay.current]);
|
||||||
|
|
||||||
const handleToggleMediaVisibility = (): void => {
|
|
||||||
setShowMedia(!showMedia);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClick = (e?: React.MouseEvent): void => {
|
const handleClick = (e?: React.MouseEvent): void => {
|
||||||
e?.stopPropagation();
|
e?.stopPropagation();
|
||||||
|
|
||||||
|
@ -134,7 +126,7 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleHotkeyToggleHidden = (): void => {
|
const handleToggleMediaVisibility = (): void => {
|
||||||
if (showMedia) {
|
if (showMedia) {
|
||||||
hideStatus(status.id);
|
hideStatus(status.id);
|
||||||
} else {
|
} else {
|
||||||
|
@ -227,7 +219,7 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
openProfile: handleHotkeyOpenProfile,
|
openProfile: handleHotkeyOpenProfile,
|
||||||
moveUp: handleHotkeyMoveUp,
|
moveUp: handleHotkeyMoveUp,
|
||||||
moveDown: handleHotkeyMoveDown,
|
moveDown: handleHotkeyMoveDown,
|
||||||
toggleHidden: handleHotkeyToggleHidden,
|
toggleHidden: handleHotkeyToggleSensitive,
|
||||||
toggleSensitive: handleHotkeyToggleSensitive,
|
toggleSensitive: handleHotkeyToggleSensitive,
|
||||||
openMedia: handleHotkeyOpenMedia,
|
openMedia: handleHotkeyOpenMedia,
|
||||||
};
|
};
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { useStatusMetaStore } from 'bigbuffet/stores/status-meta';
|
||||||
|
|
||||||
import Button from '../ui/button';
|
import Button from '../ui/button';
|
||||||
|
|
||||||
import type { Status } from 'bigbuffet/normalizers/status';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
hide: { id: 'moderation_overlay.hide', defaultMessage: 'Hide content' },
|
hide: { id: 'moderation_overlay.hide', defaultMessage: 'Hide content' },
|
||||||
|
@ -17,7 +17,7 @@ const messages = defineMessages({
|
||||||
});
|
});
|
||||||
|
|
||||||
interface ISensitiveContentOverlay {
|
interface ISensitiveContentOverlay {
|
||||||
status: Pick<Status, 'id' | 'sensitive' | 'media_attachments' | 'currentLanguage' | 'spoiler_text' | 'emojis'>;
|
status: Pick<Status, 'id' | 'sensitive' | 'media_attachments' | 'spoiler_text' | 'emojis'>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveContentOverlay>(({ status }, ref) => {
|
const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveContentOverlay>(({ status }, ref) => {
|
||||||
|
|
|
@ -9,7 +9,7 @@ import { useInstance } from 'bigbuffet/hooks/useInstance';
|
||||||
|
|
||||||
import Icon from './icon';
|
import Icon from './icon';
|
||||||
|
|
||||||
import type { Status } from 'bigbuffet/normalizers/status';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
interface ITranslateButton {
|
interface ITranslateButton {
|
||||||
status: Pick<Status, 'id' | 'account' | 'content' | 'language' | 'translating' | 'translation' | 'visibility'>;
|
status: Pick<Status, 'id' | 'account' | 'content' | 'language' | 'translating' | 'translation' | 'visibility'>;
|
||||||
|
@ -30,7 +30,7 @@ const TranslateButton: React.FC<ITranslateButton> = ({ status }) => {
|
||||||
|
|
||||||
const renderTranslate = allowUnauthenticated && (allowRemote || status.account.local) && ['public', 'unlisted'].includes(status.visibility) && status.content.trim().length && status.language !== null && intl.locale !== status.language;
|
const renderTranslate = allowUnauthenticated && (allowRemote || status.account.local) && ['public', 'unlisted'].includes(status.visibility) && status.content.trim().length && status.language !== null && intl.locale !== status.language;
|
||||||
|
|
||||||
const supportsLanguages = (translationLanguages[status.language!]?.includes(intl.locale));
|
const supportsLanguages = (translationLanguages?.[status.language!]?.includes(intl.locale));
|
||||||
|
|
||||||
const handleTranslate: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
const handleTranslate: React.MouseEventHandler<HTMLButtonElement> = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
|
@ -28,7 +28,7 @@ export const AccountHashtagTimeline: React.FC<IHashtagTimeline> = ({ params }) =
|
||||||
|
|
||||||
const path = `account:${account?.id}:hashtag:${id}`;
|
const path = `account:${account?.id}:hashtag:${id}`;
|
||||||
|
|
||||||
const statusIds = useAppSelector(state => getStatusIds(state, { type: path, prefix: 'account_timeline' }));
|
const statusIds = useAppSelector(state => getStatusIds(state, { type: path }));
|
||||||
|
|
||||||
const isLoading = useAppSelector(state => state.timelines.get(path)?.isLoading === true);
|
const isLoading = useAppSelector(state => state.timelines.get(path)?.isLoading === true);
|
||||||
const hasMore = useAppSelector(state => state.timelines.get(path)?.hasMore === true);
|
const hasMore = useAppSelector(state => state.timelines.get(path)?.hasMore === true);
|
||||||
|
|
|
@ -5,7 +5,7 @@ import Account from 'bigbuffet/components/account';
|
||||||
import Icon from 'bigbuffet/components/icon';
|
import Icon from 'bigbuffet/components/icon';
|
||||||
import Emojify from 'bigbuffet/features/emoji';
|
import Emojify from 'bigbuffet/features/emoji';
|
||||||
|
|
||||||
import type { Account as AccountEntity } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as AccountEntity } from 'pl-hooks';
|
||||||
|
|
||||||
interface IMovedNote {
|
interface IMovedNote {
|
||||||
from: Pick<AccountEntity, 'display_name' | 'emojis'>;
|
from: Pick<AccountEntity, 'display_name' | 'emojis'>;
|
||||||
|
|
|
@ -14,7 +14,7 @@ import { useFeatures } from 'bigbuffet/hooks/useFeatures';
|
||||||
import { useModalsStore } from 'bigbuffet/stores/modals';
|
import { useModalsStore } from 'bigbuffet/stores/modals';
|
||||||
import { isDefaultHeader } from 'bigbuffet/utils/accounts';
|
import { isDefaultHeader } from 'bigbuffet/utils/accounts';
|
||||||
|
|
||||||
import type { Account } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as Account } from 'pl-hooks';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
header: { id: 'account.header.alt', defaultMessage: 'Profile header' },
|
header: { id: 'account.header.alt', defaultMessage: 'Profile header' },
|
||||||
|
|
|
@ -6,10 +6,10 @@ import { useFeatures } from 'bigbuffet/hooks/useFeatures';
|
||||||
import { useModalsStore } from 'bigbuffet/stores/modals';
|
import { useModalsStore } from 'bigbuffet/stores/modals';
|
||||||
|
|
||||||
import type { ButtonThemes } from 'bigbuffet/components/ui/button';
|
import type { ButtonThemes } from 'bigbuffet/components/ui/button';
|
||||||
import type { Status as StatusEntity } from 'bigbuffet/normalizers/status';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
interface IEventAction {
|
interface IEventAction {
|
||||||
status: Pick<StatusEntity, 'url'>;
|
status: Pick<Status, 'url'>;
|
||||||
theme?: ButtonThemes;
|
theme?: ButtonThemes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,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 'bigbuffet/components/dropdown-menu';
|
import type { Menu as MenuType } from 'bigbuffet/components/dropdown-menu';
|
||||||
import type { Status } from 'bigbuffet/normalizers/status';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
bannerHeader: { id: 'event.banner', defaultMessage: 'Event banner' },
|
bannerHeader: { id: 'event.banner', defaultMessage: 'Event banner' },
|
||||||
|
|
|
@ -8,6 +8,7 @@ import StatusContent from 'bigbuffet/components/status-content';
|
||||||
import StatusMedia from 'bigbuffet/components/status-media';
|
import StatusMedia from 'bigbuffet/components/status-media';
|
||||||
import TranslateButton from 'bigbuffet/components/translate-button';
|
import TranslateButton from 'bigbuffet/components/translate-button';
|
||||||
import QuotedStatus from 'bigbuffet/features/status/containers/quoted-status-container';
|
import QuotedStatus from 'bigbuffet/features/status/containers/quoted-status-container';
|
||||||
|
import { useStatusMetaStore } from 'bigbuffet/stores/status-meta';
|
||||||
|
|
||||||
type RouteParams = { statusId: string };
|
type RouteParams = { statusId: string };
|
||||||
|
|
||||||
|
@ -100,7 +101,7 @@ const EventInformation: React.FC<IEventInformation> = ({ params: { statusId: sta
|
||||||
}, [status]);
|
}, [status]);
|
||||||
|
|
||||||
const renderLinks = useCallback(() => {
|
const renderLinks = useCallback(() => {
|
||||||
if (!status.event?.links.length) return null;
|
if (!status?.event?.links.length) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='event-information__description'>
|
<div className='event-information__description'>
|
||||||
|
|
|
@ -11,13 +11,13 @@ import QuotedStatus from 'bigbuffet/features/status/containers/quoted-status-con
|
||||||
|
|
||||||
import StatusInteractionBar from './status-interaction-bar';
|
import StatusInteractionBar from './status-interaction-bar';
|
||||||
|
|
||||||
import type { SelectedStatus } from 'bigbuffet/selectors';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
interface IDetailedStatus {
|
interface IDetailedStatus {
|
||||||
status: SelectedStatus;
|
status: Status;
|
||||||
showMedia: boolean;
|
showMedia: boolean;
|
||||||
withMedia?: boolean;
|
withMedia?: boolean;
|
||||||
onOpenCompareHistoryModal: (status: Pick<SelectedStatus, 'id'>) => void;
|
onOpenCompareHistoryModal: (status: Pick<Status, 'id'>) => void;
|
||||||
onToggleMediaVisibility: () => void;
|
onToggleMediaVisibility: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ import { useFeatures } from 'bigbuffet/hooks/useFeatures';
|
||||||
import { reduceEmoji } from 'bigbuffet/utils/emoji-reacts';
|
import { reduceEmoji } from 'bigbuffet/utils/emoji-reacts';
|
||||||
import { shortNumberFormat } from 'bigbuffet/utils/numbers';
|
import { shortNumberFormat } from 'bigbuffet/utils/numbers';
|
||||||
|
|
||||||
import type { Status } from 'bigbuffet/normalizers/status';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
interface IStatusInteractionBar {
|
interface IStatusInteractionBar {
|
||||||
status: Pick<Status, 'id' | 'account' | 'dislikes_count' | 'emoji_reactions' | 'favourited' | 'favourites_count' | 'reblogs_count' | 'replies_count' | 'quotes_count'>;
|
status: Pick<Status, 'id' | 'account' | 'dislikes_count' | 'emoji_reactions' | 'favourited' | 'favourites_count' | 'reblogs_count' | 'replies_count' | 'quotes_count'>;
|
||||||
|
|
|
@ -19,8 +19,8 @@ import DetailedStatus from './detailed-status';
|
||||||
import ThreadStatus from './thread-status';
|
import ThreadStatus from './thread-status';
|
||||||
|
|
||||||
import type { Virtualizer } from '@tanstack/react-virtual';
|
import type { Virtualizer } from '@tanstack/react-virtual';
|
||||||
import type { Status } from 'bigbuffet/normalizers/status';
|
// import type { Status } from 'bigbuffet/normalizers/status';
|
||||||
import type { SelectedStatus } from 'bigbuffet/selectors';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
export const getAncestorsIds = createSelector([
|
export const getAncestorsIds = createSelector([
|
||||||
(_: RootState, statusId: string | undefined) => statusId,
|
(_: RootState, statusId: string | undefined) => statusId,
|
||||||
|
@ -69,7 +69,7 @@ export const getDescendantsIds = createSelector([
|
||||||
});
|
});
|
||||||
|
|
||||||
interface IThread {
|
interface IThread {
|
||||||
status: SelectedStatus;
|
status: Status;
|
||||||
withMedia?: boolean;
|
withMedia?: boolean;
|
||||||
useWindowScroll?: boolean;
|
useWindowScroll?: boolean;
|
||||||
itemClassName?: string;
|
itemClassName?: string;
|
||||||
|
@ -131,7 +131,7 @@ const Thread: React.FC<IThread> = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleToggleHidden = (status: Pick<SelectedStatus, 'id' | 'sensitive'>) => {
|
const handleToggleHidden = () => {
|
||||||
if (showMedia) {
|
if (showMedia) {
|
||||||
hideStatus(status.id);
|
hideStatus(status.id);
|
||||||
} else {
|
} else {
|
||||||
|
@ -152,11 +152,11 @@ const Thread: React.FC<IThread> = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleHotkeyToggleHidden = () => {
|
const handleHotkeyToggleHidden = () => {
|
||||||
handleToggleHidden(status!);
|
handleToggleHidden();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleHotkeyToggleSensitive = () => {
|
const handleHotkeyToggleSensitive = () => {
|
||||||
handleToggleHidden(status!);
|
handleToggleHidden();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleMoveUp = (id: string) => {
|
const handleMoveUp = (id: string) => {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import Button from 'bigbuffet/components/ui/button';
|
||||||
import { useFeatures } from 'bigbuffet/hooks/useFeatures';
|
import { useFeatures } from 'bigbuffet/hooks/useFeatures';
|
||||||
import { useModalsStore } from 'bigbuffet/stores/modals';
|
import { useModalsStore } from 'bigbuffet/stores/modals';
|
||||||
|
|
||||||
import type { Account } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as Account } from 'pl-hooks';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
follow: { id: 'account.follow', defaultMessage: 'Follow' },
|
||||||
|
|
|
@ -7,8 +7,8 @@ import Video from 'bigbuffet/features/video';
|
||||||
|
|
||||||
import { BaseModalProps } from '../modal-root';
|
import { BaseModalProps } from '../modal-root';
|
||||||
|
|
||||||
import type { Account } from 'bigbuffet/normalizers/account';
|
|
||||||
import type { MediaAttachment } from 'pl-api';
|
import type { MediaAttachment } from 'pl-api';
|
||||||
|
import type { UseAccountData as Account } from 'pl-hooks';
|
||||||
|
|
||||||
interface VideoModalProps {
|
interface VideoModalProps {
|
||||||
media: MediaAttachment;
|
media: MediaAttachment;
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { ParsedContent } from 'bigbuffet/components/parsed-content';
|
||||||
import Emojify from 'bigbuffet/features/emoji';
|
import Emojify from 'bigbuffet/features/emoji';
|
||||||
import { unescapeHTML } from 'bigbuffet/utils/html';
|
import { unescapeHTML } from 'bigbuffet/utils/html';
|
||||||
|
|
||||||
import type { Account } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as Account } from 'pl-hooks';
|
||||||
|
|
||||||
// const getTicker = (value: string): string => (value.match(/\$([a-zA-Z]*)/i) || [])[1];
|
// const getTicker = (value: string): string => (value.match(/\$([a-zA-Z]*)/i) || [])[1];
|
||||||
// const isTicker = (value: string): boolean => Boolean(getTicker(value));
|
// const isTicker = (value: string): boolean => Boolean(getTicker(value));
|
||||||
|
|
|
@ -11,7 +11,7 @@ import { capitalize } from 'bigbuffet/utils/strings';
|
||||||
|
|
||||||
import ProfileField from './profile-field';
|
import ProfileField from './profile-field';
|
||||||
|
|
||||||
import type { Account } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as Account } from 'pl-hooks';
|
||||||
|
|
||||||
const messages = defineMessages({
|
const messages = defineMessages({
|
||||||
linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
|
linkVerifiedOn: { id: 'account.link_verified_on', defaultMessage: 'Ownership of this link was checked on {date}' },
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { useStatusMetaStore } from 'bigbuffet/stores/status-meta';
|
import { useStatusMetaStore } from 'bigbuffet/stores/status-meta';
|
||||||
|
|
||||||
import type { SelectedStatus } from 'bigbuffet/selectors';
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
|
|
||||||
const useShowMedia = (status: SelectedStatus) => useStatusMetaStore().statuses[status.id]?.visible ?? !status.sensitive;
|
const useShowMedia = (status: Pick<Status, 'id' | 'sensitive'>) => useStatusMetaStore().statuses[status.id]?.visible ?? !status.sensitive;
|
||||||
|
|
||||||
export { useShowMedia };
|
export { useShowMedia };
|
||||||
|
|
|
@ -10,6 +10,8 @@ import { unescapeHTML } from 'bigbuffet/utils/html';
|
||||||
|
|
||||||
import { normalizeAccount } from './account';
|
import { normalizeAccount } from './account';
|
||||||
|
|
||||||
|
import type { UseStatusData } from 'pl-hooks';
|
||||||
|
|
||||||
const domParser = new DOMParser();
|
const domParser = new DOMParser();
|
||||||
|
|
||||||
type StatusApprovalStatus = Exclude<BaseStatus['approval_status'], null>;
|
type StatusApprovalStatus = Exclude<BaseStatus['approval_status'], null>;
|
||||||
|
@ -24,7 +26,7 @@ type CalculatedValues = {
|
||||||
type OldStatus = Pick<BaseStatus, 'content' | 'spoiler_text'> & CalculatedValues;
|
type OldStatus = Pick<BaseStatus, 'content' | 'spoiler_text'> & CalculatedValues;
|
||||||
|
|
||||||
// Gets titles of poll options from status
|
// Gets titles of poll options from status
|
||||||
const getPollOptionTitles = ({ poll }: Pick<BaseStatus, 'poll'>): readonly string[] => {
|
const getPollOptionTitles = ({ poll }: Pick<BaseStatus | UseStatusData, 'poll'>): readonly string[] => {
|
||||||
if (poll && typeof poll === 'object') {
|
if (poll && typeof poll === 'object') {
|
||||||
return poll.options.map(({ title }) => title);
|
return poll.options.map(({ title }) => title);
|
||||||
} else {
|
} else {
|
||||||
|
@ -37,7 +39,7 @@ const getMentionedUsernames = (status: Pick<BaseStatus, 'mentions'>): Array<stri
|
||||||
status.mentions.map(({ acct }) => `@${acct}`);
|
status.mentions.map(({ acct }) => `@${acct}`);
|
||||||
|
|
||||||
// Creates search text from the status
|
// Creates search text from the status
|
||||||
const buildSearchContent = (status: Pick<BaseStatus, 'poll' | 'mentions' | 'spoiler_text' | 'content'>): string => {
|
const buildSearchContent = (status: Pick<BaseStatus | UseStatusData, 'poll' | 'mentions' | 'spoiler_text' | 'content'>): string => {
|
||||||
const pollOptionTitles = getPollOptionTitles(status);
|
const pollOptionTitles = getPollOptionTitles(status);
|
||||||
const mentionedUsernames = getMentionedUsernames(status);
|
const mentionedUsernames = getMentionedUsernames(status);
|
||||||
|
|
||||||
|
@ -149,8 +151,9 @@ const normalizeStatus = (status: BaseStatus & {
|
||||||
type Status = ReturnType<typeof normalizeStatus>;
|
type Status = ReturnType<typeof normalizeStatus>;
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
type Status,
|
||||||
type StatusApprovalStatus,
|
type StatusApprovalStatus,
|
||||||
type StatusVisibility,
|
type StatusVisibility,
|
||||||
|
buildSearchContent,
|
||||||
normalizeStatus,
|
normalizeStatus,
|
||||||
type Status,
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
ref: React.MutableRefObject<HTMLDivElement> | null;
|
ref: React.MutableRefObject<HTMLDivElement | null> | null;
|
||||||
accountId: string | null;
|
accountId: string | null;
|
||||||
hovered: boolean;
|
hovered: boolean;
|
||||||
openAccountHoverCard: (ref: React.MutableRefObject<HTMLDivElement>, accountId: string) => void;
|
openAccountHoverCard: (ref: React.MutableRefObject<HTMLDivElement | null>, accountId: string) => void;
|
||||||
updateAccountHoverCard: () => void;
|
updateAccountHoverCard: () => void;
|
||||||
closeAccountHoverCard: (force?: boolean) => void;
|
closeAccountHoverCard: (force?: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { create } from 'zustand';
|
import { create } from 'zustand';
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
ref: React.MutableRefObject<HTMLDivElement> | null;
|
ref: React.MutableRefObject<HTMLDivElement | null> | null;
|
||||||
statusId: string | null;
|
statusId: string | null;
|
||||||
hovered: boolean;
|
hovered: boolean;
|
||||||
openStatusHoverCard: (ref: React.MutableRefObject<HTMLDivElement>, statusId: string) => void;
|
openStatusHoverCard: (ref: React.MutableRefObject<HTMLDivElement | null>, statusId: string) => void;
|
||||||
updateStatusHoverCard: () => void;
|
updateStatusHoverCard: () => void;
|
||||||
closeStatusHoverCard: (force?: boolean) => void;
|
closeStatusHoverCard: (force?: boolean) => void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { Account } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as Account } from 'pl-hooks';
|
||||||
|
|
||||||
const getAcct = (account: Pick<Account, 'fqn' | 'acct'>, displayFqn: boolean): string =>
|
const getAcct = (account: Pick<Account, 'fqn' | 'acct'>, displayFqn: boolean): string =>
|
||||||
(displayFqn === true && account.fqn) || account.acct;
|
(displayFqn === true && account.fqn) || account.acct;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { Account } from 'bigbuffet/normalizers/account';
|
import type { UseAccountData as Account } from 'pl-hooks';
|
||||||
|
|
||||||
/** Convert a badge into a plain tag. */
|
/** Convert a badge into a plain tag. */
|
||||||
const badgeToTag = (badge: string) => badge.replace(/^badge:/, '');
|
const badgeToTag = (badge: string) => badge.replace(/^badge:/, '');
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import type { Status } from 'bigbuffet/normalizers/status';
|
import { buildSearchContent } from 'bigbuffet/normalizers/status';
|
||||||
|
|
||||||
|
import type { UseStatusData as Status } from 'pl-hooks';
|
||||||
import type { IntlShape } from 'react-intl';
|
import type { IntlShape } from 'react-intl';
|
||||||
|
|
||||||
/** Sanitize status text for use with screen readers. */
|
/** Sanitize status text for use with screen readers. */
|
||||||
const textForScreenReader = (
|
const textForScreenReader = (
|
||||||
intl: IntlShape,
|
intl: IntlShape,
|
||||||
status: Pick<Status, 'account' | 'spoiler_text' | 'search_index' | 'created_at'>,
|
status: Pick<Status, 'account' | 'content' | 'created_at' | 'mentions' | 'poll' | 'spoiler_text'>,
|
||||||
rebloggedByText?: string,
|
rebloggedByText?: string,
|
||||||
): string => {
|
): string => {
|
||||||
const { account } = status;
|
const { account } = status;
|
||||||
|
@ -14,7 +16,8 @@ const textForScreenReader = (
|
||||||
|
|
||||||
const values = [
|
const values = [
|
||||||
displayName.length === 0 ? account.acct.split('@')[0] : displayName,
|
displayName.length === 0 ? account.acct.split('@')[0] : displayName,
|
||||||
status.search_index?.slice(status.spoiler_text.length),
|
buildSearchContent(status),
|
||||||
|
// status.search_index?.slice(status.spoiler_text.length),
|
||||||
intl.formatDate(status.created_at, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }),
|
intl.formatDate(status.created_at, { hour: '2-digit', minute: '2-digit', month: 'short', day: 'numeric' }),
|
||||||
account.acct,
|
account.acct,
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in a new issue