import { ItemFlag , MatchFlag , QListWidget , QListWidgetItem , QPoint , QSize , ScrollBarPolicy , Shape , WidgetEventTypes , } from '@nodegui/nodegui' ; import { Client , Collection , Constants , DMChannel , Message , SnowflakeUtil } from 'discord.js' ; import { app } from '../..' ; import { Events as AppEvents } from '../../utilities/Events' ; import { ViewOptions } from '../../views/ViewOptions' ; import { UserButton } from '../UserButton/UserButton' ; export class DMUsersList extends QListWidget { channels = new WeakMap < DMChannel , UserButton > ( ) ; active ? : UserButton ; private prevUpdate = new Date ( ) . getTime ( ) ; private p0 = new QPoint ( 0 , 0 ) ; private btnSize = new QSize ( 224 , 44 ) ; private isLoading = false ; constructor ( ) { super ( ) ; this . setFrameShape ( Shape . NoFrame ) ; this . setObjectName ( 'UsersContainer' ) ; this . setHorizontalScrollBarPolicy ( ScrollBarPolicy . ScrollBarAlwaysOff ) ; this . addEventListener ( WidgetEventTypes . Paint , this . loadAvatars . bind ( this ) ) ; app . on ( AppEvents . NEW_CLIENT , ( client ) => { const { Events } = Constants ; client . on ( Events . CLIENT_READY , this . loadDMs . bind ( this ) ) ; client . on ( Events . MESSAGE_CREATE , this . handleNewMessage . bind ( this ) ) ; } ) ; app . on ( AppEvents . SWITCH_VIEW , this . handleSwitchView . bind ( this ) ) ; } private handleNewMessage ( message ) { const dm = message . channel ; if ( dm . type !== 'dm' ) { return ; } const btn = this . channels . get ( dm ) ; if ( ! btn ) { return ; } const items = this . findItems ( dm . id , MatchFlag . MatchExactly ) ; if ( ! items . length ) { return ; } const newItem = new QListWidgetItem ( ) ; newItem . setSizeHint ( this . btnSize ) ; newItem . setFlags ( ~ ItemFlag . ItemIsEnabled ) ; newItem . setText ( dm . id ) ; this . insertItem ( 0 , newItem ) ; this . setItemWidget ( newItem , btn ) ; const row = this . row ( items [ 0 ] ) ; this . takeItem ( row ) ; } private handleSwitchView ( view , options ? ) { if ( view === 'guild' ) { this . active ?. setActivated ( false ) ; this . active = undefined ; } if ( view === 'dm' && options && options . dm ) { const button = this . channels . get ( options . dm ) ; this . active ?. setActivated ( false ) ; button ?. setActivated ( true ) ; this . active = button ; } } async loadAvatars ( ) { if ( this . isLoading || this . native . destroyed ) { return ; } const cDate = new Date ( ) . getTime ( ) ; if ( cDate - this . prevUpdate < 100 ) { return ; } this . isLoading = true ; const y = - this . mapToParent ( this . p0 ) . y ( ) ; const height = this . size ( ) . height ( ) ; const promises = [ ] ; for ( const btn of this . nodeChildren . values ( ) ) { const button = btn as UserButton ; const iy = button . mapToParent ( this . p0 ) . y ( ) ; if ( iy >= y - 100 && iy <= y + height + 100 ) { button . load ( ) ; promises . push ( button . loadAvatar ( ) ) ; } } await Promise . all ( promises ) ; this . isLoading = false ; } param query async filter ( query ? ) { const q = ( query || '' ) . replace ( / /g , '' ) . toLowerCase ( ) . trim ( ) ; let i = 0 ; for ( const btn of this . nodeChildren . values ( ) ) { const button = btn as UserButton ; if ( button . user ) { const show = q === '' || button . user . username . toLowerCase ( ) . replace ( / /g , '' ) . includes ( q ) ; this . setRowHidden ( i , ! show ) ; i += 1 ; } } } async loadDMs ( ) { this . nodeChildren . clear ( ) ; this . clear ( ) ; this . hide ( ) ; ( app . client . channels . cache as Collection < string , DMChannel > ) . filter ( ( c ) => c . type === 'dm' && c . lastMessageID !== null ) . sort ( ( a , b ) => { const snA = SnowflakeUtil . deconstruct ( a . lastMessageID || '0' ) ; const snB = SnowflakeUtil . deconstruct ( b . lastMessageID || '0' ) ; return snB . date . getTime ( ) - snA . date . getTime ( ) ; } ) . forEach ( ( dm ) => { const btn = UserButton . createInstance ( this , dm . recipient ) ; const item = new QListWidgetItem ( ) ; item . setSizeHint ( this . btnSize ) ; item . setFlags ( ~ ItemFlag . ItemIsEnabled ) ; item . setText ( dm . id ) ; this . channels . set ( dm , btn ) ; this . addItem ( item ) ; this . setItemWidget ( item , btn ) ; } ) ; void this . loadAvatars ( ) ; this . show ( ) ; } }