harbour-fernschreiber/qml/pages/NewChatPage.qml

427 lines
19 KiB
QML
Raw Permalink Normal View History

/*
Copyright (C) 2020 Sebastian J. Wolf and other contributors
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 "../components"
import "../js/twemoji.js" as Emoji
import "../js/functions.js" as Functions
import "../js/debug.js" as Debug
Page {
id: newChatPage
allowedOrientations: Orientation.All
property bool isLoading: true;
property bool syncSupported: false;
property bool nemoSync: false;
2020-11-27 00:18:51 +03:00
function resetFocus() {
contactsSearchField.focus = false;
newChatPage.focus = true;
}
function reloadContacts() {
contactsModel.hydrateContacts();
2020-11-28 21:11:51 +03:00
contactsListView.model = contactsProxyModel;
2020-11-27 00:18:51 +03:00
newChatPage.isLoading = false;
}
2020-11-21 01:00:50 +03:00
onStatusChanged: {
if (status === PageStatus.Active) {
2020-11-27 00:18:51 +03:00
reloadContacts();
2020-11-21 01:00:50 +03:00
}
}
2020-11-27 00:18:51 +03:00
Connections {
target: tdLibWrapper
onContactsImported: {
reloadContacts();
appNotification.show(qsTr("Contacts successfully synchronized with Telegram."));
}
2020-11-24 19:28:41 +03:00
}
Component.onCompleted: {
var sailfishOSVersion = fernschreiberUtils.getSailfishOSVersion().split(".");
// With Sailfish OS 4 we can't get up-to-date contacts with the standard database anymore. We might need to enter Sailjail eventually...
// Details see https://forum.sailfishos.org/t/4-0-1-45-non-jailed-contacts-sqlite-database-no-longer-updated/4724
// We try it with the inofficial Nemo Contact API via a loader...
if (parseInt(sailfishOSVersion[0]) < 4) {
Debug.log("Sailfish OS version 3.x - contact sync should still be possible...")
newChatPage.syncSupported = true;
}
}
Connections {
target: contactSyncLoader.item
onSyncError: {
newChatPage.isLoading = false;
}
}
Loader {
id: contactSyncLoader
source: "../components/ContactSync.qml"
active: true
onLoaded: {
newChatPage.nemoSync = true;
}
}
SilicaFlickable {
id: newChatContainer
contentHeight: newChatPage.height
anchors.fill: parent
2020-11-27 00:18:51 +03:00
PullDownMenu {
enabled: newChatPage.syncSupported || newChatPage.nemoSync
2020-11-27 00:18:51 +03:00
MenuItem {
onClicked: {
newChatPage.isLoading = true;
if (newChatPage.nemoSync) {
contactSyncLoader.item.synchronize();
}
if (newChatPage.syncSupported) {
if (!contactsModel.synchronizeContacts()) {
reloadContacts();
appNotification.show(qsTr("Could not synchronize your contacts with Telegram."));
}
2020-11-28 21:11:51 +03:00
}
// Success message is not fired before TDLib returned "Contacts imported" (see above)
2020-11-27 00:18:51 +03:00
}
text: qsTr("Synchronize Contacts with Telegram")
}
}
Column {
id: newChatPageColumn
width: newChatPage.width
height: newChatPage.height
PageHeader {
id: newChatPageHeader
title: qsTr("Your Contacts")
}
2020-11-22 00:13:37 +03:00
Item {
id: contactsItem
width: newChatPageColumn.width
2020-11-22 00:13:37 +03:00
height: newChatPageColumn.height - newChatPageHeader.height
2020-11-24 19:28:41 +03:00
Column {
visible: !newChatPage.isLoading
2020-11-22 00:13:37 +03:00
width: parent.width
height: parent.height
2020-11-24 19:28:41 +03:00
SearchField {
id: contactsSearchField
width: parent.width
2020-11-26 02:25:15 +03:00
placeholderText: qsTr("Search a contact...")
2020-11-24 19:28:41 +03:00
active: !newChatPage.isLoading
2020-11-28 21:11:51 +03:00
onTextChanged: {
contactsProxyModel.setFilterWildcard("*" + text + "*");
}
2020-11-24 19:28:41 +03:00
EnterKey.iconSource: "image://theme/icon-m-enter-close"
EnterKey.onClicked: {
resetFocus();
}
}
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
SilicaListView {
id: contactsListView
clip: true
2020-11-22 00:13:37 +03:00
width: parent.width
2020-11-24 19:28:41 +03:00
height: parent.height - contactsSearchField.height
visible: !newChatPage.isLoading
opacity: visible ? 1 : 0
Behavior on opacity { FadeAnimation {} }
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
signal newChatInitiated ( int currentIndex )
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
ViewPlaceholder {
y: Theme.paddingLarge
enabled: contactsListView.count === 0
text: qsTr("You don't have any contacts.")
}
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
delegate: Item {
id: newChatListItem
2020-11-22 00:13:37 +03:00
width: parent.width
2020-11-24 19:28:41 +03:00
height: contactListItem.height
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
PhotoTextsListItem {
id: contactListItem
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
opacity: visible ? 1 : 0
Behavior on opacity { FadeAnimation {} }
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
pictureThumbnail {
2020-11-28 21:11:51 +03:00
photoData: typeof photo_small !== "undefined" ? photo_small : {}
2020-11-22 00:13:37 +03:00
}
2020-11-24 19:28:41 +03:00
width: parent.width
2020-11-22 00:13:37 +03:00
2020-11-28 21:11:51 +03:00
primaryText.text: Emoji.emojify(title, primaryText.font.pixelSize, "../js/emoji/")
prologSecondaryText.text: "@" + ( username !== "" ? username : user_id )
2020-11-24 19:28:41 +03:00
tertiaryText {
maximumLineCount: 1
2020-11-28 21:11:51 +03:00
text: Functions.getChatPartnerStatusText(user_status, user_last_online);
2020-11-24 19:28:41 +03:00
}
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
onClicked: {
contactsListView.newChatInitiated(index);
}
Connections {
target: contactsListView
onNewChatInitiated: {
if (index === currentIndex) {
contactListItem.visible = false;
} else {
contactListItem.visible = true;
}
}
}
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
Connections {
target: contactsSearchField
onFocusChanged: {
if (contactsSearchField.focus) {
contactListItem.visible = true;
}
}
2020-11-22 00:13:37 +03:00
}
2020-11-24 19:28:41 +03:00
}
Column {
id: selectChatTypeColumn
visible: !contactListItem.visible
opacity: visible ? 1 : 0
Behavior on opacity { FadeAnimation {} }
width: parent.width
height: contactListItem.height
2020-11-22 00:13:37 +03:00
Item {
2020-11-24 19:28:41 +03:00
width: parent.width
height: parent.height - chatTypeSeparator.height
2020-11-22 00:13:37 +03:00
Rectangle {
anchors.fill: parent
2020-11-28 21:11:51 +03:00
opacity: Theme.opacityLow
2020-11-24 19:28:41 +03:00
color: Theme.overlayBackgroundColor
2020-11-22 00:13:37 +03:00
}
2020-11-24 19:28:41 +03:00
Item {
id: privateChatItem
height: parent.height
2020-11-28 21:11:51 +03:00
width: parent.width / 2
2020-11-24 19:28:41 +03:00
Rectangle {
id: privateChatHighlightBackground
anchors.fill: parent
color: Theme.highlightBackgroundColor
2020-11-28 21:11:51 +03:00
opacity: Theme.opacityHigh
2020-11-24 19:28:41 +03:00
visible: false
}
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
Row {
width: parent.width
height: parent.height - ( 2 * Theme.paddingSmall )
2020-11-22 00:13:37 +03:00
anchors.verticalCenter: parent.verticalCenter
2020-11-24 19:28:41 +03:00
IconButton {
id: privateChatButton
width: Theme.itemSizeLarge
height: Theme.itemSizeLarge
icon.source: "image://theme/icon-m-chat"
anchors.verticalCenter: parent.verticalCenter
onClicked: {
tdLibWrapper.createPrivateChat(display.id, "openDirectly");
2020-11-24 19:28:41 +03:00
}
}
Column {
height: parent.height
width: parent.width - privateChatButton.width - Theme.horizontalPageMargin
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.paddingSmall
Text {
id: privateChatHeader
width: parent.width
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.ExtraBold
color: Theme.primaryColor
maximumLineCount: 1
elide: Text.ElideRight
textFormat: Text.StyledText
text: qsTr("Private Chat")
}
Text {
width: parent.width
height: parent.height - privateChatHeader.height - Theme.paddingSmall
font.pixelSize: Theme.fontSizeTiny
color: Theme.secondaryColor
wrapMode: Text.Wrap
elide: Text.ElideRight
textFormat: Text.StyledText
2020-11-25 02:23:38 +03:00
text: qsTr("Transport-encrypted, uses Telegram Cloud, sharable across devices")
2020-11-24 19:28:41 +03:00
}
2020-11-22 00:13:37 +03:00
}
2020-11-24 19:28:41 +03:00
2020-11-22 00:13:37 +03:00
}
2020-11-24 19:28:41 +03:00
MouseArea {
anchors.fill: parent
onClicked: {
tdLibWrapper.createPrivateChat(display.id, "openDirectly");
2020-11-22 00:13:37 +03:00
}
2020-11-24 19:28:41 +03:00
onPressed: {
privateChatHighlightBackground.visible = true;
}
onReleased: {
privateChatHighlightBackground.visible = false;
2020-11-22 00:13:37 +03:00
}
}
}
2020-11-24 19:28:41 +03:00
Item {
id: secretChatItem
height: parent.height
2020-11-28 21:11:51 +03:00
width: parent.width / 2
2020-11-24 19:28:41 +03:00
anchors.left: privateChatItem.right
anchors.top: parent.top
Rectangle {
id: secretChatHighlightBackground
anchors.fill: parent
color: Theme.highlightBackgroundColor
2020-11-28 21:11:51 +03:00
opacity: Theme.opacityHigh
2020-11-24 19:28:41 +03:00
visible: false
2020-11-22 00:13:37 +03:00
}
2020-11-24 19:28:41 +03:00
Row {
width: parent.width
height: parent.height - ( 2 * Theme.paddingSmall )
anchors.verticalCenter: parent.verticalCenter
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
IconButton {
id: secretChatButton
width: Theme.itemSizeLarge
height: Theme.itemSizeLarge
icon.source: "image://theme/icon-m-device-lock"
anchors.verticalCenter: parent.verticalCenter
onClicked: {
tdLibWrapper.createNewSecretChat(display.id, "openDirectly");
2020-11-24 19:28:41 +03:00
}
}
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
Column {
height: parent.height
width: parent.width - secretChatButton.width - Theme.horizontalPageMargin
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.paddingSmall
Text {
width: parent.width
font.pixelSize: Theme.fontSizeMedium
font.weight: Font.ExtraBold
color: Theme.primaryColor
maximumLineCount: 1
elide: Text.ElideRight
textFormat: Text.StyledText
text: qsTr("Secret Chat")
}
Text {
width: parent.width
height: parent.height - privateChatHeader.height - Theme.paddingSmall
font.pixelSize: Theme.fontSizeTiny
color: Theme.secondaryColor
wrapMode: Text.Wrap
elide: Text.ElideRight
textFormat: Text.StyledText
text: qsTr("End-to-end-encrypted, accessible on this device only")
}
}
2020-11-22 00:13:37 +03:00
2020-11-24 19:28:41 +03:00
}
MouseArea {
anchors.fill: parent
2020-11-22 00:13:37 +03:00
onClicked: {
tdLibWrapper.createNewSecretChat(display.id, "openDirectly");
2020-11-22 00:13:37 +03:00
}
2020-11-24 19:28:41 +03:00
onPressed: {
secretChatHighlightBackground.visible = true;
2020-11-22 00:13:37 +03:00
}
2020-11-24 19:28:41 +03:00
onReleased: {
secretChatHighlightBackground.visible = false;
2020-11-22 00:13:37 +03:00
}
}
}
}
2020-11-24 19:28:41 +03:00
Separator {
id: chatTypeSeparator
width: parent.width
color: Theme.primaryColor
horizontalAlignment: Qt.AlignHCenter
}
2020-11-22 00:13:37 +03:00
}
}
2020-11-24 19:28:41 +03:00
VerticalScrollDecorator {}
2020-11-22 00:13:37 +03:00
}
}
Column {
opacity: visible ? 1 : 0
Behavior on opacity { FadeAnimation {} }
visible: newChatPage.isLoading
width: parent.width
2020-11-22 00:13:37 +03:00
height: loadingLabel.height + loadingBusyIndicator.height + Theme.paddingMedium
spacing: Theme.paddingMedium
anchors.verticalCenter: parent.verticalCenter
2020-11-22 00:13:37 +03:00
InfoLabel {
id: loadingLabel
2020-11-25 02:23:38 +03:00
text: qsTr("Loading contacts...")
}
2020-11-22 00:13:37 +03:00
BusyIndicator {
id: loadingBusyIndicator
anchors.horizontalCenter: parent.horizontalCenter
running: newChatPage.isLoading
size: BusyIndicatorSize.Large
}
}
}
2020-11-22 00:13:37 +03:00
}
}
}