import * as React from "react" ; import styles from "./TeamsBadge.module.scss" ; import { ITeamsBadgeState } from "./ITeamsBadgeState" ; import { ITeamsBadgeProps } from "./ITeamsBadgeProps" ; import * as signalR from "@microsoft/signalr" ; import { HttpTransportType } from "@aspnet/signalr" ; import { Log } from "@microsoft/sp-core-library" ; import spservices from "../../services/spservices" ; import { IChatNotificationMessage } from "../../entities/IChatNotificationMessage" ; import { IListChat } from "../../entities/IListChat" ; import * as lodash from "lodash" ; import * as moment from "moment" ; import { IChatMessage } from "../../entities/IChatMessage" ; import { IListChatMessage } from "../../entities/IListChatMessage" ; import { ListNotifications } from "../ListNotifications/ListNotifications" ; import { PnPClientStorage , setup } from "@pnp/common" ; import { TEAMS_IMAGE } from '../../common/constants' ; import { IChatMember } from "../../entities/IChatMember" ; import { IFacepilePersona } from "office-ui-fabric-react" ; import { IUser } from "../../entities/IUser" ; const storage = new PnPClientStorage ( ) ; export default class TeamsBadge extends React . Component < ITeamsBadgeProps , ITeamsBadgeState > { private functionAppUrl : string = `${ this . props . functionAppUrl }/api` ; private listChats : IListChat [ ] = [ ] ; private listMessages : IListChatMessage [ ] = [ ] ; private _isTimerRunning : boolean = false ; constructor ( props ) { super ( props ) ; spservices . init ( this . props . context , this . props . functionAppUrl ) ; this . state = { totalNotifications : 0 , showMessages : false , listMessages : [ ] } ; } returns { Promise < void > } memberof public async componentDidMount ( ) { try { this . _getChats ( ) ; const _listMessages = storage . local . get ( 'listMessages' ) ; this . listMessages = _listMessages ? _listMessages : [ ] ; this . setState ( { totalNotifications : this . listMessages . length , listMessages : this . listMessages } ) ; let signalRConnection = new signalR . HubConnectionBuilder ( ) . withUrl ( this . functionAppUrl ) . withAutomaticReconnect ( [ 0 , 2000 , 5000 , 10000 , 45000 ] ) . build ( ) ; signalRConnection . keepAliveIntervalInMilliseconds = 5 ; await signalRConnection . start ( ) ; signalRConnection . on ( "newMessage" , ( data ) => { this . getNotification ( data . value ) ; } ) ; this . _getNewChats ( ) ; } catch ( error ) { console . error ( "Error on load extention: " , error ) ; } } private memberof private getNotification = async ( chatNotifications ) : Promise < void > => { let { totalNotifications , showMessages } = this . state ; this . setState ( { showMessages : false } ) ; this . listChats = storage . local . get ( 'listChats' ) ; for ( const chatNotificationMessage of chatNotifications ) { const chatMessage = await spservices . getChatMessage ( chatNotificationMessage . resourceData [ "@odata.id" ] ) ; let index = lodash . findIndex ( this . listChats , { subscriptionId : chatNotificationMessage . subscriptionId } ) ; if ( index !== - 1 ) { let listChatItem = this . listChats [ index ] ; this . listChats [ index ] = { ... this . listChats [ index ] , hasNotification : true } ; this . listMessages . push ( { chat : listChatItem . chat , chatMessage : chatMessage } ) ; } } storage . local . put ( 'listMessages' , this . listMessages , moment ( ) . add ( 1 , 'days' ) . toDate ( ) ) ; this . setState ( { totalNotifications : this . listMessages . length , listMessages : this . listMessages , showMessages : showMessages } ) ; } ; private memberof private _onClickShowMessages = ( event ) => { event . preventDefault ( ) ; this . setState ( { showMessages : true } ) ; } ; returns { React . ReactElement < ITeamsBadgeProps > } memberof public render ( ) { return ( < div className = { styles . divTopContainer } > < div className = { styles . badgeWrapper } > { this . state . totalNotifications > 0 ? ( < div className = { styles . badge } > { this . state . totalNotifications } < /div>) : null} < div className = { styles . teamsIcon } onClick = { this . _onClickShowMessages } > < img src = { TEAMS_IMAGE } width = "34px" height = "34px" / > < /div> < /div> { this . state . showMessages ? ( < ListNotifications context = { this . props . context } listMessages = { this . state . listMessages } showDialog = { this . state . showMessages } onDismiss = { this . _onDismissListMessages } / > ) : null } < /div>); } private memberof private _onDismissListMessages = ( ) => { this . listMessages = [ ] ; this . _getChats ( ) ; storage . local . put ( 'listMessages' , [ ] , moment ( ) . add ( 1 , 'days' ) . toDate ( ) ) ; this . setState ( { showMessages : false , listMessages : [ ] , totalNotifications : 0 } ) ; } ; private memberof private _getNewChats = ( ) => { setInterval ( async ( ) => { if ( ! this . _isTimerRunning ) { this . _isTimerRunning = true ; await this . _getChats ( ) ; this . _isTimerRunning = false ; } } , 60000 ) ; } ; private memberof private _getChats = ( ) => { return new Promise ( ( resolve , reject ) => { this . listChats = [ ] ; spservices . getChats ( ) . then ( async ( chats ) => { for ( let chat of chats ) { try { let subscriptionId = await spservices . createMessageSubs ( chat . id ) ; this . listChats . push ( { chat : chat , subscriptionId : subscriptionId , hasNotification : false , chatMembers : await this . _getChatMembers ( chat . id ) } ) ; } catch ( error ) { console . error ( `Error on create Subscription(webhook) to Chat ${ chat . id }, ` , error ) ; } } storage . local . put ( 'listChats' , this . listChats , moment ( ) . add ( 1 , 'days' ) . toDate ( ) ) ; resolve ( ) ; } ) . catch ( error => { console . error ( `Error getting chat for user: ` , error ) ; reject ( error . message ) ; } ) ; } ) ; } ; private _getChatMembers = async ( chatId ) : Promise < IFacepilePersona [ ] > => { try { let _facepilePersonas = [ ] ; if ( chatId . indexOf ( 'meeting' ) > - 1 ) { return [ ] ; } const _members = await spservices . getChatMembers ( chatId ) ; if ( _members && _members . length > 2 ) { for ( const _member of _members ) { const userInfo = await spservices . getUser ( _member . userId ) ; _facepilePersonas . push ( { personaName : _member . displayName , imageUrl : await spservices . getUserPhoto ( userInfo . userPrincipalName ) } ) ; } } return _facepilePersonas ; } catch ( error ) { console . log ( "Error get Members " , error ) ; } } ; }