mirror of
https://code.equilibrium.co.ao/ITO/doneit-web.git
synced 2026-04-18 20:47:54 +00:00
fix donwload attachment and modal to edit message
This commit is contained in:
+2
-1
@@ -36,7 +36,8 @@
|
||||
"output": "./svg"
|
||||
},
|
||||
"src/manifest.webmanifest",
|
||||
"src/firebase-messaging-sw.js"
|
||||
"src/firebase-messaging-sw.js",
|
||||
"src/shared-worker.js"
|
||||
],
|
||||
"styles": [
|
||||
"./node_modules/@angular/material/prebuilt-themes/pink-bluegrey.css",
|
||||
|
||||
@@ -14,14 +14,18 @@ export enum MessageAttachmentFileType {
|
||||
Video
|
||||
}
|
||||
|
||||
export enum IMessageType {
|
||||
normal =1,
|
||||
information
|
||||
}
|
||||
|
||||
export const MessageEntitySchema = z.object({
|
||||
$id: z.any().optional(),
|
||||
id: z.string().optional(),
|
||||
roomId: z.string().uuid().optional(),
|
||||
receiverId: z.number().optional(),
|
||||
message: z.string().optional(),
|
||||
messageType: z.number(),
|
||||
message: z.string().nullable().optional(),
|
||||
messageType: z.nativeEnum(IMessageType),
|
||||
canEdit: z.boolean(),
|
||||
oneShot: z.boolean(),
|
||||
sentAt: z.string().optional(),
|
||||
@@ -56,7 +60,7 @@ export const MessageEntitySchema = z.object({
|
||||
id: z.string().optional(),
|
||||
mimeType: z.string().optional(),
|
||||
safeFile: z.any().optional(),
|
||||
description: z.string().optional()
|
||||
description: z.string().nullable().optional()
|
||||
})).optional()
|
||||
})
|
||||
|
||||
@@ -69,7 +73,6 @@ export class MessageEntity {
|
||||
roomId?: string
|
||||
receiverId?: number
|
||||
message?: string
|
||||
messageType: number = 0
|
||||
canEdit: boolean = false
|
||||
oneShot: boolean = false
|
||||
sentAt?: string
|
||||
@@ -78,7 +81,7 @@ export class MessageEntity {
|
||||
sender!: typeof MessageEntitySchema._type.sender
|
||||
sending: boolean = false
|
||||
sendAttemp = 0
|
||||
|
||||
messageType = IMessageType.normal
|
||||
attachments: typeof MessageEntitySchema._type.attachments = []
|
||||
reactions: typeof MessageEntitySchema._type.reactions = []
|
||||
requestId!: string
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { DataSourceReturn } from "src/app/services/Repositorys/type";
|
||||
import { IMessageGetAllByRoomIdOutPut } from "../../usecase/message/message-get-all-by-room-Id";
|
||||
|
||||
export abstract class IAttachmentRemoteRepository {
|
||||
abstract getAttachment(id: string | number): DataSourceReturn<Blob>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
import { MessageTable } from "src/app/infra/database/dexie/instance/chat/schema/message";
|
||||
import { DexieRepository } from "src/app/infra/repository/dexie/dexie-repository.service";
|
||||
import { MessageEntity } from "../../entity/message";
|
||||
import { Observable as DexieObservable, PromiseExtended } from 'Dexie';
|
||||
import { AttachmentTable } from "src/app/infra/database/dexie/instance/chat/schema/attachment";
|
||||
import { Result } from "neverthrow";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import { DataSourceReturn } from "src/app/services/Repositorys/type";
|
||||
import { IMessageGetAllByRoomIdOutPut } from "../../usecase/message/message-get-all-by-room-Id";
|
||||
import { Observable } from "rxjs";
|
||||
import { Result } from "neverthrow";
|
||||
import { UserTypingDTO } from "src/app/module/chat/data/repository/typing/user-typing-live-data-source.service";
|
||||
|
||||
@@ -7,7 +7,8 @@ export const AttachmentTableSchema = z.object({
|
||||
$id: z.number().optional(), // local id
|
||||
$messageId: z.number(),
|
||||
attachmentId: z.string().optional(),
|
||||
file: zodDataUrlSchema,
|
||||
file: z.instanceof(Blob),
|
||||
base64: zodDataUrlSchema.nullable().optional(),
|
||||
//
|
||||
fileType: z.nativeEnum(MessageAttachmentFileType),
|
||||
source: z.nativeEnum(MessageAttachmentSource),
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
import { EntityTable } from 'Dexie';
|
||||
import { z } from 'zod';
|
||||
|
||||
export const DistributionTableSchema = z.object({
|
||||
$id: z.string(),
|
||||
memberId: z.number(),
|
||||
readAt: z.string().nullable(),
|
||||
deliverAt: z.string().nullable()
|
||||
})
|
||||
|
||||
export type DistributionTable = z.infer<typeof DistributionTableSchema>
|
||||
export type DexieDistributionTable = EntityTable<DistributionTable, '$id'>;
|
||||
export const DistributionTableColumn = '++$id, messageId, memberId, readAt, deliverAt'
|
||||
@@ -1,20 +1,51 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>Edit Message</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button (click)="dismiss()">Close</ion-button>
|
||||
</ion-buttons>
|
||||
<ion-header class="ion-no-border">
|
||||
<ion-toolbar class="header-toolbar">
|
||||
<div class="main-header">
|
||||
<div class="title-content width-100">
|
||||
<div class="back-icon">
|
||||
<!-- <ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="end" src='assets/images/Theme/doneIt/icons-arrow-arrow-left.svg'></ion-icon>
|
||||
<button class="btn-no-color cursor-pointer" >
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'doneIt' " slot="end" src='assets/images/theme/{{ThemeService.currentTheme}}/icons-arrow-arrow-left.svg'></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'default' " slot="end" src='assets/images/icons-arrow-arrow-left.svg'></ion-icon>
|
||||
<ion-icon *ngIf="ThemeService.currentTheme == 'gov' " slot="end" src='assets/images/theme/gov/icons-calendar-arrow-left.svg'></ion-icon>
|
||||
</button> -->
|
||||
</div>
|
||||
<div class="div-title">
|
||||
<ion-label class="title">Editar Mensagem</ion-label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content>
|
||||
<form (ngSubmit)="save()" #editForm="ngForm">
|
||||
<ion-item>
|
||||
<ion-label position="floating">Edit Message</ion-label>
|
||||
<ion-input [(ngModel)]="message" name="text" required></ion-input>
|
||||
</ion-item>
|
||||
<ion-footer>
|
||||
<ion-button expand="full" type="submit" [disabled]="!editForm.form.valid">Save</ion-button>
|
||||
</ion-footer>
|
||||
</form>
|
||||
<div class="main-content">
|
||||
|
||||
<div class="old-message-container d-flex justify-center">
|
||||
<div class="old-message">{{ oldMessage }}</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="type-message mt-40-em">
|
||||
<ion-textarea #messageInput clearOnEdit="true" placeholder="Escrever uma mensagem" class="message-input" rows="1" [(ngModel)]="message" (keyup.enter)="save()" ></ion-textarea>
|
||||
</div>
|
||||
</div>
|
||||
</ion-content>
|
||||
|
||||
<ion-footer class="ion-no-border">
|
||||
<ion-toolbar class="footer-toolbar px-20">
|
||||
<ion-buttons slot="start">
|
||||
<button class="btn-ok" fill="clear" color="#fff" (click)="save()">
|
||||
<ion-label>Enviar</ion-label>
|
||||
</button>
|
||||
</ion-buttons>
|
||||
<ion-buttons slot="end">
|
||||
<button class="btn-cancel" fill="clear" color="#061b52" (click)="dismiss()" >
|
||||
<ion-label>Cancelar</ion-label>
|
||||
</button>
|
||||
</ion-buttons>
|
||||
|
||||
</ion-toolbar>
|
||||
</ion-footer>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
@import '~src/function.scss';
|
||||
|
||||
.header-toolbar{
|
||||
--background:transparent;
|
||||
--opacity: 1;
|
||||
|
||||
.main-header{
|
||||
width: 100%; /* 400px */
|
||||
height: 100%;
|
||||
font-family: Roboto;
|
||||
border-top-left-radius: 25px;
|
||||
border-top-right-radius: 25px;
|
||||
background-color: #fff;
|
||||
overflow:hidden;
|
||||
padding: 30px 20px 0px 20px;
|
||||
color:#000;
|
||||
transform: translate3d(0, 1px, 0);
|
||||
|
||||
.div-icon{
|
||||
width: rem(40);
|
||||
float: right;
|
||||
font-size: rem(35);
|
||||
overflow: auto;
|
||||
padding: 1px;
|
||||
}
|
||||
.div-icon ion-icon{
|
||||
float: right;
|
||||
padding-left: 20px;
|
||||
}
|
||||
.title-content{
|
||||
margin: 0px auto;
|
||||
overflow: auto;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
.back-icon{
|
||||
width: 37px;
|
||||
float: left;
|
||||
font-size: rem(35);
|
||||
overflow: auto;
|
||||
|
||||
}
|
||||
.div-title{
|
||||
width: calc(100% - 45px);
|
||||
padding: 0!important;
|
||||
float: left;
|
||||
margin: 2.5px 0 0 5px;
|
||||
}
|
||||
.title{
|
||||
font-size: rem(25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ion-content{
|
||||
--background:transparent;
|
||||
}
|
||||
.main-content{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-family: Roboto;
|
||||
margin: 0 auto;
|
||||
background-color: #fff;
|
||||
overflow:auto;
|
||||
padding: 0 0 0 0;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.type-message {
|
||||
display: flex;
|
||||
border: 1px solid #ebebeb;
|
||||
border-radius: 25px;
|
||||
margin: 0 30px 0 30px;
|
||||
align-items: center;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.old-message-container {
|
||||
padding: 40px;
|
||||
}
|
||||
.old-message {
|
||||
font-size: rem(13);
|
||||
font-family: Roboto;
|
||||
overflow: auto;
|
||||
background: var(--chat-incoming-msg-color);
|
||||
border-radius: 10px;
|
||||
display: inline;
|
||||
padding: 10px 20px;
|
||||
}
|
||||
|
||||
:host {
|
||||
height: 400px;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Component, OnInit, Input, ViewChild, ElementRef } from '@angular/core';
|
||||
import { ModalController } from '@ionic/angular';
|
||||
|
||||
import { ThemeService } from 'src/app/services/theme.service'
|
||||
|
||||
@Component({
|
||||
selector: 'app-edit-message',
|
||||
@@ -9,15 +9,23 @@ import { ModalController } from '@ionic/angular';
|
||||
})
|
||||
export class EditMessagePage implements OnInit {
|
||||
|
||||
@ViewChild('messageInput', { static: false }) messageInput!: ElementRef<HTMLIonTextareaElement>;
|
||||
@Input() message: string;
|
||||
@Input() roomId: any;
|
||||
|
||||
oldMessage: string
|
||||
|
||||
constructor(
|
||||
private modalController: ModalController
|
||||
) { }
|
||||
private modalController: ModalController,
|
||||
public ThemeService: ThemeService,
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
this.oldMessage = this.message
|
||||
}
|
||||
ngAfterViewInit() {
|
||||
// Focus the textarea once the view has been initialized
|
||||
this.messageInput.nativeElement.focus();
|
||||
}
|
||||
|
||||
dismiss() {
|
||||
|
||||
@@ -7,10 +7,30 @@ import { Subject, timer } from 'rxjs';
|
||||
import { UserTypingLocalRepository } from './data/repository/typing/user-typing-local-data-source.service';
|
||||
import { UserTypingRemoteRepositoryService } from './data/repository/typing/user-typing-live-data-source.service';
|
||||
import { RoomService } from 'src/app/module/chat/domain/service/room.service'
|
||||
import { HttpListenToMessageLoadHistoryAdapter, SocketOnReconnectAdapter } from './domain/adapter';
|
||||
import { HttpListenToMessageLoadHistoryAdapter } from './domain/adapter';
|
||||
import { ISignalRService } from 'src/app/infra/socket/adapter';
|
||||
import { HttpModule } from 'src/app/infra/http/http.module';
|
||||
import { HttpListenToMessageLoadHistoryUseCase } from 'src/app/core/chat/usecase/message/http-listen-to-message-load-history-use-case';
|
||||
import { IMessageLocalRepository } from 'src/app/core/chat/repository/message/message-local-repository';
|
||||
import { MessageLocalDataSourceService } from './data/repository/message/message-local-data-source.service';
|
||||
import { MessageRemoteDataSourceService } from './data/repository/message/message-remote-data-source.service';
|
||||
import { IMessageRemoteRepository } from 'src/app/core/chat/repository/message/message-remote-repository';
|
||||
import { IMessageSocketRepository } from 'src/app/core/chat/repository/message/message-socket-repository';
|
||||
import { MessageSocketRepositoryService } from './data/repository/message/message-live-signalr-data-source.service';
|
||||
import { MemberListLocalRepository } from './data/repository/member/member-list-local-repository.service';
|
||||
import { IMemberLocalRepository } from 'src/app/core/chat/repository/member/member-local-repository';
|
||||
import { MemberListRemoteRepository } from './data/repository/member/member-list-remote-repository.service';
|
||||
import { IMemberRemoteRepository } from 'src/app/core/chat/repository/member/member-remote-repository';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
import { RoomLocalRepository } from './data/repository/room/room-local-repository.service';
|
||||
import { RoomRemoteDataSourceService } from './data/repository/room/room-remote-repository.service';
|
||||
import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-remote-repository';
|
||||
import { RoomSocketRepositoryService } from './data/repository/room/room-socket-repository.service';
|
||||
import { IRoomSocketRepository } from 'src/app/core/chat/repository/room/room-socket-repository';
|
||||
import { IAttachmentLocalRepository } from 'src/app/core/chat/repository/typing/typing-local-repository';
|
||||
import { AttachmentLocalDataSource } from './data/repository/attachment/attachment-local-repository.service';
|
||||
import { IAttachmentRemoteRepository } from 'src/app/core/chat/repository/attachment/attachment-remote-repository';
|
||||
import { AttachmentRemoteDataSourceService } from './data/repository/attachment/attachment-remote-repository.service';
|
||||
@NgModule({
|
||||
imports: [HttpModule],
|
||||
providers: [
|
||||
@@ -22,6 +42,50 @@ import { HttpListenToMessageLoadHistoryUseCase } from 'src/app/core/chat/usecase
|
||||
provide: HttpListenToMessageLoadHistoryAdapter,
|
||||
useClass: HttpListenToMessageLoadHistoryUseCase, // or MockDataService
|
||||
},
|
||||
// message repository
|
||||
{
|
||||
provide: IMessageLocalRepository,
|
||||
useClass: MessageLocalDataSourceService
|
||||
},
|
||||
{
|
||||
provide: IMessageRemoteRepository,
|
||||
useClass: MessageRemoteDataSourceService
|
||||
},
|
||||
{
|
||||
provide: IMessageSocketRepository,
|
||||
useClass: MessageSocketRepositoryService
|
||||
},
|
||||
// member repository
|
||||
{
|
||||
provide: IMemberLocalRepository,
|
||||
useClass: MemberListLocalRepository
|
||||
},
|
||||
{
|
||||
provide: IMemberRemoteRepository,
|
||||
useClass: MemberListRemoteRepository
|
||||
},
|
||||
// room repository
|
||||
{
|
||||
provide: IRoomLocalRepository,
|
||||
useClass: RoomLocalRepository
|
||||
},
|
||||
{
|
||||
provide: IRoomRemoteRepository,
|
||||
useClass: RoomRemoteDataSourceService
|
||||
},
|
||||
{
|
||||
provide: IRoomSocketRepository,
|
||||
useClass: RoomSocketRepositoryService
|
||||
},
|
||||
// attachment
|
||||
{
|
||||
provide: IAttachmentLocalRepository,
|
||||
useClass: AttachmentLocalDataSource
|
||||
},
|
||||
{
|
||||
provide: IAttachmentRemoteRepository,
|
||||
useClass: AttachmentRemoteDataSourceService
|
||||
},
|
||||
],
|
||||
declarations: [],
|
||||
schemas: [],
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { liveQuery } from 'Dexie';
|
||||
import { err, ok, Result } from 'neverthrow';
|
||||
import { Observable, Subject } from 'rxjs';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { MessageEntity } from '../../../../../core/chat/entity/message';
|
||||
import { DexieRepository } from 'src/app/infra/repository/dexie/dexie-repository.service';
|
||||
import { Observable as DexieObservable, PromiseExtended } from 'Dexie';
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Result } from 'neverthrow';
|
||||
import { HttpService } from 'src/app/services/http.service';
|
||||
import { AddMemberToRoomInputDTO, AddMemberToRoomInputDTOSchema } from '../../../domain/use-case/member/member-add-use-case.service';
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
import { APIReturn } from 'src/app/services/decorators/api-validate-schema.decorator';
|
||||
import { AddMemberToRoomInputDTO } from '../../../domain/use-case/member/member-add-use-case.service';
|
||||
import { DataSourceReturn } from 'src/app/services/Repositorys/type';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { MemberSetAdminDTO } from '../../../domain/use-case/member/member-admin-use-case.service';
|
||||
import { SignalRService } from 'src/app/infra/socket/signalR/signal-r.service';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { CreateRoomInputDTOSchema, CreateRoomInputDTO, RoomOutPutDTOSchema, RoomOutPutDTO } from '../../../domain/use-case/room/room-create-use-case.service';
|
||||
import { CreateRoomInputDTO, RoomOutPutDTO } from '../../../domain/use-case/room/room-create-use-case.service';
|
||||
import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-remote-repository';
|
||||
import { RoomByIdInputDTO, RoomByIdInputDTOSchema, RoomByIdOutputDTO, RoomByIdOutputDTOSchema } from 'src/app/module/chat/domain/use-case/room/room-get-by-id-use-case.service';
|
||||
import { RoomUpdateInputDTO, RoomUpdateInputDTOSchema, RoomUpdateOutputDTO } from 'src/app/module/chat/domain/use-case/room/room-update-by-id-use-case.service';
|
||||
import { RoomListOutPutDTO, RoomListOutPutDTOSchema } from '../../../domain/use-case/room/room-get-list-use-case.service';
|
||||
import { RoomByIdOutputDTO } from 'src/app/module/chat/domain/use-case/room/room-get-by-id-use-case.service';
|
||||
import { RoomUpdateInputDTO, RoomUpdateOutputDTO } from 'src/app/module/chat/domain/use-case/room/room-update-by-id-use-case.service';
|
||||
import { RoomListOutPutDTO } from '../../../domain/use-case/room/room-get-list-use-case.service';
|
||||
import { z } from 'zod';
|
||||
|
||||
const RoomByIdInputDTOSchema = z.string()
|
||||
type RoomByIdInputDTO = z.infer<typeof RoomByIdInputDTOSchema>
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -28,25 +30,25 @@ export class RoomRemoteDataSourceService implements IRoomRemoteRepository {
|
||||
) {}
|
||||
|
||||
|
||||
@ValidateSchema(CreateRoomInputDTOSchema)
|
||||
@APIReturn(RoomOutPutDTOSchema, 'post/Room')
|
||||
//@ValidateSchema(CreateRoomInputDTOSchema)
|
||||
//@APIReturn(RoomOutPutDTOSchema, 'post/Room')
|
||||
async createRoom(data: CreateRoomInputDTO): DataSourceReturn<RoomOutPutDTO> {
|
||||
return await this.httpService.post<RoomOutPutDTO>(`${this.baseUrl}/Room`, data);
|
||||
}
|
||||
|
||||
|
||||
@APIReturn(RoomListOutPutDTOSchema, 'get/Room')
|
||||
//@APIReturn(RoomListOutPutDTOSchema, 'get/Room')
|
||||
async getRoomList(): Promise<DataSourceReturn<RoomListOutPutDTO>> {
|
||||
return await this.httpService.get<RoomListOutPutDTO>(`${this.baseUrl}/Room?userId=${SessionStore.user.UserId}`);
|
||||
}
|
||||
|
||||
@ValidateSchema(RoomByIdInputDTOSchema)
|
||||
@APIReturn(RoomByIdOutputDTOSchema,'get/Room/${id}')
|
||||
//@ValidateSchema(RoomByIdInputDTOSchema)
|
||||
//@APIReturn(RoomByIdOutputDTOSchema,'get/Room/${id}')
|
||||
async getRoom(id: RoomByIdInputDTO): DataSourceReturn<RoomByIdOutputDTO> {
|
||||
return await this.httpService.get(`${this.baseUrl}/Room/${id}`);
|
||||
}
|
||||
|
||||
@ValidateSchema(RoomUpdateInputDTOSchema)
|
||||
//@ValidateSchema(RoomUpdateInputDTOSchema)
|
||||
//@APIReturn(RoomByIdOutputDTOSchema,'update/Room/${id}')
|
||||
async updateRoom(data: RoomUpdateInputDTO): Promise<DataSourceReturn<RoomUpdateOutputDTO>> {
|
||||
const id = data.roomId
|
||||
|
||||
@@ -9,7 +9,7 @@ import { SignalRService } from 'src/app/infra/socket/signalR/signal-r.service';
|
||||
import { SocketMessageDeleteUseCaseService } from 'src/app/module/chat/domain/use-case/socket/socket-message-delete-use-case.service';
|
||||
import { SocketMessageUpdateUseCaseService } from 'src/app/module/chat/domain/use-case/socket/socket-message-update-use-case.service';
|
||||
import { SocketMessageCreateUseCaseService } from 'src/app/module/chat/domain/use-case/socket/socket-message-create-use-case.service';
|
||||
import { DownloadMessageAttachmentUserCaseService } from 'src/app/module/chat/domain/use-case/message/message-download-attachment-user-case.service';
|
||||
import { DownloadMessageAttachmentByMessageId, DownloadMessageAttachmentUserCaseService } from 'src/app/module/chat/domain/use-case/message/message-download-attachment-user-case.service';
|
||||
import { ListenMessageByRoomIdNewUseCase } from 'src/app/module/chat/domain/use-case/message/listen-message-by-roomId.service';
|
||||
import { MemberListUpdateStatusUseCaseService } from 'src/app/module/chat/domain/use-case/socket/member-list-update-status-use-case.service';
|
||||
import { ListenMessageDeleteByRoomIdService } from './use-case/message/listene-message-delete-by-roomId.service';
|
||||
@@ -27,7 +27,7 @@ import { RoomUpdateInputDTO, UpdateRoomByIdUseCaseService } from './use-case/roo
|
||||
import { SocketConnectUseCaseService } from './use-case/socket-connect-use-case.service'
|
||||
import { MessageMarkAsReadUseCaseService } from './use-case/message/message-mark-as-read-use-case.service'
|
||||
import { MessageMarkAllMessageAsReadByRoomIdInputSchema, MessageMarkAllMessageAsReadByRoomIdService } from './use-case/message/message-mark-all-message-as-read-by-room-id.service'
|
||||
import { GetMessageAttachmentLocallyUseCaseService } from 'src/app/module/chat/domain/use-case/message/message-get-attachment-localy-use-case.service';
|
||||
import { GetMessageAttachmentLocallyByMessageId, GetMessageAttachmentLocallyUseCaseService } from 'src/app/module/chat/domain/use-case/message/message-get-attachment-localy-use-case.service';
|
||||
import { GetRoomListUseCaseService } from 'src/app/module/chat/domain/use-case/room/room-get-list-use-case.service';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
@@ -174,13 +174,13 @@ export class ChatServiceService {
|
||||
return this.MessageAttachmentByMessageIdService.execute(input)
|
||||
}
|
||||
|
||||
downloadMessageAttachmentByMessageId(input: MessageAttachmentByMessageIdInput) {
|
||||
downloadMessageAttachmentByMessageId(input: DownloadMessageAttachmentByMessageId) {
|
||||
return this.DownloadMessageAttachmentUserCaseService.execute(input)
|
||||
}
|
||||
|
||||
getMessageAttachmentLocallyByMessageId(input: MessageAttachmentByMessageIdInput) {
|
||||
return this.GetMessageAttachmentLocallyUseCaseService.execute(input)
|
||||
}
|
||||
// getMessageAttachmentLocallyByMessageId(input: GetMessageAttachmentLocallyByMessageId) {
|
||||
// return this.GetMessageAttachmentLocallyUseCaseService.execute(input)
|
||||
// }
|
||||
|
||||
|
||||
listenToMessageLoadHistory(input: HttpListenToMessageLoadHistoryUseCaseInput) {
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { captureAndReraiseAsync } from 'src/app/services/decorators/captureAndReraiseAsync';
|
||||
import { RoomRemoteDataSourceService } from '../../../data/repository/room/room-remote-repository.service';
|
||||
import { z } from 'zod';
|
||||
import { MemberListRemoteRepository } from '../../../data/repository/member/member-list-remote-repository.service';
|
||||
import { IMemberRemoteRepository } from 'src/app/core/chat/repository/member/member-remote-repository';
|
||||
|
||||
|
||||
export const AddMemberToRoomInputDTOSchema = z.object({
|
||||
@@ -19,7 +18,7 @@ export type AddMemberToRoomInputDTO = z.infer<typeof AddMemberToRoomInputDTOSche
|
||||
export class AddMemberUseCaseService {
|
||||
|
||||
constructor(
|
||||
private memberRemoteDataSourceService: MemberListRemoteRepository,
|
||||
private memberRemoteDataSourceService: IMemberRemoteRepository,
|
||||
) { }
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { z } from "zod";
|
||||
import { ValidateSchema } from 'src/app/services/decorators/validate-schema.decorator';
|
||||
import { RoomRemoteDataSourceService } from '../../../data/repository/room/room-remote-repository.service';
|
||||
import { MemberListRemoteRepository } from '../../../data/repository/member/member-list-remote-repository.service';
|
||||
import { IMemberRemoteRepository } from 'src/app/core/chat/repository/member/member-remote-repository';
|
||||
|
||||
// Define the schema for the entire response
|
||||
const MemberSetAdminDTOSchema = z.object({
|
||||
@@ -19,7 +18,7 @@ export type MemberSetAdminDTO = z.infer<typeof MemberSetAdminDTOSchema>
|
||||
export class MemberAdminUseCaseService {
|
||||
|
||||
constructor(
|
||||
public repository: MemberListRemoteRepository
|
||||
public repository: IMemberRemoteRepository
|
||||
) { }
|
||||
|
||||
@ValidateSchema(MemberSetAdminDTOSchema)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { filter, map } from 'rxjs/operators';
|
||||
import { InstanceId } from '../../chat-service.service';
|
||||
import { MessageSocketRepositoryService } from 'src/app/module/chat/data/repository/message/message-live-signalr-data-source.service'
|
||||
import { MessageEntity } from '../../../../../core/chat/entity/message';
|
||||
import { z } from 'zod';
|
||||
import { IMessageSocketRepository } from 'src/app/core/chat/repository/message/message-socket-repository';
|
||||
|
||||
|
||||
export const ListenMessageByRoomIdNewInputDTOSchema = z.object({
|
||||
@@ -18,7 +18,7 @@ export type ListenMessageByRoomIdNewInputDTO = z.infer<typeof ListenMessageByRoo
|
||||
export class ListenMessageByRoomIdNewUseCase {
|
||||
|
||||
constructor(
|
||||
private MessageSocketRepositoryService: MessageSocketRepositoryService
|
||||
private MessageSocketRepositoryService: IMessageSocketRepository
|
||||
) { }
|
||||
|
||||
execute(data: ListenMessageByRoomIdNewInputDTO) {
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { filter } from 'rxjs/operators';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
import { z } from 'zod';
|
||||
import { IMessageSocketRepository } from 'src/app/core/chat/repository/message/message-socket-repository';
|
||||
|
||||
export const ListenMessageUpdateByRoomIdInputDTOSchema = z.object({
|
||||
roomId: z.string(),
|
||||
@@ -16,7 +16,7 @@ export type ListenMessageUpdateByRoomIdInputDTO = z.infer<typeof ListenMessageUp
|
||||
export class ListenMessageUpdateByRoomIdUseCase {
|
||||
|
||||
constructor(
|
||||
private messageLiveSignalRDataSourceService: MessageSocketRepositoryService,
|
||||
private messageLiveSignalRDataSourceService: IMessageSocketRepository,
|
||||
) { }
|
||||
|
||||
execute(input: ListenMessageUpdateByRoomIdInputDTO) {
|
||||
|
||||
+70
-31
@@ -2,14 +2,16 @@ import { Injectable } from '@angular/core';
|
||||
import { z } from 'zod';
|
||||
import { AttachmentRemoteDataSourceService } from 'src/app/module/chat/data/repository/attachment/attachment-remote-repository.service'
|
||||
import { AttachmentLocalDataSource } from 'src/app/module/chat/data/repository/attachment/attachment-local-repository.service'
|
||||
import { convertBlobToDataURL } from 'src/app/utils/ToBase64';
|
||||
import { Result } from 'neverthrow';
|
||||
import { createBlobUrl } from 'src/app/utils/ToBase64';
|
||||
import { err, Result } from 'neverthrow';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { MessageEntity } from '../../../../../core/chat/entity/message';
|
||||
import { AttachmentTableSchema } from 'src/app/infra/database/dexie/instance/chat/schema/attachment';
|
||||
import { XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
|
||||
|
||||
const MessageAttachmentByMessageIdSchema = z.object({
|
||||
$messageId: z.number(),
|
||||
id: z.string()
|
||||
const MessageAttachmentByMessageIdSchema = AttachmentTableSchema.pick({
|
||||
$messageId: true,
|
||||
id: true
|
||||
})
|
||||
|
||||
export type MessageAttachmentByMessageIdInput = z.infer<typeof MessageAttachmentByMessageIdSchema>
|
||||
@@ -24,6 +26,7 @@ export class MessageAttachmentByMessageIdUseCase {
|
||||
private AttachmentLocalDataSource: AttachmentLocalDataSource
|
||||
) { }
|
||||
|
||||
@XTracerAsync({name:'Message-Attachment-By-MessageIdUseCase', module:'chat', bugPrint: true, waitNThrow: 15000})
|
||||
async execute(input: MessageEntity): Promise<Result<string, any>> {
|
||||
|
||||
const getLocalAttachment = await this.AttachmentLocalDataSource.findOne({
|
||||
@@ -31,10 +34,31 @@ export class MessageAttachmentByMessageIdUseCase {
|
||||
})
|
||||
|
||||
if(getLocalAttachment.isOk() && getLocalAttachment.value) {
|
||||
if(getLocalAttachment.value) {
|
||||
return getLocalAttachment.map(e => e.file)
|
||||
|
||||
// has blob
|
||||
if(getLocalAttachment.value.file) {
|
||||
const dataUrl = await createBlobUrl(getLocalAttachment.value.file)
|
||||
|
||||
if(dataUrl.isOk()) {
|
||||
return dataUrl
|
||||
} else {
|
||||
return dataUrl
|
||||
}
|
||||
} else {
|
||||
// has data url
|
||||
return getLocalAttachment.map((e) => {
|
||||
|
||||
// Logger.info('restored file .', {
|
||||
// data: e.base64.slice(0, 100)+'...'
|
||||
// })
|
||||
|
||||
return e.base64
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
console.log('donwload')
|
||||
const result = await this.AttachmentRemoteDataSourceService.getAttachment(input.attachments[0].id)
|
||||
|
||||
if(result.isErr()) {
|
||||
@@ -46,33 +70,48 @@ export class MessageAttachmentByMessageIdUseCase {
|
||||
})
|
||||
}
|
||||
|
||||
return result.asyncMap(async (e) => {
|
||||
|
||||
const dataUrl = await convertBlobToDataURL(e)
|
||||
// Logger.info('downloaded file .', {
|
||||
// data: dataUrl.slice(0, 100)+'...'
|
||||
// })
|
||||
if(result.isOk()) {
|
||||
|
||||
this.AttachmentLocalDataSource.insert({
|
||||
$messageId: input.$id,
|
||||
file: dataUrl,
|
||||
fileType: input.attachments[0].fileType,
|
||||
source: input.attachments[0].source,
|
||||
fileName: input.attachments[0].fileName,
|
||||
applicationId: input.attachments[0].applicationId,
|
||||
docId: input.attachments[0].docId,
|
||||
mimeType: input.attachments[0].mimeType,
|
||||
}).then((e) => {
|
||||
if(e.isErr()) {
|
||||
Logger.error('failed to create attachment locally on send message', {
|
||||
error: e.error,
|
||||
data: dataUrl.slice(0, 100)+'...'
|
||||
})
|
||||
}
|
||||
})
|
||||
console.log('convert')
|
||||
const dataUrl = await createBlobUrl(result.value)
|
||||
|
||||
if(dataUrl.isOk()) {
|
||||
|
||||
//console.log('done convert')
|
||||
Logger.info('downloaded file .', {
|
||||
// data: dataUrl.value.slice(0, 100)+'...'
|
||||
})
|
||||
|
||||
this.AttachmentLocalDataSource.insert({
|
||||
$messageId: input.$id,
|
||||
file: result.value,
|
||||
fileType: input.attachments[0].fileType,
|
||||
source: input.attachments[0].source,
|
||||
fileName: input.attachments[0].fileName,
|
||||
applicationId: input.attachments[0].applicationId,
|
||||
docId: input.attachments[0].docId,
|
||||
mimeType: input.attachments[0].mimeType,
|
||||
}).then((e) => {
|
||||
if(e.isErr()) {
|
||||
Logger.error('failed to create attachment locally on send message', {
|
||||
error: e.error,
|
||||
// data: dataUrl.value.slice(0, 100)+'...'
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return dataUrl
|
||||
} else {
|
||||
console.log('dataUrl eerror', dataUrl.error)
|
||||
return err(false)
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
return result as any
|
||||
}
|
||||
|
||||
return dataUrl
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,11 +4,9 @@ import { AttachmentLocalDataSource } from "src/app/module/chat/data/repository/a
|
||||
import { z } from 'zod';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { InstanceId } from '../../chat-service.service';
|
||||
import { createDataURL } from 'src/app/utils/ToBase64';
|
||||
import { createBlobFromBase64, createDataURL } from 'src/app/utils/ToBase64';
|
||||
import { zodSafeValidation } from 'src/app/utils/zodValidation';
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { MessageLocalDataSourceService } from '../../../data/repository/message/message-local-data-source.service';
|
||||
import { MessageSocketRepositoryService } from '../../../data/repository/message/message-live-signalr-data-source.service';
|
||||
import { err, Result } from 'neverthrow';
|
||||
import { MessageMapper } from '../../mapper/messageMapper';
|
||||
import { RoomType } from "src/app/core/chat/entity/group";
|
||||
@@ -17,6 +15,10 @@ import { MemberListLocalRepository } from 'src/app/module/chat/data/repository/m
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message';
|
||||
import { MessageAttachmentFileType, MessageOutPutDataDTO } from 'src/app/core/chat/repository/dto/messageOutputDTO';
|
||||
import { IMessageLocalRepository } from 'src/app/core/chat/repository/message/message-local-repository';
|
||||
import { IMessageSocketRepository } from 'src/app/core/chat/repository/message/message-socket-repository';
|
||||
import { IMemberLocalRepository } from 'src/app/core/chat/repository/member/member-local-repository';
|
||||
import { IAttachmentLocalRepository } from 'src/app/core/chat/repository/typing/typing-local-repository';
|
||||
|
||||
|
||||
export enum MessageEnum {
|
||||
@@ -71,11 +73,10 @@ export type MessageCreateOutPutDataDTO = z.infer<typeof MessageCreatePutDataDTOS
|
||||
export class MessageCreateUseCaseService {
|
||||
|
||||
constructor(
|
||||
private AttachmentLocalRepositoryService: AttachmentLocalDataSource,
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService,
|
||||
private MessageSocketRepositoryService: MessageSocketRepositoryService,
|
||||
private messageSocketRepositoryService: MessageSocketRepositoryService,
|
||||
private MemberListLocalRepository: MemberListLocalRepository
|
||||
private AttachmentLocalRepositoryService: IAttachmentLocalRepository,
|
||||
private messageLocalDataSourceService: IMessageLocalRepository,
|
||||
private messageSocketRepositoryService: IMessageSocketRepository,
|
||||
private MemberListLocalRepository: IMemberLocalRepository
|
||||
) { }
|
||||
|
||||
|
||||
@@ -104,7 +105,7 @@ export class MessageCreateUseCaseService {
|
||||
|
||||
this.AttachmentLocalRepositoryService.insert({
|
||||
$messageId: createMessageLocally.value,
|
||||
file: createDataURL(attachment.file, attachment.mimeType),
|
||||
base64: createDataURL(attachment.file, attachment.mimeType),
|
||||
fileType: attachment.fileType,
|
||||
source: attachment.source,
|
||||
fileName: attachment.fileName,
|
||||
@@ -133,7 +134,7 @@ export class MessageCreateUseCaseService {
|
||||
let sendMessageResult: Result<MessageOutPutDataDTO, any>
|
||||
if(messageEnum == RoomType.Group) {
|
||||
const DTO = MessageMapper.fromDomain(message, message.requestId)
|
||||
sendMessageResult = await this.MessageSocketRepositoryService.sendGroupMessage(DTO)
|
||||
sendMessageResult = await this.messageSocketRepositoryService.sendGroupMessage(DTO)
|
||||
} else {
|
||||
|
||||
if(message.receiverId) {
|
||||
@@ -182,6 +183,10 @@ export class MessageCreateUseCaseService {
|
||||
return err('no connection')
|
||||
}
|
||||
|
||||
} else {
|
||||
Logger.error('failed to insert locally', {
|
||||
error: createMessageLocally.error
|
||||
})
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
+28
-15
@@ -1,9 +1,16 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { AttachmentRemoteDataSourceService } from 'src/app/module/chat/data/repository/attachment/attachment-remote-repository.service'
|
||||
import { Logger } from 'src/app/services/logger/main/service';
|
||||
import { convertBlobToDataURL } from 'src/app/utils/ToBase64';
|
||||
import { convertBlobToDataURL, createBlobUrl } from 'src/app/utils/ToBase64';
|
||||
import { AttachmentLocalDataSource } from 'src/app/module/chat/data/repository/attachment/attachment-local-repository.service'
|
||||
import { MessageAttachmentByMessageIdInput } from './message-attachment-by-message-id.service';
|
||||
import { z } from 'zod';
|
||||
|
||||
const DownloadMessageAttachmentByMessageIdSchema = z.object({
|
||||
$messageId: z.number(),
|
||||
id: z.string()
|
||||
})
|
||||
|
||||
export type DownloadMessageAttachmentByMessageId = z.infer<typeof DownloadMessageAttachmentByMessageIdSchema>
|
||||
|
||||
|
||||
@Injectable({
|
||||
@@ -16,23 +23,29 @@ export class DownloadMessageAttachmentUserCaseService {
|
||||
private AttachmentLocalDataSource: AttachmentLocalDataSource
|
||||
) { }
|
||||
|
||||
async execute(input: MessageAttachmentByMessageIdInput) {
|
||||
async execute(input: DownloadMessageAttachmentByMessageId) {
|
||||
const result = await this.AttachmentRemoteDataSourceService.getAttachment(input.$messageId)
|
||||
return result.asyncMap(async (e) => {
|
||||
return result.asyncMap(async (blob) => {
|
||||
|
||||
const dataUrl = await convertBlobToDataURL(e)
|
||||
Logger.info('downloaded file #1', {
|
||||
data: dataUrl.slice(0, 100)+'...',
|
||||
context: 'DownloadMessageAttachmentUserCaseService'
|
||||
})
|
||||
const dataUrl = await createBlobUrl(blob)
|
||||
|
||||
this.AttachmentLocalDataSource.insert({
|
||||
$messageId: input.$messageId,
|
||||
id: input.id,
|
||||
file: dataUrl
|
||||
})
|
||||
if(dataUrl.isOk()) {
|
||||
|
||||
Logger.info('downloaded file #1', {
|
||||
// data: dataUrl.slice(0, 100)+'...',
|
||||
context: 'DownloadMessageAttachmentUserCaseService'
|
||||
})
|
||||
|
||||
return dataUrl
|
||||
this.AttachmentLocalDataSource.insert({
|
||||
$messageId: input.$messageId,
|
||||
id: input.id,
|
||||
file: blob
|
||||
})
|
||||
|
||||
return dataUrl
|
||||
} else {
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
+15
-2
@@ -3,6 +3,17 @@ import { MessageAttachmentByMessageIdInput } from './message-attachment-by-messa
|
||||
import { AttachmentRemoteDataSourceService } from 'src/app/module/chat/data/repository/attachment/attachment-remote-repository.service'
|
||||
import { AttachmentLocalDataSource } from 'src/app/module/chat/data/repository/attachment/attachment-local-repository.service'
|
||||
import { err, Result } from 'neverthrow';
|
||||
import { AttachmentTableSchema } from 'src/app/infra/database/dexie/instance/chat/schema/attachment';
|
||||
import { z } from 'zod';
|
||||
import { createBlobUrl } from 'src/app/utils/ToBase64';
|
||||
|
||||
const GetMessageAttachmentLocallyByMessageIdSchema = AttachmentTableSchema.pick({
|
||||
$messageId: true
|
||||
})
|
||||
|
||||
export type GetMessageAttachmentLocallyByMessageId = z.infer<typeof GetMessageAttachmentLocallyByMessageIdSchema>
|
||||
|
||||
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
@@ -15,7 +26,7 @@ export class GetMessageAttachmentLocallyUseCaseService {
|
||||
) { }
|
||||
|
||||
|
||||
async execute(input: MessageAttachmentByMessageIdInput): Promise<Result<string, any>> {
|
||||
async execute(input: GetMessageAttachmentLocallyByMessageId): Promise<Result<string, any>> {
|
||||
|
||||
const getLocalAttachment = await this.AttachmentLocalDataSource.findOne({
|
||||
$messageId: input.$messageId
|
||||
@@ -23,7 +34,9 @@ export class GetMessageAttachmentLocallyUseCaseService {
|
||||
|
||||
if(getLocalAttachment.isOk()) {
|
||||
if(getLocalAttachment.value) {
|
||||
return getLocalAttachment.map(e => e.file)
|
||||
const dataUrl = await createBlobUrl(getLocalAttachment.value.file)
|
||||
|
||||
return dataUrl
|
||||
}
|
||||
} else {
|
||||
return err(getLocalAttachment.error)
|
||||
|
||||
+1
-1
@@ -53,7 +53,7 @@ export class SendLocalMessagesUseCaseService {
|
||||
id: e.id,
|
||||
mimeType: e.mimeType,
|
||||
description: e.description,
|
||||
file: e.file.split(',')[1]
|
||||
file: e.base64.split(',')[1]
|
||||
}))
|
||||
console.log('to upload', messages)
|
||||
const requestId = InstanceId +'@'+ uuidv4();
|
||||
|
||||
@@ -87,7 +87,6 @@ export class SyncAllRoomMessagesService {
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
this.messageLocalDataSourceService.insertMany(addedItems.reverse())
|
||||
|
||||
} else {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { SessionStore } from 'src/app/store/session.service';
|
||||
import { RoomRemoteDataSourceService } from '../../../data/repository/room/room-remote-repository.service';
|
||||
import { RoomSocketRepositoryService } from '../../../data/repository/room/room-socket-repository.service';
|
||||
import { RoomLocalRepository } from '../../../data/repository/room/room-local-repository.service';
|
||||
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
|
||||
import { z } from "zod";
|
||||
import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-remote-repository';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
import { IRoomSocketRepository } from 'src/app/core/chat/repository/room/room-socket-repository';
|
||||
|
||||
export const CreateRoomInputDTOSchema = z.object({
|
||||
roomName: z.string(),
|
||||
@@ -36,9 +36,9 @@ export type RoomOutPutDTO = z.infer<typeof RoomOutPutDTOSchema>
|
||||
export class CreateRoomUseCaseService {
|
||||
|
||||
constructor(
|
||||
private roomRemoteDataSourceService: RoomRemoteDataSourceService,
|
||||
private roomLocalDataSourceService: RoomLocalRepository,
|
||||
private RoomSocketRepositoryService: RoomSocketRepositoryService
|
||||
private roomRemoteDataSourceService: IRoomRemoteRepository,
|
||||
private roomLocalDataSourceService: IRoomLocalRepository,
|
||||
private RoomSocketRepositoryService: IRoomSocketRepository
|
||||
) { }
|
||||
|
||||
@XTracerAsync({name:'room-create-use-case.service', module:'chat', bugPrint: true, waitNThrow: 5000})
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { captureAndReraiseAsync } from 'src/app/services/decorators/captureAndReraiseAsync';
|
||||
import { isHttpResponse } from 'src/app/services/http.service';
|
||||
import { RoomRemoteDataSourceService } from '../../../data/repository/room/room-remote-repository.service';
|
||||
import { RoomLocalRepository } from '../../../data/repository/room/room-local-repository.service';
|
||||
import { z } from "zod";
|
||||
import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-remote-repository';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
|
||||
export const DeleteRoomByIdInputDTOSchema = z.string()
|
||||
export type DeleteRoomByIdInputDTO = z.infer<typeof DeleteRoomByIdInputDTOSchema>
|
||||
@@ -15,9 +15,9 @@ export type DeleteRoomByIdInputDTO = z.infer<typeof DeleteRoomByIdInputDTOSchema
|
||||
export class DeleteRoomUseCaseService {
|
||||
|
||||
constructor(
|
||||
private roomRemoteDataSourceService: RoomRemoteDataSourceService,
|
||||
private roomRemoteDataSourceService: IRoomRemoteRepository,
|
||||
// private roomMemoryDataSourceService: Store<RoomRemoteDataSourceState>,
|
||||
private roomLocalDataSourceService: RoomLocalRepository,
|
||||
private roomLocalDataSourceService: IRoomLocalRepository,
|
||||
) { }
|
||||
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ import { id } from 'date-fns/locale';
|
||||
import { isHttpResponse } from 'src/app/services/http.service';
|
||||
import { roomListDetermineChanges } from '../../../data/async/list/rooms/roomListChangeDetector';
|
||||
import { roomMemberListDetermineChanges } from '../../../data/async/list/rooms/roomMembersChangeDetector';
|
||||
import { RoomRemoteDataSourceService } from '../../../data/repository/room/room-remote-repository.service';
|
||||
import { RoomLocalRepository } from '../../../data/repository/room/room-local-repository.service';
|
||||
import { MemberListLocalRepository } from '../../../data/repository/member/member-list-local-repository.service';
|
||||
import { MemberListMapper } from '../../mapper/memberLIstMapper';
|
||||
import { captureAndReraiseAsync } from 'src/app/services/decorators/captureAndReraiseAsync';
|
||||
import { z } from 'zod';
|
||||
import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-remote-repository';
|
||||
import { IMemberLocalRepository } from 'src/app/core/chat/repository/member/member-local-repository';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
|
||||
const UserSchema = z.object({
|
||||
wxUserId: z.number(),
|
||||
@@ -44,8 +44,6 @@ export type RoomByIdOutputDTO = z.infer<typeof RoomByIdOutputDTOSchema>
|
||||
|
||||
|
||||
export const RoomByIdInputDTOSchema = z.string()
|
||||
|
||||
|
||||
export type RoomByIdInputDTO = z.infer<typeof RoomByIdInputDTOSchema>
|
||||
|
||||
@Injectable({
|
||||
@@ -54,14 +52,14 @@ export type RoomByIdInputDTO = z.infer<typeof RoomByIdInputDTOSchema>
|
||||
export class GetRoomByIdUseCaseService {
|
||||
|
||||
constructor(
|
||||
private roomRemoteDataSourceService: RoomRemoteDataSourceService,
|
||||
private roomRemoteDataSourceService: IRoomRemoteRepository,
|
||||
// private roomMemoryDataSourceService: Store<RoomRemoteDataSourceState>,
|
||||
private roomLocalDataSourceService: RoomLocalRepository,
|
||||
private MemberListLocalRepository: MemberListLocalRepository
|
||||
private roomLocalDataSourceService: IRoomLocalRepository,
|
||||
private MemberListLocalRepository: IMemberLocalRepository
|
||||
) { }
|
||||
|
||||
@captureAndReraiseAsync('RoomRepositoryService/getRoomById')
|
||||
async execute(id: string) {
|
||||
async execute(id: RoomByIdInputDTO) {
|
||||
const result = await this.roomRemoteDataSourceService.getRoom(id)
|
||||
|
||||
if(result.isOk()) {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { roomListDetermineChanges } from '../../../data/async/list/rooms/roomListChangeDetector';
|
||||
import { RoomRemoteDataSourceService } from '../../../data/repository/room/room-remote-repository.service';
|
||||
import { RoomLocalRepository } from '../../../data/repository/room/room-local-repository.service';
|
||||
import { captureAndReraiseAsync } from 'src/app/services/decorators/captureAndReraiseAsync';
|
||||
import { CronJobService } from 'src/app/utils/task-scheduler'
|
||||
import { z } from "zod";
|
||||
import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-remote-repository';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
|
||||
|
||||
const CreatedBySchema = z.object({
|
||||
@@ -46,9 +46,9 @@ export type RoomListOutPutDTO = z.infer<typeof RoomListOutPutDTOSchema>
|
||||
export class GetRoomListUseCaseService {
|
||||
|
||||
constructor(
|
||||
private roomRemoteDataSourceService: RoomRemoteDataSourceService,
|
||||
private roomRemoteDataSourceService: IRoomRemoteRepository,
|
||||
// private roomMemoryDataSourceService: Store<RoomRemoteDataSourceState>,
|
||||
private roomLocalDataSourceService: RoomLocalRepository,
|
||||
private roomLocalDataSourceService: IRoomLocalRepository,
|
||||
private CronJobService: CronJobService
|
||||
) { }
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { isHttpResponse } from 'src/app/services/http.service';
|
||||
import { RoomLocalRepository } from '../../../data/repository/room/room-local-repository.service';
|
||||
import { MemberListRemoteRepository } from '../../../data/repository/member/member-list-remote-repository.service';
|
||||
import { z } from "zod";
|
||||
import { IMemberRemoteRepository } from 'src/app/core/chat/repository/member/member-remote-repository';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
|
||||
// Define the schema for the entire response
|
||||
export const UserRemoveListInputDTOSchema = z.object({
|
||||
@@ -19,8 +19,8 @@ export type UserRemoveListInputDTO = z.infer<typeof UserRemoveListInputDTOSchema
|
||||
export class RoomLeaveUseCase {
|
||||
|
||||
constructor(
|
||||
private memberRemoteDataSourceService: MemberListRemoteRepository,
|
||||
private roomLocalDataSourceService: RoomLocalRepository,
|
||||
private memberRemoteDataSourceService: IMemberRemoteRepository,
|
||||
private roomLocalDataSourceService: IRoomLocalRepository,
|
||||
) { }
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { captureAndReraiseAsync } from 'src/app/services/decorators/captureAndReraiseAsync';
|
||||
import { RoomRemoteDataSourceService } from '../../../data/repository/room/room-remote-repository.service';
|
||||
import { RoomLocalRepository } from '../../../data/repository/room/room-local-repository.service';
|
||||
import { z } from "zod";
|
||||
import { DataSourceReturn } from 'src/app/services/Repositorys/type';
|
||||
import { IRoomLocalRepository } from 'src/app/core/chat/repository/room/room-local-repository';
|
||||
import { IRoomRemoteRepository } from 'src/app/core/chat/repository/room/room-remote-repository';
|
||||
|
||||
export const RoomUpdateInputDTOSchema = z.object({
|
||||
roomName: z.string(),
|
||||
@@ -47,13 +48,13 @@ export type RoomUpdateOutputDTO = z.infer<typeof RoomUpdateOutputDTOSchema>
|
||||
export class UpdateRoomByIdUseCaseService {
|
||||
|
||||
constructor(
|
||||
private roomRemoteDataSourceService: RoomRemoteDataSourceService,
|
||||
private roomLocalDataSourceService: RoomLocalRepository,
|
||||
private roomRemoteDataSourceService: IRoomRemoteRepository,
|
||||
private roomLocalDataSourceService: IRoomLocalRepository,
|
||||
) { }
|
||||
|
||||
|
||||
@captureAndReraiseAsync('RoomRepositoryService/updateRoomBy')
|
||||
async execute(data: RoomUpdateInputDTO) {
|
||||
async execute(data: RoomUpdateInputDTO): Promise<DataSourceReturn<RoomUpdateOutputDTO>> {
|
||||
|
||||
const result = await this.roomRemoteDataSourceService.updateRoom(data)
|
||||
|
||||
|
||||
@@ -45,12 +45,16 @@
|
||||
|
||||
<div
|
||||
*ngFor="let message of messages1[roomId]; let messageIndex = index" class="messages-list-item-wrapper"
|
||||
[ngClass]="{'my-message': message.sender.wxUserId === SessionStore.user.UserId, 'other-message': message.sender.wxUserId !== SessionStore.user.UserId}"
|
||||
[ngClass]="{
|
||||
'info-meeting': message.messageType == IMessageType.information,
|
||||
'my-message': message.messageType != IMessageType.information && message?.sender?.wxUserId === SessionStore.user.UserId,
|
||||
'other-message': message.messageType != IMessageType.information && message?.sender?.wxUserId !== SessionStore.user.UserId
|
||||
}"
|
||||
>
|
||||
<div class="message-container rotate-div" *ngIf="message.isDeleted != true">
|
||||
<div class="message-container rotate-div" *ngIf="message.isDeleted != true && message.messageType != IMessageType.information">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div>
|
||||
<div>
|
||||
<div >
|
||||
{{ message.message }}
|
||||
</div>
|
||||
|
||||
@@ -146,8 +150,11 @@
|
||||
<div class="message-container rotate-div" *ngIf="message.isDeleted == true">
|
||||
Mensagem foi eliminada
|
||||
</div>
|
||||
<div *ngIf="message.messageType == IMessageType.information" class="text-center">
|
||||
{{ message.message }}
|
||||
</div>
|
||||
<!-- current emoji -->
|
||||
<div class="rotate-div" *ngIf="message.isDeleted != true">
|
||||
<div class="rotate-div emoji-container" *ngIf="message.isDeleted != true && message.messageType != IMessageType.information">
|
||||
<span *ngFor="let reaction of message.reactions" class="emoji-icon">
|
||||
{{ reaction.reaction }}
|
||||
</span>
|
||||
|
||||
@@ -504,3 +504,10 @@ ion-footer {
|
||||
// -ms-transform: rotate(180deg);
|
||||
// -o-transform: rotate(180deg);
|
||||
// }
|
||||
.emoji-container{
|
||||
padding: 0px 20px;
|
||||
/* margin-bottom: -10px; */
|
||||
position: relative;
|
||||
top: -10px;
|
||||
margin-bottom: -15px;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, SimpleChanges, TemplateRef, ViewChild } from '@angular/core';
|
||||
import { AfterViewInit, Component, ElementRef, EventEmitter, Input, OnChanges, OnDestroy, OnInit, Output, QueryList, SimpleChanges, TemplateRef, ViewChild, ViewChildren } from '@angular/core';
|
||||
import { AnimationController, GestureController, IonRange, ModalController, PopoverController } from '@ionic/angular';
|
||||
import { ToastService } from 'src/app/services/toast.service';
|
||||
import { ContactsPage } from '../contacts/contacts.page';
|
||||
@@ -26,7 +26,7 @@ import { RoomLocalRepository } from 'src/app/module/chat/data/repository/room/ro
|
||||
import { MemberListLocalRepository } from 'src/app/module/chat/data/repository/member/member-list-local-repository.service'
|
||||
import { ChatServiceService } from 'src/app/module/chat/domain/chat-service.service';
|
||||
import { EditMessagePage } from 'src/app/modals/edit-message/edit-message.page';
|
||||
import { MessageAttachmentFileType, MessageAttachmentSource, MessageEntity } from 'src/app/core/chat/entity/message';
|
||||
import { IMessageType, MessageAttachmentFileType, MessageAttachmentSource, MessageEntity } from 'src/app/core/chat/entity/message';
|
||||
import { JSFileToDataUrl } from 'src/app/utils/ToBase64';
|
||||
import { CameraService } from 'src/app/infra/camera/camera.service'
|
||||
import { FilePickerWebService } from 'src/app/infra/file-picker/web/file-picker-web.service'
|
||||
@@ -48,6 +48,9 @@ import { MemberTable } from 'src/app/infra/database/dexie/instance/chat/schema/m
|
||||
import { MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message';
|
||||
import { RoomTable } from 'src/app/infra/database/dexie/instance/chat/schema/room';
|
||||
import { TypingTable } from 'src/app/infra/database/dexie/instance/chat/schema/typing';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { MatMenuTrigger } from '@angular/material/menu';
|
||||
|
||||
@Component({
|
||||
selector: 'app-messages',
|
||||
@@ -144,11 +147,15 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
messages1: {[key: string]: MessageEntity[]} = {}
|
||||
MessageAttachmentFileType = MessageAttachmentFileType
|
||||
MessageAttachmentFileSource = MessageAttachmentSource
|
||||
IMessageType = IMessageType
|
||||
|
||||
@ViewChild('imageModal') imageModal: TemplateRef<any>;
|
||||
totalMembers = 0
|
||||
members: MemberTable[] = []
|
||||
|
||||
private worker: SharedWorker;
|
||||
private port: MessagePort;
|
||||
|
||||
constructor(
|
||||
public popoverController: PopoverController,
|
||||
private modalController: ModalController,
|
||||
@@ -173,14 +180,55 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
private userTypingLocalRepository: UserTypingLocalRepository,
|
||||
private UserTypingRemoteRepositoryService: UserTypingRemoteRepositoryService,
|
||||
private messageLocalDataSourceService: MessageLocalDataSourceService,
|
||||
private alertController: AlertController
|
||||
private alertController: AlertController,
|
||||
private http: HttpClient
|
||||
) {
|
||||
// update
|
||||
this.checkAudioPermission()
|
||||
//this.sendChunks()
|
||||
|
||||
this.worker = new SharedWorker('shared-worker.js');
|
||||
this.port = this.worker.port;
|
||||
|
||||
this.port.onmessage = (event) => {
|
||||
console.log('Received from worker:', event.data);
|
||||
}
|
||||
|
||||
this.port.postMessage('hello');
|
||||
}
|
||||
|
||||
sendChunks() {
|
||||
const base64String = 'data:video/mp4;base64,AAAAHGZ0eXBtcDQyAAAAAGlzb21tcDQyAAACAGlzb21tcDQyaXNvbXJtZGEAAAAHZnJlZS1ybWRhAAAAGXZmY2MtbGF2ZjU4LmEyLTkyLm12NTZjAGZyZWUtcm1kYQAAAAVyZWZsYXYAAABWZGF0YTqBgIAAAAs9AAABM/f/+6mpg6z+d0+j5adJHVD+lk75p0ntRFEyTlHT/GRYbDg4ODhISEhAQK/jMCAxCBAIEwMmJgAABNmY2MtbGF2ZjU4LmEyLTkyLm12NTZjAGZyZWUtcm1kYQAAAAVyZWZsYXY=';
|
||||
const chunkSize = Math.ceil(base64String.length / 2);
|
||||
const chunks = [
|
||||
{ chunk: base64String.slice(0, chunkSize), index: 0 },
|
||||
{ chunk: base64String.slice(chunkSize), index: 1 }
|
||||
];
|
||||
|
||||
const identifier = uuidv4(); // You can set a unique identifier for the file
|
||||
|
||||
const totalChunks = chunks.length;
|
||||
|
||||
chunks.forEach((chunkData) => {
|
||||
const payload = {
|
||||
chunk: chunkData.chunk,
|
||||
identifier,
|
||||
index: chunkData.index,
|
||||
totalChunks
|
||||
};
|
||||
|
||||
this.http.post('https://gdapi-dev.dyndns.info/stage/api/v2/File/UploadBase64Chunks', payload)
|
||||
.subscribe(response => {
|
||||
console.log('Chunk sent successfully:', response);
|
||||
}, error => {
|
||||
console.error('Error sending chunk:', error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges): void {
|
||||
|
||||
|
||||
this.roomData$ = this.RoomLocalRepository.getRoomByIdLive(this.roomId)
|
||||
|
||||
this.roomData$.subscribe(e => {
|
||||
@@ -1387,7 +1435,6 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
|
||||
closeModal(a: any) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -173,7 +173,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
this.listenToIncomingMessage();
|
||||
this.listenToDeleteMessage();
|
||||
this.listenToUpdateMessage();
|
||||
this.listenToSendMessage()
|
||||
this.listenToSendMessage();
|
||||
|
||||
|
||||
// this.roomMessage$ = this.messageRepositoryService.getItemsLive(this.roomId)
|
||||
@@ -211,14 +211,19 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
async loadAttachment() {
|
||||
for(const message of this.messages1[this.roomId]) {
|
||||
if(message.hasAttachment) {
|
||||
console.log('get attachment')
|
||||
|
||||
|
||||
const result = await this.chatServiceService.getMessageAttachmentByMessageId(message)
|
||||
|
||||
console.log('result')
|
||||
if(result.isOk()) {
|
||||
|
||||
console.log(result.value, message)
|
||||
message.attachments[0].safeFile = result.value
|
||||
|
||||
} else {
|
||||
console.log('error', result.error)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -562,6 +567,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
|
||||
|
||||
const message = new MessageEntity();
|
||||
message.roomId = this.roomId
|
||||
message.sentAt = new Date().toISOString()
|
||||
|
||||
message.sender = {
|
||||
userPhoto: '',
|
||||
|
||||
@@ -1,52 +1,45 @@
|
||||
import { SafeResourceUrl } from "@angular/platform-browser";
|
||||
import { MessageAttachmentFileType, MessageAttachmentSource, MessageEntity } from "src/app/core/chat/entity/message";
|
||||
import { IMessageType, MessageEntity, MessageEntitySchema } from "src/app/core/chat/entity/message";
|
||||
import { SessionStore } from "src/app/store/session.service";
|
||||
|
||||
export class MessageViewModal {
|
||||
$id!: number
|
||||
id!: string
|
||||
$id?: number
|
||||
id?: string
|
||||
roomId?: string
|
||||
receiverId?: number
|
||||
message!: string
|
||||
message?: string
|
||||
messageType: number = 0
|
||||
canEdit: boolean = false
|
||||
oneShot: boolean = false
|
||||
sentAt!: string
|
||||
sentAt?: string
|
||||
requireUnlock: boolean = false
|
||||
info: {
|
||||
memberId?: number
|
||||
readAt?: string,
|
||||
deliverAt?: string
|
||||
}[] = []
|
||||
sender!: {
|
||||
wxUserId: number,
|
||||
wxFullName: string,
|
||||
wxeMail: string,
|
||||
userPhoto: string,
|
||||
}
|
||||
info: typeof MessageEntitySchema._type.info = []
|
||||
sender!: typeof MessageEntitySchema._type.sender
|
||||
sending: boolean = false
|
||||
sendAttemp = 0
|
||||
|
||||
attachments: {
|
||||
safeFile?: SafeResourceUrl;
|
||||
fileType: MessageAttachmentFileType,
|
||||
source: MessageAttachmentSource,
|
||||
file?: string,
|
||||
fileName: string,
|
||||
applicationId?: number,
|
||||
docId?: string,
|
||||
mimeType?: string,
|
||||
description?: string
|
||||
id?: string
|
||||
}[] = []
|
||||
|
||||
reactions = []
|
||||
attachments: typeof MessageEntitySchema._type.attachments = []
|
||||
reactions: typeof MessageEntitySchema._type.reactions = []
|
||||
requestId!: string
|
||||
status = ''
|
||||
isDeleted: typeof MessageEntitySchema._type.isDeleted = false
|
||||
|
||||
status!: 'allViewed' | 'allReceived'| 'enviado'| 'enviar'
|
||||
messageUiType!: 'info-meeting'| 'my-message'| 'other-message'
|
||||
|
||||
constructor(model: MessageEntity) {
|
||||
Object.assign(this, model)
|
||||
this.setMessageUIType()
|
||||
}
|
||||
|
||||
setMessageUIType() {
|
||||
if(this.messageType == IMessageType.information) {
|
||||
this.messageUiType = 'info-meeting'
|
||||
} else if (this.sender?.wxUserId === SessionStore.user.UserId) {
|
||||
this.messageUiType = 'my-message'
|
||||
} else {
|
||||
this.messageUiType = 'other-message'
|
||||
}
|
||||
}
|
||||
|
||||
messageStatus(totalMembers: number) {
|
||||
if(this.allViewed(totalMembers)) {
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { err, ok, Result } from "neverthrow";
|
||||
import { defer, from } from "rxjs";
|
||||
import { catchError, timeout } from "rxjs/operators";
|
||||
|
||||
/**
|
||||
* Retrieves a `FileReader` instance, accounting for potential Zone.js modifications.
|
||||
@@ -56,7 +58,22 @@ export function createDataURL(base64String: string, mimeType: string): string {
|
||||
|
||||
|
||||
|
||||
export function createBlobFromBase64(base64String: string, mimeType: string): Blob {
|
||||
// Make sure the base64 string doesn't have the data URL scheme or extra padding
|
||||
const cleanedBase64String = base64String.replace(/^data:[a-z]+\/[a-z]+;base64,/, '');
|
||||
|
||||
// Decode the base64 string
|
||||
const binaryString = atob(cleanedBase64String);
|
||||
|
||||
// Convert binary string to Uint8Array
|
||||
const bytes = new Uint8Array(binaryString.length);
|
||||
for (let i = 0; i < binaryString.length; i++) {
|
||||
bytes[i] = binaryString.charCodeAt(i);
|
||||
}
|
||||
|
||||
// Create and return the Blob object
|
||||
return new Blob([bytes], { type: mimeType });
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -74,7 +91,7 @@ export function createDataURL(base64String: string, mimeType: string): string {
|
||||
*/
|
||||
export function convertBlobToDataURL(blob: Blob): Promise<string> {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const reader = new FileReader();
|
||||
const reader = getFileReader();
|
||||
|
||||
reader.onloadend = () => {
|
||||
// Resolve the promise with the Data URL
|
||||
@@ -90,3 +107,56 @@ export function convertBlobToDataURL(blob: Blob): Promise<string> {
|
||||
reader.readAsDataURL(blob);
|
||||
});
|
||||
}
|
||||
|
||||
// export function convertBlobToDataURLWithTimeoutNoThrow(blob: Blob): Promise<Result<string, any>> {
|
||||
// const convert = () => new Promise<Result<string, any>>((resolve, reject) => {
|
||||
// const reader = new FileReader();
|
||||
// reader.onloadend = () => resolve(ok(reader.result as string));
|
||||
// reader.onerror = () => resolve(err(new Error('Failed to convert Blob to Data URL')));
|
||||
// reader.readAsDataURL(blob);
|
||||
// });
|
||||
|
||||
// return defer(() => from(convert()))
|
||||
// .pipe(
|
||||
// timeout(15000),
|
||||
// catchError(error => {
|
||||
// console.error('Warning: Operation took too long, but continuing:', error);
|
||||
// return from(convert()); // Continue with the original operation
|
||||
// })
|
||||
// )
|
||||
// .toPromise();
|
||||
// }
|
||||
|
||||
// export function convertBlobToDataURLWithTimeout(blob: Blob): Promise<Result<string, any>> {
|
||||
// return from(new Promise<Result<string, any>>((resolve, reject) => {
|
||||
// const reader = getFileReader();
|
||||
|
||||
// reader.onloadend = () => resolve(ok(reader.result as string));
|
||||
// reader.onerror = () => resolve(err(new Error('Failed to convert Blob to Data URL')));
|
||||
// reader.readAsDataURL(blob);
|
||||
// }))
|
||||
// .pipe(
|
||||
// timeout(15000),
|
||||
// catchError(error => {
|
||||
// console.error('Error: Operation took too long or failed:', error);
|
||||
// return Promise.resolve(err('timeout'));
|
||||
// })
|
||||
// )
|
||||
// .toPromise();
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* Converts a `Blob` to a Data URL.
|
||||
* @param {Blob} blob - The `Blob` to be converted.
|
||||
* @returns {Promise<string>} A promise that resolves with the Data URL representation of the `Blob`.
|
||||
* @example result.value = 'data:audio/aac;base64,ZGF0YTphdWRpby9hYWM7YmFzZTY0…RnNRQmxmL0FGQUl'
|
||||
*/
|
||||
export function createBlobUrl(blob: Blob): Result<string, any> {
|
||||
try {
|
||||
return ok(URL.createObjectURL(blob));
|
||||
} catch (error) {
|
||||
return err('error '+ error);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// src/shared-worker.js
|
||||
self.onconnect = function (event) {
|
||||
const port = event.ports[0];
|
||||
|
||||
port.onmessage = function (e) {
|
||||
const message = e.data;
|
||||
console.log('Received from client:', message);
|
||||
|
||||
// Echo the message back to all connected clients
|
||||
port.postMessage('Echo: ' + message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// src/shared-worker.js
|
||||
self.onconnect = function (event) {
|
||||
const port = event.ports[0];
|
||||
|
||||
port.onmessage = function (e) {
|
||||
const message = e.data;
|
||||
console.log('Received from client:', message);
|
||||
|
||||
// Echo the message back to all connected clients
|
||||
port.postMessage('Echo: ' + message);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user