notification and chat slow

This commit is contained in:
Peter Maquiran
2024-12-16 12:04:02 +01:00
parent aef73625f0
commit 18a8d90d99
60 changed files with 363 additions and 381 deletions
-40
View File
@@ -1,40 +0,0 @@
{
"project_info": {
"project_number": "800733765231",
"firebase_url": "https://gabinete-digital-2020.firebaseio.com",
"project_id": "gabinete-digital-2020",
"storage_bucket": "gabinete-digital-2020.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:800733765231:android:e7ffc0b310037d9f13779a",
"android_client_info": {
"package_name": "com.gpr.gabinetedigital"
}
},
"oauth_client": [
{
"client_id": "800733765231-92oa7ib62ob0pkouphb5i5sp01vkalid.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyD0pfW45DLoW6mqvZRklJdbfSTskW22Fok"
}
],
"services": {
"appinvite_service": {
"other_platform_oauth_client": [
{
"client_id": "800733765231-92oa7ib62ob0pkouphb5i5sp01vkalid.apps.googleusercontent.com",
"client_type": 3
}
]
}
}
}
],
"configuration_version": "1"
}
-36
View File
@@ -1,36 +0,0 @@
<?xml version='1.0' encoding='utf-8'?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:requestLegacyExternalStorage="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:exported="true" android:label="@string/title_activity_main" android:launchMode="singleTop" android:name=".MainActivity" android:theme="@style/AppTheme.NoActionBarLaunch">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:exported="true" android:label="@string/app_name" android:name="de.mindlib.sendIntent.SendIntentActivity" android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="video/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="image/*" />
<data android:mimeType="video/*" />
</intent-filter>
</activity>
<provider android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true" android:name="androidx.core.content.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

@@ -1,34 +0,0 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>
@@ -1,170 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@mipmap/ic_launcher_foreground"/>
</adaptive-icon>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

+4 -2
View File
@@ -95,9 +95,11 @@ export class MessageEntity {
constructor() {}
get messageStatus() {
get messageHasId() {
if(this.id) {
return 'send'
return true
} else {
return false
}
}
@@ -0,0 +1,236 @@
import { Injectable } from '@angular/core';
import { IMessage, MessageAttachmentSource, MessageEntity, MessageEntitySchema, } from '../../entity/message';
import { z } from 'zod';
import { v4 as uuidv4 } from 'uuid';
import { InstanceId } from '../../../../module/chat/domain/chat-service.service';
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 { err, Result } from 'neverthrow';
import { MessageMapper } from '../../mapper/messageMapper';
import { RoomType } from "src/app/core/chat/entity/group";
import { TracingType, XTracerAsync } from 'src/app/services/monitoring/opentelemetry/tracer';
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';
import { base64Schema } from 'src/app/utils/zod';
export const MessageInputDTOSchema = z.object({
roomId: z.string().uuid().optional(),
receiverId: z.number().optional(),
senderId: z.number(),
message: z.string().nullable().optional(),
messageType: z.number(),
canEdit: z.boolean(),
oneShot: z.boolean(),
requireUnlock: z.boolean(),
requestId: z.string(),
attachment: z.object({
fileType: z.nativeEnum(MessageAttachmentFileType),
source: z.nativeEnum(MessageAttachmentSource),
file: base64Schema.optional(),
fileName: z.string().optional(),
applicationId: z.number().optional(),
docId: z.number().optional(),
mimeType: z.string().nullable().optional(),
description: z.string().optional()
}).optional()
});
export type MessageInputDTO = z.infer<typeof MessageInputDTOSchema>
export const MessageCreatePutDataDTOSchema = z.object({
id: z.string(),
roomId: z.string(),
sender: z.object({
wxUserId: z.number(),
wxFullName: z.string(),
wxeMail: z.string(),
userPhoto: z.string().optional()
}),
message: z.string().nullable().optional(),
messageType: z.number(),
sentAt: z.string(),
canEdit: z.boolean(),
oneShot: z.boolean(),
requireUnlock: z.boolean(),
requestId: z.string().optional().nullable(),
reactions: z.object({
id: z.string(),
reactedAt: z.string(),
reaction: z.string(),
sender: z.object({}),
}).array(),
info: z.array(z.object({
memberId: z.number(),
readAt: z.string().nullable(),
deliverAt: z.string().nullable()
})),
attachments: z.array(z.object({
fileType: z.nativeEnum(MessageAttachmentFileType),
source: z.nativeEnum(MessageAttachmentSource),
file: z.string().optional(),
fileName: z.string().optional(),
applicationId: z.number().optional(),
docId: z.number().optional(),
id: z.string().optional()
}))
});
export type MessageCreateOutPutDataDTO = z.infer<typeof MessageCreatePutDataDTOSchema>
@Injectable({
providedIn: 'root'
})
export class MessageCreateUseCaseService {
constructor(
private AttachmentLocalRepositoryService: IAttachmentLocalRepository,
private messageLocalDataSourceService: IMessageLocalRepository,
private messageSocketRepositoryService: IMessageSocketRepository,
private MemberListLocalRepository: IMemberLocalRepository
) { }
@XTracerAsync({name:'MessageCreateUseCaseService', module:'chat', bugPrint: true, waitNThrow: 5000})
async execute(message: IMessage, messageEnum: RoomType, tracing?: TracingType) {
const validation = zodSafeValidation<IMessage>(MessageEntitySchema, message)
if(validation.isOk()) {
message.sendAttemp++;
message.requestId = InstanceId +'@'+ uuidv4();
message.sending = true;
const createMessageLocally = this.messageLocalDataSourceService.insert(message)
createMessageLocally.then(async (value) => {
if(value.isOk()) {
const localId = value.value
message.$id = localId
if(message.hasAttachment) {
for (const attachment of message.attachments) {
if(attachment.source != MessageAttachmentSource.Webtrix) {
this.AttachmentLocalRepositoryService.insert({
$messageId: localId,
file: createBlobFromBase64(attachment.file, attachment.mimeType),
fileType: attachment.fileType,
source: attachment.source,
fileName: attachment.fileName,
applicationId: attachment.applicationId,
docId: attachment.docId,
mimeType: attachment.mimeType,
base64: createDataURL(attachment.file, attachment.mimeType)
}).then((e) => {
if(e.isErr()) {
Logger.error('failed to create attachment locally on send message', {
error: e.error,
data: createDataURL(attachment.file, attachment.mimeType).slice(0, 100) +'...'
})
}
})
attachment.safeFile = createDataURL(attachment.file, attachment.mimeType)
}
}
}
} else {
Logger.error('failed to insert locally', {
error: value.error.message
})
}
}).catch((error) => {
Logger.error('failed to insert catch', {
//error: createMessageLocally.error.message
})
})
let sendMessageResult: Result<MessageOutPutDataDTO, any>
if(messageEnum == RoomType.Group) {
const DTO = MessageMapper.fromDomain(message, message.requestId)
message.sending = true
sendMessageResult = await this.messageSocketRepositoryService.sendGroupMessage(DTO)
} else {
const DTO = MessageMapper.fromDomain(message, message.requestId)
delete DTO.roomId
message.sending = true
sendMessageResult = await this.messageSocketRepositoryService.sendDirectMessage(DTO)
}
// return this sendMessageResult
if(sendMessageResult.isOk()) {
message.id = sendMessageResult.value.id
console.log('sendMessageResult', sendMessageResult.value.id)
if(sendMessageResult.value.sender == undefined || sendMessageResult.value.sender == null) {
delete sendMessageResult.value.sender
}
let clone: MessageTable = {
...sendMessageResult.value,
id: sendMessageResult.value.id,
$id : message.$id
}
createMessageLocally.then(() => {
this.messageLocalDataSourceService.update(message.$id, {...clone, sending: false, roomId: clone.roomId}).then((data)=> {
if(data.isOk()) {
} else {
tracing.hasError('failed to update send message')
console.log(sendMessageResult)
console.log(data.error)
}
})
})
return sendMessageResult
} else {
Logger.error('failed to send message to the server', {
error: sendMessageResult.error
})
await this.messageLocalDataSourceService.update(message.$id, {sending: false, $id: message.$id})
return err('no connection')
}
} else {
if(validation.error.formErrors.fieldErrors.attachments) {
Logger.error('failed to send message doe to invalid attachment', {
zodErrorList: validation.error.errors,
data: message.attachments
})
} else {
Logger.error('failed to send message, validation failed', {
zodErrorList: validation.error.errors,
data: message
})
}
}
}
}
@@ -1,5 +1,6 @@
import { Injectable } from '@angular/core';
import { RemoteNotificationService } from 'src/app/module/notification/data/datasource/remote-notification.service';
import { SessionStore } from 'src/app/store/session.service';
import { z } from 'zod';
const NotificationDeleteAllByUserIdSchema = z.any()
@@ -14,8 +15,7 @@ export class NotificationDeleteAllServiceUseCase {
private RemoteNotificationService:RemoteNotificationService
) { }
async execute(userId: INotificationDeleteAllByUserId) {
return this.RemoteNotificationService.notificationDeleteAll(userId)
async execute() {
return this.RemoteNotificationService.notificationDeleteAll(SessionStore.user.UserId)
}
}
-5
View File
@@ -7,12 +7,7 @@ const routes: Routes = [
{
path: '',
component: IndexPage,
/* canActivate: [IndexGuard], */
children: [
/*{
path: '',
loadChildren: ()=> import('../pages/welcome/welcome.module').then(m => m.WelcomePageModule)
}, */
{
path: '',
loadChildren: ()=> import('../pages/login/login.module').then(m => m.LoginPageModule),
@@ -1,22 +1,22 @@
import { Dexie } from 'Dexie';
import { DexieMessageTable, messageTableColumn, MessageTable } from 'src/app/infra/database/dexie/instance/chat/schema/message';
import { DexieMessageTable, messageTableColumn } from 'src/app/infra/database/dexie/instance/chat/schema/message';
import { DexieMembersTableSchema, MemberTableColumn } from 'src/app/infra/database/dexie/instance/chat/schema/members';
import { DexieRoomsTable, RoomTableColumn } from 'src/app/infra/database/dexie/instance/chat/schema/room';
import { DexieTypingsTable, TypingTableColumn } from 'src/app/infra/database/dexie/instance/chat/schema/typing';
import { MessageEntity } from 'src/app/core/chat/entity/message';
import { AttachmentTableColumn, DexieAttachmentsTableSchema } from 'src/app/infra/database/dexie/instance/chat/schema/attachment';
import { DexieDistributionTable, DistributionTable, DistributionTableColumn } from './schema/destribution';
import { DexieDistributionTable, DistributionTableColumn } from './schema/destribution';
import { BoldTableColumn, DexieBoldTable } from './schema/bold';
import { DexieUserPhotoTable, UserPhotoTable, UserPhotoTableColumn } from './schema/user-foto';
// import FDBFactory from 'fake-indexeddb/lib/FDBFactory';
// import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange';
import { DexieUserPhotoTable, UserPhotoTableColumn } from './schema/user-foto';
import FDBFactory from 'fake-indexeddb/lib/FDBFactory';
import FDBKeyRange from 'fake-indexeddb/lib/FDBKeyRange';
// Database declaration (move this to its own module also)
export const chatDatabase = new Dexie('chat-database-v4',{
// indexedDB: new FDBFactory,
// IDBKeyRange: FDBKeyRange, // Mocking IDBKeyRange
//indexedDB: new FDBFactory,
//IDBKeyRange: FDBKeyRange, // Mocking IDBKeyRange
}) as Dexie & {
message: DexieMessageTable,
members: DexieMembersTableSchema,
+6 -2
View File
@@ -85,19 +85,23 @@
<div class="line"></div>
<ion-progress-bar type="indeterminate" *ngIf="isloading"></ion-progress-bar>
<!-- <ion-label (click)="asyncNotification()" *ngIf="NotificationHolderService.notificationList">{{notificationStatus}}</ion-label> -->
<button *ngIf="(notificationList$ | async) as notificationList" style="background: transparent; padding-top: 5px; float: right;" (click)="deleteAllNotification()" class="pointer cursor-pointer">
<ion-icon *ngIf="notificationList.length >= 1" (click)="deleteAllNotification()" style="height: 25px;width: 25px;float: right;" class="delete" src='assets/images/theme/gov/icons-delete.svg'></ion-icon>
</button>
</div>
</ion-header>
<ion-content class=" bg-blue">
<div class="d-flex flex-column height-100 overflow-y-auto">
<div class="notifications-content height-100">
<ion-list *ngIf="(notificationList$ | async) as notificationList">
<div class=" cursor-pointer ion-no-padding ion-no-margin" lines="none"
*ngFor="let item of notificationList; let i = index">
<div *ngIf="item.status==false " class="item" (click)="notificatinsRoutes(item.index, item)">
<div class="item" (click)="notificatinsRoutes(item.index, item)">
<div *ngIf="objectRead[item.notificationId] != true" class="item-conten1 item-conten-{{item.service}}-{{item.typeAgenda}}-{{item.role}} llll" >
<div class="notification-item">
+1
View File
@@ -77,6 +77,7 @@
}
.profile-content {
padding: 20px 20px;
padding-bottom: 5px;
//color: var(--profile-text-color) !important;
}
+10 -4
View File
@@ -4,7 +4,6 @@ import { AnimationController, ModalController } from '@ionic/angular';
import { AuthService } from 'src/app/services/auth.service';
import { EditProfilePage } from './edit-profile/edit-profile.page';
import { StorageService } from '../../services/storage.service';
import { NotificationsService } from '../../services/notifications.service';
import { SessionStore } from 'src/app/store/session.service';
import { ThemeService } from 'src/app/services/theme.service'
import { environment } from 'src/environments/environment';
@@ -20,7 +19,7 @@ import { isHttpError } from 'src/app/services/http.service';
import { UserRepositoryService } from 'src/app/module/user/data/user-repository.service';
import { UserProfilePicture } from 'src/app/module/user/data/datasource/user-local-repository.service';
import { UserService } from 'src/app/module/user/domain/user.service'
import { NotificationService } from 'src/app/module/notification/domain/notification.service'
@Component({
selector: 'app-profile',
@@ -63,7 +62,7 @@ export class ProfilePage implements OnInit {
private router: Router,
private zone: NgZone,
public ThemeService: ThemeService,
private notificationService: NotificationsService,
private NotificationService: NotificationService,
private processesService: ProcessesService,
private storageService: StorageService,
public NotificationHolderService: NotificationHolderService,
@@ -72,7 +71,7 @@ export class ProfilePage implements OnInit {
private toastService: ToastService,
private notificationRepositoryService: NotificationRepositoryService,
private UserRepositoryService: UserRepositoryService,
private UserService:UserService
private UserService:UserService,
) {
this.profilePictureSubject = this.UserRepositoryService.getProfilePictureLive() as any
@@ -417,4 +416,11 @@ export class ProfilePage implements OnInit {
this.deleteNotification(item);
}
async deleteAllNotification() {
console.log('nice job')
await this.NotificationService.deleteAllNotificationByUserId()
this.notificationRepositoryService.init()
}
}
@@ -21,7 +21,7 @@ export function NotificationListChanges(
const localItem = localMap.get(id);
if (!localItem) {
changes.insert.push(serverItem);
} else if (localItem.status !== serverItem.status) {
} else if (localItem.viewDate !== serverItem.viewDate) {
changes.update.push(serverItem);
}
}
@@ -122,7 +122,7 @@ export class LocalNotificationService {
return from(liveQuery( () => {
return NotificationDataSource.notification.orderBy('createdAt').reverse().toArray()
.then(notifications => {
return notifications.filter(notification => notification.status === false)
return notifications.filter(notification => notification.viewDate == null)
})
}))
}
@@ -132,7 +132,7 @@ export class LocalNotificationService {
return NotificationDataSource.notification
.toArray()
.then(notifications => {
return notifications.filter(notification => notification.status === false).length
return notifications.filter(notification => notification.viewDate == null).length
})
}))
}
@@ -22,7 +22,7 @@ export class RemoteNotificationService {
}
async notificationStatus(id: string) {
async notificationStatus(id: number) {
return await this.httpService.patch<NotificationOutputDTO>(`${this.baseUrl}/Notifications/${id}/status`);
}
@@ -30,5 +30,4 @@ export class RemoteNotificationService {
async notificationDeleteAll(userId: any) {
return await this.httpService.delete<NotificationOutputDTO>(`${this.baseUrl}/Notifications/${userId}`);
}
}
@@ -8,7 +8,7 @@ export const NotificationOutputDTOSchema = z.object({
total: z.number(),
result: z.array(
z.object({
id: z.string(),
id: z.number(),
service: z.string(),
title: z.string(),
body: z.string(),
@@ -17,7 +17,6 @@ export const NotificationOutputDTOSchema = z.object({
folderId: z.string().nullable(),
createdAt: z.string(),
viewDate: z.string().nullable(),
status: z.boolean(),
startDate: z.string().nullable(),
endDate: z.string().nullable(),
bodyEvent: z.string().nullable(),
@@ -2,16 +2,16 @@ import { Dexie, EntityTable, liveQuery } from 'Dexie';
import { z } from 'zod';
export const NotificationTableSchema = z.object({
notificationId: z.string().nullable(),
notificationId: z.number().nullable(),
title: z.string().optional().nullable(),
service: z.string().nullable(),
object: z.string().optional().nullable(),
idObject: z.string().nullable(),
viewDate: z.string().nullable(),
folderId: z.string().optional().nullable(),
dateInit: z.string().optional().nullable(),
dateEnd: z.string().optional().nullable(),
location: z.string().optional().nullable(),
status: z.boolean().optional(),
notificationBody: z.any().optional()
})
export type NotificationTable = z.infer<typeof NotificationTableSchema>
@@ -83,7 +83,7 @@ export class NotificationRepositoryService {
async notificationStatus(item: NotificationTable) {
await this.RemoteNotificationService.notificationStatus(item.notificationId)
item.status = true
item.viewDate = new Date().toUTCString()
this.LocalNotificationService.updateNotification(item)
this
this.init()
@@ -93,14 +93,14 @@ export class NotificationRepositoryService {
async RemoveNotificationStatus(item: NotificationTable) {
await this.RemoteNotificationService.notificationStatus(item.notificationId)
item.status = true
item.viewDate = new Date().toUTCString()
this.LocalNotificationService.updateNotification(item)
this.init()
return
}
async localNotificationStatus(item: NotificationTable) {
item.status = true
item.viewDate = new Date().toUTCString()
this.LocalNotificationService.updateNotification(item)
this.init()
return
@@ -14,9 +14,9 @@ export function NotificationListMapper(NotificationOutputDTO: NotificationOutput
dateInit: e.startDate,
dateEnd: e.endDate,
createdAt: e.createdAt,
status: e.status,
location: e.location,
notificationBody: e.body
notificationBody: e.body,
viewDate: e.viewDate
}
))
}
@@ -11,8 +11,8 @@ export class NotificationService {
) { }
deleteAllNotificationByUserId(userId: INotificationDeleteAllByUserId) {
this.NotificationDeleteAllServiceUseCase.execute(userId)
deleteAllNotificationByUserId() {
return this.NotificationDeleteAllServiceUseCase.execute()
}
@@ -3,7 +3,7 @@ import { ProcessesService } from 'src/app/services/processes.service';
import { ActivatedRoute } from '@angular/router';
import { Event } from '../../../../models/event.model';
import { MenuController, ModalController, PopoverController } from '@ionic/angular';
import { momentG } from 'src/plugin/momentG'
import { momentG } from 'src/plugin/momentG';
import { DiscartExpedientModalPage } from '../../discart-expedient-modal/discart-expedient-modal.page';
import { BookMeetingModalPage } from '../../expediente/book-meeting-modal/book-meeting-modal.page';
import { CreateProcessPage } from 'src/app/modals/create-process/create-process.page';
@@ -189,40 +189,38 @@ export class GroupContactsPage implements OnInit {
async deleteMember(user: UserContacts) {
this.showLoader = true;
// this.chatServiceService.removeMember({
// roomId: this.roomId,
// members: [ user.wxUserId]
// })
// if(this.currentMembers.length >= 3) {
this.showLoader = true;
// this.currentMembers = this.currentMembers.filter( e => e.wxUserId != user.wxUserId)
const result = await this.chatServiceService.removeMemberToRoom({
id: this.roomId,
members: [ user.wxUserId]
})
const result = await this.chatServiceService.removeMemberToRoom({
id: this.roomId,
members: [ user.wxUserId]
})
if(result.isOk()) {
this.currentMembers = this.currentMembers.filter( e => e.wxUserId != user.wxUserId)
if(result.isOk()) {
this.currentMembers = this.currentMembers.filter( e => e.wxUserId != user.wxUserId)
const firstLetter = user.wxFullName.charAt(0)
const firstLetter = user.wxFullName.charAt(0)
if(!this.userContainer[firstLetter]) {
user['isChecked'] = false
this.userContainer[firstLetter] = [user as any]
} else {
user['isChecked'] = false
this.userContainer[firstLetter].push(user as any)
}
if(!this.userContainer[firstLetter]) {
user['isChecked'] = false
this.userContainer[firstLetter] = [user as any]
} else {
user['isChecked'] = false
this.userContainer[firstLetter].push(user as any)
} else if(result.error instanceof HttpRequest) {
this.httpErrorHandle.httpStatusHandle(result.error)
} else if(result.error instanceof ZodError) {
console.log(result.error.issues)
}
} else if(result.error instanceof HttpRequest) {
this.httpErrorHandle.httpStatusHandle(result.error)
} else if(result.error instanceof ZodError) {
console.log(result.error.issues)
}
this.showLoader = false;
this.showLoader = false;
//} else {
// alert('---')
//}
}
@@ -59,6 +59,11 @@
</div>
<div class="message-container rotate-div" *ngIf="message.showMessage">
<div *ngIf="message.sender.wxUserId != SessionStore.user.UserId && roomType == RoomTypeEnum.Group">
<b>
{{ message.sender.wxFullName }}
</b>
</div>
<div class="d-flex justify-content-between">
<div>
<div style="white-space: pre-line;">
@@ -125,8 +130,8 @@
<div class="message-item-options d-flex justify-content-end">
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer"></fa-icon>
<mat-menu class="d-block" #beforeMenu="matMenu" xPosition="before">
<button (click)="messageDelete(message)" class="menuButton d-block py-2 px-10">Apagar mensagem</button>
<button *ngIf="!message.hasAttachment" (click)="editMessage(message)" class="menuButton d-block py-2 px-10">Editar mensagem</button>
<button *ngIf="message.sender.wxUserId == SessionStore.user.UserId" (click)="messageDelete(message)" class="menuButton d-block py-2 px-10">Apagar mensagem</button>
<button *ngIf="!message.hasAttachment && message.sender.wxUserId == SessionStore.user.UserId" (click)="editMessage(message)" class="menuButton d-block py-2 px-10">Editar mensagem</button>
<button (click)="toggleEmojiPicker(message)" class="menuButton d-block py-2 px-10">Reagir mensagem</button>
</mat-menu>
</div>
@@ -300,7 +300,7 @@ export class MessagesPage implements OnInit, OnChanges, AfterViewInit, OnDestroy
return 'allViewed'
} else if(this.allReceived(message)) {
return 'allReceived'
} else if (message.messageStatus == 'send') {
} else if (message.messageHasId) {
return 'enviado'
} else {
return 'enviar'
@@ -5,12 +5,17 @@ import { ThemeService } from 'src/app/services/theme.service'
import { SetRoomOwnerPage } from 'src/app/ui/chat/modal/set-room-owner/set-room-owner.page';
import { SessionStore } from 'src/app/store/session.service';
import { ZodError } from 'zod';
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 { RoomInfoPage } from '../room-info/room-info.page';
import { RoomType } from 'src/app/core/chat/entity/group';
import { isHttpResponse } from 'src/app/infra/http/http.service';
interface ISetRoomOwner {
addAdminBeforeLeave: null | boolean
}
@Component({
selector: 'app-chat-popover',
templateUrl: './chat-popover.page.html',
@@ -31,7 +36,8 @@ export class ChatPopoverPage implements OnInit {
private navParams: NavParams,
private toastService: ToastService,
public ThemeService: ThemeService,
private ChatServiceService: ChatServiceService
private ChatServiceService: ChatServiceService,
private MemberListLocalRepository: MemberListLocalRepository
) {
this.roomId = this.navParams.get('roomId');
this.isAdmin = this.navParams.get('isAdmin');
@@ -55,7 +61,7 @@ export class ChatPopoverPage implements OnInit {
//Top menu options
//Close
async setRoomOwner() {
async setRoomOwner({addAdminBeforeLeave = null}: ISetRoomOwner) {
let classs;
if (window.innerWidth < 701) {
classs = 'modal modal-desktop'
@@ -68,26 +74,36 @@ export class ChatPopoverPage implements OnInit {
backdropDismiss: true,
componentProps: {
roomId: this.roomId,
isAdmin: this.isAdmin
isAdmin: this.isAdmin,
addAdminBeforeLeave
}
});
await modal.present();
modal.onDidDismiss().then((res)=>{
modal.onDidDismiss().then((res) => {
if(res.data == 'success'){
this.leaveGroup();
//this.ChatSystemService.hidingRoom(this.roomId);
}
});
}
}
setAdmin() {
this.setRoomOwner();
setAdmin(data:ISetRoomOwner) {
this.setRoomOwner(data);
}
async leaveGroup() {
//this.setRoomOwner();
if(this.isAdmin) {
const currentMemberToMap = await this.MemberListLocalRepository.getRoomMemberById(this.roomId)
const adminCount = currentMemberToMap.filter(e => e.isAdmin);
this.toastService._badRequest("É necessário adicionar um administrador");
if(adminCount.length <= 1) {
this.setAdmin({addAdminBeforeLeave: true});
return;
}
}
this.showLoader = true
const result = await this.ChatServiceService.leaveRoom({
id: this.roomId,
@@ -68,6 +68,11 @@
</div>
<div class="message-container rotate-div" *ngIf="message.showMessage">
<div *ngIf="message.sender.wxUserId != SessionStore.user.UserId && RoomStore.room.roomType == RoomTypeEnum.Group">
<b>
{{ message.sender.wxFullName }}
</b>
</div>
<div class="d-flex justify-content-between">
<div>
<div style="white-space: pre-line;">
@@ -142,8 +147,8 @@
<div class="message-item-options d-flex justify-content-end">
<fa-icon [matMenuTriggerFor]="beforeMenu" icon="chevron-down" class="message-options-icon cursor-pointer"></fa-icon>
<mat-menu class="custom-menu d-block" #beforeMenu="matMenu" xPosition="before">
<button (click)="messageDelete(message)" class="menuButton d-block py-2 px-10">Apagar mensagem</button>
<button *ngIf="!message.hasAttachment" (click)="editMessage(message)" class="menuButton d-block py-2 px-10">Editar mensagem</button>
<button *ngIf="message.sender.wxUserId == SessionStore.user.UserId" (click)="messageDelete(message)" class="menuButton d-block py-2 px-10">Apagar mensagem</button>
<button *ngIf="!message.hasAttachment && message.sender.wxUserId == SessionStore.user.UserId" (click)="editMessage(message)" class="menuButton d-block py-2 px-10">Editar mensagem</button>
<button (click)="toggleEmojiPicker(message)" class="menuButton d-block py-2 px-10">Reagir mensagem</button>
</mat-menu>
</div>
@@ -149,7 +149,7 @@ export class MessagesPage implements OnInit, AfterViewInit, OnDestroy {
return 'allViewed'
} else if(this.allReceived(message)) {
return 'allReceived'
} else if (message.messageStatus == 'send') {
} else if (message.messageHasId) {
return 'enviado'
} else {
return 'enviar'
@@ -19,6 +19,7 @@ export class SetRoomOwnerPage implements OnInit {
textSearch:string = "";
roomId:any;
members:any;
addAdminBeforeLeave: boolean | null;
roomMembers$!: DexieObservable<MemberTable[] | undefined>
constructor(
@@ -31,6 +32,7 @@ export class SetRoomOwnerPage implements OnInit {
) {
this.roomId = this.navParams.get('roomId');
this.members = this.navParams.get('members');
this.addAdminBeforeLeave = this.navParams.get('addAdminBeforeLeave');
}
ngOnInit() {
@@ -68,8 +70,10 @@ export class SetRoomOwnerPage implements OnInit {
});
if(result.isOk()) {
this.chatServiceService.getRoomById(this.roomId);
// this.modalController.dismiss('success');
await this.chatServiceService.getRoomById(this.roomId);
if(this.addAdminBeforeLeave) {
this.modalController.dismiss('success');
}
} else {
this.toastService._badRequest('Não foi possível completar a ação, por favor tente novamente.');
}
+4 -2
View File
@@ -99,9 +99,11 @@ export class MessageViewModal {
}
get messageStatus() {
get messageHasId() {
if(this.id) {
return 'send'
return true
} else {
return false
}
}
+6 -6
View File
@@ -1,11 +1,11 @@
export let versionData = {
"shortSHA": "5a1bbe610",
"SHA": "5a1bbe6103c983534e6a66d69a7344a8520d67f5",
"shortSHA": "aef73625f",
"SHA": "aef73625f081830c368591d90bc09f12a31d7fef",
"branch": "feature/login-v2",
"lastCommitAuthor": "'Peter Maquiran'",
"lastCommitTime": "'Thu Dec 5 19:14:11 2024 +0100'",
"lastCommitMessage": "fix issues",
"lastCommitNumber": "6134",
"changeStatus": "On branch feature/login-v2\nYour branch is ahead of 'origin/feature/login-v2' by 1 commit.\n (use \"git push\" to publish your local commits)\n\nChanges to be committed:\n (use \"git restore --staged <file>...\" to unstage)\n\tnew file: src/app/core/notification/repository/notification-remote-repository.ts\n\tnew file: src/app/core/notification/use-case/notification-delete-all-use-case.service.ts\n\tmodified: src/app/module/notification/data/datasource/remote-notification.service.ts\n\tdeleted: src/app/module/notification/data/notification-repository.service.spec.ts\n\tnew file: src/app/module/notification/domain/notification.service.ts\n\tnew file: src/app/module/notification/notification.module.ts\n\tmodified: src/app/pages/gabinete-digital/gabinete-digital.page.html\n\tmodified: src/app/ui/chat/chat.page.ts\n\tmodified: src/environments/suport/dev.ts\n\tmodified: version/git-version.ts",
"lastCommitTime": "'Fri Dec 6 11:21:32 2024 +0100'",
"lastCommitMessage": "fix errors",
"lastCommitNumber": "6135",
"changeStatus": "On branch feature/login-v2\nYour branch is up to date with 'origin/feature/login-v2'.\n\nChanges to be committed:\n (use \"git restore --staged <file>...\" to unstage)\n\tdeleted: android/app/google-services.json\n\tdeleted: android/app/src/main/AndroidManifest.xml\n\tdeleted: android/app/src/main/res/drawable-land-hdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-land-ldpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-land-mdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-land-xhdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-land-xxhdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-land-xxxhdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-port-hdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-port-ldpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-port-mdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-port-xhdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-port-xxhdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-port-xxxhdpi/splash.png\n\tdeleted: android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml\n\tdeleted: android/app/src/main/res/drawable/ic_launcher_background.xml\n\tdeleted: android/app/src/main/res/drawable/splash.png\n\tdeleted: android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml\n\tdeleted: android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml\n\tdeleted: android/app/src/main/res/mipmap-hdpi/ic_launcher.png\n\tdeleted: android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png\n\tdeleted: android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png\n\tdeleted: android/app/src/main/res/mipmap-mdpi/ic_launcher.png\n\tdeleted: android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png\n\tdeleted: android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png\n\tdeleted: android/app/src/main/res/mipmap-xhdpi/ic_launcher.png\n\tdeleted: android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png\n\tdeleted: android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png\n\tdeleted: android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png\n\tdeleted: android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png\n\tdeleted: android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png\n\tdeleted: android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png\n\tdeleted: android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png\n\tdeleted: android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png\n\tmodified: src/app/core/chat/entity/message.ts\n\tnew file: src/app/core/chat/usecase/message/message-create-use-case.service copy.ts\n\tmodified: src/app/core/notification/use-case/notification-delete-all-use-case.service.ts\n\tmodified: src/app/index/index-routing.module.ts\n\tmodified: src/app/infra/database/dexie/instance/chat/service.ts\n\tmodified: src/app/modals/profile/profile.page.html\n\tmodified: src/app/modals/profile/profile.page.scss\n\tmodified: src/app/modals/profile/profile.page.ts\n\tmodified: src/app/module/notification/data/async/changes/notificationListChange.ts\n\tmodified: src/app/module/notification/data/datasource/local-notification.service.ts\n\tmodified: src/app/module/notification/data/datasource/remote-notification.service.ts\n\tmodified: src/app/module/notification/data/dto/NotificationOutputDTO.ts\n\tmodified: src/app/module/notification/data/infra/db/notification.db.ts\n\tmodified: src/app/module/notification/data/notification-repository.service.ts\n\tmodified: src/app/module/notification/domain/mapper/notificationListMapper.ts\n\tmodified: src/app/module/notification/domain/notification.service.ts\n\tmodified: src/app/pages/gabinete-digital/despachos/despacho/despacho.page.ts\n\tmodified: src/app/ui/chat/component/group-contacts/group-contacts.page.ts\n\tmodified: src/app/ui/chat/component/messages/messages.page.html\n\tmodified: src/app/ui/chat/component/messages/messages.page.ts\n\tmodified: src/app/ui/chat/modal/chat-popover/chat-popover.page.ts\n\tmodified: src/app/ui/chat/modal/messages/messages.page.html\n\tmodified: src/app/ui/chat/modal/messages/messages.page.ts\n\tmodified: src/app/ui/chat/modal/set-room-owner/set-room-owner.page.ts\n\tmodified: src/app/ui/chat/store/model/message.ts",
"changeAuthor": "peter.maquiran"
}