import PropTypes from "prop-types"; import { useRef, useCallback, useEffect } from "react"; import { useIntl, defineMessages, FormattedMessage } from "react-intl"; import { Helmet } from "react-helmet"; import { NavLink } from "react-router-dom"; import { addColumn } from "mastodon/actions/columns"; import { changeSetting } from "mastodon/actions/settings"; import { connectPublicStream, connectCommunityStream } from "mastodon/actions/streaming"; import { expandPublicTimeline, expandCommunityTimeline } from "mastodon/actions/timelines"; import { DismissableBanner } from "mastodon/components/dismissable_banner"; import initialState, { domain } from "mastodon/initial_state"; import { useAppDispatch, useAppSelector } from "mastodon/store"; import Column from "../../components/column"; import ColumnHeader from "../../components/column_header"; import SettingToggle from "../notifications/components/setting_toggle"; import StatusListContainer from "../ui/containers/status_list_container"; const messages = defineMessages({ title: { id: "column.firehose", defaultMessage: "Live feeds" }, }); // TODO: use a proper React context later on const useIdentity = () => ({ signedIn: !!initialState.meta.me, accountId: initialState.meta.me, disabledAccountId: initialState.meta.disabled_account_id, accessToken: initialState.meta.access_token, permissions: initialState.role ? initialState.role.permissions : 0, }); const ColumnSettings = () => { const dispatch = useAppDispatch(); const settings = useAppSelector((state) => state.getIn(["settings", "firehose"])); const onChange = useCallback( (key, checked) => dispatch(changeSetting(["firehose", ...key], checked)), [dispatch], ); return (
} />
); }; const Firehose = ({ feedType, multiColumn }) => { const dispatch = useAppDispatch(); const intl = useIntl(); const { signedIn } = useIdentity(); const columnRef = useRef(null); const onlyMedia = useAppSelector((state) => state.getIn(["settings", "firehose", "onlyMedia"], false)); const hasUnread = useAppSelector((state) => state.getIn(["timelines", `${feedType}${onlyMedia ? ":media" : ""}`, "unread"], 0) > 0); const handlePin = useCallback( () => { switch(feedType) { case "community": dispatch(addColumn("COMMUNITY", { other: { onlyMedia } })); break; case "public": dispatch(addColumn("PUBLIC", { other: { onlyMedia } })); break; case "public:remote": dispatch(addColumn("REMOTE", { other: { onlyMedia, onlyRemote: true } })); break; } }, [dispatch, onlyMedia, feedType], ); const handleLoadMore = useCallback( (maxId) => { switch(feedType) { case "community": dispatch(expandCommunityTimeline({ maxId, onlyMedia })); break; case "public": dispatch(expandPublicTimeline({ maxId, onlyMedia })); break; case "public:remote": dispatch(expandPublicTimeline({ maxId, onlyMedia, onlyRemote: true })); break; } }, [dispatch, onlyMedia, feedType], ); const handleHeaderClick = useCallback(() => columnRef.current?.scrollTop(), []); useEffect(() => { let disconnect; switch(feedType) { case "community": dispatch(expandCommunityTimeline({ onlyMedia })); if (signedIn) { disconnect = dispatch(connectCommunityStream({ onlyMedia })); } break; case "public": dispatch(expandPublicTimeline({ onlyMedia })); if (signedIn) { disconnect = dispatch(connectPublicStream({ onlyMedia })); } break; case "public:remote": dispatch(expandPublicTimeline({ onlyMedia, onlyRemote: true })); if (signedIn) { disconnect = dispatch(connectPublicStream({ onlyMedia, onlyRemote: true })); } break; } return () => disconnect?.(); }, [dispatch, signedIn, feedType, onlyMedia]); const prependBanner = feedType === "community" ? ( ) : ( ); const emptyMessage = feedType === "community" ? ( ) : ( ); return (
{intl.formatMessage(messages.title)}
); }; Firehose.propTypes = { multiColumn: PropTypes.bool, feedType: PropTypes.string, }; export default Firehose;