Browse Source

Restore student wordbook self-study flow

彭峰 2 weeks ago
parent
commit
f12d66f46c

+ 47 - 0
projects/xiaoshu-mobile/src/app/core/home-learning-modules.integration.spec.ts

@@ -369,6 +369,53 @@ describe('home learning modules', () => {
     expect(play).toHaveBeenCalledTimes(2);
   });
 
+  it('lets a student study selected words from their wordbook while keeping course stages teacher-led', async () => {
+    localStorage.removeItem('xiaoshu.learning.100.100.practice.learn_mode');
+    localStorage.removeItem('xiaoshu.learning.100.100.practice.choose_newword_learn');
+    const harness = await RouterTestingHarness.create();
+    const router = TestBed.inject(Router);
+    await harness.navigateByUrl('/pages/member/starshop');
+    (harness.routeNativeElement?.querySelector('.word-select-list > button') as HTMLButtonElement).click();
+    (harness.routeNativeElement?.querySelector('.selection-header .primary-button') as HTMLButtonElement).click();
+    await harness.fixture.whenStable();
+    harness.fixture.detectChanges();
+
+    const learning = () => harness.fixture.debugElement.query(By.directive(LearningPageComponent)).componentInstance as LearningPageComponent;
+    expect(router.url).toContain('/pages/stu/stu_con');
+    expect(learning().words().map((word) => word.word)).toEqual(['tend']);
+    learning().skipStudyList();
+    await harness.fixture.whenStable();
+    harness.fixture.detectChanges();
+    expect(router.url).toContain('/pages/stu/stu3');
+    expect(learning().words().map((word) => word.word)).toEqual(['tend']);
+    learning().chooseMatch('left', learning().words()[0]);
+    learning().chooseMatch('right', learning().words()[0]);
+    learning().continueAfterStage();
+    await harness.fixture.whenStable();
+    harness.fixture.detectChanges();
+    expect(router.url).toContain('/pages/stu/stu4');
+    expect(learning().words().map((word) => word.word)).toEqual(['tend']);
+    learning().chooseMeaning(learning().words()[0]);
+    learning().continueAfterStage();
+    await harness.fixture.whenStable();
+    harness.fixture.detectChanges();
+    expect(router.url).toContain('/pages/stu/stu5');
+    for (const letter of learning().current()!.word) {
+      const index = learning().letters().findIndex((choice) => !choice.used && choice.value === letter);
+      expect(index).toBeGreaterThanOrEqual(0);
+      learning().spellLetter(index);
+    }
+    learning().nextSpellingWord();
+    learning().continueAfterStage();
+    await harness.fixture.whenStable();
+    expect(router.url).toBe('/pages/member/starshop');
+    expect(localStorage.getItem('xiaoshu.learning.100.100.practice.learn_mode')).toBeNull();
+
+    await harness.navigateByUrl('/pages/stu/stu_con?nids=811&pnid=801');
+    await harness.fixture.whenStable();
+    expect(router.url).toBe('/pages/home/cart');
+  });
+
   it('still pronounces pending and completed words when a coach reveals them', async () => {
     user.set({ userId: 300, userName: 'coach', honeyName: '张老师', groupId: 3 });
     session.groupId.set(3);

+ 12 - 3
projects/xiaoshu-mobile/src/app/features/learning/learning-page.component.ts

@@ -274,7 +274,7 @@ export class LearningPageComponent implements OnInit, OnDestroy {
   private stopLiveRefresh?: () => void;
 
   ngOnInit(): void {
-    if (isTeacherLedLearningPath(this.meta.path) && !this.isReadOnlyWordView && !this.isReadOnlySelectionPage && !this.canStartPointReading) {
+    if (isTeacherLedLearningPath(this.meta.path) && !this.isReadOnlyWordView && !this.isReadOnlySelectionPage && !this.canStartPointReading && !this.isNewWordSelfStudyStage) {
       this.platform.toast('点读学习由陪练老师在上课时发起', 'error');
       void this.router.navigateByUrl('/pages/home/cart');
       return;
@@ -336,6 +336,14 @@ export class LearningPageComponent implements OnInit, OnDestroy {
     return canStartTeacherLedLearning(this.session.groupId());
   }
 
+  get isNewWordSelfStudyStage(): boolean {
+    if (Number(this.session.groupId()) !== 1
+      || !['pages/stu/stu_con', 'pages/stu/stu3', 'pages/stu/stu4', 'pages/stu/stu5'].includes(this.meta.path)
+      || ['nid', 'nids', 'bindingId', 'orderId'].some((key) => this.query(key))) return false;
+    return this.storageGet('learn_mode') === 'newword'
+      && this.parseArray(this.storageGet('choose_newword_learn')).length > 0;
+  }
+
   get isReadOnlyWordView(): boolean {
     if (this.isHistoryWordView) return true;
     return !this.canStartPointReading && this.isStudyListPage && this.query('readonly') === '1';
@@ -583,10 +591,11 @@ export class LearningPageComponent implements OnInit, OnDestroy {
   }
 
   startSelected(): void {
-    const chosen = this.pendingSelectionWords().filter((word) => this.selected().has(word.id));
+    const chosen = (this.isRefineSelectionPage ? this.pendingSelectionWords() : this.words())
+      .filter((word) => this.selected().has(word.id));
     const newlyKnown = this.newlyKnownWords();
     if (!chosen.length && !newlyKnown.length) {
-      this.platform.toast('请先判断单词是否认识,或选择要学习的单词', 'error');
+      this.platform.toast(this.isRefineSelectionPage ? '请先判断单词是否认识,或选择要学习的单词' : '请先选择要学习的单词', 'error');
       return;
     }