Add Streaming hooks

environments/review-streaming-wgs1pl/deployments/3677
Alex Gleason 2023-07-22 12:49:02 -05:00
rodzic bea4707743
commit 77f0f4d377
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 7211D1F99744FBB7
6 zmienionych plików z 88 dodań i 44 usunięć

Wyświetl plik

@ -73,8 +73,9 @@ const updateChatQuery = (chat: IChat) => {
queryClient.setQueryData<Chat>(ChatKeys.chat(chat.id), newChat as any);
};
interface StreamOpts {
interface TimelineStreamOpts {
statContext?: IStatContext
enabled?: boolean
}
const connectTimelineStream = (
@ -82,7 +83,7 @@ const connectTimelineStream = (
path: string,
pollingRefresh: ((dispatch: AppDispatch, done?: () => void) => void) | null = null,
accept: ((status: APIEntity) => boolean) | null = null,
opts?: StreamOpts,
opts?: TimelineStreamOpts,
) => connectStream(path, pollingRefresh, (dispatch: AppDispatch, getState: () => RootState) => {
const locale = getLocale(getState());
@ -196,7 +197,7 @@ const refreshHomeTimelineAndNotification = (dispatch: AppDispatch, done?: () =>
dispatch(expandNotifications({}, () =>
dispatch(fetchAnnouncements(done))))));
const connectUserStream = (opts?: StreamOpts) =>
const connectUserStream = (opts?: TimelineStreamOpts) =>
connectTimelineStream('home', 'user', refreshHomeTimelineAndNotification, null, opts);
const connectCommunityStream = ({ onlyMedia }: Record<string, any> = {}) =>
@ -236,4 +237,5 @@ export {
connectListStream,
connectGroupStream,
connectNostrStream,
type TimelineStreamOpts,
};

Wyświetl plik

@ -43,3 +43,7 @@ export { useSuggestedGroups } from './groups/useSuggestedGroups';
export { useUnmuteGroup } from './groups/useUnmuteGroup';
export { useUpdateGroup } from './groups/useUpdateGroup';
export { useUpdateGroupTag } from './groups/useUpdateGroupTag';
// Streaming
export { useUserStream } from './streaming/useUserStream';
export { useNostrStream } from './streaming/useNostrStream';

Wyświetl plik

@ -0,0 +1,11 @@
import { useFeatures } from 'soapbox/hooks';
import { useTimelineStream } from './useTimelineStream';
function useNostrStream() {
const features = useFeatures();
const enabled = features.nostrSign && Boolean(window.nostr);
return useTimelineStream('nostr', 'nostr', null, null, { enabled });
}
export { useNostrStream };

Wyświetl plik

@ -0,0 +1,41 @@
import { useEffect, useRef } from 'react';
import { connectTimelineStream } from 'soapbox/actions/streaming';
import { useAppDispatch, useAppSelector, useInstance } from 'soapbox/hooks';
import { getAccessToken } from 'soapbox/utils/auth';
function useTimelineStream(...args: Parameters<typeof connectTimelineStream>) {
// TODO: get rid of streaming.ts and move the actual opts here.
const { enabled = true } = args[4] ?? {};
const dispatch = useAppDispatch();
const instance = useInstance();
const stream = useRef<(() => void) | null>(null);
const accessToken = useAppSelector(getAccessToken);
const streamingUrl = instance.urls.get('streaming_api');
const connect = () => {
if (enabled && accessToken && streamingUrl && !stream.current) {
stream.current = dispatch(connectTimelineStream(...args));
}
};
const disconnect = () => {
if (stream.current) {
stream.current();
stream.current = null;
}
};
useEffect(() => {
connect();
return disconnect;
}, [accessToken, streamingUrl, enabled]);
return {
disconnect,
};
}
export { useTimelineStream };

Wyświetl plik

@ -0,0 +1,22 @@
import { fetchAnnouncements } from 'soapbox/actions/announcements';
import { expandNotifications } from 'soapbox/actions/notifications';
import { expandHomeTimeline } from 'soapbox/actions/timelines';
import { useStatContext } from 'soapbox/contexts/stat-context';
import { useTimelineStream } from './useTimelineStream';
import type { AppDispatch } from 'soapbox/store';
function useUserStream() {
const statContext = useStatContext();
return useTimelineStream('home', 'user', refresh, null, { statContext });
}
/** Refresh home timeline and notifications. */
function refresh(dispatch: AppDispatch, done?: () => void) {
return dispatch(expandHomeTimeline({}, () =>
dispatch(expandNotifications({}, () =>
dispatch(fetchAnnouncements(done))))));
}
export { useUserStream };

Wyświetl plik

@ -14,16 +14,15 @@ import { openModal } from 'soapbox/actions/modals';
import { expandNotifications } from 'soapbox/actions/notifications';
import { register as registerPushNotifications } from 'soapbox/actions/push-notifications';
import { fetchScheduledStatuses } from 'soapbox/actions/scheduled-statuses';
import { connectNostrStream, connectUserStream } from 'soapbox/actions/streaming';
import { fetchSuggestionsForTimeline } from 'soapbox/actions/suggestions';
import { expandHomeTimeline } from 'soapbox/actions/timelines';
import { useNostrStream, useUserStream } from 'soapbox/api/hooks';
import GroupLookupHoc from 'soapbox/components/hoc/group-lookup-hoc';
import withHoc from 'soapbox/components/hoc/with-hoc';
import SidebarNavigation from 'soapbox/components/sidebar-navigation';
import ThumbNavigation from 'soapbox/components/thumb-navigation';
import { Layout } from 'soapbox/components/ui';
import { useStatContext } from 'soapbox/contexts/stat-context';
import { useAppDispatch, useAppSelector, useOwnAccount, useSoapboxConfig, useFeatures, useInstance, useDraggedFiles } from 'soapbox/hooks';
import { useAppDispatch, useAppSelector, useOwnAccount, useSoapboxConfig, useFeatures, useDraggedFiles } from 'soapbox/hooks';
import AdminPage from 'soapbox/pages/admin-page';
import ChatsPage from 'soapbox/pages/chats-page';
import DefaultPage from 'soapbox/pages/default-page';
@ -39,7 +38,7 @@ import RemoteInstancePage from 'soapbox/pages/remote-instance-page';
import SearchPage from 'soapbox/pages/search-page';
import StatusPage from 'soapbox/pages/status-page';
import { usePendingPolicy } from 'soapbox/queries/policies';
import { getAccessToken, getVapidKey } from 'soapbox/utils/auth';
import { getVapidKey } from 'soapbox/utils/auth';
import { isStandalone } from 'soapbox/utils/state';
import BackgroundShapes from './components/background-shapes';
@ -363,21 +362,13 @@ const UI: React.FC<IUI> = ({ children }) => {
const history = useHistory();
const dispatch = useAppDispatch();
const { data: pendingPolicy } = usePendingPolicy();
const instance = useInstance();
const statContext = useStatContext();
const userStream = useRef<any>(null);
const nostrStream = useRef<any>(null);
const node = useRef<HTMLDivElement | null>(null);
const me = useAppSelector(state => state.me);
const { account } = useOwnAccount();
const features = useFeatures();
const vapidKey = useAppSelector(state => getVapidKey(state));
const dropdownMenuIsOpen = useAppSelector(state => state.dropdown_menu.isOpen);
const accessToken = useAppSelector(state => getAccessToken(state));
const streamingUrl = instance.urls.get('streaming_api');
const standalone = useAppSelector(isStandalone);
const { isDragging } = useDraggedFiles(node);
@ -390,28 +381,6 @@ const UI: React.FC<IUI> = ({ children }) => {
}
};
const connectStreaming = () => {
if (accessToken && streamingUrl) {
if (!userStream.current) {
userStream.current = dispatch(connectUserStream({ statContext }));
}
if (!nostrStream.current && features.nostrSign && window.nostr) {
nostrStream.current = dispatch(connectNostrStream());
}
}
};
const disconnectStreaming = () => {
if (userStream.current) {
userStream.current();
userStream.current = null;
}
if (nostrStream.current) {
nostrStream.current();
nostrStream.current = null;
}
};
const handleDragEnter = (e: DragEvent) => e.preventDefault();
const handleDragLeave = (e: DragEvent) => e.preventDefault();
const handleDragOver = (e: DragEvent) => e.preventDefault();
@ -458,10 +427,6 @@ const UI: React.FC<IUI> = ({ children }) => {
if (window.Notification?.permission === 'default') {
window.setTimeout(() => Notification.requestPermission(), 120 * 1000);
}
return () => {
disconnectStreaming();
};
}, []);
useEffect(() => {
@ -477,9 +442,8 @@ const UI: React.FC<IUI> = ({ children }) => {
};
}, []);
useEffect(() => {
connectStreaming();
}, [accessToken, streamingUrl]);
useUserStream();
useNostrStream();
// The user has logged in
useEffect(() => {