namespace Views { export class ChatMessageList extends Views . DataBoundList < Models . Chat , HTMLUListElement , HTMLLIElement > { private _updateDateTime : number ; private _onResize : ( e : UIEvent ) => void ; constructor ( ) { super ( document . createElement ( 'ul' ) ) ; this . root . className = 'chat-message-list' ; this . _onResize = ( e ) => this . scrollToEnd ( ) ; } public activate ( ) { window . addEventListener ( "resize" , this . _onResize ) ; super . activate ( ) ; } public deactivate ( ) { super . deactivate ( ) ; window . removeEventListener ( "resize" , this . _onResize ) ; } public update ( chats ) { this . _updateDateTime = new Date ( ) . getTime ( ) ; this . bindArray ( chats ) ; this . scrollToEnd ( ) ; } private updateInfoSpan ( datum , span ) { let receivedTime = datum . received . getTime ( ) ; let minutes = ( this . _updateDateTime - receivedTime ) / 60000 ; if ( minutes < 5 ) span . innerText = "minutes ago" ; else if ( minutes < 60 ) span . innerText = "within the hour" ; else if ( minutes < 1440 ) span . innerText = "today" ; else if ( minutes < 2880 ) span . innerText = "yesterday" ; else span . innerText = "long ago" ; if ( ! span . title ) span . title = new Date ( receivedTime - datum . received . getTimezoneOffset ( ) * 60000 ) . toISOString ( ) . replace ( "T" , " " ) . substring ( 0 , 16 ) ; } private buildInfoTitle ( datum ) { return new Date ( datum . received . getTime ( ) - datum . received . getTimezoneOffset ( ) * 60000 ) . toISOString ( ) . replace ( "T" , " " ) . substring ( 0 , 16 ) ; } protected createChild ( key , datum ) { let senderName = document . createElement ( 'span' ) ; senderName . innerText = datum . sender ; let messageInfo = document . createElement ( 'span' ) ; messageInfo . className = 'secondary' ; this . updateInfoSpan ( datum , messageInfo ) ; let paragraph = document . createElement ( 'p' ) ; paragraph . innerText = datum . text ; let listItem = document . createElement ( 'li' ) ; listItem . appendChild ( senderName ) ; listItem . appendChild ( messageInfo ) ; listItem . appendChild ( paragraph ) ; return listItem ; } protected updateChild ( key , datum , element ) { let spans = element . getElementsByTagName ( 'span' ) ; this . updateInfoSpan ( datum , spans [ 1 ] ) ; } private scrollToEnd ( ) { if ( this . root . lastElementChild ) ( < HTMLElement > this . root . lastElementChild ) . scrollIntoView ( false ) ; } } }