(Chat Panel) Don't unfold the panel on hover

(Chat Panel) Always keep the contacts list in view
This commit is contained in:
Sercan Yemen 2018-07-10 14:55:30 +03:00
parent 585709cf93
commit e1c906f08b
8 changed files with 105 additions and 78 deletions

View File

@ -1,6 +1,6 @@
<div class="header mat-elevation-z4 mat-primary-bg" fxLayout="row" fxLayoutAlign="space-between center">
<ng-container *ngIf="view === 'contacts'">
<ng-container *ngIf="selectedContact === null">
<div class="title ml-16" fxLayout="row" fxLayoutAlign="start center">
<mat-icon class="s-32 white-fg">chat</mat-icon>
@ -9,21 +9,17 @@
</ng-container>
<ng-container *ngIf="view === 'chat'">
<ng-container *ngIf="selectedContact !== null">
<div class="title" fxLayout="row" fxLayoutAlign="start center">
<button class="mx-8" mat-icon-button (click)="goToContacts()">
<mat-icon>arrow_back</mat-icon>
</button>
<img [src]="contact.avatar" class="avatar mr-0 w-32 h-32">
<h3 class="ml-12 text-truncate">{{contact.name}}</h3>
<img [src]="selectedContact.avatar" class="avatar mx-16">
<h3 class="text-truncate">{{selectedContact.name}}</h3>
</div>
</ng-container>
<button mat-icon-button class="toggle-sidebar-folded mr-8" (click)="toggleSidebarFolded()" fxHide fxShow.gt-md>
<mat-icon class="secondary-text s-20" *ngIf="sidebarFolded">lock_open</mat-icon>
<mat-icon class="secondary-text s-20" *ngIf="!sidebarFolded">lock_outline</mat-icon>
<button mat-icon-button class="toggle-sidebar-folded mr-8" (click)="foldSidebarTemporarily()" fxHide fxShow.gt-md>
<mat-icon class="secondary-text s-20">arrow_forward</mat-icon>
</button>
<button mat-icon-button class="toggle-sidebar-folded mr-8" (click)="toggleSidebarOpen()" fxHide.gt-md>
@ -32,33 +28,34 @@
</div>
<ng-container *ngIf="view === 'contacts'">
<div>
<!-- Contacts -->
<mat-list id="contacts-list" fusePerfectScrollbar [fusePerfectScrollbarOptions]="{suppressScrollX: true}">
<mat-list-item *ngFor="let contact of contacts" [ngClass]="contact.status" (click)="goToChat(contact)"
<mat-list-item *ngFor="let contact of contacts"
[ngClass]="contact.status"
[class.active]="contact.id === selectedContact?.id"
(click)="goToChat(contact)"
[matTooltip]="contact.name"
matTooltipPosition="left"
matRipple>
<img matListAvatar [src]="contact.avatar">
<h3 matLine>
{{contact.name}}
</h3>
<div class="unread-count" *ngIf="contact.unread">{{contact.unread}}</div>
<div class="status-icon" [ngClass]="contact.status"></div>
</mat-list-item>
</mat-list>
<!-- / Contacts -->
</ng-container>
<ng-container *ngIf="view === 'chat'">
<!-- Chat -->
<div id="chat" fxLayout="column" fxFlex="1 1 auto">
<div class="messages" fxFlex="1 1 auto" fusePerfectScrollbar>
<div id="messages" class="messages" fxFlex="1 1 auto" fusePerfectScrollbar>
<ng-container *ngIf="chat && chat.dialog && chat.dialog.length > 0">
<div *ngFor="let message of chat.dialog; let i = index" class="message-row"
[ngClass]="{
@ -69,7 +66,7 @@
}">
<img *ngIf="shouldShowContactAvatar(message, i)"
src="{{contact.avatar}}"
src="{{selectedContact.avatar}}"
class="avatar">
<div class="bubble">
@ -79,7 +76,9 @@
</div>
<ng-container *ngIf="chat.dialog.length === 0">
</ng-container>
<ng-container *ngIf="chat && chat.dialog && chat.dialog.length === 0">
<div class="no-messages-icon">
<mat-icon class="s-128">chat</mat-icon>
@ -115,5 +114,6 @@
</div>
</div>
<!-- / Chat -->
</ng-container>
</div>

View File

@ -4,9 +4,9 @@ chat-panel {
display: flex;
flex-direction: column;
flex: 1 1 auto;
width: 280px;
min-width: 280px;
max-width: 280px;
width: 360px;
min-width: 360px;
max-width: 360px;
z-index: 99;
overflow: hidden;
@ -31,11 +31,28 @@ chat-panel {
#contacts-list {
padding: 8px 0;
overflow: auto;
width: 72px;
min-width: 72px;
max-width: 72px;
// Perfect scrollbar
.ps__rail-y {
width: 3px !important;
.ps__thumb-y {
width: 3px !important;
}
}
.mat-list-item {
cursor: pointer;
position: relative;
&.active {
background-color: mat-color(mat-palette($mat-grey, 300));
@include mat-elevation(2);
}
&.offline {
.mat-list-item-content {
@ -316,6 +333,9 @@ chat-panel {
fuse-sidebar {
&.chat-panel {
width: 360px;
min-width: 360px;
max-width: 360px;
// Folded
&.folded {

View File

@ -1,4 +1,4 @@
import { Component, ElementRef, OnDestroy, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { AfterViewInit, Component, ElementRef, OnDestroy, OnInit, QueryList, ViewChild, ViewChildren, ViewEncapsulation } from '@angular/core';
import { NgForm } from '@angular/forms';
import { HttpClient } from '@angular/common/http';
@ -15,20 +15,13 @@ import { ChatPanelService } from 'app/layout/components/chat-panel/chat-panel.se
styleUrls : ['./chat-panel.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class ChatPanelComponent implements OnInit, OnDestroy
export class ChatPanelComponent implements OnInit, AfterViewInit, OnDestroy
{
contacts: any[];
contact: any;
chat: any;
selectedContact: any;
sidebarFolded: boolean;
user: any;
view: string;
@ViewChild(FusePerfectScrollbarDirective)
set fusePerfectScrollbarDirective(content: FusePerfectScrollbarDirective)
{
this._fusePerfectScrollbarDirective = content;
}
@ViewChild('replyForm')
set replyForm(content: NgForm)
@ -42,8 +35,11 @@ export class ChatPanelComponent implements OnInit, OnDestroy
this._replyInput = content;
}
@ViewChildren(FusePerfectScrollbarDirective)
private _fusePerfectScrollbarDirectives: QueryList<FusePerfectScrollbarDirective>;
// Private
private _fusePerfectScrollbarDirective: FusePerfectScrollbarDirective;
private _chatViewScrollbar: FusePerfectScrollbarDirective;
private _replyForm: NgForm;
private _replyInput: ElementRef;
private _unsubscribeAll: Subject<any>;
@ -62,9 +58,8 @@ export class ChatPanelComponent implements OnInit, OnDestroy
)
{
// Set the defaults
this.contact = null;
this.selectedContact = null;
this.sidebarFolded = true;
this.view = 'contacts';
// Set the private defaults
this._unsubscribeAll = new Subject();
@ -94,6 +89,16 @@ export class ChatPanelComponent implements OnInit, OnDestroy
});
}
/**
* After view init
*/
ngAfterViewInit(): void
{
this._chatViewScrollbar = this._fusePerfectScrollbarDirectives.find((directive) => {
return directive.elementRef.nativeElement.id === 'messages';
});
}
/**
* On destroy
*/
@ -122,12 +127,12 @@ export class ChatPanelComponent implements OnInit, OnDestroy
this._replyInput.nativeElement.focus();
// Scroll to the bottom of the messages list
if ( this._fusePerfectScrollbarDirective )
if ( this._chatViewScrollbar )
{
this._fusePerfectScrollbarDirective.update();
this._chatViewScrollbar.update();
setTimeout(() => {
this._fusePerfectScrollbarDirective.scrollToBottom(0);
this._chatViewScrollbar.scrollToBottom(0);
});
}
});
@ -145,6 +150,22 @@ export class ChatPanelComponent implements OnInit, OnDestroy
this._fuseSidebarService.getSidebar('chatPanel').toggleFold();
}
/**
* Fold the temporarily unfolded sidebar back
*/
foldSidebarTemporarily(): void
{
this._fuseSidebarService.getSidebar('chatPanel').foldTemporarily();
}
/**
* Unfold the sidebar temporarily
*/
unfoldSidebarTemporarily(): void
{
this._fuseSidebarService.getSidebar('chatPanel').unfoldTemporarily();
}
/**
* Toggle sidebar opened status
*/
@ -163,8 +184,8 @@ export class ChatPanelComponent implements OnInit, OnDestroy
shouldShowContactAvatar(message, i): boolean
{
return (
message.who === this.contact.id &&
((this.chat.dialog[i + 1] && this.chat.dialog[i + 1].who !== this.contact.id) || !this.chat.dialog[i + 1])
message.who === this.selectedContact.id &&
((this.chat.dialog[i + 1] && this.chat.dialog[i + 1].who !== this.selectedContact.id) || !this.chat.dialog[i + 1])
);
}
@ -199,11 +220,11 @@ export class ChatPanelComponent implements OnInit, OnDestroy
*/
goToChat(contact): void
{
// Change the view
this.view = 'chat';
// Unfold the sidebar temporarily
this.unfoldSidebarTemporarily();
// Set the current contact
this.contact = contact;
// Set the selected contact
this.selectedContact = contact;
// Load the chat
this._chatPanelService.getChat(contact.id).then((chat) => {
@ -216,21 +237,6 @@ export class ChatPanelComponent implements OnInit, OnDestroy
});
}
/**
* Go to contact view
*/
goToContacts(): void
{
// Change the view
this.view = 'contacts';
// Set the current contact as null
this.contact = null;
// Clear the chat data
this.chat = null;
}
/**
* Reply
*/

View File

@ -1,5 +1,5 @@
import { NgModule } from '@angular/core';
import { MatButtonModule, MatFormFieldModule, MatIconModule, MatInputModule, MatListModule, MatRippleModule, MatTabsModule } from '@angular/material';
import { MatButtonModule, MatFormFieldModule, MatIconModule, MatInputModule, MatListModule, MatRippleModule, MatTabsModule, MatTooltipModule } from '@angular/material';
import { FuseSharedModule } from '@fuse/shared.module';
@ -20,6 +20,7 @@ import { ChatPanelService } from 'app/layout/components/chat-panel/chat-panel.se
MatInputModule,
MatListModule,
MatTabsModule,
MatTooltipModule,
MatRippleModule,
FuseSharedModule

View File

@ -57,7 +57,7 @@
<!-- CHAT PANEL -->
<fuse-sidebar class="chat-panel" name="chatPanel" position="right"
[folded]="true" [foldedWidth]="70"
[folded]="true" [foldedWidth]="70" [foldedAutoTriggerOnHover]="false"
lockedOpen="gt-md">
<chat-panel></chat-panel>
</fuse-sidebar>

View File

@ -69,7 +69,7 @@
<!-- CHAT PANEL -->
<fuse-sidebar class="chat-panel" name="chatPanel" position="right"
[folded]="true" [foldedWidth]="70"
[folded]="true" [foldedWidth]="70" [foldedAutoTriggerOnHover]="false"
lockedOpen="gt-md">
<chat-panel></chat-panel>
</fuse-sidebar>

View File

@ -69,7 +69,7 @@
<!-- CHAT PANEL -->
<fuse-sidebar class="chat-panel" name="chatPanel" position="right"
[folded]="true" [foldedWidth]="70"
[folded]="true" [foldedWidth]="70" [foldedAutoTriggerOnHover]="false"
lockedOpen="gt-md">
<chat-panel></chat-panel>
</fuse-sidebar>

View File

@ -55,7 +55,7 @@
<!-- CHAT PANEL -->
<fuse-sidebar class="chat-panel" name="chatPanel" position="right"
[folded]="true" [foldedWidth]="70"
[folded]="true" [foldedWidth]="70" [foldedAutoTriggerOnHover]="false"
lockedOpen="gt-md">
<chat-panel></chat-panel>
</fuse-sidebar>