Skip to content

Commit

Permalink
M2-7137, M2-6958, M2-6960, M2-6959, M2-6949: [Mobile]: Modify activit…
Browse files Browse the repository at this point in the history
…y-progress finish/interim screens: re-use layout from blocker screens ; (#820)

M2-6958: [Mobile]: Implement UI components for displaying progress ;
M2-6960: [Mobile]: Integrate progress tracking into Finish/Interim screens ;
M2-6959: [Mobile]: Integrate progress tracking into autocompletion blocker-progress screens ;
M2-6949: [Mobile]: Implement App-level timer and hook which will call auto completion services ;

Co-authored-by: Nalivaiko, Aleksej <Nalivaiko@scnsoft.com>
  • Loading branch information
anq83 and Nalivaiko, Aleksej committed Jul 24, 2024
1 parent 589d4da commit 8001dc3
Show file tree
Hide file tree
Showing 40 changed files with 766 additions and 324 deletions.
6 changes: 4 additions & 2 deletions assets/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
"progress": {
"upload_files": "Uploading your files...",
"encrypt_answers": "Encrypting your answers...",
"upload_answers": "Uploading your answers..."
}
"upload_answers": "Uploading your answers...",
"completed": "Activity uploaded"
},
"step": "Step"
},
"activity_time": {
"time_remaining": "remaining for this item"
Expand Down
6 changes: 4 additions & 2 deletions assets/translations/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
"progress": {
"upload_files": "Téléchargement de vos fichiers...",
"encrypt_answers": "Chiffrer vos réponses...",
"upload_answers": "Téléchargement de vos réponses..."
}
"upload_answers": "Téléchargement de vos réponses...",
"completed": "Activité téléchargée"
},
"step": "Étape"
},
"activity_time": {
"time_remaining": "reste pour cet article"
Expand Down
27 changes: 27 additions & 0 deletions src/abstract/lib/types/autocompletion.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export type SafeChecks =
| 'in-progress-activity'
| 'refresh'
| 'start-entity'
| 'uploading'
| 'already-opened'
| 'is-offline';

export type LogAutocompletionTrigger =
| 'app-start'
| 'to-foreground'
| 'to-online'
| 'check-availability'
| 'close-entity'
| 'expired-while-alert-opened'
| 'retry-on-banner'
| 'app-level-timer';

export type AutocompletionExecuteOptions = {
checksToExclude?: Array<SafeChecks>;
checksToInclude?: Array<SafeChecks>;
forceUpload?: boolean;
};

export type AutocompletionEventOptions = AutocompletionExecuteOptions & {
logTrigger: LogAutocompletionTrigger;
};
1 change: 1 addition & 0 deletions src/abstract/lib/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './storage';
export * from './primitive';
export * from './flanker';
export * from './abTrails';
export * from './autocompletion';
4 changes: 1 addition & 3 deletions src/entities/activity/lib/hooks/useQueueProcessing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type Result = {
isPostponed: boolean;
};

const useQueueProcessing = (): Result => {
export const useQueueProcessing = (): Result => {
const update = useForceUpdate();

useEffect(() => {
Expand Down Expand Up @@ -60,5 +60,3 @@ const useQueueProcessing = (): Result => {
isCompleted: UploadObservable.isCompleted,
};
};

export default useQueueProcessing;
19 changes: 15 additions & 4 deletions src/entities/activity/lib/services/AnswersUploadService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ class AnswersUploadService implements IAnswersUploadService {
): Promise<SendAnswersInput> {
const fileIds = this.collectFileIds(body.answers);

this.uploadProgressObservable.totalFilesInActivity = fileIds.length;
await this.uploadProgressObservable.setTotalFilesInActivity(fileIds.length);

if (fileIds.length === 0) {
return body;
Expand All @@ -234,6 +234,7 @@ class AnswersUploadService implements IAnswersUploadService {

const updatedAnswers = [];
let logAnswerIndex = -1;
this.uploadProgressObservable.currentFile = -1;

for (const itemAnswer of itemsAnswers) {
logAnswerIndex++;
Expand Down Expand Up @@ -483,7 +484,9 @@ class AnswersUploadService implements IAnswersUploadService {
'[UploadAnswersService.sendAnswers] executing upload files',
);

this.uploadProgressObservable.currentSecondLevelStep = 'upload_files';
await this.uploadProgressObservable.setCurrentSecondLevelStepKey(
'upload_files',
);

const modifiedBody: SendAnswersInput = await this.uploadAllMediaFiles(body);

Expand All @@ -508,21 +511,29 @@ class AnswersUploadService implements IAnswersUploadService {
'[UploadAnswersService.sendAnswers] executing prepare answers',
);

this.uploadProgressObservable.currentSecondLevelStep = 'encrypt_answers';
await this.uploadProgressObservable.setCurrentSecondLevelStepKey(
'encrypt_answers',
);

const encryptedData = this.encryptAnswers(modifiedBody);

this.logger.log(
'[UploadAnswersService.sendAnswers] executing upload answers',
);

this.uploadProgressObservable.currentSecondLevelStep = 'upload_answers';
await this.uploadProgressObservable.setCurrentSecondLevelStepKey(
'upload_answers',
);

await this.uploadAnswers(encryptedData);

this.logger.log('[UploadAnswersService.sendAnswers] executing clean up');

MediaFilesCleaner.cleanUpByAnswers(body.answers);

await this.uploadProgressObservable.setCurrentSecondLevelStepKey(
'completed',
);
}
}

Expand Down
13 changes: 7 additions & 6 deletions src/entities/activity/lib/services/QueueProcessingService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ class QueueProcessingService implements IPushToQueue {
private async processInternal(): Promise<boolean> {
const queueLength = this.queueService.getLength();

this.uploadProgressObservable.totalActivities = queueLength;

for (let i = 0; i < queueLength; i++) {
const uploadItem = this.queueService.pick();

Expand All @@ -76,11 +74,12 @@ class QueueProcessingService implements IPushToQueue {

const logEntity = `"${uploadItem.input.activityName}, which completed at ${uploadItem.input.logCompletedAt}"`;

this.uploadProgressObservable.currentActivity = i;
this.uploadProgressObservable.currentActivityName =
uploadItem.input.activityName;

try {
this.uploadProgressObservable.totalActivities = queueLength;
this.uploadProgressObservable.currentActivity = i;
this.uploadProgressObservable.currentActivityName =
uploadItem.input.activityName;

this.logger.info(
`[QueueProcessingService:processInternal]: Processing activity ${logEntity}`,
);
Expand All @@ -101,6 +100,8 @@ class QueueProcessingService implements IPushToQueue {
);

this.queueService.swap();
} finally {
this.uploadProgressObservable.reset();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { useQueryClient } from '@tanstack/react-query';

import {
ActivityRecordKeyParams,
AutocompletionEventOptions,
CheckAvailability,
CompleteEntityIntoUploadToQueue,
EntityPath,
Expand Down Expand Up @@ -225,7 +226,9 @@ export function useOnNotificationTap({
}

const autocomplete = () => {
Emitter.emit('autocomplete');
Emitter.emit<AutocompletionEventOptions>('autocomplete', {
logTrigger: 'expired-while-alert-opened',
});
};

if (entityType === 'flow') {
Expand Down
9 changes: 7 additions & 2 deletions src/screens/ui/ActivityListScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { BottomTabScreenProps } from '@react-navigation/bottom-tabs';
import { useIsFocused } from '@react-navigation/core';
import { useQueryClient } from '@tanstack/react-query';

import { EntityPath, StoreProgress } from '@app/abstract/lib';
import {
AutocompletionEventOptions,
EntityPath,
StoreProgress,
} from '@app/abstract/lib';
import { AppletModel } from '@app/entities/applet';
import {
AnalyticsService,
Expand Down Expand Up @@ -54,8 +58,9 @@ const ActivityListScreen: FC<Props> = props => {
});

if (!isSuccess) {
Emitter.emit<SurveyModel.AutocompletionExecuteOptions>('autocomplete', {
Emitter.emit<AutocompletionEventOptions>('autocomplete', {
checksToExclude: ['start-entity'],
logTrigger: 'check-availability',
});
}
return isSuccess;
Expand Down
6 changes: 4 additions & 2 deletions src/screens/ui/InProgressActivityScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { FC, useEffect } from 'react';

import { NativeStackScreenProps } from '@react-navigation/native-stack';

import { AutocompletionEventOptions } from '@app/abstract/lib';
import { Emitter } from '@app/shared/lib';
import { FlowSurvey, SurveyModel } from '@app/widgets/survey';
import { FlowSurvey } from '@app/widgets/survey';
import { useUpcomingNotificationsObserver } from '@entities/notification';
import { RootStackParamList } from '@screens/config';
import { Box } from '@shared/ui';
Expand All @@ -17,8 +18,9 @@ const InProgressActivityScreen: FC<Props> = ({ navigation, route }) => {

useEffect(() => {
const callback = navigation.addListener('beforeRemove', () => {
Emitter.emit<SurveyModel.AutocompletionExecuteOptions>('autocomplete', {
Emitter.emit<AutocompletionEventOptions>('autocomplete', {
checksToExclude: ['in-progress-activity'],
logTrigger: 'close-entity',
});
});

Expand Down
25 changes: 18 additions & 7 deletions src/screens/ui/RootNavigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack';
import { useQueryClient } from '@tanstack/react-query';
import { useTranslation } from 'react-i18next';

import { EntityPath, StoreProgress } from '@app/abstract/lib';
import {
AutocompletionEventOptions,
AutocompletionExecuteOptions,
EntityPath,
LogAutocompletionTrigger,
StoreProgress,
} from '@app/abstract/lib';
import { ActivityModel } from '@app/entities/activity';
import { MediaFilesCleaner } from '@app/entities/activity';
import { AppletModel } from '@app/entities/applet';
Expand All @@ -17,10 +23,6 @@ import { TapOnNotificationModel } from '@app/features/tap-on-notification';
import { SystemRecord } from '@app/shared/lib/records';
import { ActivityGroupsModel } from '@app/widgets/activity-group';
import { SurveyModel } from '@app/widgets/survey';
import {
AutocompletionExecuteOptions,
LogAutocompletionTrigger,
} from '@app/widgets/survey/model';
import { SessionModel } from '@entities/session';
import { EnterForegroundModel } from '@features/enter-foreground';
import { LogoutModel } from '@features/logout';
Expand All @@ -38,6 +40,7 @@ import {
useOnceRef,
Emitter,
useOnForegroundDebounced,
useDelayedInterval,
} from '@shared/lib';
import {
UserProfileIcon,
Expand Down Expand Up @@ -76,7 +79,7 @@ import {

const Stack = createNativeStackNavigator<RootStackParamList>();

const AUTOCOMPLETION_DELAY = 2000;
const AUTOCOMPLETION_DELAY = 2000; // time-window to handle notification

export default () => {
const { t } = useTranslation();
Expand Down Expand Up @@ -133,8 +136,9 @@ export default () => {
});

if (!isSuccess) {
Emitter.emit<SurveyModel.AutocompletionExecuteOptions>('autocomplete', {
Emitter.emit<AutocompletionEventOptions>('autocomplete', {
checksToExclude: ['start-entity'],
logTrigger: 'check-availability',
});
}
return isSuccess;
Expand Down Expand Up @@ -164,6 +168,13 @@ export default () => {
[executeAutocompletion],
);

useDelayedInterval(() =>
executeAutocompletion('app-level-timer', {
forceUpload: false,
checksToInclude: ['is-offline'],
}),
);

useOnlineEstablished(() =>
executeAutocompletion('to-online', { forceUpload: true }),
);
Expand Down
3 changes: 3 additions & 0 deletions src/shared/lib/constants/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,17 @@ export const colors = {
lighterGrey8: '#e0ebf4',
lightGrey: '#00000026',
lightGrey2: '#00000032',
lightGrey3: '#D2E2EC4D',
outlineGrey: '#C2C7CF',
alert: '#e63232',
alertLight: '#FFCCCC',
alertDark: '#93000A',
blue: '#005fa3',
blue2: '#24A3FF',
blue3: '#00639A',
blue4: '$02649B',
lightBlue: '#dbf2ff',
lightBlue2: '#D8E4ED',
darkBlue: 'darkblue',
green: '#008800',
lightGreen: '#35FDB5',
Expand Down
22 changes: 22 additions & 0 deletions src/shared/lib/hooks/useOnBackground.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { useEffect, useRef } from 'react';
import { AppState } from 'react-native';

function useOnBackground(callback: () => void) {
const callbackRef = useRef(callback);

callbackRef.current = callback;

useEffect(() => {
const subscription = AppState.addEventListener('change', status => {
if (status === 'background') {
callbackRef.current();
}
});

return () => {
subscription.remove();
};
}, []);
}

export default useOnBackground;
Loading

0 comments on commit 8001dc3

Please sign in to comment.