我们正在尝试完成此聊天组件。当用户单击左侧聊天项时,它将打开与该选定用户的消息。我们有一个活动的班级,它会更改聊天列表项的颜色。当用户选择任何聊天列表项时尝试实现活动类。这是代码:
消息服务
import { Observable } from 'rxjs';
import { HttpClient } from '@angular/common/http';
import { Injectable,EventEmitter } from '@angular/core';
import { Message } from '@angular/compiler/src/i18n/i18n_ast';
const BASEURL = 'http://localhost:3000/api/chatapp';
@Injectable({
providedIn: 'root'
})
export class MessageService {
constructor(private http: HttpClient) {}
SendMessage(senderId, receiverId, receiverName, message): Observable<any> {
return this.http.post(`${BASEURL}/chat-messages/${senderId}/${receiverId}`, {
receiverId,
receiverName,
message
});
}
GetAllMessages(senderId, receiverId): Observable<any> {
return this.http.get(`${BASEURL}/chat-messages/${senderId}/${receiverId}`);
}
MarkMessages(sender, receiver): Observable<any> {
return this.http.get(`${BASEURL}/receiver-messages/${sender}/${receiver}`);
}
MarkAllMessages(): Observable<any> {
return this.http.get(`${BASEURL}/mark-all-messages`);
}
chatSelected = new EventEmitter<Message>();
}
路线
path: 'chat/:name',
component: MessageComponent,
canActivate: [AuthGuard]
HTML
<div id="frame">
<div id="sidepanel">
<div id="contacts" >
<ul *ngFor="let chat of chatList">
<li class="contact"
[ngClass]="{'active': chat.receiverId.username === this.selectedChat.receiverId.username}">
<div class="wrap" (click)="GoToChatPage(chat.receiverId.username)">
<span class="contact-status online"></span>
<img src="http://res.cloudinary.com/ratingapp/image/upload/v{{chat.receiverId.picVersion}}/{{chat.receiverId.picId}}" alt="" />
<div class="meta">
<p class="name">{{chat.receiverId.username}}</p>
<p class="preview">
{{chat.msgId.message[chat.msgId.message.length - 1].body.substr(0, 10)}}...</p>
</div>
</div>
</li>
</ul>
</div>
</div>
<div class="content">
<div class="contact-profile">
<img src="http://emilcarlsson.se/assets/harveyspecter.png" alt="" />
<p>Harvey Specter</p>
<div class="social-media">
<i class="material-icons">cancel</i>
</div>
</div>
<div class="messages">
<ul *ngFor="let message of messagesArray">
<li class="sent" *ngIf="user.username !== receiver && user.username !== message.sendername">
<img src="http://res.cloudinary.com/ratingapp/image/upload/v{{chat.receiverId.picVersion}}/{{chat.receiverId.picId}}" alt="" />
<p>{{message.body}}</p>
</li>
<li class="replies" *ngIf="user.username === message.sendername">
<img src="http://res.cloudinary.com/ratingapp/image/upload/v{{chat.receiverId.picVersion}}/{{chat.senderId.picId}}" alt="" />
<p>{{message.body}}</p>
</li>
</ul>
</div>
<form (ngSubmit)="SendMessage()">
<div class="message-input">
<div class="wrap">
<input [(ngModel)]="message" (keypress)="IsTyping()" type="text" placeholder="Write your message..." />
<button class="emojiBtn" (click)="Toggled()"></button>
<div class="emoji-content-editable" (emojiPickerCaretEmitter)="HandleCurrentCaret($event)" (input)="content = $event.target.textContent"
[textContent]="content" contenteditable="true"></div>
<i class="emoji-toggle-button imgBtn" [(emojiPickerIf)]="toggled" [emojiPickerPreserveSelection]="false" [emojiPickerDirection]="direction"
[emojiPickerAutofocus]="true" (emojiPickerSelect)="HandleSelection($event)"></i>
<button class="submit"><i class="fa fa-paper-plane" aria-hidden="true"></i></button>
</div>
</div>
</form>
</div>
</div>
TypeScript
export class MessageComponent implements OnInit {
@Input() users;
receiver: string;
user: any;
message: string;
receiverData: any;
messagesArray = [];
socket: any;
typingMessage;
typing = false;
isOnline = false;
chatList = [];
public eventMock;
public eventPosMock;
public direction =
Math.random() > 0.5 ? (Math.random() > 0.5 ? 'top' : 'bottom') : Math.random() > 0.5 ? 'right' : 'left';
public toggled = false;
public content = ' ';
private _lastCaretEvent: CaretEvent;
constructor(
private tokenService: TokenService,
private msgService: MessageService,
private route: ActivatedRoute,
private usersService: UsersService
) {
this.socket = io('http://localhost:3000');
}
ngOnInit() {
this.user = this.tokenService.GetPayload();
this.route.params.subscribe(params => {
this.receiver = params.name;
this.GetUserByUsername(this.receiver);
this.socket.on('refreshPage', () => {
this.GetUserByUsername(this.receiver);
});
});
this.socket.on('is_typing', data => {
if (data.sender === this.receiver) {
this.typing = true;
}
});
this.socket.on('has_stopped_typing', data => {
if (data.sender === this.receiver) {
this.typing = false;
}
});
}
ngOnChanges(changes: SimpleChanges) {
const title = document.querySelector('.nameCol');
if (changes.users.currentValue.length > 0) {
const result = _.indexOf(changes.users.currentValue, this.receiver);
if (result > -1) {
this.isOnline = true;
(title as HTMLElement).style.marginTop = '10px';
} else {
this.isOnline = false;
(title as HTMLElement).style.marginTop = '20px';
}
}
}
ngAfterViewInit() {
const params = {
room1: this.user.username,
room2: this.receiver
};
this.socket.emit('join chat', params);
}
GetUser(id) {
this.usersService.GetUserById(id).subscribe(data => {
this.chatList = data.result.chatList;
});
}
GetUserByUsername(name) {
this.usersService.GetUserByName(name).subscribe(data => {
this.receiverData = data.result;
this.GetMessages(this.user._id, data.result._id);
});
}
GoToChatPage(chat, name) {
this.selectedChat = chat;
this.router.navigate(['chat', name]);
this.msgService.MarkMessages(this.user.username, name).subscribe(data => {
this.socket.emit('refresh', {});
});
}
GetMessages(senderId, receiverId) {
this.msgService.GetAllMessages(senderId, receiverId).subscribe(data => {
this.messagesArray = data.messages.message;
});
}
SendMessage() {
if (this.message) {
this.msgService
.SendMessage(this.user._id, this.receiverData._id, this.receiverData.username, this.message)
.subscribe(data => {
this.socket.emit('refresh', {});
this.message = '';
});
}
}
HandleSelection(event: EmojiEvent) {
this.content =
this.content.slice(0, this._lastCaretEvent.caretOffset) +
event.char +
this.content.slice(this._lastCaretEvent.caretOffset);
this.eventMock = JSON.stringify(event);
this.message = this.content;
this.toggled = !this.toggled;
this.content = '';
}
HandleCurrentCaret(event: CaretEvent) {
this._lastCaretEvent = event;
this.eventPosMock = `{ caretOffset : ${event.caretOffset}, caretRange: Range{...}, textContent: ${
event.textContent
} }`;
}
Toggled() {
this.toggled = !this.toggled;
}
IsTyping() {
this.socket.emit('start_typing', {
sender: this.user.username,
receiver: this.receiver
});
if (this.typingMessage) {
clearTimeout(this.typingMessage);
}
this.typingMessage = setTimeout(() => {
this.socket.emit('stop_typing', {
sender: this.user.username,
receiver: this.receiver
});
}, 500);
}
}
我本以为添加事件发射器,但不知道在这种情况下它将如何工作。那么,当用户从左侧聊天列表中选择一个聊天用户并打开右侧带有该用户的消息时,如何在左侧聊天列表项中添加活动类别?
答案 0 :(得分:1)
不确定其中的所有逻辑,但是解决方案非常简单:
1-保留一个包含当前user
(来自路由)的变量,该变量已经具有=> this.receiver
。
2-使用[class]
将active
添加到每个元素。
<li class="content" [ngClass]="{'active': chat.receiverId.username === this.receiver}">