2020-10-19 13:20:02 +03:00
/ *
2020-10-19 20:34:47 +03:00
Copyright ( C ) 2020 Sebastian J . Wolf and other contributors
2020-10-19 13:20:02 +03:00
This file is part of Fernschreiber .
Fernschreiber is free software: you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Fernschreiber is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Fernschreiber . If not , see < http: //www.gnu.org/licenses/>.
* /
import QtQuick 2.6
import Sailfish . Silica 1.0
import QtQml . Models 2.3
import "../"
import "../../pages"
import "../../js/twemoji.js" as Emoji
import "../../js/functions.js" as Functions
ChatInformationTabItemBase {
id: tabBase
title: chatInformationPage . isPrivateChat ? qsTr ( "Groups" , "Button: groups in common (short)" ) : qsTr ( "Members" , "Button: Group Members" )
image: "image://theme/icon-m-people"
loadingText: isPrivateChat ? qsTr ( "Loading common chats…" , "chats you have in common with a user" ) : qsTr ( "Loading group members…" )
loading: chatInformationPage . isSuperGroup || chatInformationPage . isPrivateChat
loadingVisible: loading && membersView . count === 0
property variant chatPartnerCommonGroupsIds: ( [ ] ) ;
SilicaListView {
id: membersView
2020-10-19 22:06:28 +03:00
model: isPrivateChat ? ( chatPartnerCommonGroupsIds . length > 0 ? delegateModel : null ) : chatInformationPage . membersList
2020-10-19 13:20:02 +03:00
clip: true
height: tabBase . height
width: tabBase . width
opacity: tabBase . loading ? ( count > 0 ? 0.5 : 0.0 ) : 1.0
Behavior on opacity { NumberAnimation { } }
function handleScrollIntoView ( force ) {
if ( ! tabBase . loading && ! dragging && ! quickScrollAnimating ) {
if ( ! atYBeginning ) {
chatInformationPage . scrollDown ( )
} else {
chatInformationPage . scrollUp ( force ) ;
}
}
}
onDraggingChanged: {
handleScrollIntoView ( )
}
onAtYBeginningChanged: {
handleScrollIntoView ( )
}
onAtYEndChanged: {
if ( tabBase . active && ! tabBase . loading && chatInformationPage . isSuperGroup && ( groupInformation . member_count > membersView . count ) && membersView . atYEnd ) {
tabBase . loading = true ;
fetchMoreMembersTimer . start ( )
}
}
onQuickScrollAnimatingChanged: {
handleScrollIntoView ( true )
}
2020-10-19 22:06:28 +03:00
ViewPlaceholder {
enabled: membersView . count === 0
text: chatInformationPage . isPrivateChat ? qsTr ( "You don't have any groups in common with this user." ) : qsTr ( "This group is empty." )
}
2020-10-19 13:20:02 +03:00
delegate: PhotoTextsListItem {
pictureThumbnail {
photoData: ( typeof user . profile_photo !== "undefined" ) ? user.profile_photo.small : ""
}
width: parent . width
// chat title isPrivateChat ? () :
primaryText.text: Emoji . emojify ( Functions . getUserName ( user ) , primaryText . font . pixelSize )
// last user
prologSecondaryText.text: "@" + ( user . username !== "" ? user.username : user_id ) + ( user_id === chatInformationPage . myUserId ? " " + qsTr ( "You" ) : "" )
secondaryText {
horizontalAlignment: Text . AlignRight
property string statusText: Functions . getChatMemberStatusText ( model . status [ "@type" ] )
property string customText: model . status . custom_title ? Emoji . emojify ( model . status . custom_title , secondaryText . font . pixelSize ) : ""
text: ( statusText !== "" && customText !== "" ) ? statusText + ", " + customText : statusText + customText
}
tertiaryText {
maximumLineCount: 1
text: user . type [ "@type" ] === "userTypeBot" ? ( Emoji . emojify ( "🤖 " + bot_info . description , tertiaryText . font . pixelSize ) ) : Functions . getChatPartnerStatusText ( user . status [ "@type" ] , user . status . was_online ) ;
elide: Text . ElideRight
}
onClicked: {
tdLibWrapper . createPrivateChat ( user_id ) ;
}
}
footer: Component {
Item {
property bool active: tabBase . active && chatInformationPage . isSuperGroup && ( groupInformation . member_count > membersView . count )
width: tabBase . width
height: active ? Theme.itemSizeLarge : Theme . paddingMedium
BusyIndicator {
id: loadMoreIndicator
anchors.centerIn: parent
size: BusyIndicatorSize . Small
running: parent . active
}
}
}
VerticalScrollDecorator { }
}
DelegateModel {
id: delegateModel
model: chatListModel
groups: [
DelegateModelGroup {
name: "filterGroup" ; includeByDefault: true
}
]
filterOnGroup: "filterGroup"
function hasMatch ( searchInArray ) {
for ( var i = 0 ; i < searchInArray . length ; i ++ ) {
if ( searchInArray [ i ] . toLowerCase ( ) . indexOf ( chatInformationPage . searchString ) > - 1 ) {
return true ;
}
}
return false ;
}
function applyFilter ( ) {
var numberOfEntries = chatListModel . rowCount ( ) ;
var hasFilterString = ! ! chatInformationPage . searchString && chatInformationPage . searchString !== ""
for ( var i = 0 ; i < numberOfEntries ; i ++ ) {
var metadata = chatListModel . get ( i ) ;
if ( tabBase . chatPartnerCommonGroupsIds . indexOf ( metadata . chat_id ) > - 1 ) {
items . addGroups ( i , 1 , "filterGroup" ) ;
} else {
items . removeGroups ( i , 1 , "filterGroup" ) ;
}
}
}
delegate: ChatListViewItem {
ownUserId: chatInformationPage . myUserId
unreadCount: unread_count
onClicked: {
pageStack . pop ( pageStack . find ( function ( page ) { return ( page . _depth === 0 ) } ) , PageStackAction . Immediate ) ;
pageStack . push ( Qt . resolvedUrl ( "../../pages/ChatPage.qml" ) , { "chatInformation" : display } ) ;
}
Connections {
target: chatListModel
onChatChanged: {
if ( changedChatId === chat_id ) {
// Force update of some list item elements (currently only last message text seems to create problems). dataChanged() doesn't seem to trigger them all :(
secondaryText . text = last_message_text ? Emoji . emojify ( last_message_text , Theme . fontSizeExtraSmall ) : qsTr ( "Unknown" )
}
}
}
}
}
Timer {
id: fetchMoreMembersTimer
interval: 600
property int fetchLimit: 50
onTriggered: {
if ( isSuperGroup ) {
tabBase . loading = true
tdLibWrapper . getSupergroupMembers ( chatInformationPage . chatPartnerGroupId , fetchLimit , membersList . count ) ;
fetchLimit = 200
interval = 400
}
}
}
Connections {
target: tdLibWrapper
onChatMembersReceived: {
if ( isSuperGroup && chatInformationPage . chatPartnerGroupId === extra ) {
if ( members && members . length > 0 ) {
for ( var memberIndex in members ) {
var memberData = members [ memberIndex ] ;
var userInfo = tdLibWrapper . getUserInformation ( memberData . user_id ) || { user: { } , bot_info: { } } ;
memberData . user = userInfo ;
memberData . bot_info = memberData . bot_info || { } ;
membersList . append ( memberData ) ;
}
groupInformation . member_count = totalMembers
updateGroupStatusText ( ) ;
if ( membersList . count < totalMembers ) {
// fetchMoreMembersTimer.start()
}
}
// if we set it directly, the views start scrolling
loadedTimer . start ( ) ;
}
}
onChatsReceived: { // common chats with user
if ( isPrivateChat && chats [ "@extra" ] === chatInformationPage . chatPartnerGroupId ) {
tabBase . chatPartnerCommonGroupsIds = chats . chat_ids ;
delegateModel . applyFilter ( ) ;
// if we set it directly, the views start scrolling
loadedTimer . start ( ) ;
}
}
}
Timer {
id: loadedTimer
interval: 50
onTriggered: {
tabBase . loading = false
}
}
Component.onCompleted: {
if ( isPrivateChat ) {
tdLibWrapper . getGroupsInCommon ( chatInformationPage . chatPartnerGroupId , 200 , 0 ) ; // we only use the first 200
} else if ( isSuperGroup ) {
fetchMoreMembersTimer . start ( ) ;
}
}
}