Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
6 changes: 5 additions & 1 deletion ts/components/dialog/SessionCTA.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ export const useShowSessionCTACbWithVariant = () => {
};
};

export async function handleTriggeredProCTAs(dispatch: Dispatch<any>) {
export async function handleTriggeredCTAs(dispatch: Dispatch<any>, fromAppStart: boolean) {
const proAvailable = getFeatureFlag('proAvailable');

if (Storage.get(SettingsKey.proExpiringSoonCTA)) {
Expand All @@ -441,6 +441,10 @@ export async function handleTriggeredProCTAs(dispatch: Dispatch<any>) {
);
await Storage.put(SettingsKey.proExpiredCTA, false);
} else {
if (!fromAppStart) {
// we only want to show the DonateCTA when the app starts, if needed
return;
}
const dbCreationTimestampMs = await Data.getDBCreationTimestampMs();
if (dbCreationTimestampMs && dbCreationTimestampMs + 7 * DURATION.DAYS < Date.now()) {
const donateInteractions = getUrlInteractionsForUrl(APP_URL.DONATE);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
type UserSettingsPage,
} from '../../../../state/ducks/modalDialog';
import { assertUnreachable } from '../../../../types/sqlSharedTypes';
import { handleTriggeredProCTAs } from '../../SessionCTA';
import { handleTriggeredCTAs } from '../../SessionCTA';
import { getFeatureFlag } from '../../../../state/ducks/types/releasedFeaturesReduxTypes';

export function useUserSettingsTitle(page: UserSettingsModalState | undefined) {
Expand Down Expand Up @@ -82,7 +82,7 @@ export function useUserSettingsCloseAction(props: UserSettingsModalState) {
return () => {
dispatch(userSettingsModal(null));
if (getFeatureFlag('proAvailable')) {
void handleTriggeredProCTAs(dispatch);
void handleTriggeredCTAs(dispatch, false);
}
props.afterCloseAction?.();
};
Expand Down
12 changes: 11 additions & 1 deletion ts/session/apis/snode_api/swarmPolling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ import {
getCachedUserConfig,
UserConfigWrapperActions,
} from '../../../webworker/workers/browser/libsession/libsession_worker_userconfig_interface';
import { isTestIntegration } from '../../../shared/env_vars';

const minMsgCountShouldRetry = 95;
/**
Expand Down Expand Up @@ -969,6 +970,11 @@ export class SwarmPolling {
window.log.info(
`[onboarding] about to pollOnceForOurDisplayName of ${ed25519Str(pubkey.key)} from snode: ${ed25519Str(toPollFrom.pubkey_ed25519)} namespaces: ${[SnodeNamespaces.UserProfile]} `
);
if (isTestIntegration()) {
// During integration tests, often deviceA might not have pushed to the swarm the userConfig that deviceB is looking for.
// To deal with, this, we wait a bit here before trying to fetch the userConfig.
await sleepFor(2000);
}
const retrieved = await SnodeAPIRetrieve.retrieveNextMessagesNoRetries(
toPollFrom,
pubkey.key,
Expand All @@ -983,13 +989,17 @@ export class SwarmPolling {
`[onboarding] pollOnceForOurDisplayName of ${ed25519Str(pubkey.key)} from snode: ${ed25519Str(toPollFrom.pubkey_ed25519)} namespaces: ${[SnodeNamespaces.UserProfile]} returned: ${retrieved?.length}`
);
if (!retrieved?.length) {
// Note: always print something so we know if the polling is hanging
window.log.info(
`[onboarding] pollOnceForOurDisplayName of ${ed25519Str(pubkey.key)} from snode: ${ed25519Str(toPollFrom.pubkey_ed25519)} namespaces: ${[SnodeNamespaces.UserProfile]} returned: ${retrieved?.length}`
);

/**
* Sometimes, a snode is out of sync with its swarm but still replies with what he thinks is the swarm's content.
* When that happens, we can get a "no display name" error, as indeed, that snode didn't have a config message on user profile.
* To fix this, we've added a check over all of the snodes of our swarm, and we pick the first one that reports having a config message on user profile.
* This won't take care of the case where a snode has a message with an empty display name, but it's not the root issue that this was added for.
*/

throw new Error(
`pollOnceForOurDisplayName of ${ed25519Str(pubkey.key)} from snode: ${ed25519Str(toPollFrom.pubkey_ed25519)} no results from user profile`
);
Expand Down
4 changes: 2 additions & 2 deletions ts/state/ducks/conversations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { sectionActions } from './section';
import { ed25519Str } from '../../session/utils/String';
import { UserUtils } from '../../session/utils';
import type { ProMessageFeature } from '../../models/proMessageFeature';
import { handleTriggeredProCTAs } from '../../components/dialog/SessionCTA';
import { handleTriggeredCTAs } from '../../components/dialog/SessionCTA';
import { getFeatureFlag } from './types/releasedFeaturesReduxTypes';

export type MessageModelPropsWithoutConvoProps = {
Expand Down Expand Up @@ -1148,7 +1148,7 @@ export async function openConversationWithMessages(args: {

if (window.inboxStore) {
if (getFeatureFlag('proAvailable')) {
await handleTriggeredProCTAs(window.inboxStore.dispatch);
await handleTriggeredCTAs(window.inboxStore.dispatch, false);
}
}
}
Expand Down
27 changes: 14 additions & 13 deletions ts/state/startup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import { initialNetworkDataState, networkDataActions } from './ducks/networkData
import { initialProBackendDataState, proBackendDataActions } from './ducks/proBackendData';
import { MessageQueue } from '../session/sending';
import { AvatarMigrate } from '../session/utils/job_runners/jobs/AvatarMigrateJob';
import { handleTriggeredProCTAs } from '../components/dialog/SessionCTA';
import { handleTriggeredCTAs } from '../components/dialog/SessionCTA';
import { UserSync } from '../session/utils/job_runners/jobs/UserSyncJob';
import { forceSyncConfigurationNowIfNeeded } from '../session/utils/sync/syncUtils';
import { SnodePool } from '../session/apis/snode_api/snodePool';
Expand Down Expand Up @@ -166,18 +166,19 @@ export const doAppStartUp = async () => {
proBackendDataActions.refreshGetProDetailsFromProBackend({}) as any
);
if (window.inboxStore) {
if (getDataFeatureFlag('useLocalDevNet') && isTestIntegration()) {
/**
* When running on the local dev net (during the regression tests), the network is too fast
* and we show the DonateCTA before we got the time to grab the recovery phrase.
* This sleepFor is there to give some time so we can grab the recovery phrase.
* The regression test this is about is `Donate CTA, DB age >= 7 days`
*/
await sleepFor(1000);
}
if (window.inboxStore?.dispatch) {
void handleTriggeredProCTAs(window.inboxStore.dispatch);
}
const delayedTimeout = getDataFeatureFlag('useLocalDevNet') && isTestIntegration() ? 2000 : 0;
/**
* When running on the local dev net (during the regression tests), the network is too fast
* and we show the DonateCTA before we got the time to grab the recovery phrase.
* This sleepFor is there to give some time so we can grab the recovery phrase.
* The regression test this is about is `Donate CTA, DB age >= 7 days`
*/
// eslint-disable-next-line more/no-then
void sleepFor(delayedTimeout).then(() => {
if (window.inboxStore?.dispatch) {
void handleTriggeredCTAs(window.inboxStore.dispatch, true);
}
});
}
// we want to (try) to fetch from the revocation server before we process
// incoming messages, as some might have a pro proof that has been revoked
Expand Down