Przeglądaj źródła

fix(mobile): page history words from loaded record

彭峰 1 tydzień temu
rodzic
commit
9c41859143

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

@@ -329,6 +329,40 @@ describe('home learning modules', () => {
     expect(play).not.toHaveBeenCalled();
     expect(play).not.toHaveBeenCalled();
   });
   });
 
 
+  it('pages through all words in a history record without requesting a course unit', async () => {
+    const api = TestBed.inject(ApiService) as unknown as LearningModulesApiService;
+    const originalPost = api.post.bind(api);
+    const post = spyOn(api, 'post').and.callFake((action, params) => action === 'e_record_detail'
+      ? of({ retcode: 1, result: Array.from({ length: 31 }, (_, index) => ({
+        GeneralID: 700 + index,
+        Title: `history-${index + 1}`,
+        detail: [{ GeneralID: 700 + index, Title: `history-${index + 1}`, sy: `释义 ${index + 1}` }],
+      })), addon: [] } as ApiEnvelope<any>)
+      : originalPost(action, params));
+    const get = spyOn(api, 'get').and.callThrough();
+    const harness = await RouterTestingHarness.create();
+    await harness.navigateByUrl('/pages/his/his_words?id=201');
+    harness.fixture.detectChanges();
+
+    const list = () => harness.routeNativeElement?.querySelectorAll('.readonly-word-list article') ?? [];
+    expect(list().length).toBe(30);
+    expect(harness.routeNativeElement?.textContent).toContain('共 31 个单词');
+    (harness.routeNativeElement?.querySelector('.word-preview-pagination .page-direction:last-of-type') as HTMLButtonElement).click();
+    await harness.fixture.whenStable();
+    harness.fixture.detectChanges();
+    expect(list().length).toBe(1);
+    expect(list()[0].textContent).toContain('history-31');
+    expect(harness.routeNativeElement?.textContent).toContain('2 / 2 页');
+    expect(get.calls.allArgs().some(([action]) => action === 'e_ck_list')).toBeFalse();
+    expect(post.calls.allArgs().filter(([action]) => action === 'e_record_detail').length).toBe(1);
+
+    (harness.routeNativeElement?.querySelector('.word-preview-pagination .page-direction:first-child') as HTMLButtonElement).click();
+    await harness.fixture.whenStable();
+    harness.fixture.detectChanges();
+    expect(list().length).toBe(30);
+    expect(list()[0].textContent).toContain('history-1');
+  });
+
   it('plays student history words on click without changing learning records or enabling unit preview audio', async () => {
   it('plays student history words on click without changing learning records or enabling unit preview audio', async () => {
     const api = TestBed.inject(ApiService) as unknown as LearningModulesApiService;
     const api = TestBed.inject(ApiService) as unknown as LearningModulesApiService;
     api.historyWordAudio = 'apple.mp3';
     api.historyWordAudio = 'apple.mp3';

+ 10 - 1
projects/xiaoshu-mobile/src/app/features/learning/learning-page.component.ts

@@ -118,6 +118,7 @@ export class LearningPageComponent implements OnInit, OnDestroy {
   readonly wordPreviewPage = signal(1);
   readonly wordPreviewPage = signal(1);
   readonly wordPreviewTotal = signal(0);
   readonly wordPreviewTotal = signal(0);
   readonly wordPreviewLoading = signal(false);
   readonly wordPreviewLoading = signal(false);
+  private historyPreviewWords: Word[] = [];
   readonly selected = signal<Set<string>>(new Set());
   readonly selected = signal<Set<string>>(new Set());
   readonly selectionRevealed = signal<Set<string>>(new Set());
   readonly selectionRevealed = signal<Set<string>>(new Set());
   readonly selectionAssessment = signal<Record<string, 'known' | 'unknown'>>({});
   readonly selectionAssessment = signal<Record<string, 'known' | 'unknown'>>({});
@@ -487,6 +488,12 @@ export class LearningPageComponent implements OnInit, OnDestroy {
     if (target === this.wordPreviewPage() || this.wordPreviewLoading()) return;
     if (target === this.wordPreviewPage() || this.wordPreviewLoading()) return;
     const previous = this.wordPreviewPage();
     const previous = this.wordPreviewPage();
     this.wordPreviewPage.set(target);
     this.wordPreviewPage.set(target);
+    if (this.isHistoryWordView) {
+      const start = (target - 1) * this.wordPreviewPageSize;
+      this.words.set(this.historyPreviewWords.slice(start, start + this.wordPreviewPageSize));
+      setTimeout(() => document.getElementById('readonly-word-title')?.scrollIntoView({ behavior: 'smooth', block: 'start' }));
+      return;
+    }
     this.wordPreviewLoading.set(true);
     this.wordPreviewLoading.set(true);
     this.loadReadOnlyWords(true, previous);
     this.loadReadOnlyWords(true, previous);
   }
   }
@@ -1157,7 +1164,8 @@ export class LearningPageComponent implements OnInit, OnDestroy {
       this.api.post<unknown>('e_record_detail', { id: this.query('id') }).pipe(finalize(() => this.loading.set(false))).subscribe({
       this.api.post<unknown>('e_record_detail', { id: this.query('id') }).pipe(finalize(() => this.loading.set(false))).subscribe({
         next: ({ result, addon }) => {
         next: ({ result, addon }) => {
           const words = this.findList(result).map((item) => this.toWord(item)).filter((word) => word.word);
           const words = this.findList(result).map((item) => this.toWord(item)).filter((word) => word.word);
-          this.words.set(words);
+          this.historyPreviewWords = words;
+          this.words.set(words.slice(0, this.wordPreviewPageSize));
           this.wordPreviewTotal.set(words.length);
           this.wordPreviewTotal.set(words.length);
           const sourceAddon = this.findList(addon)[0];
           const sourceAddon = this.findList(addon)[0];
           if (sourceAddon) this.orderInfo.set(sourceAddon);
           if (sourceAddon) this.orderInfo.set(sourceAddon);
@@ -1850,6 +1858,7 @@ export class LearningPageComponent implements OnInit, OnDestroy {
     this.nodes.set([]);
     this.nodes.set([]);
     this.selectedNodes.set(new Set());
     this.selectedNodes.set(new Set());
     this.words.set([]);
     this.words.set([]);
+    this.historyPreviewWords = [];
     this.wordPreviewPage.set(1);
     this.wordPreviewPage.set(1);
     this.wordPreviewTotal.set(0);
     this.wordPreviewTotal.set(0);
     this.wordPreviewLoading.set(false);
     this.wordPreviewLoading.set(false);