mirror of
				https://github.com/richard-loafle/fuse-angular.git
				synced 2025-11-04 14:03:33 +00:00 
			
		
		
		
	(Chat Panel) Don't unfold the panel on hover
(Chat Panel) Always keep the contacts list in view
This commit is contained in:
		
							parent
							
								
									585709cf93
								
							
						
					
					
						commit
						e1c906f08b
					
				@ -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>
 | 
			
		||||
@ -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 {
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
     */
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
 | 
			
		||||
@ -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>
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user