receive user typing

This commit is contained in:
Peter Maquiran
2024-07-17 16:39:18 +01:00
parent 0312df88e8
commit cf6fe3a4c8
17 changed files with 424 additions and 33 deletions
@@ -40,18 +40,30 @@ const TableMemberListSchema = z.object({
joinAt: z.string()
})
export const TypingSchema = z.object({
id: z.string().optional(),
userId: z.string(),
roomId: z.string(),
entryDate: z.string()
})
export type TableRoom = z.infer<typeof tableSchema>
export type TableMemberList = z.infer<typeof TableMemberListSchema>
export type TypingList = z.infer<typeof TypingSchema>
// Database declaration (move this to its own module also)
export const roomDataSource = new Dexie('FriendDatabase') as Dexie & {
room: EntityTable<TableRoom, 'id'>;
memberList: EntityTable<TableMemberList, '$roomIdUserId'>;
typing: EntityTable<TableMemberList, '$roomIdUserId'>;
};
roomDataSource.version(1).stores({
room: 'id, createdBy, roomName, roomType, expirationDate, lastMessage',
memberList: '$roomIdUserId, id, user, joinAt, roomId',
TypingList: '++id, userId, roomId, entryDate'
});
@Injectable({
@@ -63,6 +75,20 @@ export class RoomLocalDataSourceService {
constructor() {}
@ValidateSchema(TypingSchema)
async addUserTyping(data: any) {
try {
const result = await roomDataSource.typing.add(data)
return ok(result)
} catch (e) {
return err(false)
}
}
async removeUserTyping() {
}
@ValidateSchema(tableSchema)
async createRoom(data: TableRoom) {
try {
@@ -0,0 +1,18 @@
import { Injectable } from '@angular/core';
import { SignalRService } from '../../../infra/socket/signal-r.service';
import { SessionStore } from 'src/app/store/session.service';
@Injectable({
providedIn: 'root'
})
export class UserTypingLiveDataSourceService {
constructor(
private SignalRLiveDataSourceService: SignalRService
) { }
sendTyping(ChatRoomId) {
return this.SignalRLiveDataSourceService.sendTyping({ChatRoomId, UserName:SessionStore.user.FullName})
}
}
@@ -0,0 +1,63 @@
import { Injectable } from '@angular/core';
import { z } from 'zod';
import { Dexie, EntityTable, liveQuery, Observable } from 'Dexie';
import { err, ok } from 'neverthrow';
export const TypingSchema = z.object({
id: z.string().optional(),
userId: z.string().optional(),
userName: z.string(),
chatRoomId: z.string(),
entryDate: z.string()
})
export type TypingList = z.infer<typeof TypingSchema>
export type UserTypingList = z.infer<typeof TypingSchema>
// Database declaration (move this to its own module also)
export const TypingDataSource = new Dexie('UserTyping') as Dexie & {
TypingList: EntityTable<TypingList, 'id'>;
}
TypingDataSource.version(1).stores({
TypingList: 'id, userId, userName, chatRoomId, entryDate'
});
@Injectable({
providedIn: 'root'
})
export class UserTypingLocalDataSourceService {
constructor() { }
async addUserTyping(data: TypingList) {
data.id = data.chatRoomId + '@' + data.userName
try {
const result = await TypingDataSource.TypingList.add(data)
return ok(result)
} catch (e) {
return err(false)
}
}
async removeUserTyping(data: TypingList) {
const id = data.chatRoomId + '@' + data.userName
try {
const result = await TypingDataSource.TypingList.delete(id)
return ok(result)
} catch (e) {
return err(false)
}
}
getUserTypingLive() {
return liveQuery(() => TypingDataSource.TypingList.toArray());
}
}
@@ -0,0 +1,70 @@
import { createAction, createFeatureSelector, createReducer, createSelector, on, props } from '@ngrx/store';
import { TypingList } from './user-typing-local-data-source.service';
export const addUserTyping = createAction(
'[Typing] Add User Typing',
props<{ data: TypingList }>()
);
export const removeUserTyping = createAction(
'[Typing] Remove User Typing',
props<{ data: TypingList }>()
);
export const loadUserTyping = createAction('[Typing] Load User Typing');
export const loadUserTypingSuccess = createAction(
'[Typing] Load User Typing Success',
props<{ data: TypingList[] }>()
);
export const loadUserTypingFailure = createAction(
'[Typing] Load User Typing Failure',
props<{ error: any }>()
);
export interface TypingState {
typingList: TypingList[];
error: any;
}
export const initialState: TypingState = {
typingList: [],
error: null
};
export const typingReducer = createReducer(
initialState,
on(loadUserTypingSuccess, (state, { data }) => ({
...state,
typingList: data
})),
on(loadUserTypingFailure, (state, { error }) => ({
...state,
error
})),
on(addUserTyping, (state, { data }) => ({
...state,
typingList: [...state.typingList, data]
})),
on(removeUserTyping, (state, { data }) => ({
...state,
typingList: state.typingList.filter(
typing => typing.chatRoomId !== data.chatRoomId || typing.userName !== data.userName
)
}))
);
export const selectCalendarState = createFeatureSelector<TypingState>('userTyping');
export const selectAllUserSource = createSelector(
selectCalendarState,
(state: TypingState) => state.typingList
);
export const selectUserTypingList = () => createSelector(
selectAllUserSource,
(typingList) => typingList
);