diff --git a/projects/v3/src/app/components/activity/activity.component.ts b/projects/v3/src/app/components/activity/activity.component.ts index 484dbbccb..7e61561ff 100644 --- a/projects/v3/src/app/components/activity/activity.component.ts +++ b/projects/v3/src/app/components/activity/activity.component.ts @@ -1,4 +1,5 @@ -import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; +import { Subject } from 'rxjs'; +import { Component, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges } from '@angular/core'; import { SharedService } from '@v3/app/services/shared.service'; import { UnlockIndicatorService } from '@v3/app/services/unlock-indicator.service'; import { Activity, ActivityService, Task } from '@v3/services/activity.service'; @@ -6,13 +7,14 @@ import { Submission } from '@v3/services/assessment.service'; import { NotificationsService } from '@v3/services/notifications.service'; import { BrowserStorageService } from '@v3/services/storage.service'; import { UtilsService } from '@v3/services/utils.service'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-activity', templateUrl: './activity.component.html', styleUrls: ['./activity.component.scss'], }) -export class ActivityComponent implements OnInit, OnChanges { +export class ActivityComponent implements OnInit, OnChanges, OnDestroy { @Input() activity: Activity; @Input() currentTask: Task; @Input() submission: Submission; @@ -25,6 +27,7 @@ export class ActivityComponent implements OnInit, OnChanges { // false: at least one non-team task @Output() cannotAccessTeamActivity = new EventEmitter(); isForTeamOnly: boolean = false; + private unsubscribe$: Subject = new Subject(); constructor( private utils: UtilsService, @@ -32,17 +35,28 @@ export class ActivityComponent implements OnInit, OnChanges { private notificationsService: NotificationsService, private sharedService: SharedService, private activityService: ActivityService, - private unlockIndicatorService: UnlockIndicatorService, + private unlockIndicatorService: UnlockIndicatorService ) {} - ngOnInit() { - this.leadImage = this.storageService.getUser().programImage; - this.unlockIndicatorService.unlockedTasks$.subscribe((unlockedTasks) => { - this.newTasks = {}; - unlockedTasks.forEach((task) => { + ngOnDestroy(): void { + this.unsubscribe$.next(); + this.unsubscribe$.complete(); + } + + resetTaskIndicator(unlockedTasks) { + this.newTasks = {}; + unlockedTasks + .filter((task) => task.taskId) + .forEach((task) => { this.newTasks[task.taskId] = true; }); - }); + } + + ngOnInit() { + this.leadImage = this.storageService.getUser().programImage; + this.unlockIndicatorService.unlockedTasks$ + .pipe(takeUntil(this.unsubscribe$)) + .subscribe(this.resetTaskIndicator); } ngOnChanges(changes: SimpleChanges): void { @@ -56,23 +70,28 @@ export class ActivityComponent implements OnInit, OnChanges { const currentValue = changes.activity.currentValue; if (currentValue.tasks?.length > 0) { - this.activityService.nonTeamActivity(changes.activity.currentValue?.tasks).then((nonTeamActivity) => { - this.isForTeamOnly = !nonTeamActivity; - this.cannotAccessTeamActivity.emit(this.isForTeamOnly); - }); + this.activityService + .nonTeamActivity(changes.activity.currentValue?.tasks) + .then((nonTeamActivity) => { + this.isForTeamOnly = !nonTeamActivity; + this.cannotAccessTeamActivity.emit(this.isForTeamOnly); + }); const unlockedTasks = this.unlockIndicatorService.getTasksByActivity(this.activity); + this.resetTaskIndicator(unlockedTasks); if (unlockedTasks.length === 0) { const clearedActivities = this.unlockIndicatorService.clearActivity(this.activity.id); clearedActivities.forEach((activity) => { - this.notificationsService.markTodoItemAsDone(activity).subscribe(); + this.notificationsService + .markTodoItemAsDone(activity) + .pipe(takeUntil(this.unsubscribe$)) + .subscribe(); }); } } } } - /** * Task icon type * diff --git a/projects/v3/src/app/pages/activity-desktop/activity-desktop.page.ts b/projects/v3/src/app/pages/activity-desktop/activity-desktop.page.ts index 7ea3220e8..ab1d0d5b8 100644 --- a/projects/v3/src/app/pages/activity-desktop/activity-desktop.page.ts +++ b/projects/v3/src/app/pages/activity-desktop/activity-desktop.page.ts @@ -1,3 +1,4 @@ +import { UnlockIndicatorService } from './../../services/unlock-indicator.service'; import { DOCUMENT } from '@angular/common'; import { Component, Inject, OnInit } from '@angular/core'; import { ActivatedRoute, Router } from '@angular/router'; @@ -45,7 +46,8 @@ export class ActivityDesktopPage { private notificationsService: NotificationsService, private storageService: BrowserStorageService, private utils: UtilsService, - @Inject(DOCUMENT) private readonly document: Document + private unlockIndicatorService: UnlockIndicatorService, + @Inject(DOCUMENT) private readonly document: Document, ) { } ionViewWillEnter() { @@ -117,6 +119,7 @@ export class ActivityDesktopPage { }); })); + // refresh when review is available (AI review, peer review, etc.) this.subscriptions.push( this.utils.getEvent('notification').subscribe(event => { const review = event?.meta?.AssessmentReview; @@ -127,6 +130,17 @@ export class ActivityDesktopPage { } }) ); + + // check new unlock indicator to refresh + this.subscriptions.push( + this.unlockIndicatorService.unlockedTasks$.subscribe(unlockedTasks => { + if (this.activity) { + if (unlockedTasks.some(task => task.activityId === this.activity.id)) { + this.activityService.getActivity(this.activity.id); + } + } + }) + ); } ionViewWillLeave() {