Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@gorhom/bottom-sheet": "^4",
"@metamask/eth-sig-util": "^5.0.0",
"@notifee/react-native": "^9.1.8",
"@pushprotocol/restapi": "^1.7.28",
"@pushprotocol/restapi": "^1.7.30",
"@pushprotocol/socket": "latest",
"@react-native-async-storage/async-storage": "1.17.11",
"@react-native-clipboard/clipboard": "^1.11.1",
Expand Down
77 changes: 70 additions & 7 deletions src/components/buttons/SubscriptionStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,57 @@
import {Ionicons, MaterialIcons} from '@expo/vector-icons';
import React, {useMemo, useState} from 'react';
import React, {useEffect, useMemo, useState} from 'react';
import {
ActivityIndicator,
Pressable,
StyleSheet,
Text,
View,
} from 'react-native';
import {useSelector} from 'react-redux';
import {useDispatch, useSelector} from 'react-redux';
import GLOBALS from 'src/Globals';
import PrimaryButton from 'src/components/buttons/PrimaryButton';
import {usePushApi} from 'src/contexts/PushApiContext';
import {useToaster} from 'src/contexts/ToasterContext';
import {TimeoutHelper} from 'src/helpers/TimeoutHelper';
import useSubscriptions from 'src/hooks/channel/useSubscriptions';
import {selectIsGuest} from 'src/redux/authSlice';
import {
Channel,
selectChannelPendingSubscription,
selectIsLoadingSubscriptions,
selectSubscriptions,
setChannelPendingSubscription,
} from 'src/redux/channelSlice';

import {ToasterOptions} from '../indicators/Toaster';

export type SubscriptionStatusProps = {
channel: Channel;
selectChannelForSettings: (channel: Channel) => void;
};

export type ChannelPendingSubscriptionType = {
channel_id: string | null;
status: boolean;
};

const SubscriptionStatus = ({
selectChannelForSettings,
channel: channelData,
}: {
channel: Channel;
selectChannelForSettings: (channel: Channel) => void;
}) => {
}: SubscriptionStatusProps) => {
const dispatch = useDispatch();
const [processing, setProcessing] = useState(false);

const subscriptions = useSelector(selectSubscriptions);
const channelPendingSubscription = useSelector(
selectChannelPendingSubscription,
);
const isLoadingSubscriptions = useSelector(selectIsLoadingSubscriptions);
const isGuest = useSelector(selectIsGuest);

const {subscribe} = useSubscriptions();
const {toastRef} = useToaster();
const {showUnlockProfileModal, isUnlockProfileModalOpen} = usePushApi();

const channelSettings = channelData.channel_settings;
const channel = channelData.channel;
Expand All @@ -41,8 +60,52 @@ const SubscriptionStatus = ({
return subscriptions?.[channel] !== undefined;
}, [subscriptions, channel]);

useEffect(() => {
// If the channel is pending subscription and the unlock profile modal is not open
if (
channelPendingSubscription.status &&
channelPendingSubscription.channel_id === channelData.channel_id &&
!isUnlockProfileModalOpen
) {
// If the user is not guest, then subscribe/unsubscribe the channel
if (!isGuest) {
dispatch(
setChannelPendingSubscription({
channel_id: null,
status: false,
}),
);
handleChangeSubStatus();
} else {
dispatch(
setChannelPendingSubscription({
channel_id: null,
status: false,
}),
);
setProcessing(false);
}
}
}, [isGuest]);

const checkIfGuest = async () => {
// If the user is a guest, show the unlock profile modal
if (isGuest) {
setProcessing(true);
dispatch(
setChannelPendingSubscription({
channel_id: channelData.channel_id,
status: true,
}),
);
showUnlockProfileModal();
return true;
}
return false;
};

const handleChangeSubStatus = async () => {
setProcessing(true);
if (await checkIfGuest()) return;
if (subscribed === true) {
selectChannelForSettings(channelData);
} else {
Expand Down
7 changes: 6 additions & 1 deletion src/components/ui/ChannelsDisplayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,12 @@ const ChannelsDisplayer = () => {
onEndReached={loadMore}
onEndReachedThreshold={0.8}
renderItem={({item: channel}) => (
<ChannelItem {...{channel, selectChannelForSettings}} />
<ChannelItem
{...{
channel,
selectChannelForSettings,
}}
/>
)}
ListFooterComponent={() => {
return isLoading || isLoadingMore ? (
Expand Down
4 changes: 4 additions & 0 deletions src/contexts/PushApiContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type PushApiContextType = {
getReadOnlyInstance: (overrideAccount?: string) => Promise<void>;
isLoading: boolean;
showUnlockProfileModal: () => void;
isUnlockProfileModalOpen: boolean;
};

export const PushApiContext = createContext<PushApiContextType>({
Expand All @@ -47,6 +48,7 @@ export const PushApiContext = createContext<PushApiContextType>({
getReadOnlyInstance: () => Promise.resolve(),
isLoading: true,
showUnlockProfileModal: () => {},
isUnlockProfileModalOpen: false,
});

export const usePushApi = () => {
Expand Down Expand Up @@ -77,6 +79,7 @@ const PushApiContextProvider = ({children}: {children: React.ReactNode}) => {
ModalComponent: UnlockProfileModal,
hideModal: hideUnlockProfileModal,
showModal: showUnlockProfileModal,
isModalOpen: isUnlockProfileModalOpen,
} = useModalBlur();

const {
Expand Down Expand Up @@ -234,6 +237,7 @@ const PushApiContextProvider = ({children}: {children: React.ReactNode}) => {
userInfo,
isLoading,
showUnlockProfileModal,
isUnlockProfileModalOpen,
}}>
<AddressMismatchModal
InnerComponent={AuthModalWrapper}
Expand Down
6 changes: 6 additions & 0 deletions src/hooks/channel/useSubscriptions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {

import {usePushApiMode} from '../pushapi/usePushApiMode';
import {useSigner} from '../pushapi/useSigner';
import useModalBlur from '../ui/useModalBlur';

const useSubscriptions = () => {
const [loaded, setLoaded] = useState(false);
Expand Down Expand Up @@ -81,6 +82,7 @@ const useSubscriptions = () => {
? // @ts-ignore
baseClass.getMinimalUserSetting(pushSettings)
: null;
const pgpPrivateKey = userPushSDKInstance?.decryptedPgpPvtKey;
await channels.subscribeV2({
channelAddress: channelCaip,
signer: signer,
Expand All @@ -89,6 +91,7 @@ const useSubscriptions = () => {
settings: settings,
onSuccess: onSuccess,
onError: onError,
pgpPrivateKey,
});
} catch (e) {
console.error(e);
Expand Down Expand Up @@ -120,13 +123,15 @@ const useSubscriptions = () => {
const {account, signer} = await getPushSigner();
if (isSignerEnabled && signer && account) {
try {
const pgpPrivateKey = userPushSDKInstance?.decryptedPgpPvtKey;
await channels.unsubscribeV2({
channelAddress: channelCaip,
signer,
userAddress: account,
env: envConfig.ENV as ENV,
onSuccess: onSuccess,
onError: onError,
pgpPrivateKey,
});
} catch (e) {
console.error(e);
Expand All @@ -139,6 +144,7 @@ const useSubscriptions = () => {
const refreshSubscriptions = async (force = false) => {
try {
if (loaded && !force) return;
console.log('Refreshing subscriptions');
dispatch(setLoadingSubscriptions(true));
const response = await userPushSDKInstance?.notification.subscriptions({
account: caip10ToWallet(userPushSDKInstance?.account),
Expand Down
15 changes: 15 additions & 0 deletions src/redux/channelSlice.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {PayloadAction, createSlice} from '@reduxjs/toolkit';
import {ChannelPendingSubscriptionType} from 'src/components/buttons/SubscriptionStatus';
import {
ChannelSetting,
UserSetting,
Expand Down Expand Up @@ -30,12 +31,17 @@ type ChannelSliceData = {
channels: Array<Channel>;
subscriptions: SubscriptionsMapping;
isLoadingSubscriptions: boolean;
channelPendingSubscription: ChannelPendingSubscriptionType;
};

const initialState: ChannelSliceData = {
channels: [],
subscriptions: {},
isLoadingSubscriptions: false,
channelPendingSubscription: {
channel_id: null,
status: false,
},
};

const channelSlice = createSlice({
Expand Down Expand Up @@ -66,6 +72,12 @@ const channelSlice = createSlice({
setLoadingSubscriptions: (state, action: PayloadAction<boolean>) => {
state.isLoadingSubscriptions = action.payload;
},
setChannelPendingSubscription: (
state,
action: PayloadAction<ChannelPendingSubscriptionType>,
) => {
state.channelPendingSubscription = action.payload;
},
},
});

Expand All @@ -77,6 +89,7 @@ export const {
removeChannelSubscription,
setSubscriptions,
setLoadingSubscriptions,
setChannelPendingSubscription,
} = channelSlice.actions;

type ReturnTypeChannel = {channel: ChannelSliceData};
Expand All @@ -88,5 +101,7 @@ export const selectSubscriptions = (state: ReturnTypeChannel) =>
state.channel.subscriptions;
export const selectIsLoadingSubscriptions = (state: ReturnTypeChannel) =>
state.channel.isLoadingSubscriptions;
export const selectChannelPendingSubscription = (state: ReturnTypeChannel) =>
state.channel.channelPendingSubscription;

export default channelSlice.reducer;
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4807,9 +4807,9 @@ __metadata:
languageName: node
linkType: hard

"@pushprotocol/restapi@npm:^1.7.28":
version: 1.7.28
resolution: "@pushprotocol/restapi@npm:1.7.28"
"@pushprotocol/restapi@npm:^1.7.30":
version: 1.7.30
resolution: "@pushprotocol/restapi@npm:1.7.30"
dependencies:
"@metamask/eth-sig-util": "npm:^5.0.2"
axios: "npm:^0.27.2"
Expand All @@ -4832,7 +4832,7 @@ __metadata:
peerDependenciesMeta:
ethers:
optional: true
checksum: 10/63fe891a9adb7a9bb911d059bbcb633d432eeed2c71ec1c1ab54a91895ca59f205fd46b450f9f50890d9b1e74120180b0ac45b869a3bdf0c7077445235c45d65
checksum: 10/327dbd17b7b3f34d56e5326502358196fcf9320a2fcdc0b73efa60e959c90f7c9359f1ea5d53387dbc8dc0551bbd9f60685dffd688ef6215558fe9939f2aee8a
languageName: node
linkType: hard

Expand Down Expand Up @@ -16861,7 +16861,7 @@ __metadata:
"@gorhom/bottom-sheet": "npm:^4"
"@metamask/eth-sig-util": "npm:^5.0.0"
"@notifee/react-native": "npm:^9.1.8"
"@pushprotocol/restapi": "npm:^1.7.28"
"@pushprotocol/restapi": "npm:^1.7.30"
"@pushprotocol/socket": "npm:latest"
"@react-native-async-storage/async-storage": "npm:1.17.11"
"@react-native-clipboard/clipboard": "npm:^1.11.1"
Expand Down