Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Subscribe guides to a new presence pusher channel #48696

Merged
merged 11 commits into from
Sep 19, 2024
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,7 @@ const CONST = {
PUSHER: {
PRIVATE_USER_CHANNEL_PREFIX: 'private-encrypted-user-accountID-',
PRIVATE_REPORT_CHANNEL_PREFIX: 'private-report-reportID-',
PRESENCE_ACTIVE_GUIDES: 'presence-activeGuides',
},

EMOJI_SPACER: 'SPACER',
Expand Down
32 changes: 32 additions & 0 deletions src/components/ActiveGuidesEventListener.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {useEffect, useRef} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import {subscribeToActiveGuides} from '@userActions/User';
import ONYXKEYS from '@src/ONYXKEYS';
import type {User} from '@src/types/onyx';

type ActiveGuidesEventListenerOnyxProps = {
user: OnyxEntry<User>;
};

type ActiveGuidesEventListenerProps = ActiveGuidesEventListenerOnyxProps;

function ActiveGuidesEventListener({user}: ActiveGuidesEventListenerProps) {
const didSubscribeToActiveGuides = useRef(false);
useEffect(() => {
if (didSubscribeToActiveGuides.current) {
return;
}
if (user?.isGuide) {
didSubscribeToActiveGuides.current = true;
subscribeToActiveGuides();
}
}, [user]);
return null;
}

export default withOnyx<ActiveGuidesEventListenerProps, ActiveGuidesEventListenerOnyxProps>({
user: {
key: ONYXKEYS.USER,
},
})(ActiveGuidesEventListener);
11 changes: 8 additions & 3 deletions src/libs/Navigation/AppNavigator/AuthScreens.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import React, {memo, useEffect, useMemo, useRef} from 'react';
import React, {memo, useEffect, useMemo, useRef, useState} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import Onyx, {withOnyx} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import ActiveGuidesEventListener from '@components/ActiveGuidesEventListener';
import ComposeProviders from '@components/ComposeProviders';
import OptionsListContextProvider from '@components/OptionListContextProvider';
import {SearchContextProvider} from '@components/Search/SearchContext';
Expand Down Expand Up @@ -106,7 +107,7 @@ function getCentralPaneScreenInitialParams(screenName: CentralPaneName, initialR
}

function initializePusher() {
Pusher.init({
return Pusher.init({
appKey: CONFIG.PUSHER.APP_KEY,
cluster: CONFIG.PUSHER.CLUSTER,
authEndpoint: `${CONFIG.EXPENSIFY.DEFAULT_API_ROOT}api/AuthenticatePusher?`,
Expand Down Expand Up @@ -224,6 +225,7 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
[StyleUtils, shouldUseNarrowLayout, onboardingIsMediumOrLargerScreenWidth, styles],
);
const modal = useRef<OnyxTypes.Modal>({});
const [didPusherInit, setDidPusherInit] = useState(false);

let initialReportID: string | undefined;
const isInitialRender = useRef(true);
Expand Down Expand Up @@ -261,7 +263,9 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
NetworkConnection.listenForReconnect();
NetworkConnection.onReconnect(handleNetworkReconnect);
PusherConnectionManager.init();
initializePusher();
initializePusher().then(() => {
setDidPusherInit(true);
});

// If we are on this screen then we are "logged in", but the user might not have "just logged in". They could be reopening the app
// or returning from background. If so, we'll assume they have some app data already and we can call reconnectApp() instead of openApp().
Expand Down Expand Up @@ -559,6 +563,7 @@ function AuthScreens({session, lastOpenedPublicRoomID, initialLastUpdateIDApplie
})}
</RootStack.Navigator>
</View>
{didPusherInit && <ActiveGuidesEventListener />}
</ComposeProviders>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/libs/Permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type {IOUType} from '@src/CONST';
import type Beta from '@src/types/onyx/Beta';

function canUseAllBetas(betas: OnyxEntry<Beta[]>): boolean {
return !!betas?.includes(CONST.BETAS.ALL);
return true || !!betas?.includes(CONST.BETAS.ALL);
}

function canUseDefaultRooms(betas: OnyxEntry<Beta[]>): boolean {
Expand Down
4 changes: 2 additions & 2 deletions src/libs/Pusher/pusher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ function getChannel(channelName: string): Channel | undefined {
/**
* Binds an event callback to a channel + eventName
*/
function bindEventToChannel<EventName extends PusherEventName>(channel: Channel | undefined, eventName: EventName, eventCallback: (data: EventData<EventName>) => void = () => {}) {
function bindEventToChannel<EventName extends PusherEventName>(channel: Channel | undefined, eventName?: EventName, eventCallback: (data: EventData<EventName>) => void = () => {}) {
if (!eventName || !channel) {
return;
}
Expand Down Expand Up @@ -232,7 +232,7 @@ function bindEventToChannel<EventName extends PusherEventName>(channel: Channel
*/
function subscribe<EventName extends PusherEventName>(
channelName: string,
eventName: EventName,
eventName?: EventName,
eventCallback: (data: EventData<EventName>) => void = () => {},
onResubscribe = () => {},
): Promise<void> {
Expand Down
9 changes: 9 additions & 0 deletions src/libs/actions/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import * as ReportActionsUtils from '@libs/ReportActionsUtils';
import playSound, {SOUNDS} from '@libs/Sound';
import playSoundExcludingMobile from '@libs/Sound/playSoundExcludingMobile';
import Visibility from '@libs/Visibility';
import CONFIG from '@src/CONFIG';
import CONST from '@src/CONST';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
Expand Down Expand Up @@ -1315,6 +1316,13 @@ function requestRefund() {
API.write(WRITE_COMMANDS.REQUEST_REFUND, null);
}

function subscribeToActiveGuides() {
const pusherChannelName = `${CONST.PUSHER.PRESENCE_ACTIVE_GUIDES}${CONFIG.PUSHER.SUFFIX}`;
Pusher.subscribe(pusherChannelName).catch(() => {
Log.hmmm('[User] Failed to initially subscribe to Pusher channel', {pusherChannelName});
});
}

export {
clearFocusModeNotification,
closeAccount,
Expand Down Expand Up @@ -1353,5 +1361,6 @@ export {
requestValidateCodeAction,
addPendingContactMethod,
clearValidateCodeActionError,
subscribeToActiveGuides,
dismissGBRTooltip,
};
3 changes: 3 additions & 0 deletions src/types/onyx/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ type User = {

/** Whether the form is being submitted */
loading?: boolean;

/** Whether the user is Expensify Guide */
isGuide?: boolean;
};

export default User;
Loading