| |
| |
| |
| |
|
|
| import * as d3 from 'd3'; |
| import type { TextAnalysisAPI, AnalyzeResponse } from '../api/GLTR_API'; |
| import type { TextInputController } from '../controllers/textInputController'; |
| import type { DemoManager } from '../ui/demoManager'; |
| import type { AppStateManager } from './appStateManager'; |
| import type { VisualizationUpdater } from './visualizationUpdater'; |
| import type { DemoBusinessLogic } from './demoBusinessLogic'; |
| import type { ServerStorage } from '../storage/demoStorage'; |
| import type { GLTR_Text_Box } from '../vis/GLTR_Text_Box'; |
| import { showAlertDialog } from '../ui/dialog'; |
| import { handleServerDemoSave } from '../controllers/serverDemoController'; |
| |
| import { tr } from '../lang/i18n-lite'; |
| import { playAnalysisCompleteSound } from './soundNotification'; |
|
|
| |
| |
| |
| export type AnalyzeProgressCallback = (step: number, totalSteps: number, stage: string, percentage?: number) => void; |
|
|
| |
| |
| |
| export interface AnalyzeFlowDependencies { |
| api: TextAnalysisAPI; |
| textInputController: TextInputController; |
| demoManager: DemoManager | null; |
| appStateManager: AppStateManager; |
| visualizationUpdater: VisualizationUpdater; |
| demoBusinessLogic: DemoBusinessLogic; |
| serverStorage: ServerStorage; |
| lmf: GLTR_Text_Box; |
| modelName: string; |
| enableDemo: boolean; |
| showToast: (message: string, type: 'success' | 'error') => void; |
| updateFileNameDisplay: (filename: string | null) => void; |
| } |
|
|
| |
| |
| |
| export interface AnalyzeUploadTask { |
| name: string; |
| path: string; |
| text: string; |
| } |
|
|
| |
| |
| |
| export class AnalyzeFlowManager { |
| private deps: AnalyzeFlowDependencies; |
|
|
| constructor(deps: AnalyzeFlowDependencies) { |
| this.deps = deps; |
| } |
|
|
| |
| |
| |
| setDemoManager(demoManager: DemoManager | null): void { |
| this.deps.demoManager = demoManager; |
| } |
|
|
| |
| |
| |
| updateAnalyzeProgress(step: number, totalSteps: number, stage: string, percentage?: number): void { |
| |
| const progressText = percentage !== undefined && percentage !== null |
| ? `Step ${step}/${totalSteps}:\t ${stage} ${percentage}%` |
| : `Step ${step}/${totalSteps}:\t ${stage}`; |
|
|
| d3.select('#analyze_progress') |
| .text(progressText) |
| .style('display', 'inline-block'); |
| } |
|
|
| |
| |
| |
| private scrollToTop(): void { |
| requestAnimationFrame(() => { |
| const rightPanel = document.querySelector('.right_panel') as HTMLElement; |
| if (rightPanel) { |
| rightPanel.scrollTop = 0; |
| } |
| }); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| async runAnalyze(text: string, enableAnimation: boolean = true): Promise<AnalyzeResponse | null> { |
| |
| |
| const currentText = this.deps.textInputController.getTextValue(); |
| if (currentText !== text) { |
| this.deps.textInputController.setTextValue(text); |
| } |
|
|
| |
| this.scrollToTop(); |
|
|
| |
| this.deps.appStateManager.updateState({ |
| dataSource: null, |
| isSavedToLocal: false, |
| isSavedToServer: false, |
| currentFileName: null |
| }); |
|
|
| this.deps.appStateManager.setIsAnalyzing(true); |
| this.deps.appStateManager.setGlobalLoading(true); |
| this.deps.demoManager?.highlightDemo(null); |
|
|
| |
| this.deps.demoBusinessLogic.clearDemoUrlParam(); |
| |
| |
| this.deps.updateFileNameDisplay(null); |
|
|
| |
| d3.select('#all_result').style('opacity', 1).style('display', null); |
| this.deps.lmf.setTextOnly(text); |
| this.deps.visualizationUpdater.updateHistogramVisibilityForPending('infoDensity', text); |
|
|
| try { |
| const data = await this.deps.api.analyze( |
| this.deps.modelName, |
| text, |
| null, |
| true, |
| (step: number, totalSteps: number, stage: string, percentage?: number) => { |
| |
| this.updateAnalyzeProgress(step, totalSteps, stage, percentage); |
| } |
| ); |
|
|
| this.deps.visualizationUpdater.updateFromRequest(data, !enableAnimation, { enableSave: true }); |
| |
| |
| playAnalysisCompleteSound(); |
| |
| return data; |
| } catch (error) { |
| console.error('Analyze failed:', error); |
| this.deps.appStateManager.setIsAnalyzing(false); |
| this.deps.appStateManager.setGlobalLoading(false); |
| this.deps.appStateManager.updateState({ hasValidData: false }); |
| this.deps.visualizationUpdater.rerenderHistograms(); |
| const message = error instanceof Error ? error.message : tr('Analysis failed'); |
| showAlertDialog(tr('Error'), `${tr('Analysis failed')}: ${message}`); |
| return null; |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| async runAnalyzeAndUpload(task: AnalyzeUploadTask): Promise<void> { |
| const textValue = task.text || ''; |
|
|
| |
| const analyzeResult = await this.runAnalyze(textValue, true); |
| if (!analyzeResult) { |
| |
| return; |
| } |
|
|
| |
| try { |
| await handleServerDemoSave({ |
| api: this.deps.api, |
| currentData: this.deps.visualizationUpdater.getCurrentData(), |
| rawApiResponse: this.deps.visualizationUpdater.getRawApiResponse(), |
| textFieldValue: textValue, |
| enableDemo: this.deps.enableDemo, |
| demoManager: this.deps.demoManager, |
| presetSaveInfo: { |
| name: task.name, |
| path: task.path |
| }, |
| serverStorage: this.deps.serverStorage, |
| showSuccessToast: false, |
| onSaveStart: () => { |
| this.deps.appStateManager.updateState({ isSaving: true }); |
| }, |
| onSaveSuccess: () => { |
| this.deps.appStateManager.updateState({ |
| isSaving: false, |
| isSavedToServer: true |
| }); |
| this.deps.showToast(tr('Demo "{name}" analyzed and uploaded successfully!').replace('{name}', task.name), 'success'); |
| }, |
| onSaveComplete: () => { |
| this.deps.appStateManager.updateState({ isSavedToServer: true }); |
| }, |
| onSaveError: () => { |
| |
| this.deps.appStateManager.updateState({ isSaving: false }); |
| this.deps.appStateManager.updateButtonStates(); |
| }, |
| setGlobalLoading: (loading: boolean) => this.deps.appStateManager.setGlobalLoading(loading), |
| showToast: this.deps.showToast |
| }); |
| } catch (error) { |
| |
| this.deps.appStateManager.setGlobalLoading(false); |
| |
| this.deps.appStateManager.updateState({ isSaving: false }); |
| this.deps.appStateManager.updateButtonStates(); |
| console.error('Upload failed in runAnalyzeAndUpload:', error); |
| } |
| } |
| } |
|
|
| |
| export { buildFolderOptions } from './demoPathUtils'; |
|
|
|
|