Skip to content

Commit 8ee9da8

Browse files
committed
Load Messages
1 parent c84fb58 commit 8ee9da8

File tree

7 files changed

+119
-4
lines changed

7 files changed

+119
-4
lines changed

client/src/app/graphql/graphql-root.component.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { pluck } from 'rxjs/operators';
55

66
import { Chat, Pages, PageChangeEvent, MessageEvent, ID } from '../whatsapp';
77
import GetChats from './queries/get-chats.graphql';
8+
import GetChat from './queries/get-chat.graphql';
89

910
@Component({
1011
selector: 'app-graphql-root',
@@ -52,5 +53,11 @@ export class GraphQLRootComponent {
5253
.valueChanges.pipe(pluck('data', 'chats'));
5354
}
5455

55-
loadChat(id: ID) {}
56+
loadChat(id: ID) {
57+
this.chat = this.loona
58+
.query(GetChat, {
59+
id,
60+
})
61+
.valueChanges.pipe(pluck('data', 'chat'));
62+
}
5663
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import gql from 'graphql-tag';
2+
3+
import { MessageFragment, UserFragment } from './fragments.graphql';
4+
5+
export default gql`
6+
query getChat($id: ID!) {
7+
chat(id: $id) @rest(type: "Chat", path: "/chats/{args.id}") {
8+
id @export(as: "chatId")
9+
members @rest(type: "[User]", path: "/chats/:chatId/members") {
10+
...UserFragment
11+
}
12+
messages @rest(type: "[Message]", path: "/chats/:chatId/messages") {
13+
...MessageFragment
14+
}
15+
}
16+
}
17+
${MessageFragment}
18+
${UserFragment}
19+
`;

client/src/app/ngrx/chats.service.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ export class ChatsService {
1919
);
2020
}
2121

22+
getMessages(chatId: ID) {
23+
return this.fetchChatMessages(chatId);
24+
}
25+
2226
private fetchChats() {
2327
return this.http.get<ChatsResponse>(api('/chats'));
2428
}
@@ -27,6 +31,10 @@ export class ChatsService {
2731
return this.http.get<UserResponse>(link);
2832
}
2933

34+
private fetchChatMessages(id: string) {
35+
return this.http.get<ChatMessagesResponse>(api(`/chats/${id}/messages`));
36+
}
37+
3038
private resolveChat(chat: ChatResponse) {
3139
return combineLatest(chat.members.map(link => this.fetchUser(link))).pipe(
3240
map(members => {

client/src/app/ngrx/ngrx-root.component.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { Observable } from 'rxjs';
33
import { Store } from '@ngrx/store';
44

55
import { Chat, Pages, PageChangeEvent, MessageEvent, ID } from '../whatsapp';
6-
import { LoadChats } from './state/chat.actions';
6+
import { LoadChats, LoadMessages } from './state/chat.actions';
77
import { AppState } from './app.state';
88

99
@Component({
@@ -55,5 +55,13 @@ export class NgRxRootComponent {
5555
this.chats = this.store.select(state => state.chats);
5656
}
5757

58-
loadChat(id: ID) {}
58+
loadChat(id: ID) {
59+
this.store.dispatch(
60+
new LoadMessages({
61+
chatId: id,
62+
}),
63+
);
64+
65+
this.chat = this.store.select(state => state.chats.find(c => c.id === id));
66+
}
5967
}

client/src/app/ngrx/state/chat.actions.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ export enum ActionTypes {
55
LoadChats = '[Chats] Load',
66
LoadChatsSuccess = '[Chats] Load Success',
77
LoadChatsFailure = '[Chats] Load Failure',
8+
9+
LoadMessages = '[Chat] Load messages',
10+
LoadMessagesSuccess = '[Chat] Load messages Success',
11+
LoadMessagesFailure = '[Chat] Load messages Failure',
812
}
913

1014
// All chats
@@ -26,4 +30,36 @@ export class LoadChatsFailure implements Action {
2630
readonly type = ActionTypes.LoadChatsFailure;
2731
}
2832

29-
export type ChatAction = LoadChats | LoadChatsSuccess | LoadChatsFailure;
33+
// Chat's messages
34+
35+
export class LoadMessages implements Action {
36+
readonly type = ActionTypes.LoadMessages;
37+
38+
constructor(
39+
public payload: {
40+
chatId: ID;
41+
},
42+
) {}
43+
}
44+
45+
export class LoadMessagesSuccess implements Action {
46+
readonly type = ActionTypes.LoadMessagesSuccess;
47+
constructor(
48+
public payload: {
49+
chatId: ID;
50+
messages: Message[];
51+
},
52+
) {}
53+
}
54+
55+
export class LoadMessagesFailure implements Action {
56+
readonly type = ActionTypes.LoadMessagesFailure;
57+
}
58+
59+
export type ChatAction =
60+
| LoadChats
61+
| LoadChatsSuccess
62+
| LoadChatsFailure
63+
| LoadMessages
64+
| LoadMessagesSuccess
65+
| LoadMessagesFailure;

client/src/app/ngrx/state/chat.effects.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import {
99
ActionTypes,
1010
LoadChatsSuccess,
1111
LoadChatsFailure,
12+
LoadMessagesSuccess,
13+
LoadMessagesFailure,
1214
} from './chat.actions';
1315
import { User } from '../../whatsapp';
1416
import { ChatsService } from '../chats.service';
@@ -31,4 +33,24 @@ export class ChatEffects {
3133
);
3234
}),
3335
);
36+
37+
@Effect()
38+
loadMessages$: Observable<ChatAction> = this.actions$.pipe(
39+
ofType(ActionTypes.LoadMessages),
40+
mergeMap(action =>
41+
this.store$
42+
.select(state => state.chats.find(c => c.id === action.payload.chatId))
43+
.pipe(first()),
44+
),
45+
mergeMap(chat =>
46+
this.chats
47+
.getMessages(chat.id)
48+
.pipe(
49+
mergeMap(messages =>
50+
of(new LoadMessagesSuccess({ messages, chatId: chat.id })),
51+
),
52+
),
53+
),
54+
catchError(() => of(new LoadMessagesFailure())),
55+
);
3456
}

client/src/app/ngrx/state/chat.reducer.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@ export function chatReducer(
1414
return chats;
1515
}
1616

17+
case ActionTypes.LoadMessagesSuccess: {
18+
const { chatId, messages } = action.payload;
19+
20+
return state.map(chat => {
21+
if (chat.id === chatId) {
22+
return {
23+
...chat,
24+
messages,
25+
};
26+
}
27+
28+
return chat;
29+
});
30+
}
31+
1732
default:
1833
return state;
1934
}

0 commit comments

Comments
 (0)