1 import type { GetNode } from './../../UseCase/GetNode'
2 import type { LoggerInterface } from '@proton/utils/logs'
3 import { DocController } from '../../Controller/Document/DocController'
4 import type { SquashDocument } from '../../UseCase/SquashDocument'
5 import type { InternalEventBusInterface, CommentControllerInterface } from '@proton/docs-shared'
6 import type { EncryptComment } from '../../UseCase/EncryptComment'
7 import type { DuplicateDocument } from '../../UseCase/DuplicateDocument'
8 import type { CreateNewDocument } from '../../UseCase/CreateNewDocument'
9 import { EditorOrchestrator } from '../Orchestrator/EditorOrchestrator'
10 import type { LoadDocument } from '../../UseCase/LoadDocument'
11 import type { SeedInitialCommit } from '../../UseCase/SeedInitialCommit'
12 import type { GetDocumentMeta } from '../../UseCase/GetDocumentMeta'
13 import type { DriveCompat, NodeMeta } from '@proton/drive-store'
14 import type { HandleRealtimeCommentsEvent } from '../../UseCase/HandleRealtimeCommentsEvent'
15 import type { CreateComment } from '../../UseCase/CreateComment'
16 import type { CreateThread } from '../../UseCase/CreateThread'
17 import type { LoadThreads } from '../../UseCase/LoadThreads'
18 import type { DocLoaderInterface } from './DocLoaderInterface'
19 import type { EditorOrchestratorInterface } from '../Orchestrator/EditorOrchestratorInterface'
20 import type { DocControllerInterface } from '../../Controller/Document/DocControllerInterface'
21 import { CommentController } from '../Comments/CommentController'
22 import type { WebsocketServiceInterface } from '../Websockets/WebsocketServiceInterface'
23 import type { LoadCommit } from '../../UseCase/LoadCommit'
24 import type { ExportAndDownload } from '../../UseCase/ExportAndDownload'
25 import type { DocsApi } from '../../Api/DocsApi'
26 import type { MetricService } from '../Metrics/MetricService'
27 import type { UnleashClient } from '@proton/unleash'
29 export type StatusObserver = {
30 onSuccess: (orchestrator: EditorOrchestratorInterface) => void
31 onError: (error: string) => void
34 export class DocLoader implements DocLoaderInterface {
35 private docController?: DocControllerInterface
36 private commentsController?: CommentControllerInterface
37 private orchestrator?: EditorOrchestratorInterface
38 private readonly statusObservers: StatusObserver[] = []
41 private websocketSerivce: WebsocketServiceInterface,
42 private driveCompat: DriveCompat,
43 private metricService: MetricService,
44 private docsApi: DocsApi,
45 private squashDoc: SquashDocument,
46 private createInitialCommit: SeedInitialCommit,
47 private loadDocument: LoadDocument,
48 private loadCommit: LoadCommit,
49 private encryptComment: EncryptComment,
50 private createComment: CreateComment,
51 private createThread: CreateThread,
52 private loadThreads: LoadThreads,
53 private handleRealtimeCommentsEvent: HandleRealtimeCommentsEvent,
54 private duplicateDocument: DuplicateDocument,
55 private createNewDocument: CreateNewDocument,
56 private getDocumentMeta: GetDocumentMeta,
57 private getNode: GetNode,
58 private exportAndDownload: ExportAndDownload,
59 private unleashClient: UnleashClient,
60 private eventBus: InternalEventBusInterface,
61 private logger: LoggerInterface,
65 this.docController?.destroy()
68 public async initialize(nodeMeta: NodeMeta): Promise<void> {
69 if (this.docController) {
70 throw new Error('[DocLoader] docController already initialized')
73 const controller = new DocController(
77 this.createInitialCommit,
80 this.duplicateDocument,
81 this.createNewDocument,
83 this.exportAndDownload,
85 this.websocketSerivce,
90 this.docController = controller
92 const result = await this.docController.initialize()
94 if (result.isFailed()) {
95 this.statusObservers.forEach((observer) => {
96 observer.onError(result.getError())
101 const { entitlements } = result.getValue()
103 const getLatestDocumentName = () => controller.getSureDocument().name
105 this.commentsController = new CommentController(
108 this.websocketSerivce,
115 this.handleRealtimeCommentsEvent,
116 getLatestDocumentName,
122 this.commentsController.fetchAllComments()
124 this.orchestrator = new EditorOrchestrator(this.commentsController, this.docController, this.docsApi, this.eventBus)
126 this.statusObservers.forEach((observer) => {
127 if (this.orchestrator) {
128 observer.onSuccess(this.orchestrator)
133 public getDocController(): DocControllerInterface {
134 if (!this.docController) {
135 throw new Error('DocController not ready')
138 return this.docController
141 public addStatusObserver(observer: StatusObserver): () => void {
142 this.statusObservers.push(observer)
144 if (this.orchestrator) {
145 observer.onSuccess(this.orchestrator)
149 this.statusObservers.splice(this.statusObservers.indexOf(observer), 1)