From f8de3f833b6b1ed74671429729043fa8040bd6f9 Mon Sep 17 00:00:00 2001 From: nonodev96 Date: Thu, 31 Mar 2022 20:16:13 +0200 Subject: [PATCH] Refactor in all firebase method with new modular functions and providers for electron. angular 12 with firebase 9 @angular/fire 7 electron 12 with electron-builder 23 --- UML/Core/Interface.puml | 51 +++ UML/Core/Machine.puml | 71 ++++ UML/Core/Manager.puml | 90 +++++ UML/Core/PixiTHUMDER.puml | 102 ++++++ UML/Playground.puml | 9 +- UML/THUMDER-core-Auth.puml | 11 +- UML/THUMDER-core-Machine.puml | 311 ++---------------- UML/THUMDER-core-Services.puml | 12 +- UML/THUMDER-core-Storage.puml | 9 +- main.ts | 2 +- package.json | 12 +- src/app/Types.ts | 3 +- src/app/__core/auth/auth.service.ts | 90 ++--- .../services/electron/electron.service.ts | 13 +- .../file-system-storage.service.ts | 224 ++++++++----- .../file-system/file-system.service.ts | 62 +++- .../socket/socket-provider-connect.service.ts | 5 +- src/app/app.module.ts | 68 +++- .../monaco-editor.component.html | 2 +- .../monaco-editor/monaco-editor.component.ts | 83 +++-- .../auth-navbar/auth-navbar.component.html | 13 +- .../auth-navbar/auth-navbar.component.ts | 2 + .../_auth/_views/multiples-views.component.ts | 8 +- src/app/views/_auth/editor/editor.view.html | 14 +- src/app/views/_auth/editor/editor.view.ts | 82 +++-- .../_auth/file-manager/file-manager.view.ts | 7 +- 26 files changed, 809 insertions(+), 547 deletions(-) create mode 100644 UML/Core/Interface.puml create mode 100644 UML/Core/Machine.puml create mode 100644 UML/Core/Manager.puml create mode 100644 UML/Core/PixiTHUMDER.puml diff --git a/UML/Core/Interface.puml b/UML/Core/Interface.puml new file mode 100644 index 0000000..75d377c --- /dev/null +++ b/UML/Core/Interface.puml @@ -0,0 +1,51 @@ +@startdef(id=InterfaceRegisters) + interface InterfaceRegisters { + +PC: Int32 + +IMAR: Int32 + +IR: Int32 + +A: Int32 + +AHI: Int32 + +B: Int32 + +BHI: Int32 + +BTA: Int32 + +ALU: Int32 + +ALUHI: Int32 + +FPSR: Int32 + +DMAR: Int32 + +SDR: Int32 + +SDRHI: Int32 + +LDR: Int32 + +LDRHI: Int32 + +R: Int32[] + +F: Float32[] + +processRegisterToUpdateArray(response: TypeRegisterToUpdate[]): void + +reset(): void + } +@enddef + +@startdef(id=InterfaceBreakpoints) + interface InterfaceBreakpoints { + +_breakpoints: TypeBreakpoints + +getBreakpoints(): TypeBreakpoints[] + +reset(): void + } +@enddef + +@startdef(id=InterfaceMemory) + interface InterfaceMemory { + +_memorySizeBytes: number + +_memoryInt8Array: Uint8Array + +processResponseMachineDirectives(directives: TypeDirectiveData[]): void + +processResponseMachineInstructions(instructions: TypeInstructionsData[]): void + +processMemoryToUpdateArray(response: TypeMemoryToUpdate[]): void + +reset(newMemorySizeBytes: number): void + } +@enddef + +@startdef(id=InterfaceDataStatistics) + interface InterfaceDataStatistics { + +_data: TypeDataStatistics + +processResponse(response: Partial): void + +reset() + } +@enddef diff --git a/UML/Core/Machine.puml b/UML/Core/Machine.puml new file mode 100644 index 0000000..6003d00 --- /dev/null +++ b/UML/Core/Machine.puml @@ -0,0 +1,71 @@ +@startdef(id=MachineService) + class MachineService { + +floatingPointStageConfiguration: TypeFloatingPointStageConfiguration + +pipeline: PixiTHUMDER_Pipeline + +cycleClockDiagram: PixiTHUMDER_CycleClockDiagram + +dataStatistics: ManagerStatistics + +registers: ManagerRegisters + +memory: ManagerMemory + +memorySize: any + +breakpointManager: ManagerBreakpoints + +code: UtilsDataStructures.THUMDER_Map + +canSimulate: boolean + -statusMachineInStep: TypeSimulationStep + +isBreakpoint$: Subject + +codeSimulation$: Subject + +stepSimulation$: Subject + +dataStatistics$: Subject + +logger: string + -level: EnumLogLevel + -privateStep: number + -privateLine: number + -timer: Observable + -timerObserver: PartialObserver + +reset$: Subject + +logger$: Subject + +step$: Subject + +line$: Subject + +isRunning$: Subject + +isComplete$: Subject + +isRunning: boolean + +isComplete: boolean + +isBreakpoint: boolean + -store: StorageService + -socketProviderConnect: SocketProviderConnectService + -translate: TranslateService + -toast: ToastrService + +resetMachineStatus(): Promise + +getResetObservable(): Observable + +getStepObservable(): Observable + +getLineObservable(): Observable + +getIsRunningObservable(): Observable + +getIsCompleteObservable(): Observable + +getStepSimulationObservable(): Observable + +getCodeSimulationObservable(): Observable + +getDebuggerObservable(): Observable + +getDataStatisticsObservable(): Observable + +getLoggerObservable(): Observable + +getStatusWebsocketObservable(): Observable<"Connect" | "Disconnect"> + +getStatusWebsocket(): "Connect" | "Disconnect" + +getListStatusPipeline(): TypePipelineToProcess[] + +play(): Promise + +reset(): Promise + +nextStep(): Promise + +pause(): Promise + +resume(): Promise + +end(): Promise + -SimulationInit(): Promise + -SimulationNextStep(): Promise + -CheckConditions(): Promise + -ProcessStep(): Promise + +updateRegisterInServer(registersToUpdate: TypeRegisterToUpdate[]): Promise + +updateMemoryInServer(memoryToUpdate: TypeMemoryToUpdate[]): Promise + +writeToLog(msg: string, level?: EnumLogLevel, params?: TypeLogger[]): void + +getCode(address: TypeAddress): TypeInstructionsData + +getAllStatusMachine(): TypeStatusMachine + +resetConnection(): void + -stringFormat(msg: string, params: TypeLogger[]): string + -shouldLog(level: EnumLogLevel): boolean + -toastMessage(key_title?: string, key_message?: string): Promise + } +@enddef diff --git a/UML/Core/Manager.puml b/UML/Core/Manager.puml new file mode 100644 index 0000000..c675e7f --- /dev/null +++ b/UML/Core/Manager.puml @@ -0,0 +1,90 @@ +@startdef(id=ManagerMemory) +' implements InterfaceMemory + class ManagerMemory { + +_memorySizeBytes: number + +_memoryInt8Array: Uint8Array + +processResponseMachineDirectives(directives: TypeDirectiveData[]): void + +processResponseMachineInstructions(instructions: TypeInstructionsData[]): void + +processMemoryToUpdateArray(response: TypeMemoryToUpdate[]): void + +getMemoryWordByIndex(index: number): Int32 + +getMemoryWordByAddress(address: string): Int32 + +getMemoryWordBinaryByIndex(index: number): string + +setMemoryWordByIndex(index: number, data: Int32): void + +setMemoryWordByAddress(address: string, data: Int32): void + +setMemoryWordBinaryByAddress(address: string, binary32: string): void + +setMemoryWordBinaryByIndex(index: number, binary32: string): void + +getMemoryByteBinaryByIndex(index: number): string + +setMemoryByteBinaryByIndex(index: number, binary: string): void + +setMemoryByteBinaryByAddress(address: string, binary08: string): void + +getMemoryHalfWordBinaryByIndex(index: number): string + +setMemoryHalfWordBinaryByIndex(index: number, binary16: string): void + +setMemoryHalfWordBinaryByAddress(address: string, binary16: string): void + +setMemoryFloatBinaryByAddress(address: string, binary32: string): void + +setMemoryDoubleBinaryByAddress(address: string, binary64: string): void + -setMemory_stringBinary_ByIndex(index: number, binary_08_16_32_64: string): void + +getAllMemoryWord(): Int32[] + +getAllIndexByWord(): number[] + +setSize(memorySize: number): void + +getAllMemory(): TypeMemory[] + +reset(newMemorySizeBytes: number): void + } +@enddef + +@startdef(id=ManagerBreakpoints) +' implements InterfaceBreakpoints + class ManagerBreakpoints { + +_breakpoints: TypeBreakpoints + +toggleBreakpoint(lineNumber: number): void + +getBreakpoint(lineNumber: number): boolean + +updateManager(breakpoints: TypeBreakpoints): void + +getAllBreakpoints(): TypeBreakpoints + +getAllLinesWithBreakpoints(): number[] + +isBreakpoint(line: number): boolean + +reset(): void + } +@enddef + +@startdef(id=ManagerStatistics) + ' implements InterfaceDataStatistics + class ManagerStatistics { + +_data: TypeDataStatistics + +processResponse(response: Partial): void + +getData(): TypeDataStatistics + +reset(): void + } +@enddef + +@startdef(id=ManagerRegisters) + ' implements InterfaceRegisters + class ManagerRegisters { + +PC: Int32 + +IMAR: Int32 + +IR: Int32 + +A: Int32 + +AHI: Int32 + +B: Int32 + +BHI: Int32 + +BTA: Int32 + +ALU: Int32 + +ALUHI: Int32 + +FPSR: Int32 + +DMAR: Int32 + +SDR: Int32 + +SDRHI: Int32 + +LDR: Int32 + +LDRHI: Int32 + +R: Int32[] + +F: Float32[] + +processRegisterToUpdateArray(response: TypeRegisterToUpdate[]): void + +setRegisterControlWithHexadecimal(registerControl: TypeRegisterControl, hexadecimal: string): void + +setRegisterIntegerWithHexadecimal(index: number, hexadecimal: string): void + +setRegisterFloatWithHexadecimal(index: number, hexadecimal: string): void + +setRegisterDoubleWithHexadecimal(index: number, hexadecimal: string): void + +setRegisterControlWithBinary(registerControl: TypeRegisterControl, binary: string): void + +setRegisterIntegerWithBinary(index: number, binary: string): void + +setRegisterFloatWithBinary(index: number, binary: string): void + +setRegisterDoubleWithBinary(index: number, binary: string): void + +reset(): void + } +@enddef + diff --git a/UML/Core/PixiTHUMDER.puml b/UML/Core/PixiTHUMDER.puml new file mode 100644 index 0000000..f3a1ef0 --- /dev/null +++ b/UML/Core/PixiTHUMDER.puml @@ -0,0 +1,102 @@ +@startdef(id=PixiTHUMDER_Pipeline) + class PixiTHUMDER_Pipeline { + -InstStages_text: PIXI.Text + -IF_text: PIXI.Text + -ID_text: PIXI.Text + -intEX_text: PIXI.Text + -MEM_text: PIXI.Text + -WB_text: PIXI.Text + -faddEX_array: PIXI.Text[] + -fmultEX_array: PIXI.Text[] + -fdivEX_array: PIXI.Text[] + -faddEX_count: any + -fmultEX_count: any + -fdivEX_count: any + +reset(faddEX_count: number, fmultEX_count: number, fdivEX_count: number): void + -initTexts(): void + -drawText(object: PIXI.Text, coords: CoordsType): void + -initArrows(): void + -initBoxes(): void + -drawBox(color: number, positionStart: CoordsType, text: string): void + -drawLine(from: CoordsType, to: CoordsType): void + -drawArrow(from: CoordsType, to: CoordsType): void + +update_IF_text(value: string): void + +update_ID_text(value: string): void + +update_intEX_text(value: string): void + +update_faddEX_text(count: number, value: string): void + +update_fmultEX_text(count: number, value: string): void + +update_fdivEX_text(count: number, value: string): void + +update_MEM_text(value: string): void + +update_WB_text(value: string): void + +draw(): PIXI.Container + +toString(): string + } +@enddef + +@startdef(id=Position) + class Position { + +row: any + +col: any + +toString(): string + } +@enddef + +@startdef(id=PixiTHUMDER_Table) + class PixiTHUMDER_Table { + +table: Map + -cellMaxWidth: any + -cellMaxHeight: any + -rowSeparation: any + -columnSeparation: any + -isDebug: false + +getAllPositions(): Position[] + +getAllRows(): number[] + +getAllColumns(): number[] + +deleteRow(row: number): void + +deleteCol(col: number): void + +deleteCell(row: number, col: number): boolean + +clearCell(row: number, col: number): void + +setCell(row: number, col: number, content: PIXI.Container): void + +drawCell(row: number, col: number): void + +draw(): PIXI.Container + +existCell(row: number, col: number): boolean + -getCell(row: number, col: number): PIXI.Container + } +@enddef + + +@startdef(id=PixiTHUMDER_CycleClockDiagram) + class PixiTHUMDER_CycleClockDiagram { + +realStep: number + +instructions: number + -table: PixiTHUMDER_Table + -tableSteps: PixiTHUMDER_Table + -tableInstructions: PixiTHUMDER_Table + -arrows: PIXI.Graphics[] + -arrowsContainer: PIXI.Container + -borderTitle: PIXI.Graphics + -borderLeft: PIXI.Graphics + -borderTop: PIXI.Graphics + -stepToStart: number + -last: number + +borderTopWidth: number + +borderLeftHeight: number + +reset(): void + -initTables(): void + -drawArrow(arrowDirection: TypeArrowDirection, color?: number): void + -drawBorders(): void + -drawSteps(displayStep?: number): void + -drawInstruction(textValue: string): void + +nextStep(pipeline: TypePipeline, step?: number): void + +addInstruction(text: string): void + +addArrow(instructionArrow: TypeArrowDirection, color: number): void + +moveLeft(): void + +moveRight(): void + +moveTop(): void + +moveBottom(): void + +debug(): void + +draw(): PIXI.Container + +toString(): string + -{static} drawCycle(code?: TypePipelineStage | TypeStall): PIXI.Graphics + } +@enddef diff --git a/UML/Playground.puml b/UML/Playground.puml index dda4f56..7624a24 100644 --- a/UML/Playground.puml +++ b/UML/Playground.puml @@ -1,8 +1,9 @@ @startuml -hide class fields -hide class method -hide interface fields -hide interface method +'hide class fields +'hide class method +'hide interface fields +'hide interface method + skinparam linetype ortho class CoreModule diff --git a/UML/THUMDER-core-Auth.puml b/UML/THUMDER-core-Auth.puml index 2151134..3056134 100644 --- a/UML/THUMDER-core-Auth.puml +++ b/UML/THUMDER-core-Auth.puml @@ -1,9 +1,10 @@ @startuml -hide class fields -hide class method -hide interface fields -hide interface method - +!theme plain +'hide class fields +'hide class method +'hide interface fields +'hide interface method +skinparam defaultFontName "JetBrains Mono" skinparam linetype ortho package Auth #DDDDDD { diff --git a/UML/THUMDER-core-Machine.puml b/UML/THUMDER-core-Machine.puml index 08cea54..623e438 100644 --- a/UML/THUMDER-core-Machine.puml +++ b/UML/THUMDER-core-Machine.puml @@ -1,284 +1,36 @@ @startuml -hide class fields -hide class method -hide interface fields -hide interface method +!theme plain +'hide class fields +'hide class method +'hide interface fields +'hide interface method +skinparam defaultFontName "JetBrains Mono" skinparam linetype ortho -package Machine #DDDDDD { - class PixiTHUMDER_Pipeline { - -InstStages_text: PIXI.Text - -IF_text: PIXI.Text - -ID_text: PIXI.Text - -intEX_text: PIXI.Text - -MEM_text: PIXI.Text - -WB_text: PIXI.Text - -faddEX_array: PIXI.Text[] - -fmultEX_array: PIXI.Text[] - -fdivEX_array: PIXI.Text[] - -faddEX_count: any - -fmultEX_count: any - -fdivEX_count: any - +reset(faddEX_count: number, fmultEX_count: number, fdivEX_count: number): void - -initTexts(): void - -drawText(object: PIXI.Text, coords: CoordsType): void - -initArrows(): void - -initBoxes(): void - -drawBox(color: number, positionStart: CoordsType, text: string): void - -drawLine(from: CoordsType, to: CoordsType): void - -drawArrow(from: CoordsType, to: CoordsType): void - +update_IF_text(value: string): void - +update_ID_text(value: string): void - +update_intEX_text(value: string): void - +update_faddEX_text(count: number, value: string): void - +update_fmultEX_text(count: number, value: string): void - +update_fdivEX_text(count: number, value: string): void - +update_MEM_text(value: string): void - +update_WB_text(value: string): void - +draw(): PIXI.Container - +toString(): string - } - class Position { - +row: any - +col: any - +toString(): string - } - class PixiTHUMDER_Table { - +table: Map - -cellMaxWidth: any - -cellMaxHeight: any - -rowSeparation: any - -columnSeparation: any - -isDebug: false - +getAllPositions(): Position[] - +getAllRows(): number[] - +getAllColumns(): number[] - +deleteRow(row: number): void - +deleteCol(col: number): void - +deleteCell(row: number, col: number): boolean - +clearCell(row: number, col: number): void - +setCell(row: number, col: number, content: PIXI.Container): void - +drawCell(row: number, col: number): void - +draw(): PIXI.Container - +existCell(row: number, col: number): boolean - -getCell(row: number, col: number): PIXI.Container - } - class PixiTHUMDER_CycleClockDiagram { - +realStep: number - +instructions: number - -table: PixiTHUMDER_Table - -tableSteps: PixiTHUMDER_Table - -tableInstructions: PixiTHUMDER_Table - -arrows: PIXI.Graphics[] - -arrowsContainer: PIXI.Container - -borderTitle: PIXI.Graphics - -borderLeft: PIXI.Graphics - -borderTop: PIXI.Graphics - -stepToStart: number - -last: number - +borderTopWidth: number - +borderLeftHeight: number - +reset(): void - -initTables(): void - -drawArrow(arrowDirection: TypeArrowDirection, color?: number): void - -drawBorders(): void - -drawSteps(displayStep?: number): void - -drawInstruction(textValue: string): void - +nextStep(pipeline: TypePipeline, step?: number): void - +addInstruction(text: string): void - +addArrow(instructionArrow: TypeArrowDirection, color: number): void - +moveLeft(): void - +moveRight(): void - +moveTop(): void - +moveBottom(): void - +debug(): void - +draw(): PIXI.Container - +toString(): string - -{static} drawCycle(code?: TypePipelineStage | TypeStall): PIXI.Graphics - } - class ManagerRegisters implements InterfaceRegisters { - +PC: Int32 - +IMAR: Int32 - +IR: Int32 - +A: Int32 - +AHI: Int32 - +B: Int32 - +BHI: Int32 - +BTA: Int32 - +ALU: Int32 - +ALUHI: Int32 - +FPSR: Int32 - +DMAR: Int32 - +SDR: Int32 - +SDRHI: Int32 - +LDR: Int32 - +LDRHI: Int32 - +R: Int32[] - +F: Float32[] - +processRegisterToUpdateArray(response: TypeRegisterToUpdate[]): void - +setRegisterControlWithHexadecimal(registerControl: TypeRegisterControl, hexadecimal: string): void - +setRegisterIntegerWithHexadecimal(index: number, hexadecimal: string): void - +setRegisterFloatWithHexadecimal(index: number, hexadecimal: string): void - +setRegisterDoubleWithHexadecimal(index: number, hexadecimal: string): void - +setRegisterControlWithBinary(registerControl: TypeRegisterControl, binary: string): void - +setRegisterIntegerWithBinary(index: number, binary: string): void - +setRegisterFloatWithBinary(index: number, binary: string): void - +setRegisterDoubleWithBinary(index: number, binary: string): void - +reset(): void - } - class ManagerMemory implements InterfaceMemory { - +_memorySizeBytes: number - +_memoryInt8Array: Uint8Array - +processResponseMachineDirectives(directives: TypeDirectiveData[]): void - +processResponseMachineInstructions(instructions: TypeInstructionsData[]): void - +processMemoryToUpdateArray(response: TypeMemoryToUpdate[]): void - +getMemoryWordByIndex(index: number): Int32 - +getMemoryWordByAddress(address: string): Int32 - +getMemoryWordBinaryByIndex(index: number): string - +setMemoryWordByIndex(index: number, data: Int32): void - +setMemoryWordByAddress(address: string, data: Int32): void - +setMemoryWordBinaryByAddress(address: string, binary32: string): void - +setMemoryWordBinaryByIndex(index: number, binary32: string): void - +getMemoryByteBinaryByIndex(index: number): string - +setMemoryByteBinaryByIndex(index: number, binary: string): void - +setMemoryByteBinaryByAddress(address: string, binary08: string): void - +getMemoryHalfWordBinaryByIndex(index: number): string - +setMemoryHalfWordBinaryByIndex(index: number, binary16: string): void - +setMemoryHalfWordBinaryByAddress(address: string, binary16: string): void - +setMemoryFloatBinaryByAddress(address: string, binary32: string): void - +setMemoryDoubleBinaryByAddress(address: string, binary64: string): void - -setMemory_stringBinary_ByIndex(index: number, binary_08_16_32_64: string): void - +getAllMemoryWord(): Int32[] - +getAllIndexByWord(): number[] - +setSize(memorySize: number): void - +getAllMemory(): TypeMemory[] - +reset(newMemorySizeBytes: number): void - } - class ManagerBreakpoints implements InterfaceBreakpoints { - +_breakpoints: TypeBreakpoints - +toggleBreakpoint(lineNumber: number): void - +getBreakpoint(lineNumber: number): boolean - +updateManager(breakpoints: TypeBreakpoints): void - +getAllBreakpoints(): TypeBreakpoints - +getAllLinesWithBreakpoints(): number[] - +isBreakpoint(line: number): boolean - +reset(): void - } - class ManagerStatistics implements InterfaceDataStatistics { - +_data: TypeDataStatistics - +processResponse(response: Partial): void - +getData(): TypeDataStatistics - +reset(): void - } - class MachineService { - +floatingPointStageConfiguration: TypeFloatingPointStageConfiguration - +pipeline: PixiTHUMDER_Pipeline - +cycleClockDiagram: PixiTHUMDER_CycleClockDiagram - +dataStatistics: ManagerStatistics - +registers: ManagerRegisters - +memory: ManagerMemory - +memorySize: any - +breakpointManager: ManagerBreakpoints - +code: UtilsDataStructures.THUMDER_Map - +canSimulate: boolean - -statusMachineInStep: TypeSimulationStep - +isBreakpoint$: Subject - +codeSimulation$: Subject - +stepSimulation$: Subject - +dataStatistics$: Subject - +logger: string - -level: EnumLogLevel - -privateStep: number - -privateLine: number - -timer: Observable - -timerObserver: PartialObserver - +reset$: Subject - +logger$: Subject - +step$: Subject - +line$: Subject - +isRunning$: Subject - +isComplete$: Subject - +isRunning: boolean - +isComplete: boolean - +isBreakpoint: boolean - -store: StorageService - -socketProviderConnect: SocketProviderConnectService - -translate: TranslateService - -toast: ToastrService - +resetMachineStatus(): Promise - +getResetObservable(): Observable - +getStepObservable(): Observable - +getLineObservable(): Observable - +getIsRunningObservable(): Observable - +getIsCompleteObservable(): Observable - +getStepSimulationObservable(): Observable - +getCodeSimulationObservable(): Observable - +getDebuggerObservable(): Observable - +getDataStatisticsObservable(): Observable - +getLoggerObservable(): Observable - +getStatusWebsocketObservable(): Observable<"Connect" | "Disconnect"> - +getStatusWebsocket(): "Connect" | "Disconnect" - +getListStatusPipeline(): TypePipelineToProcess[] - +play(): Promise - +reset(): Promise - +nextStep(): Promise - +pause(): Promise - +resume(): Promise - +end(): Promise - -SimulationInit(): Promise - -SimulationNextStep(): Promise - -CheckConditions(): Promise - -ProcessStep(): Promise - +updateRegisterInServer(registersToUpdate: TypeRegisterToUpdate[]): Promise - +updateMemoryInServer(memoryToUpdate: TypeMemoryToUpdate[]): Promise - +writeToLog(msg: string, level?: EnumLogLevel, params?: TypeLogger[]): void - +getCode(address: TypeAddress): TypeInstructionsData - +getAllStatusMachine(): TypeStatusMachine - +resetConnection(): void - -stringFormat(msg: string, params: TypeLogger[]): string - -shouldLog(level: EnumLogLevel): boolean - -toastMessage(key_title?: string, key_message?: string): Promise - } - interface InterfaceRegisters { - +PC: Int32 - +IMAR: Int32 - +IR: Int32 - +A: Int32 - +AHI: Int32 - +B: Int32 - +BHI: Int32 - +BTA: Int32 - +ALU: Int32 - +ALUHI: Int32 - +FPSR: Int32 - +DMAR: Int32 - +SDR: Int32 - +SDRHI: Int32 - +LDR: Int32 - +LDRHI: Int32 - +R: Int32[] - +F: Float32[] - +processRegisterToUpdateArray(response: TypeRegisterToUpdate[]): void - +reset(): void - } - interface InterfaceBreakpoints { - +_breakpoints: TypeBreakpoints - +reset(): void - } - interface InterfaceMemory { - +_memorySizeBytes: number - +_memoryInt8Array: Uint8Array - +processResponseMachineDirectives(directives: TypeDirectiveData[]): void - +processResponseMachineInstructions(instructions: TypeInstructionsData[]): void - +processMemoryToUpdateArray(response: TypeMemoryToUpdate[]): void - +reset(newMemorySizeBytes: number): void - } - interface InterfaceDataStatistics { - +_data: TypeDataStatistics - +processResponse(response: Partial): void - +reset() - } +package Core #DDDDDD { + +'left +!include ./Core/Interface.puml!InterfaceMemory +!include ./Core/Manager.puml!ManagerMemory +!include ./Core/Interface.puml!InterfaceRegisters +!include ./Core/Manager.puml!ManagerRegisters + +'right +!include ./Core/Interface.puml!InterfaceDataStatistics +!include ./Core/Manager.puml!ManagerStatistics +!include ./Core/Interface.puml!InterfaceBreakpoints +!include ./Core/Manager.puml!ManagerBreakpoints + +'down +!include ./Core/PixiTHUMDER.puml!PixiTHUMDER_Pipeline +!include ./Core/PixiTHUMDER.puml!PixiTHUMDER_Table +!include ./Core/PixiTHUMDER.puml!Position +!include ./Core/PixiTHUMDER.puml!PixiTHUMDER_CycleClockDiagram + +'center +!include ./Core/Machine.puml!MachineService + PixiTHUMDER_Table--*Position PixiTHUMDER_Pipeline-->PixiTHUMDER_Table MachineService-->PixiTHUMDER_Pipeline @@ -287,6 +39,11 @@ package Machine #DDDDDD { MachineService--right>ManagerMemory MachineService--left>ManagerBreakpoints MachineService--left>ManagerStatistics + + ManagerStatistics..up|>InterfaceDataStatistics + ManagerBreakpoints..up|>InterfaceBreakpoints + ManagerMemory..up|>InterfaceMemory + ManagerRegisters..up|>InterfaceRegisters } @enduml diff --git a/UML/THUMDER-core-Services.puml b/UML/THUMDER-core-Services.puml index 7e50d50..88713da 100644 --- a/UML/THUMDER-core-Services.puml +++ b/UML/THUMDER-core-Services.puml @@ -1,9 +1,11 @@ @startuml -hide class fields -hide class method -hide interface fields -hide interface method +!theme plain +'hide class fields +'hide class method +'hide interface fields +'hide interface method +skinparam defaultFontName "JetBrains Mono" skinparam linetype ortho package Services #DDDDDD { @@ -19,7 +21,7 @@ package Services #DDDDDD { +nativeImage: Electron.NativeImage +screen: Electron.Screen +shell: Electron.Shell - +{static} isElectron(): "" | "browser" | "renderer" | "worker" + +{static} serviceElectron(): "" | "browser" | "renderer" | "worker" +{static} isServer: boolean +{static} isElectronApp: boolean +{static} isMacOS: boolean diff --git a/UML/THUMDER-core-Storage.puml b/UML/THUMDER-core-Storage.puml index 0f6af42..b6cb648 100644 --- a/UML/THUMDER-core-Storage.puml +++ b/UML/THUMDER-core-Storage.puml @@ -1,9 +1,10 @@ @startuml -hide class fields -hide class method -hide interface fields -hide interface method +'hide class fields +'hide class method +'hide interface fields +'hide interface method +skinparam defaultFontName "JetBrains Mono" skinparam linetype ortho package Storage #DDDDDD { diff --git a/main.ts b/main.ts index e460962..5871912 100644 --- a/main.ts +++ b/main.ts @@ -34,7 +34,7 @@ function createWindow(): BrowserWindow { nativeWindowOpen: true, allowRunningInsecureContent: (isServe), contextIsolation: false, // false if you want to run 2e2 test with Spectron - enableRemoteModule: true // true if you want to run 2e2 test with Spectron or use remote module in renderer context (ie. Angular) + // enableRemoteModule: true // true if you want to run 2e2 test with Spectron or use remote module in renderer context (ie. Angular) }, }); diff --git a/package.json b/package.json index 46e4320..5df852e 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ }, "main": "main.js", "scripts": { - "ws:server": "node ../THUMDER-server/dist/main.js", + "ws:server": "node ../THUMDER-server/dist/main.js --startWebSocketServer", "postinstall": "electron-builder install-app-deps", "ng:build:dev": "ng run thumder-angular-electron:build:dev", "ng:build:web": "ng run thumder-angular-electron:build:web", @@ -67,7 +67,7 @@ "@angular/compiler": "12.2.11", "@angular/compiler-cli": "12.2.11", "@angular/core": "12.2.11", - "@angular/fire": "6.1.5", + "@angular/fire": "^7.0", "@angular/forms": "12.2.11", "@angular/material": "12.2.11", "@angular/platform-browser": "12.2.11", @@ -85,7 +85,7 @@ "cookieconsent": "3.1.1", "devextreme": "21.1.5", "devextreme-angular": "21.1.5", - "firebase": "8.8.1", + "firebase": "9.6.10", "jquery": "3.6.0", "ng-table-virtual-scroll": "1.3.7", "ng2-charts": "^2.4.2", @@ -97,7 +97,7 @@ "pixi.js": "6.1.2", "pixi.js-keyboard": "^1.1.6", "pixi.js-mouse": "^1.1.6", - "rxjs": "6.6.6", + "rxjs": "6.6.7", "string-to-argv": "1.0.0", "thumder-ontology": "1.1.1", "xterm": "4.13.0", @@ -132,8 +132,8 @@ "core-js": "3.6.5", "cross-env": "7.0.2", "cypress": "9.1.0", - "electron": "12.2.2", - "electron-builder": "22.10.5", + "electron": "16.2.0", + "electron-builder": "23.0.3", "electron-chromedriver": "14.0.0", "electron-reload": "1.5.0", "eslint": "7.10.0", diff --git a/src/app/Types.ts b/src/app/Types.ts index 17ccbdf..3cf4b7b 100644 --- a/src/app/Types.ts +++ b/src/app/Types.ts @@ -51,7 +51,7 @@ export interface InterfaceUser { } export interface InterfaceFileItem { - $key?: string; // ---? Firebase + $key: string; // ---? Firebase f_id: string; //- e1_uid: string; //- key: string; //- @@ -677,7 +677,6 @@ export type TypeSimulationStep = { // stage: TypeStage; pipeline: TypePipeline; - registers: TypeRegisterToUpdate[]; memory: TypeMemoryToUpdate[]; statistics: Partial; diff --git a/src/app/__core/auth/auth.service.ts b/src/app/__core/auth/auth.service.ts index 9ec19fa..146e456 100644 --- a/src/app/__core/auth/auth.service.ts +++ b/src/app/__core/auth/auth.service.ts @@ -1,15 +1,30 @@ import { Injectable, NgZone } from "@angular/core"; -import { AngularFirestore, AngularFirestoreDocument } from "@angular/fire/firestore"; import { Router } from "@angular/router"; -import { AngularFireAuth } from "@angular/fire/auth"; +//import { AngularFirestore, AngularFirestoreDocument } from "@angular/fire/compat/firestore"; +// import { AngularFireAuth } from '@angular/fire/compat/auth'; + +// import { Auth } from '@angular/fire/auth'; +// import { setPersistence, inMemoryPersistence, browserSessionPersistence, Persistence, } from '@firebase/auth'; + import { Observable, Subject, Subscription } from "rxjs"; import { TranslateService } from "@ngx-translate/core"; import { ToastrService } from "ngx-toastr"; -import firebase from "firebase/app"; -import UserCredential = firebase.auth.UserCredential; + import { DEFAULT_CONFIG_TOAST } from "../../CONSTANTS"; import { InterfaceUser } from "../../Types"; import { ElectronService } from "../services"; +import { doc, Firestore, setDoc } from "@angular/fire/firestore"; +import { + Auth, + GithubAuthProvider, + GoogleAuthProvider, + getRedirectResult, sendEmailVerification, sendPasswordResetEmail, + createUserWithEmailAndPassword, + signInAnonymously, signInWithEmailAndPassword, signInWithPopup, +} from "@angular/fire/auth"; +import { UserCredential } from "@angular/fire/auth"; +import { FirebaseError } from "@angular/fire/app" + @Injectable({ providedIn: "root" @@ -21,15 +36,16 @@ export class AuthService { public userData: InterfaceUser; // Save logged in user data private subscriptions$ = new Subscription(); - constructor(private afs: AngularFirestore, // Inject Firestore service - private afAuth: AngularFireAuth, // Inject Firebase auth service + constructor(private afs: Firestore, // Inject Firestore service + private afAuth: Auth, // Inject Firebase auth service private ngZone: NgZone, // NgZone service to remove outside scope warning private router: Router, private toast: ToastrService, private translate: TranslateService, + // private auth: Auth, private electronService: ElectronService) { this.subscriptions$.add( - this.afAuth.authState.subscribe(user => { + this.afAuth.onAuthStateChanged((user) => { if (user) { window.document.body.className = ""; window.document.body.classList.add("dx-viewport", "sidebar-mini", "layout-fixed", "layout-footer-fixed", "layout-navbar-fixed"); @@ -62,12 +78,12 @@ export class AuthService { // Sign in with email/password public async SignIn(email, password): Promise { try { - const userCredential = await this.afAuth.signInWithEmailAndPassword(email, password); + const userCredential = await signInWithEmailAndPassword(this.afAuth, email, password); await this.SetUserData(userCredential); return Promise.resolve(true); } catch (error) { console.error(error); - this.displayError(error as firebase.FirebaseError); + this.displayError(error); } return Promise.resolve(false); } @@ -75,15 +91,13 @@ export class AuthService { // Sign up with email/password public async SignUp(email, password): Promise { try { - const userCredential = await this.afAuth.createUserWithEmailAndPassword(email, password); - /* Call the SendVerificationMail(userCredential) function when new user sign - up and returns promise */ + const userCredential = await createUserWithEmailAndPassword(this.afAuth, email, password); await this.SendVerificationMail(userCredential); await this.SetUserData(userCredential); return Promise.resolve(userCredential); } catch (error) { console.error(error); - this.displayError(error as firebase.FirebaseError); + this.displayError(error); } return Promise.resolve(); } @@ -91,11 +105,11 @@ export class AuthService { // Send email verification when new user sign up public async SendVerificationMail(userCredential: UserCredential): Promise { try { - await userCredential.user.sendEmailVerification(); - await this.router.navigate([ "/" ]); + await sendEmailVerification(userCredential.user) + await this.router.navigate(["/"]); } catch (error) { console.error(error); - this.displayError(error as firebase.FirebaseError); + this.displayError(error); } return Promise.resolve(); } @@ -103,11 +117,11 @@ export class AuthService { // Reset Forgot password public async ForgotPassword(passwordResetEmail): Promise { try { - await this.afAuth.sendPasswordResetEmail(passwordResetEmail); + await sendPasswordResetEmail(this.afAuth, passwordResetEmail); this.displayMessage("Email send, heck your inbox."); } catch (error) { console.error(error); - this.displayError(error as firebase.FirebaseError); + this.displayError(error); } return Promise.resolve(); } @@ -120,25 +134,25 @@ export class AuthService { // Sign in with Google async GoogleAuth(): Promise { - return this.AuthLogin(new firebase.auth.GoogleAuthProvider()); + return this.AuthLogin(new GoogleAuthProvider()); } // Sign in with Google async GithubAuth(): Promise { - return this.AuthLogin(new firebase.auth.GithubAuthProvider()); + return this.AuthLogin(new GithubAuthProvider()); } // Auth logic to run auth providers async AuthLoginAnonymously(): Promise { try { - const userCredential = await this.afAuth.signInAnonymously(); + const userCredential = await signInAnonymously(this.afAuth); await this.SetUserData(userCredential); this.ngZone.run(() => { - this.router.navigate([ "/" ]); + this.router.navigate(["/"]); }); } catch (error) { console.error(error); - this.displayError(error as firebase.FirebaseError); + this.displayError(error); } return Promise.resolve(); } @@ -146,15 +160,14 @@ export class AuthService { // Auth logic to run auth providers private async AuthLogin(provider): Promise { try { - const userCredential = await this.afAuth.signInWithPopup(provider); - console.log(" AuthLogin"); + const userCredential = await signInWithPopup(this.afAuth, provider); await this.SetUserData(userCredential); this.ngZone.run(() => { - this.router.navigate([ "/" ]); + this.router.navigate(["/"]); }); } catch (error) { console.error(error); - this.displayError(error as firebase.FirebaseError); + this.displayError(error); } return Promise.resolve(); } @@ -166,10 +179,10 @@ export class AuthService { for (const key of Object.keys(localStorage)) { localStorage.removeItem(key); } - await this.router.navigate([ "/login" ]); + await this.router.navigate(["/login"]); } catch (error) { console.error(error); - this.displayError(error as firebase.FirebaseError); + this.displayError(error); } } @@ -178,12 +191,12 @@ export class AuthService { */ public async AuthCheckLoginRedirect(): Promise { if (!this.electronService.isElectronApp) { - const userCredential = await firebase.auth().getRedirectResult(); + const userCredential = await getRedirectResult(this.afAuth); if (userCredential.user !== null) { console.log("getRedirectResult", userCredential); await this.SetUserData(userCredential); this.ngZone.run(() => { - this.router.navigate([ "/" ]); + this.router.navigate(["/"]); }); } return Promise.resolve(true); @@ -196,8 +209,8 @@ export class AuthService { sign up with username/password and sign in with social auth provider in Firestore database using AngularFirestore + AngularFirestoreDocument service */ - SetUserData(userCredential: UserCredential): any { - const userRef: AngularFirestoreDocument = this.afs.doc(`users/${ userCredential.user.uid }`); + SetUserData(userCredential: UserCredential) { + const userRef = doc(this.afs, `users/${userCredential.user.uid}`); const userData: InterfaceUser = { uid: userCredential.user.uid, email: userCredential.user.email, @@ -205,18 +218,21 @@ export class AuthService { photoURL: userCredential.user.photoURL, emailVerified: userCredential.user.emailVerified }; - return userRef.set(userData, { - merge: true - }); + return setDoc(userRef, userData); } private displayMessage(message: string) { this.toast.info(message, "", DEFAULT_CONFIG_TOAST); } - private displayError(error: firebase.FirebaseError) { + private displayError(error: FirebaseError) { const error_title = this.translate.instant("ERROR.TITLE", { title: error?.code ?? "" }); const error_message = this.translate.instant("ERROR.MESSAGE", { message: error?.message ?? "" }); this.toast.error(error_message, error_title, DEFAULT_CONFIG_TOAST); } + + public async setPersistence(persistence: boolean): Promise { + // const type: Persistence = persistence ? browserSessionPersistence : inMemoryPersistence; + // await setPersistence(this.auth, type); + } } diff --git a/src/app/__core/services/electron/electron.service.ts b/src/app/__core/services/electron/electron.service.ts index 5bdc6c0..dc5c962 100644 --- a/src/app/__core/services/electron/electron.service.ts +++ b/src/app/__core/services/electron/electron.service.ts @@ -1,6 +1,7 @@ import { Injectable } from "@angular/core"; -import { ipcRenderer, webFrame, remote } from "electron"; +import { ipcRenderer, webFrame } from "electron"; +// import { remote } from "electron"; import * as childProcess from "child_process"; import * as fs from "fs"; @@ -12,7 +13,7 @@ export class ElectronService { public ipcRenderer: typeof ipcRenderer; public webFrame: typeof webFrame; - public remote: typeof remote; + // public remote: typeof remote; public childProcess: typeof childProcess; public fs: typeof fs; @@ -21,7 +22,7 @@ export class ElectronService { if (ElectronService.isElectron()) { this.ipcRenderer = window.require("electron").ipcRenderer; this.webFrame = window.require("electron").webFrame; - this.remote = window.require("electron").remote; + // this.remote = window.require("electron").remote; this.childProcess = window.require("child_process"); this.fs = window.require("fs"); @@ -83,9 +84,9 @@ export class ElectronService { return ElectronService.isElectronApp && process.arch === "x64"; } - public get nativeImage(): Electron.nativeImage { - return this.electron ? this.electron.nativeImage : null; - } + // public get nativeImage(): Electron.nativeImage { + // return this.electron ? this.electron.nativeImage : null; + // } public get screen(): Electron.Screen { return this.electron ? this.electron.screen : null; diff --git a/src/app/__core/services/file-system/file-system-storage.service.ts b/src/app/__core/services/file-system/file-system-storage.service.ts index 9f011fe..13e3efc 100644 --- a/src/app/__core/services/file-system/file-system-storage.service.ts +++ b/src/app/__core/services/file-system/file-system-storage.service.ts @@ -1,44 +1,72 @@ import { Injectable } from "@angular/core"; import { HttpClient } from "@angular/common/http"; -import { AngularFirestore, AngularFirestoreCollection } from "@angular/fire/firestore"; + import { Observable } from "rxjs"; -import { map } from "rxjs/operators"; -import firebase from "firebase/app"; import { Utils } from "../../../Utils"; import { THUMDER_FileItem } from "./file-system.service"; -import { InterfaceFileItem, InterfaceUser } from "../../../Types"; -import Timestamp = firebase.firestore.Timestamp; +import { InterfaceUser } from "../../../Types"; +import { map, filter } from "rxjs/operators"; +import { from } from "rxjs"; + +import { + CollectionReference, + Firestore, Timestamp, + query, where, + doc, + getDoc, + getDocs, + updateDoc, + setDoc, + deleteDoc, + collection, + onSnapshot, + // for valueChanges and snapShotChanges + docSnapshots, + collectionChanges, + collectionData, + docData, +} from "@angular/fire/firestore"; +import { DocumentReference } from "@firebase/firestore"; @Injectable({ providedIn: "root" }) export class FileSystemStorageService { + private readonly dbFileItemsPath = "/fileitems"; + + // https://dev.to/jdgamble555/angular-12-with-firebase-9-49a0 constructor(private httpClient: HttpClient, - private afs: AngularFirestore) { + private afs: Firestore) { } + // TODO public async isInitialize(): Promise { - const vector = await this.collectionFileItems().get().toPromise(); - return Promise.resolve(vector.size > 0); + const documents = await getDocs(this.queryAllFilesFromUser()); + return Promise.resolve(documents.size > 0); } // region getters - public getCollectionFileItemsByFilter(name: string) { + public queryFileFromUser(filename: string) { const userData = JSON.parse(localStorage.getItem("user")) as InterfaceUser; - return this.afs.collection("/fileitems", (ref) => { - return ref - .where("e1_uid", "==", userData.uid) - .where("name", "==", name); - }); + return getDocs(query( + collection(this.afs, this.dbFileItemsPath), + where("e1_uid", "==", userData.uid), + where("name", "==", filename) + )); } - public collectionFileItems(): AngularFirestoreCollection { + private queryAllFilesFromUser() { const userData = JSON.parse(localStorage.getItem("user")) as InterfaceUser; - return this.afs.collection("/fileitems", (ref) => { - return ref.where("e1_uid", "==", userData.uid); - }); + return query( + collection(this.afs, this.dbFileItemsPath), + where("e1_uid", "==", userData.uid), + ) + } + + private collectionFileItems() { + return getDocs(this.queryAllFilesFromUser()); } // endregion @@ -47,7 +75,7 @@ export class FileSystemStorageService { if (await this.isInitialize()) { return Promise.resolve(1); } - const files = [ "prim.s", "win-dlx.s" ]; + const files = ["prim.s", "win-dlx.s"]; const userData = JSON.parse(localStorage.getItem("user")) as InterfaceUser; for (const filename of files) { const defaultFileItem = new THUMDER_FileItem("", false, []); @@ -56,20 +84,21 @@ export class FileSystemStorageService { defaultFileItem.e1_uid = userData.uid; defaultFileItem.dateModified = new Date(); defaultFileItem.content = await this.httpClient.get("assets/examples-dlx/" + filename, { responseType: "text" }).toPromise(); - await this.addFileItem(defaultFileItem); + await this.createFileItem(defaultFileItem); } return Promise.resolve(0); } - public getAllFilesFromFirestoreAsObservable(): Observable { - return this.collectionFileItems().valueChanges([ "added", "removed", "modified" ]).pipe( + // Observable + public getAllFilesFromFirestoreAsObservable() { + return this.FileItems_Collections_valueChanges().pipe( map((changes) => { const items = changes.map((interfaceFileItem) => { - const time = interfaceFileItem.dateModified as unknown as Timestamp; + // const time = interfaceFileItem.dateModified as unknown as Timestamp; return { ...interfaceFileItem, - dateModified: new Timestamp(time.seconds, time.nanoseconds).toDate() - } as unknown as InterfaceFileItem; + // dateModified: new Timestamp(time.seconds, time.nanoseconds).toDate() + } as unknown as THUMDER_FileItem; }); return items.sort((a, b) => { if (a.name < b.name) return -1; @@ -80,28 +109,15 @@ export class FileSystemStorageService { ); } - public getFileItemsAsObservable(): Observable { - return this.collectionFileItems().snapshotChanges().pipe( - map((changes) => { - return changes.map((c) => { - const time = c.payload.doc.data().dateModified as unknown as Timestamp; - return { - $key: c.payload.doc.id, - ...c.payload.doc.data(), - dateModified: new Timestamp(time.seconds, time.nanoseconds).toDate() - } as unknown as InterfaceFileItem; - }); - }) - ); - } - - public async addFileItem(fileItem: THUMDER_FileItem): Promise { + public async createFileItem(fileItem: THUMDER_FileItem): Promise { try { const userData = JSON.parse(localStorage.getItem("user")) as InterfaceUser; - const $key = this.afs.createId(); + const newDocument = this.createNewDocument(); + const { path, isDirectory, pathKeys } = fileItem; const thumderFileItem = new THUMDER_FileItem(path, isDirectory, pathKeys); - thumderFileItem.$key = $key; + thumderFileItem.$key = newDocument.id; // ID firebase doc + thumderFileItem.e1_uid = userData.uid; thumderFileItem.content = fileItem.content ?? ""; thumderFileItem.dataItem = fileItem.dataItem ?? ""; @@ -117,54 +133,94 @@ export class FileSystemStorageService { thumderFileItem.size = fileItem.size ?? 0; thumderFileItem.thumbnail = fileItem.thumbnail ?? ""; - const obj: InterfaceFileItem = { - $key: thumderFileItem.$key, - content: thumderFileItem.content, - dataItem: thumderFileItem.dataItem, - dateModified: thumderFileItem.dateModified, - description: thumderFileItem.description, - e1_uid: thumderFileItem.e1_uid, - f_id: thumderFileItem.f_id, - hasSubDirectories: thumderFileItem.hasSubDirectories, - isDirectory: thumderFileItem.isDirectory, - key: thumderFileItem.key, - name: thumderFileItem.name, - path: thumderFileItem.path, - pathKeys: thumderFileItem.pathKeys, - size: thumderFileItem.size, - thumbnail: thumderFileItem.thumbnail, - }; - - console.log("New document in firestore with ID: %s, %o", $key, obj); - - await this.collectionFileItems().doc($key).set(obj, { merge: true }); - return Promise.resolve(thumderFileItem); + console.log("New document in firestore with ID: %s, %o", thumderFileItem.$key, thumderFileItem); + await setDoc(newDocument.ref, JSON.parse(JSON.stringify(thumderFileItem)), { merge: true }) + return Promise.resolve(true); } catch (error) { console.error(error); return Promise.reject(); } } - public async deleteFileItem($key: string): Promise { - try { - await this.collectionFileItems().doc($key).delete(); - return Promise.resolve(); - } catch (error) { - console.error(error); - return Promise.reject(error.message); - } + public async deleteFileItem($key: string): Promise { + await deleteDoc(doc(this.afs, this.dbFileItemsPath, $key)); + return Promise.resolve(true) } - public async editFileItem(fileItem: THUMDER_FileItem, $key: string): Promise { - try { - console.debug("Se va a editar en el servidor el documento con ID: %s", $key); - const id = $key ?? this.afs.createId(); - const data = { $key: id, ...fileItem }; - const result_void = await this.collectionFileItems().doc(id).set(data); - return Promise.resolve(result_void); - } catch (error) { - console.error(error); - return Promise.reject(error.message); - } + public async updateFileItem($key: string, fileItem: THUMDER_FileItem): Promise { + await updateDoc(doc(this.afs, this.dbFileItemsPath, $key), JSON.parse(JSON.stringify(fileItem))); + return Promise.resolve(true) + } + + // Documents + public FileItem_Documents_valueChanges(id) { + return docData( + doc(this.afs, this.dbFileItemsPath, id) as DocumentReference + ); + } + + public FileItem_Documents_snapShotChanges(id) { + return docSnapshots( + doc(this.afs, id) as DocumentReference + ); + } + + // Collections + public FileItems_Collections_valueChanges() { + const userData = JSON.parse(localStorage.getItem("user")) as InterfaceUser; + return collectionData( + query( + collection(this.afs, this.dbFileItemsPath) as CollectionReference, + where('e1_uid', '==', userData.uid) + ), { idField: '$key' } + ); + } + + public FileItems_Collections_snapShotChanges() { + const userData = JSON.parse(localStorage.getItem("user")) as InterfaceUser; + return collectionChanges( + query( + collection(this.afs, this.dbFileItemsPath) as CollectionReference, + where('e1_uid', '==', userData.uid) + ) + ); + } + + public createNewDocument() { + const newDocument = doc(collection(this.afs, this.dbFileItemsPath)); + return { + ref: newDocument, + id: newDocument.id + }; + } + + public async getAllFilesFromFirestore() { + const userData = JSON.parse(localStorage.getItem("user")) as InterfaceUser; + return getDocs( + query( + collection(this.afs, this.dbFileItemsPath) as CollectionReference, + where('e1_uid', '==', userData.uid) + ) + ); + } + + public async getFiles(): Promise { + const files: THUMDER_FileItem[] = []; + const userData = JSON.parse(localStorage.getItem("user")) as InterfaceUser; + const q = query( + collection(this.afs, this.dbFileItemsPath) as CollectionReference, + where("e1_uid", "==", userData.uid) + ); + const querySnapshot = await getDocs(q); + querySnapshot.forEach((doc) => { + files.push(doc.data()); + }); + return files; } } + +// update file +// delete file +// create file +// async data +// generate 2 files by default diff --git a/src/app/__core/services/file-system/file-system.service.ts b/src/app/__core/services/file-system/file-system.service.ts index b2ea39b..4e037ab 100644 --- a/src/app/__core/services/file-system/file-system.service.ts +++ b/src/app/__core/services/file-system/file-system.service.ts @@ -1,5 +1,5 @@ import { Injectable } from "@angular/core"; -import { Observable, Subject } from "rxjs"; +import { Observable, Subject, Subscription } from "rxjs"; import FileSystemItem from "devextreme/file_management/file_system_item"; import UploadInfo from "devextreme/file_management/upload_info"; import { FileSystemStorageService } from "./file-system-storage.service"; @@ -30,15 +30,21 @@ export class FileSystemService { public items: THUMDER_FileItem[] = []; private updateUI$: Subject = new Subject(); + private subscription: Subscription = new Subscription(); constructor(public fileSystemStorageService: FileSystemStorageService) { + + } public async init(): Promise { - this.fileSystemStorageService.getAllFilesFromFirestoreAsObservable().subscribe(async (items) => { + await this.setList_FileItems(await this.fileSystemStorageService.getFiles()); + + this.subscription = this.fileSystemStorageService.getAllFilesFromFirestoreAsObservable().subscribe(async (items) => { this.items = []; - await this.updateItems(items); + await this.setList_FileItems(items); }); + return Promise.resolve(); } @@ -47,7 +53,7 @@ export class FileSystemService { } public async getItems(path: FileSystemItem): Promise> { - //await this.updateLocalItems(); + await this.updateLocalItems(); const results = this.items.filter(value => value.path === path.path); const fileItems = results.map((fileItem) => { const item: THUMDER_FileItem = new THUMDER_FileItem(fileItem.path, fileItem.isDirectory, fileItem.pathKeys); @@ -72,7 +78,7 @@ export class FileSystemService { const newItem = new THUMDER_FileItem(path, false, pathKeys); newItem.key = Utils.uuidv4(); newItem.name = "New file - " + newItem.key + extension; - await this.fileSystemStorageService.addFileItem(newItem); + await this.fileSystemStorageService.createFileItem(newItem); this.updateUI$.next(); return Promise.resolve(true); } catch (error) { @@ -89,18 +95,20 @@ export class FileSystemService { item.dataItem.category = newCategory; this.items[index].dataItem.category = newCategory; const { $key } = this.items[index]; - await this.fileSystemStorageService.editFileItem(this.items[index], $key); + await this.fileSystemStorageService.updateFileItem($key, this.items[index]); } } this.updateUI$.next(); return Promise.resolve(items.length > 0); } - public async editFileItem(updateFileItem: InterfaceFileItem, $key: string): Promise { + public async editFileItem(updateFileItem: THUMDER_FileItem, $key: string): Promise { const index = this.items.findIndex(value => value.key === updateFileItem.key); if (index > -1) { + this.items[index] = FileSystemService.transform_InterfaceFileItem_to_THUMDER_FileItem(updateFileItem); + this.items[index].dateModified = new Date(); - await this.fileSystemStorageService.editFileItem(this.items[index], $key); + await this.fileSystemStorageService.updateFileItem($key, this.items[index]); this.updateUI$.next(); } return Promise.resolve(); @@ -111,7 +119,7 @@ export class FileSystemService { this.items[index].name = newName; this.items[index].dateModified = new Date(); const { $key } = this.items[index]; - await this.fileSystemStorageService.editFileItem(this.items[index], $key); + await this.fileSystemStorageService.updateFileItem($key, this.items[index]); this.updateUI$.next(); return Promise.resolve(this.items[index]); } @@ -145,26 +153,50 @@ export class FileSystemService { return Promise.resolve() } - private async updateItems(items: InterfaceFileItem[]): Promise { + private async setList_FileItems(items: THUMDER_FileItem[]): Promise { + // console.log({items: items}) for (const item of items) { - const { pathKeys, path, isDirectory }: InterfaceFileItem = item; + const { pathKeys, path, isDirectory, $key }: THUMDER_FileItem = item; const thumderFileItem = new THUMDER_FileItem(path, isDirectory, pathKeys); const newItem = Object.assign({}, thumderFileItem, { ...item }); + // newItem.$key = $key; const index = this.items.findIndex(value => value.key === newItem.key); if (index > -1) { this.items[index] = newItem; } else this.items.push(newItem); } + // console.log({this_items: this.items}) this.updateUI$.next(); return Promise.resolve(); } private async updateLocalItems(): Promise { - this.fileSystemStorageService.getAllFilesFromFirestoreAsObservable().subscribe((items) => { - this.items = []; - this.updateItems(items); - }); + await this.setList_FileItems(await this.fileSystemStorageService.getFiles()); return Promise.resolve(); } + + private static transform_InterfaceFileItem_to_THUMDER_FileItem(interfaceFileItem: InterfaceFileItem): THUMDER_FileItem { + const file = new THUMDER_FileItem( + interfaceFileItem.path, + interfaceFileItem.isDirectory, + interfaceFileItem.pathKeys + ); + + file.$key = interfaceFileItem.$key; + file.f_id = interfaceFileItem.f_id; + file.e1_uid = interfaceFileItem.e1_uid; + file.key = interfaceFileItem.key; + + file.name = interfaceFileItem.name; + file.content = interfaceFileItem.content; + file.description = interfaceFileItem.description; + file.dateModified = interfaceFileItem.dateModified; + file.size = interfaceFileItem.size; + file.isDirectory = interfaceFileItem.isDirectory; + file.hasSubDirectories = interfaceFileItem.hasSubDirectories; + file.thumbnail = interfaceFileItem.thumbnail; + file.dataItem = interfaceFileItem.dataItem; + return file; + } } diff --git a/src/app/__core/services/socket/socket-provider-connect.service.ts b/src/app/__core/services/socket/socket-provider-connect.service.ts index c64840c..7acc313 100644 --- a/src/app/__core/services/socket/socket-provider-connect.service.ts +++ b/src/app/__core/services/socket/socket-provider-connect.service.ts @@ -21,7 +21,7 @@ export class SocketProviderConnectService { constructor( private translate: TranslateService, private toast: ToastrService) { - console.log("constructor socket"); + const configWebSocket = JSON.parse(localStorage.getItem("web_socket_configuration")) as TypeWebSocketConfiguration; const config: SocketIoConfig = CONFIG_WEBSOCKET; config.url = configWebSocket.socket_url; @@ -41,7 +41,6 @@ export class SocketProviderConnectService { // When the client is in the process of connecting. this.socketIO.ioSocket.on("connecting", () => { console.debug("WebSocket-connecting"); - }); // When the client is disconnected. this.socketIO.ioSocket.on("disconnect", () => { @@ -114,6 +113,6 @@ export class SocketProviderConnectService { } private static handleErrors(err) { - console.error(err); + // console.error(err); } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 480095b..55f134d 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,9 +3,20 @@ import "../polyfills"; import { NgModule, SecurityContext } from "@angular/core"; import { RouterModule } from "@angular/router"; -import { AngularFireModule } from "@angular/fire"; -import { AngularFireAuthModule } from "@angular/fire/auth"; -import { AngularFirestoreModule } from "@angular/fire/firestore"; +import { AngularFireModule } from "@angular/fire/compat"; +import { AngularFireAnalyticsModule } from "@angular/fire/compat/analytics"; +import { AngularFireDatabaseModule } from '@angular/fire/compat/database'; +import { AngularFireStorageModule } from "@angular/fire/compat/storage"; +import { AngularFirestoreModule } from "@angular/fire/compat/firestore"; +import { AngularFireAuthModule } from "@angular/fire/compat/auth"; +import { provideFirebaseApp, getApp, initializeApp } from '@angular/fire/app'; +import { provideAuth, getAuth, initializeAuth } from "@angular/fire/auth"; +import { provideStorage, getStorage } from "@angular/fire/storage"; +import { provideFirestore, getFirestore, initializeFirestore } from '@angular/fire/firestore'; +import { provideAnalytics, getAnalytics, initializeAnalytics } from '@angular/fire/analytics'; +import { provideDatabase, getDatabase } from "@angular/fire/database"; +import { provideFunctions, getFunctions } from "@angular/fire/functions"; + import { MatTableModule } from "@angular/material/table"; import { MatSortModule } from "@angular/material/sort"; import { ScrollingModule } from "@angular/cdk/scrolling"; @@ -151,17 +162,17 @@ export function markedOptionsFactory(): MarkedOptions { // console.log(header, body); // console.log(`${ header }${ body }
`); // return defaultMarkedRenderer.table.call(this, header, body); - return `${ header }${ body }
`; + return `${header}${body}
`; }; markedRenderer.heading = (text: string, level: number) => { const escapedText = text.toLowerCase().replace(/[^\w]+/g, "-"); return ` - - + + - ${ text } -`; + ${text} +`; }; markedRenderer.link = (href: string, title: string, text: string) => { @@ -171,12 +182,12 @@ export function markedOptionsFactory(): MarkedOptions { const isElectron = window && window.process && window.process.type; if (isElectron) { if (href.startsWith("http://") || href.startsWith("https://")) { - return `${ text }`; + return `${text}`; } else if (href.indexOf("#") !== -1) { - return `${ text }`; + return `${text}`; } } else { - return `${ text }`; + return `${text}`; } }; @@ -191,6 +202,14 @@ export function markedOptionsFactory(): MarkedOptions { }; } +// const app = initializeApp(AppConfig.firebase); +// const auth = getAuth(app); +// const analytics = getAnalytics(app); +// const firebase_firestore = getFirestore(app); +// const firebase_storage = getStorage(app); +// const firebase_database = getDatabase(app); +// const firebase_functions = getFunctions(app); + @NgModule({ declarations: [ AppComponent, @@ -255,7 +274,7 @@ export function markedOptionsFactory(): MarkedOptions { loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, - deps: [ HttpClient ] + deps: [HttpClient] } }), // MonacoEditorModule, @@ -269,10 +288,27 @@ export function markedOptionsFactory(): MarkedOptions { // use forRoot() in main app module only. BrowserAnimationsModule, - AngularFireModule.initializeApp(AppConfig.firebase), - AngularFirestoreModule, - AngularFireAuthModule, - + // AngularFireModule, + // AngularFireModule.initializeApp(AppConfig.firebase), + // AngularFireAnalyticsModule, + // AngularFireDatabaseModule, + // AngularFireStorageModule, + // AngularFirestoreModule, + // AngularFireAuthModule, + provideFirebaseApp(() => initializeApp(AppConfig.firebase)), + provideAuth(() => getAuth()), + provideAnalytics(() => getAnalytics()), + provideFirestore(() => getFirestore()), + provideStorage(() => getStorage()), + provideDatabase(() => getDatabase()), + provideFunctions(() => getFunctions()), + // provideFirebaseApp(() => app), + // provideAuth(() => auth), + // provideAnalytics(() => analytics), + // provideFirestore(() => firebase_firestore), + // provideStorage(() => firebase_storage), + // provideDatabase(() => firebase_database), + // provideFunctions(() => firebase_functions), MatSortModule, MatTableModule, ScrollingModule, diff --git a/src/app/components/monaco-editor/monaco-editor.component.html b/src/app/components/monaco-editor/monaco-editor.component.html index a257c6d..0748d55 100644 --- a/src/app/components/monaco-editor/monaco-editor.component.html +++ b/src/app/components/monaco-editor/monaco-editor.component.html @@ -11,7 +11,7 @@ theme="thumderTheme" language="thumderLanguage" [editorOptions]="EDITOR_OPTIONS_THUMDER" - [(ngModel)]="file.content" + [(ngModel)]="editorFile.content" (ngModelChange)="callBackFunc($event)" (editorInitialized)="editorInitialized($any($event))" (editorConfigurationChanged)="editorConfigurationChanged()" diff --git a/src/app/components/monaco-editor/monaco-editor.component.ts b/src/app/components/monaco-editor/monaco-editor.component.ts index d02f530..c5862ac 100644 --- a/src/app/components/monaco-editor/monaco-editor.component.ts +++ b/src/app/components/monaco-editor/monaco-editor.component.ts @@ -19,8 +19,8 @@ export class MonacoEditorComponent implements OnInit, AfterViewInit, OnDestroy { public _height = 70; // public content: string = ""; - public file: THUMDER_FileItem = new THUMDER_FileItem("", false, []); - public breakpoints: TypeBreakpoints = {}; + public editorFile: THUMDER_FileItem = new THUMDER_FileItem("", false, []); + private breakpoints: TypeBreakpoints = {}; private editor: IStandaloneCodeEditor; private oldDecorationDebugTag_targetId: string[] = []; private oldDecorationDebugLine: string[] = []; @@ -29,7 +29,7 @@ export class MonacoEditorComponent implements OnInit, AfterViewInit, OnDestroy { public initialized$: Subject = new Subject(); public breakpoints$: Subject = new Subject(); public componentStatus$: Subject = new Subject(); - public fileSave$: Subject = new Subject(); + public editorFileSave$: Subject = new Subject(); constructor() { } @@ -58,9 +58,9 @@ export class MonacoEditorComponent implements OnInit, AfterViewInit, OnDestroy { editorInitialized($event: IStandaloneCodeEditor): void { this.editor = $event; this.editor.layout(); - this.editor.updateOptions({ readOnly: this.file.$key == "" }); + this.editor.updateOptions({ readOnly: this.editorFile.$key == "" }); this.editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_S, async () => { - await this.save(); + this.save(); }); this.editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_D, () => { this.toggleDebuggerTag(); @@ -87,13 +87,13 @@ export class MonacoEditorComponent implements OnInit, AfterViewInit, OnDestroy { return this.componentStatus$.asObservable(); } - getFileSaveObservable(): Observable { - return this.fileSave$.asObservable(); + getFileSaveStorageObservable(): Observable { + return this.editorFileSave$.asObservable(); } - async updateContent(content: string): Promise { - this.file.content = content; - this.editor.setValue(this.file.content); + async setEditorContent(content: string): Promise { + this.editorFile.content = content; + this.editor.setValue(this.editorFile.content); return Promise.resolve(); } @@ -233,14 +233,12 @@ export class MonacoEditorComponent implements OnInit, AfterViewInit, OnDestroy { monaco.editor.setModelMarkers(this.editor.getModel(), "IDK", markers) } - public async save(): Promise { - if (this.file.$key === "") { - console.warn("Debes crear un fichero antes de guardarlo"); - return Promise.resolve(); + private updatedEditorFile() { + if (this.editorFile.$key === "") { + throw new Error("Debes crear un fichero antes de guardarlo"); } - localStorage.setItem("interfaceFileItem", JSON.stringify(this.file)); - this.fileSave$.next(this.file); - return Promise.resolve(); + console.log("editorFile", this.editorFile) + this.editorFile.content = this.editor?.getModel()?.getLinesContent()?.join("\n") ?? ""; } public async setBreakpoints(breakpoints: TypeBreakpoints): Promise { @@ -251,26 +249,39 @@ export class MonacoEditorComponent implements OnInit, AfterViewInit, OnDestroy { return Promise.resolve(); } - public async updateFile(fileItem: InterfaceFileItem): Promise { - console.log(this.file, fileItem); - this.file.$key = fileItem.$key; - this.file.f_id = fileItem.f_id; - this.file.e1_uid = fileItem.e1_uid; - this.file.key = fileItem.key; - this.file.pathKeys = fileItem.pathKeys; - this.file.path = fileItem.path; - this.file.name = fileItem.name; - this.file.content = fileItem.content; - this.file.description = fileItem.description; - this.file.dateModified = fileItem.dateModified; - this.file.size = fileItem.size; - this.file.isDirectory = fileItem.isDirectory; - this.file.hasSubDirectories = fileItem.hasSubDirectories; - this.file.thumbnail = fileItem.thumbnail; - this.file.dataItem = fileItem.dataItem; - - this.editor.updateOptions({ readOnly: this.file.$key == "" }); + public getBreakpoints(): TypeBreakpoints { + return this.breakpoints + } + + public async setEditorFile(fileItem: InterfaceFileItem): Promise { + console.log(this.editorFile, fileItem); + this.editorFile.$key = fileItem.$key; + this.editorFile.f_id = fileItem.f_id; + this.editorFile.e1_uid = fileItem.e1_uid; + this.editorFile.key = fileItem.key; + this.editorFile.pathKeys = fileItem.pathKeys; + this.editorFile.path = fileItem.path; + this.editorFile.name = fileItem.name; + this.editorFile.content = fileItem.content; + this.editorFile.description = fileItem.description; + this.editorFile.dateModified = fileItem.dateModified; + this.editorFile.size = fileItem.size; + this.editorFile.isDirectory = fileItem.isDirectory; + this.editorFile.hasSubDirectories = fileItem.hasSubDirectories; + this.editorFile.thumbnail = fileItem.thumbnail; + this.editorFile.dataItem = fileItem.dataItem; + + this.editor.updateOptions({ readOnly: this.editorFile.$key == "" }); return Promise.resolve(); } + + public getEditorFile():THUMDER_FileItem { + return this.editorFile; + } + + public save() { + this.updatedEditorFile(); + this.editorFileSave$.next(this.editorFile); + } } diff --git a/src/app/components/navbars/auth-navbar/auth-navbar.component.html b/src/app/components/navbars/auth-navbar/auth-navbar.component.html index 36bc65b..489c5a3 100644 --- a/src/app/components/navbars/auth-navbar/auth-navbar.component.html +++ b/src/app/components/navbars/auth-navbar/auth-navbar.component.html @@ -52,11 +52,14 @@ - + + + + diff --git a/src/app/components/navbars/auth-navbar/auth-navbar.component.ts b/src/app/components/navbars/auth-navbar/auth-navbar.component.ts index d91afa9..2fa9e6c 100644 --- a/src/app/components/navbars/auth-navbar/auth-navbar.component.ts +++ b/src/app/components/navbars/auth-navbar/auth-navbar.component.ts @@ -7,6 +7,7 @@ import { AuthService } from "../../../__core/auth/auth.service"; import { MachineService } from "../../../__core/machine/machine.service"; import { PublicRoutes } from "../../../Types"; import { AUTH_ROUTES } from "../../../CONSTANTS"; +import { AppConfig } from "../../../../environments/_environment"; @Component({ selector: "app-auth-navbar", @@ -14,6 +15,7 @@ import { AUTH_ROUTES } from "../../../CONSTANTS"; }) export class AuthNavbarComponent implements OnInit, OnDestroy, AfterViewInit { public readonly PRIVATE_AUTH_ROUTES = Object.values(AUTH_ROUTES); + public readonly isDEV = AppConfig.environment === "DEV"; public navbarOpen = false; public isRunning = false; public colorWebsocketStatus: string = "orange"; diff --git a/src/app/views/_auth/_views/multiples-views.component.ts b/src/app/views/_auth/_views/multiples-views.component.ts index c565f17..4ecb3bf 100644 --- a/src/app/views/_auth/_views/multiples-views.component.ts +++ b/src/app/views/_auth/_views/multiples-views.component.ts @@ -1,4 +1,4 @@ -import { AfterViewInit, Component, OnInit, QueryList, ViewChildren } from "@angular/core"; +import { AfterViewInit, Component, OnDestroy, OnInit, QueryList, ViewChildren } from "@angular/core"; import { TypeMultiviewConfiguration } from "../../../Types"; import { CdkDragDrop, @@ -15,7 +15,7 @@ import { DEFAULT_MULTIVIEW_CONFIGURATION } from "../../../CONSTANTS"; templateUrl: "./multiples-views.component.html", styleUrls: [] }) -export class MultiplesViewsComponent implements OnInit, AfterViewInit { +export class MultiplesViewsComponent implements OnInit, AfterViewInit, OnDestroy { @ViewChildren(CdkDrag) draggable_list: QueryList; public multiviewConfiguration: TypeMultiviewConfiguration = DEFAULT_MULTIVIEW_CONFIGURATION; public main_list_1 = []; @@ -45,6 +45,10 @@ export class MultiplesViewsComponent implements OnInit, AfterViewInit { }); } + ngOnDestroy(): void { + + } + private static closeAllCards() { window.jQuery(".card").not("#card-debug").CardWidget("collapse"); } diff --git a/src/app/views/_auth/editor/editor.view.html b/src/app/views/_auth/editor/editor.view.html index de98b7f..e90e902 100644 --- a/src/app/views/_auth/editor/editor.view.html +++ b/src/app/views/_auth/editor/editor.view.html @@ -13,7 +13,7 @@

{{ 'NAVIGATION.EDITOR' | translate }} | {{ interfaceFileI - @@ -37,12 +37,12 @@

{{ 'NAVIGATION.EDITOR' | translate }} | {{ interfaceFileI
-  $Key: {{interfaceFileItem.$key ?? ''}}
-  User: {{interfaceFileItem.e1_uid ?? ''}}
-  Key: {{interfaceFileItem.key ?? ''}}
-  Name: {{interfaceFileItem.name ?? ''}}
-  Path: {{interfaceFileItem.path ?? ''}}
-  Date modified: {{(interfaceFileItem?.dateModified ?? date) | date: "yyyy-MM-dd HH:mm:ss"}}
+$Key: {{interfaceFileItem.$key ?? ''}}
+User: {{interfaceFileItem.e1_uid ?? ''}}
+Key: {{interfaceFileItem.key ?? ''}}
+Name: {{interfaceFileItem.name ?? ''}}
+Path: {{interfaceFileItem.path ?? ''}}
+Date modified: {{(interfaceFileItem?.dateModified ?? date) | date: "yyyy-MM-dd HH:mm:ss"}}
 
diff --git a/src/app/views/_auth/editor/editor.view.ts b/src/app/views/_auth/editor/editor.view.ts index 69b131a..d2ca481 100644 --- a/src/app/views/_auth/editor/editor.view.ts +++ b/src/app/views/_auth/editor/editor.view.ts @@ -24,7 +24,9 @@ export class EditorView implements OnInit, AfterViewInit, OnDestroy { private initializedSubscription: Subscription = new Subscription(); private breakpointSubscription: Subscription = new Subscription(); private debuggerSubscription: Subscription = new Subscription(); + private fileSaveSubscription: Subscription = new Subscription(); private lineSubscription: Subscription = new Subscription(); + private readonly extrasIDE: TypeExtrasIDE; public date: Date = new Date(); @@ -55,12 +57,21 @@ export class EditorView implements OnInit, AfterViewInit, OnDestroy { ngAfterViewInit(): void { this.initializedSubscription = this.monacoEditorComponent.getInitializedObservable().subscribe(async (isInitialized) => { if (isInitialized) { - this.interfaceFileItem = (this.extrasIDE?.interfaceFileItem ?? JSON.parse(localStorage.getItem("interfaceFileItem")) ?? DEFAULT_INTERFACE_FILE_ITEM) as InterfaceFileItem; + this.interfaceFileItem = ( + this.extrasIDE?.interfaceFileItem ?? + JSON.parse(localStorage.getItem("interfaceFileItem")) ?? + DEFAULT_INTERFACE_FILE_ITEM + ) as InterfaceFileItem; + // console.log({ + // extra: this.extrasIDE?.interfaceFileItem, + // local: JSON.parse(localStorage.getItem("interfaceFileItem")), + // default_interface: DEFAULT_INTERFACE_FILE_ITEM + // }); + await this.monacoEditorComponent.setEditorFile(this.interfaceFileItem); + await this.monacoEditorComponent.setEditorContent(this.interfaceFileItem.content); + const breakpoints = JSON.parse(localStorage.getItem("breakpoints")) as TypeBreakpoints ?? {}; - await this.monacoEditorComponent.updateFile(this.interfaceFileItem); - await this.monacoEditorComponent.updateContent(this.interfaceFileItem.content); await this.monacoEditorComponent.setBreakpoints(breakpoints); - return Promise.resolve(); } }); this.breakpointSubscription = this.monacoEditorComponent.getBreakpointsObservable().subscribe((breakpoints) => { @@ -79,38 +90,25 @@ export class EditorView implements OnInit, AfterViewInit, OnDestroy { this.monacoEditorComponent.printLine(line); } }); - this.monacoEditorComponent.getFileSaveObservable().subscribe(async (interfaceFileItem) => { - try { - await this.fileSystem.editFileItem(interfaceFileItem, interfaceFileItem.$key); - const title = await this.translate.get("TOAST.TITLE_SAVE_FILE").toPromise(); - const message = await this.translate.get("TOAST.MESSAGE_SAVE_FILE").toPromise(); - this.toastService.success(message, title, { - timeOut: 1500, - positionClass: "toast-bottom-left" - }); - } catch (error) { - console.error(error); - const title = await this.translate.get("TOAST.TITLE_ERROR_SAVE_FILE").toPromise(); - const message = await this.translate.get("TOAST.MESSAGE_ERROR_SAVE_FILE").toPromise(); - this.toastService.error(message, title, { - timeOut: 2500, - positionClass: "toast-bottom-left" - }); - } + this.fileSaveSubscription = this.monacoEditorComponent.getFileSaveStorageObservable().subscribe(async (editorFile) => { + await this.saveFileInLocalStorage(editorFile); + await this.saveFileInCloudStorage(editorFile); }); } async ngOnDestroy(): Promise { - const auto_save = localStorage.getItem("auto_save_configuration") ?? false; + const auto_save = JSON.parse(localStorage.getItem("auto_save_configuration") ?? "false"); if (auto_save) { - localStorage.setItem("breakpoints", JSON.stringify(this.monacoEditorComponent.breakpoints)); - await this.save(); + const breakpoints = this.monacoEditorComponent.getBreakpoints(); + localStorage.setItem("breakpoints", JSON.stringify(breakpoints)); + await this.closeAndSave() } else { localStorage.setItem("breakpoints", JSON.stringify({})); } this.initializedSubscription.unsubscribe(); this.breakpointSubscription.unsubscribe(); this.debuggerSubscription.unsubscribe(); + this.fileSaveSubscription.unsubscribe(); this.lineSubscription.unsubscribe(); return Promise.resolve(); } @@ -129,8 +127,36 @@ export class EditorView implements OnInit, AfterViewInit, OnDestroy { this.monacoEditorComponent.height = 1000; } - public async save(): Promise { - await this.monacoEditorComponent.save(); - return Promise.resolve(); + + public async closeAndSave() { + const editorFile = await this.monacoEditorComponent.getEditorFile(); + + await this.saveFileInLocalStorage(editorFile); + await this.saveFileInCloudStorage(editorFile); + } + + private async saveFileInLocalStorage(editorFile: THUMDER_FileItem) { + localStorage.setItem("interfaceFileItem", JSON.stringify(editorFile)); + } + + private async saveFileInCloudStorage(editorFile: THUMDER_FileItem) { + try { + await this.fileSystem.editFileItem(editorFile, editorFile.$key); + + const title = await this.translate.get("TOAST.TITLE_SAVE_FILE").toPromise(); + const message = await this.translate.get("TOAST.MESSAGE_SAVE_FILE").toPromise(); + this.toastService.success(message, title, { + timeOut: 1500, + positionClass: "toast-bottom-left" + }); + } catch (error) { + console.error(error); + const title = await this.translate.get("TOAST.TITLE_ERROR_SAVE_FILE").toPromise(); + const message = await this.translate.get("TOAST.MESSAGE_ERROR_SAVE_FILE").toPromise(); + this.toastService.error(message, title, { + timeOut: 2500, + positionClass: "toast-bottom-left" + }); + } } } diff --git a/src/app/views/_auth/file-manager/file-manager.view.ts b/src/app/views/_auth/file-manager/file-manager.view.ts index 2b55c61..746378c 100644 --- a/src/app/views/_auth/file-manager/file-manager.view.ts +++ b/src/app/views/_auth/file-manager/file-manager.view.ts @@ -7,6 +7,7 @@ import CustomFileSystemProvider from "devextreme/file_management/custom_provider import FileSystemItem from "devextreme/file_management/file_system_item"; import FileManager from "devextreme/ui/file_manager"; import { Subscription } from "rxjs"; +import { getDoc } from "@angular/fire/firestore"; export type FileMenuOptions = { items: { @@ -138,7 +139,7 @@ export class FileManagerView implements OnInit, OnDestroy { } public onSelectedFileOpened($event: TypeEventSelectedFileOpened): void { - const index = this.fileSystemService.items.findIndex(value => $event.file.key === value.key); + const index = this.fileSystemService.items.findIndex((value) => $event.file.key === value.key); if (index > -1) { const interfaceFileItem = this.fileSystemService.items[index]; const extras: NavigationExtras = { @@ -188,12 +189,12 @@ export class FileManagerView implements OnInit, OnDestroy { } public debug(): void { - this.fileSystemService.fileSystemStorageService.collectionFileItems().valueChanges().subscribe((i) => { + this.fileSystemService.fileSystemStorageService.FileItems_Collections_valueChanges().subscribe((i) => { console.log(i); }); } public async tests() { - await this.fileSystemService.fileSystemStorageService.getAllFilesFromFirestoreAsObservable(); + await this.fileSystemService.fileSystemStorageService.getFiles(); } }