Chat shows messages

This commit is contained in:
2021-04-01 16:20:13 +02:00
parent 0d626bf7d9
commit 45e3ada041
11 changed files with 141 additions and 36 deletions

6
package-lock.json generated
View File

@@ -2086,6 +2086,12 @@
"integrity": "sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==",
"dev": true
},
"@types/matrix-js-sdk": {
"version": "9.2.1",
"resolved": "https://registry.npmjs.org/@types/matrix-js-sdk/-/matrix-js-sdk-9.2.1.tgz",
"integrity": "sha512-RgNJ5ffGdt0bXyxQpbDXtuyAp/kH205Pgv/RZCoI29jbQXOScY6HlKxi6HJAlW5vexaYlCzGu+70tYqK0sxraQ==",
"dev": true
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",

View File

@@ -38,6 +38,7 @@
"@angular/compiler-cli": "~11.2.6",
"@types/jasmine": "~3.5.0",
"@types/jasminewd2": "~2.0.3",
"@types/matrix-js-sdk": "^9.2.1",
"@types/node": "^12.20.6",
"codelyzer": "^6.0.0",
"jasmine-core": "~3.6.0",

View File

@@ -7,6 +7,10 @@ import { NgxMatDatetimePickerModule } from '@angular-material-components/datetim
import { AppComponent } from './app.component';
import { MaterialModule } from './material/material.module';
import { MatGridListModule } from '@angular/material/grid-list';
import { MatDatepickerModule } from '@angular/material/datepicker';
import {MatListModule} from '@angular/material/list';
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
import { HomeComponent } from './pages/home/home.component';
import { TravelComponent } from './pages/travel/travel.component';
@@ -16,11 +20,10 @@ import { HeaderComponent } from './views/header/header.component';
import { ListComponent } from './views/list/list.component';
import { TravelFormComponent } from './views/travel-form/travel-form.component';
import { NewTravelComponent } from './pages/new-travel/new-travel.component';
import { MatDatepickerModule } from '@angular/material/datepicker';
import { NgxMatMomentModule } from '@angular-material-components/moment-adapter';
import { AppRouterModule } from './router.module';
import { AvailablePlacesPipe } from './pipes/available-places.pipe';
import { AuthConfigModule } from './auth/auth-config.module';
import { ChatComponent } from './views/chat/chat.component';
@NgModule({
imports: [
@@ -31,6 +34,8 @@ import { AuthConfigModule } from './auth/auth-config.module';
BrowserAnimationsModule,
AppRouterModule,
MaterialModule,
MatListModule,
MatGridListModule,
MatDatepickerModule,
NgxMatDatetimePickerModule,
NgxMatMomentModule,
@@ -45,7 +50,8 @@ import { AuthConfigModule } from './auth/auth-config.module';
ListComponent,
TravelFormComponent,
NewTravelComponent,
AvailablePlacesPipe
AvailablePlacesPipe,
ChatComponent
],
providers: [
// (useHash) ? { provide: LocationStrategy, useClass: HashLocationStrategy } : [],

View File

@@ -0,0 +1,4 @@
export interface MatrixLoginDto {
access_token: string;
user_id: string;
}

View File

@@ -16,6 +16,13 @@
</mat-card-content>
</mat-card>
<mat-card *ngIf="travel">
<mat-card-title>Chat</mat-card-title>
<mat-card-content>
<app-chat [roomId]="travel.matrixRoomId"></app-chat>
</mat-card-content>
</mat-card>
<button mat-raised-button class="btn btn-default" (click)="goBack()">Back</button>
<button *ngIf="canJoin" mat-raised-button class="btn btn-default" (click)="join()">Join</button>
<button *ngIf="canLeave" mat-raised-button class="btn btn-default" (click)="leave()">Leave</button>

View File

@@ -82,16 +82,6 @@ export class TravelComponent implements OnInit {
.subscribe(res => {
if (res.success) {
this.travel = Object.assign( new Travel(), res.data );
console.log({travel: this.travel});
this.chatService.getRoomMessages(this.travel.matrixRoomId);
this.chatService.listemRoomMessages(this.travel.matrixRoomId, (event: any) => {
console.log(
// the room name will update with m.room.name events automatically
"%s: %s", event.getSender(), event.getContent().body
);
});
}
else {
console.error('Error getting travel ' + this.travelId + ': ' + res.error);

View File

@@ -3,6 +3,11 @@ import { Injectable } from '@angular/core';
import * as olm from 'olm';
global.Olm = olm;
import * as matrix from 'matrix-js-sdk';
import { RoomMember } from 'matrix-js-sdk/src/models/room';
import { Room } from 'matrix-js-sdk/src/models/room';
import { EventTimeline } from 'matrix-js-sdk/src/models/event-timeline';
import { MatrixLoginDto } from '../entities/matrix-login-dto';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
@Injectable({
providedIn: 'root'
@@ -19,7 +24,7 @@ export class ChatService {
}
async login(loginToken: string): Promise<void> {
const res = await this.http.post<object>(
const matrixLogin = await this.http.post<MatrixLoginDto>(
'http://synapse:8008/_matrix/client/r0/login',
{
initial_device_display_name: 'Okupa mi coche',
@@ -28,42 +33,39 @@ export class ChatService {
}
).toPromise();
console.log('LOGGED TO CHAT');
console.log(res);
console.log(matrixLogin);
this.client = matrix.createClient({
baseUrl: 'http://localhost:8008',
accessToken: res['access_token'],
userId: res['user_id']
accessToken: matrixLogin.access_token,
userId: matrixLogin.user_id
});
await this.client.startClient({ initialSyncLimit: 10 });
await this.client.startClient({ initialSyncLimit: 100 });
this.client.once('sync', function (state, prevState, res) {
this.client.once('sync', (state: string, prevState: string, _: any) => {
if (state === 'PREPARED') {
console.log("CHAT SYNC FINISHED");
console.log('CHAT SYNC FINISHED');
} else {
console.log(state);
}
});
// this.client.publicRooms((err: any, data: any) => {
// console.log('Public Rooms: %s', JSON.stringify(data));
// });
}
getRoomMessages(roomId: string): void {
const room = this.client?.getRoom(roomId);
const members = room?.getJoinedMembers();
members?.forEach(member => {
console.log(member);
});
room?.timeline.forEach(t => {
console.log(JSON.stringify(t.event));
});
getRoomMessages(roomId: string): MatrixEvent[] {
console.log('roomId=' + roomId);
const room: Room = this.client?.getRoom(roomId) as Room;
console.log({room});
return room?.timeline
.filter((t: MatrixEvent) => (t.getType() === 'm.room.message'));
}
listemRoomMessages(roomId: string, handle: (event: any) => void): void {
this.client?.on('Room.timeline', function (event, room, toStartOfTimeline) {
getRoomMembers(roomId: string): RoomMember[] {
const room: Room = this.client?.getRoom(roomId) as Room;
return room?.getJoinedMembers();
}
listemRoomMessages(roomId: string, handle: (event: EventTimeline) => void): void {
this.client?.on('Room.timeline', (event: EventTimeline, room: Room, toStartOfTimeline: boolean) => {
if (room.roomId !== roomId) {
return; // only listen to specified room
}

View File

@@ -0,0 +1,5 @@
.chat-messages {
width: 100%;
height: 100%;
overflow-y: scroll;
}

View File

@@ -0,0 +1,18 @@
<mat-grid-list cols="5">
<mat-grid-tile colspan=4>
<mat-list class="chat-messages">
<mat-list-item #messageItem *ngFor="let message of messages">
<h3 matLine> {{message.getSender()}} </h3>
<p matLine>
{{message.getContent().body}}
</p>
</mat-list-item>
</mat-list>
</mat-grid-tile>
<mat-grid-tile>
<mat-list>
Miembros
</mat-list>
</mat-grid-tile>
</mat-grid-list>

View File

@@ -0,0 +1,25 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ChatComponent } from './chat.component';
describe('ChatComponent', () => {
let component: ChatComponent;
let fixture: ComponentFixture<ChatComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChatComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ChatComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,41 @@
import { Component, Input, OnInit, AfterViewInit, ElementRef, ViewChildren } from '@angular/core';
import { ChatService } from 'src/app/services/chat.service';
import { RoomMember } from 'matrix-js-sdk/src/models/room';
import { Room } from 'matrix-js-sdk/src/models/room';
import { MatrixEvent } from 'matrix-js-sdk/src/models/event';
import { QueryList } from '@angular/core';
@Component({
selector: 'app-chat',
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.css']
})
export class ChatComponent implements OnInit, AfterViewInit {
@Input() roomId: string;
@ViewChildren('messageItem', { read: ElementRef }) messageItems: QueryList<ElementRef>;
messages: MatrixEvent[];
constructor(private chatService: ChatService) { }
ngOnInit(): void {
this.messages = this.chatService.getRoomMessages(this.roomId);
this.chatService.listemRoomMessages(this.roomId, (event: any) => {
console.log(
// the room name will update with m.room.name events automatically
'%s: %s', event.getSender(), event.getContent().body
);
});
}
ngAfterViewInit(): void {
// Always scroll to last chat message.
this.messageItems?.last.nativeElement?.scrollIntoView(false);
this.messageItems.changes.subscribe((c) => {
console.log({ c });
this.messageItems?.last.nativeElement?.scrollIntoView(false);
});
}
}