Merge pull request #250 from Wunderfitz/searching
Fernschreiber learns filtering and searching
This commit is contained in:
commit
33878bb480
24 changed files with 1238 additions and 100 deletions
|
@ -84,6 +84,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
|
||||||
qml/pages/AboutPage.qml \
|
qml/pages/AboutPage.qml \
|
||||||
qml/pages/PollCreationPage.qml \
|
qml/pages/PollCreationPage.qml \
|
||||||
qml/pages/PollResultsPage.qml \
|
qml/pages/PollResultsPage.qml \
|
||||||
|
qml/pages/SearchChatsPage.qml \
|
||||||
qml/pages/SettingsPage.qml \
|
qml/pages/SettingsPage.qml \
|
||||||
qml/pages/VideoPage.qml \
|
qml/pages/VideoPage.qml \
|
||||||
rpm/harbour-fernschreiber.changes \
|
rpm/harbour-fernschreiber.changes \
|
||||||
|
|
|
@ -64,9 +64,9 @@ Item {
|
||||||
audioType = ( audioData['@type'] === "voiceNote" ) ? "voice" : "audio";
|
audioType = ( audioData['@type'] === "voiceNote" ) ? "voice" : "audio";
|
||||||
audioFileId = audioData[audioType].id;
|
audioFileId = audioData[audioType].id;
|
||||||
if (typeof audioData.album_cover_thumbnail !== "undefined") {
|
if (typeof audioData.album_cover_thumbnail !== "undefined") {
|
||||||
previewFileId = audioData.album_cover_thumbnail.photo.id;
|
previewFileId = audioData.album_cover_thumbnail.file.id;
|
||||||
if (audioData.album_cover_thumbnail.photo.local.is_downloading_completed) {
|
if (audioData.album_cover_thumbnail.file.local.is_downloading_completed) {
|
||||||
placeholderImage.source = audioData.album_cover_thumbnail.photo.local.path;
|
placeholderImage.source = audioData.album_cover_thumbnail.file.local.path;
|
||||||
} else {
|
} else {
|
||||||
tdLibWrapper.downloadFile(previewFileId);
|
tdLibWrapper.downloadFile(previewFileId);
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ Item {
|
||||||
if (typeof audioData === "object") {
|
if (typeof audioData === "object") {
|
||||||
if (fileInformation.local.is_downloading_completed) {
|
if (fileInformation.local.is_downloading_completed) {
|
||||||
if (fileId === previewFileId) {
|
if (fileId === previewFileId) {
|
||||||
audioData.thumbnail.photo = fileInformation;
|
audioData.album_cover_thumbnail.file = fileInformation;
|
||||||
placeholderImage.source = fileInformation.local.path;
|
placeholderImage.source = fileInformation.local.path;
|
||||||
}
|
}
|
||||||
if (fileId === audioFileId) {
|
if (fileId === audioFileId) {
|
||||||
|
|
|
@ -332,6 +332,14 @@ Page {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetFocus() {
|
||||||
|
if (searchInChatField.text === "") {
|
||||||
|
chatOverviewItem.visible = true;
|
||||||
|
}
|
||||||
|
searchInChatField.focus = false;
|
||||||
|
chatPage.focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: forwardMessagesTimer
|
id: forwardMessagesTimer
|
||||||
interval: 200
|
interval: 200
|
||||||
|
@ -348,6 +356,17 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: searchInChatTimer
|
||||||
|
interval: 300
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
Debug.log("Searching for '" + searchInChatField.text + "'");
|
||||||
|
chatModel.setSearchQuery(searchInChatField.text);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
initializePage();
|
initializePage();
|
||||||
}
|
}
|
||||||
|
@ -461,7 +480,7 @@ Page {
|
||||||
chatView.lastReadSentIndex = lastReadSentIndex;
|
chatView.lastReadSentIndex = lastReadSentIndex;
|
||||||
chatView.scrollToIndex(modelIndex);
|
chatView.scrollToIndex(modelIndex);
|
||||||
chatPage.loading = false;
|
chatPage.loading = false;
|
||||||
if (modelIndex >= (chatView.count - 10)) {
|
if (chatOverviewItem.visible && modelIndex >= (chatView.count - 10)) {
|
||||||
chatView.inCooldown = true;
|
chatView.inCooldown = true;
|
||||||
chatModel.triggerLoadMoreFuture();
|
chatModel.triggerLoadMoreFuture();
|
||||||
}
|
}
|
||||||
|
@ -470,6 +489,8 @@ Page {
|
||||||
Debug.log("[ChatPage] Chat content quite small...");
|
Debug.log("[ChatPage] Chat content quite small...");
|
||||||
viewMessageTimer.queueViewMessage(chatView.count - 1);
|
viewMessageTimer.queueViewMessage(chatView.count - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chatViewCooldownTimer.restart();
|
||||||
}
|
}
|
||||||
onNewMessageReceived: {
|
onNewMessageReceived: {
|
||||||
if (chatView.manuallyScrolledToBottom || message.sender.user_id === chatPage.myUserId) {
|
if (chatView.manuallyScrolledToBottom || message.sender.user_id === chatPage.myUserId) {
|
||||||
|
@ -480,7 +501,7 @@ Page {
|
||||||
onUnreadCountUpdated: {
|
onUnreadCountUpdated: {
|
||||||
Debug.log("[ChatPage] Unread count updated, new count: ", unreadCount);
|
Debug.log("[ChatPage] Unread count updated, new count: ", unreadCount);
|
||||||
chatInformation.unread_count = unreadCount;
|
chatInformation.unread_count = unreadCount;
|
||||||
chatUnreadMessagesCountBackground.visible = ( !chatPage.loading && unreadCount > 0 );
|
chatUnreadMessagesItem.visible = ( !chatPage.loading && chatInformation.unread_count > 0 && chatOverviewItem.visible );
|
||||||
chatUnreadMessagesCount.text = unreadCount > 99 ? "99+" : unreadCount;
|
chatUnreadMessagesCount.text = unreadCount > 99 ? "99+" : unreadCount;
|
||||||
}
|
}
|
||||||
onLastReadSentMessageUpdated: {
|
onLastReadSentMessageUpdated: {
|
||||||
|
@ -490,7 +511,7 @@ Page {
|
||||||
onMessagesIncrementalUpdate: {
|
onMessagesIncrementalUpdate: {
|
||||||
Debug.log("Incremental update received. View now has ", chatView.count, " messages, view is on index ", modelIndex, ", own messages were read before index ", lastReadSentIndex);
|
Debug.log("Incremental update received. View now has ", chatView.count, " messages, view is on index ", modelIndex, ", own messages were read before index ", lastReadSentIndex);
|
||||||
chatView.lastReadSentIndex = lastReadSentIndex;
|
chatView.lastReadSentIndex = lastReadSentIndex;
|
||||||
chatViewCooldownTimer.start();
|
chatViewCooldownTimer.restart();
|
||||||
}
|
}
|
||||||
onNotificationSettingsUpdated: {
|
onNotificationSettingsUpdated: {
|
||||||
chatInformation = chatModel.getChatInformation();
|
chatInformation = chatModel.getChatInformation();
|
||||||
|
@ -630,6 +651,17 @@ Page {
|
||||||
}
|
}
|
||||||
text: chatInformation.notification_settings.mute_for > 0 ? qsTr("Unmute Chat") : qsTr("Mute Chat")
|
text: chatInformation.notification_settings.mute_for > 0 ? qsTr("Unmute Chat") : qsTr("Mute Chat")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
id: searchInChatMenuItem
|
||||||
|
visible: !chatPage.isSecretChat && chatOverviewItem.visible
|
||||||
|
onClicked: {
|
||||||
|
// This automatically shows the search field as well
|
||||||
|
chatOverviewItem.visible = false;
|
||||||
|
searchInChatField.focus = true;
|
||||||
|
}
|
||||||
|
text: qsTr("Search in Chat")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundItem {
|
BackgroundItem {
|
||||||
|
@ -703,6 +735,8 @@ Page {
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
id: chatOverviewItem
|
id: chatOverviewItem
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
width: parent.width - chatPictureThumbnail.width - Theme.paddingMedium
|
width: parent.width - chatPictureThumbnail.width - Theme.paddingMedium
|
||||||
height: chatNameText.height + chatStatusText.height
|
height: chatNameText.height + chatStatusText.height
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
|
@ -735,6 +769,39 @@ Page {
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: searchInChatItem
|
||||||
|
visible: !chatOverviewItem.visible
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
width: parent.width - chatPictureThumbnail.width - Theme.paddingMedium
|
||||||
|
height: searchInChatField.height
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: chatPage.isPortrait ? Theme.paddingSmall : 0
|
||||||
|
|
||||||
|
SearchField {
|
||||||
|
id: searchInChatField
|
||||||
|
visible: false
|
||||||
|
width: visible ? parent.width : 0
|
||||||
|
placeholderText: qsTr("Search in chat...")
|
||||||
|
active: searchInChatItem.visible
|
||||||
|
canHide: text === ""
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
searchInChatTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
onHideClicked: {
|
||||||
|
resetFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
||||||
|
EnterKey.onClicked: {
|
||||||
|
resetFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PinnedMessageItem {
|
PinnedMessageItem {
|
||||||
|
@ -823,7 +890,7 @@ Page {
|
||||||
|
|
||||||
function handleScrollPositionChanged() {
|
function handleScrollPositionChanged() {
|
||||||
Debug.log("Current position: ", chatView.contentY);
|
Debug.log("Current position: ", chatView.contentY);
|
||||||
if (chatInformation.unread_count > 0) {
|
if (chatOverviewItem.visible && chatInformation.unread_count > 0) {
|
||||||
var bottomIndex = chatView.indexAt(chatView.contentX, ( chatView.contentY + chatView.height - Theme.horizontalPageMargin ));
|
var bottomIndex = chatView.indexAt(chatView.contentX, ( chatView.contentY + chatView.height - Theme.horizontalPageMargin ));
|
||||||
if (bottomIndex > -1) {
|
if (bottomIndex > -1) {
|
||||||
viewMessageTimer.queueViewMessage(bottomIndex)
|
viewMessageTimer.queueViewMessage(bottomIndex)
|
||||||
|
@ -850,7 +917,7 @@ Page {
|
||||||
Debug.log("[ChatPage] Trying to get older history items...");
|
Debug.log("[ChatPage] Trying to get older history items...");
|
||||||
chatView.inCooldown = true;
|
chatView.inCooldown = true;
|
||||||
chatModel.triggerLoadMoreHistory();
|
chatModel.triggerLoadMoreHistory();
|
||||||
} else if (chatView.indexAt(chatView.contentX, chatView.contentY) > ( count - 10)) {
|
} else if (chatOverviewItem.visible && chatView.indexAt(chatView.contentX, chatView.contentY) > ( count - 10)) {
|
||||||
Debug.log("[ChatPage] Trying to get newer history items...");
|
Debug.log("[ChatPage] Trying to get newer history items...");
|
||||||
chatView.inCooldown = true;
|
chatView.inCooldown = true;
|
||||||
chatModel.triggerLoadMoreFuture();
|
chatModel.triggerLoadMoreFuture();
|
||||||
|
@ -986,12 +1053,13 @@ Page {
|
||||||
anchors.rightMargin: Theme.paddingMedium
|
anchors.rightMargin: Theme.paddingMedium
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: Theme.paddingMedium
|
anchors.bottomMargin: Theme.paddingMedium
|
||||||
|
visible: !chatPage.loading && chatInformation.unread_count > 0 && chatOverviewItem.visible
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: chatUnreadMessagesCountBackground
|
id: chatUnreadMessagesCountBackground
|
||||||
color: Theme.highlightBackgroundColor
|
color: Theme.highlightBackgroundColor
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
radius: width / 2
|
radius: width / 2
|
||||||
visible: !chatPage.loading && chatInformation.unread_count > 0
|
visible: chatUnreadMessagesItem.visible
|
||||||
}
|
}
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
|
@ -1000,7 +1068,7 @@ Page {
|
||||||
font.bold: true
|
font.bold: true
|
||||||
color: Theme.primaryColor
|
color: Theme.primaryColor
|
||||||
anchors.centerIn: chatUnreadMessagesCountBackground
|
anchors.centerIn: chatUnreadMessagesCountBackground
|
||||||
visible: chatUnreadMessagesCountBackground.visible
|
visible: chatUnreadMessagesItem.visible
|
||||||
text: chatInformation.unread_count > 99 ? "99+" : chatInformation.unread_count
|
text: chatInformation.unread_count > 99 ? "99+" : chatInformation.unread_count
|
||||||
}
|
}
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
|
@ -86,6 +86,16 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: searchChatTimer
|
||||||
|
interval: 300
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
chatListProxyModel.setFilterWildcard("*" + chatSearchField.text + "*");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function setPageStatus() {
|
function setPageStatus() {
|
||||||
switch (overviewPage.connectionState) {
|
switch (overviewPage.connectionState) {
|
||||||
case TelegramAPI.WaitingForNetwork:
|
case TelegramAPI.WaitingForNetwork:
|
||||||
|
@ -145,6 +155,16 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resetFocus() {
|
||||||
|
if (chatSearchField.text === "") {
|
||||||
|
chatSearchField.visible = false;
|
||||||
|
pageHeader.visible = true;
|
||||||
|
searchChatButton.visible = overviewPage.connectionState === TelegramAPI.ConnectionReady;
|
||||||
|
}
|
||||||
|
chatSearchField.focus = false;
|
||||||
|
overviewPage.focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: tdLibWrapper
|
target: tdLibWrapper
|
||||||
onAuthorizationStateChanged: {
|
onAuthorizationStateChanged: {
|
||||||
|
@ -217,16 +237,19 @@ Page {
|
||||||
text: qsTr("Settings")
|
text: qsTr("Settings")
|
||||||
onClicked: pageStack.push(Qt.resolvedUrl("../pages/SettingsPage.qml"))
|
onClicked: pageStack.push(Qt.resolvedUrl("../pages/SettingsPage.qml"))
|
||||||
}
|
}
|
||||||
|
MenuItem {
|
||||||
|
text: qsTr("Search Chats")
|
||||||
|
onClicked: pageStack.push(Qt.resolvedUrl("../pages/SearchChatsPage.qml"))
|
||||||
|
}
|
||||||
MenuItem {
|
MenuItem {
|
||||||
text: qsTr("New Chat")
|
text: qsTr("New Chat")
|
||||||
onClicked: pageStack.push(Qt.resolvedUrl("../pages/NewChatPage.qml"))
|
onClicked: pageStack.push(Qt.resolvedUrl("../pages/NewChatPage.qml"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PageHeader {
|
Row {
|
||||||
id: pageHeader
|
id: headerRow
|
||||||
title: qsTr("Fernschreiber")
|
width: parent.width - Theme.horizontalPageMargin
|
||||||
leftMargin: Theme.itemSizeMedium
|
|
||||||
|
|
||||||
GlassItem {
|
GlassItem {
|
||||||
id: pageStatus
|
id: pageStatus
|
||||||
|
@ -237,12 +260,64 @@ Page {
|
||||||
radius: 0.2
|
radius: 0.2
|
||||||
cache: false
|
cache: false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PageHeader {
|
||||||
|
id: pageHeader
|
||||||
|
title: qsTr("Fernschreiber")
|
||||||
|
width: visible ? ( parent.width - pageStatus.width - searchChatButton.width ) : 0
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
}
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
id: searchChatButton
|
||||||
|
width: visible ? height : 0
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on opacity { NumberAnimation {} }
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
icon {
|
||||||
|
source: "image://theme/icon-m-search?" + Theme.highlightColor
|
||||||
|
asynchronous: true
|
||||||
|
}
|
||||||
|
visible: overviewPage.connectionState === TelegramAPI.ConnectionReady
|
||||||
|
onClicked: {
|
||||||
|
chatSearchField.focus = true;
|
||||||
|
chatSearchField.visible = true;
|
||||||
|
pageHeader.visible = false;
|
||||||
|
searchChatButton.visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchField {
|
||||||
|
id: chatSearchField
|
||||||
|
visible: false
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
width: visible ? ( parent.width - pageStatus.width ) : 0
|
||||||
|
height: pageHeader.height
|
||||||
|
placeholderText: qsTr("Filter your chats...")
|
||||||
|
canHide: text === ""
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
searchChatTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
onHideClicked: {
|
||||||
|
resetFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
||||||
|
EnterKey.onClicked: {
|
||||||
|
resetFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SilicaListView {
|
SilicaListView {
|
||||||
id: chatListView
|
id: chatListView
|
||||||
anchors {
|
anchors {
|
||||||
top: pageHeader.bottom
|
top: headerRow.bottom
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
|
@ -250,7 +325,7 @@ Page {
|
||||||
clip: true
|
clip: true
|
||||||
opacity: overviewPage.chatListCreated ? 1 : 0
|
opacity: overviewPage.chatListCreated ? 1 : 0
|
||||||
Behavior on opacity { FadeAnimation {} }
|
Behavior on opacity { FadeAnimation {} }
|
||||||
model: chatListModel
|
model: chatSearchField.text !== "" ? chatListProxyModel : chatListModel
|
||||||
delegate: ChatListViewItem {
|
delegate: ChatListViewItem {
|
||||||
ownUserId: overviewPage.ownUserId
|
ownUserId: overviewPage.ownUserId
|
||||||
isVerified: is_verified
|
isVerified: is_verified
|
||||||
|
|
262
qml/pages/SearchChatsPage.qml
Normal file
262
qml/pages/SearchChatsPage.qml
Normal file
|
@ -0,0 +1,262 @@
|
||||||
|
/*
|
||||||
|
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 WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../components"
|
||||||
|
import "../js/debug.js" as Debug
|
||||||
|
import "../js/twemoji.js" as Emoji
|
||||||
|
import "../js/functions.js" as Functions
|
||||||
|
|
||||||
|
Page {
|
||||||
|
id: searchChatsPage
|
||||||
|
allowedOrientations: Orientation.All
|
||||||
|
|
||||||
|
function resetFocus() {
|
||||||
|
publicChatsSearchField.focus = false;
|
||||||
|
searchChatsPage.focus = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: searchPublicChatsTimer
|
||||||
|
interval: 800
|
||||||
|
running: false
|
||||||
|
repeat: false
|
||||||
|
onTriggered: {
|
||||||
|
Debug.log("Searching for '" + publicChatsSearchField.text + "'");
|
||||||
|
tdLibWrapper.searchPublicChats(publicChatsSearchField.text);
|
||||||
|
searchChatsPage.isLoading = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: tdLibWrapper
|
||||||
|
onChatsReceived: {
|
||||||
|
searchChatsPage.isLoading = false;
|
||||||
|
Debug.log(JSON.stringify(chats));
|
||||||
|
chatsFound = chats;
|
||||||
|
}
|
||||||
|
onErrorReceived: {
|
||||||
|
searchChatsPage.isLoading = false;
|
||||||
|
Functions.handleErrorMessage(code, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property bool isLoading: false;
|
||||||
|
property var chatsFound;
|
||||||
|
readonly property var ownUserId: tdLibWrapper.getUserInformation().id;
|
||||||
|
|
||||||
|
SilicaFlickable {
|
||||||
|
id: searchChatsContainer
|
||||||
|
contentHeight: searchChatsPage.height
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: searchChatsPageColumn
|
||||||
|
width: searchChatsPage.width
|
||||||
|
height: searchChatsPage.height
|
||||||
|
|
||||||
|
PageHeader {
|
||||||
|
id: searchChatsPageHeader
|
||||||
|
title: qsTr("Search Chats")
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: publicChatsItem
|
||||||
|
|
||||||
|
width: searchChatsPageColumn.width
|
||||||
|
height: searchChatsPageColumn.height - searchChatsPageHeader.height
|
||||||
|
|
||||||
|
Column {
|
||||||
|
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
SearchField {
|
||||||
|
id: publicChatsSearchField
|
||||||
|
width: parent.width
|
||||||
|
placeholderText: qsTr("Search a chat...")
|
||||||
|
focus: true
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
searchPublicChatsTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
||||||
|
EnterKey.onClicked: {
|
||||||
|
resetFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SilicaListView {
|
||||||
|
id: searchChatsListView
|
||||||
|
clip: true
|
||||||
|
width: parent.width
|
||||||
|
height: parent.height - publicChatsSearchField.height
|
||||||
|
visible: !searchChatsPage.isLoading
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
model: searchChatsPage.chatsFound.chat_ids
|
||||||
|
|
||||||
|
ViewPlaceholder {
|
||||||
|
y: Theme.paddingLarge
|
||||||
|
enabled: searchChatsListView.count === 0
|
||||||
|
text: publicChatsSearchField.text.length < 5 ? qsTr("Enter your query to start searching (at least 5 characters needed)") : qsTr("No chats found.")
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
id: foundChatListDelegate
|
||||||
|
width: parent.width
|
||||||
|
height: foundChatListItem.height
|
||||||
|
|
||||||
|
property var foundChatInformation: tdLibWrapper.getChat(modelData);
|
||||||
|
property var relatedInformation;
|
||||||
|
property bool isPrivateChat: false;
|
||||||
|
property bool isBasicGroup: false;
|
||||||
|
property bool isSupergroup: false;
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
switch (foundChatInformation.type["@type"]) {
|
||||||
|
case "chatTypePrivate":
|
||||||
|
relatedInformation = tdLibWrapper.getUserInformation(foundChatInformation.type.user_id);
|
||||||
|
foundChatListItem.prologSecondaryText.text = qsTr("Private Chat");
|
||||||
|
foundChatListItem.secondaryText.text = "@" + ( relatedInformation.username !== "" ? relatedInformation.username : relatedInformation.user_id );
|
||||||
|
tdLibWrapper.getUserFullInfo(foundChatInformation.type.user_id);
|
||||||
|
isPrivateChat = true;
|
||||||
|
break;
|
||||||
|
case "chatTypeBasicGroup":
|
||||||
|
relatedInformation = tdLibWrapper.getBasicGroup(foundChatInformation.type.basic_group_id);
|
||||||
|
foundChatListItem.prologSecondaryText.text = qsTr("Group");
|
||||||
|
tdLibWrapper.getGroupFullInfo(foundChatInformation.type.basic_group_id, false);
|
||||||
|
isBasicGroup = true;
|
||||||
|
break;
|
||||||
|
case "chatTypeSupergroup":
|
||||||
|
relatedInformation = tdLibWrapper.getSuperGroup(foundChatInformation.type.supergroup_id);
|
||||||
|
if (relatedInformation.is_channel) {
|
||||||
|
foundChatListItem.prologSecondaryText.text = qsTr("Channel");
|
||||||
|
} else {
|
||||||
|
foundChatListItem.prologSecondaryText.text = qsTr("Group");
|
||||||
|
}
|
||||||
|
tdLibWrapper.getGroupFullInfo(foundChatInformation.type.supergroup_id, true);
|
||||||
|
isSupergroup = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: tdLibWrapper
|
||||||
|
onUserFullInfoUpdated: {
|
||||||
|
if (foundChatListDelegate.isPrivateChat && userId.toString() === foundChatListDelegate.foundChatInformation.type.user_id.toString()) {
|
||||||
|
foundChatListItem.tertiaryText.text = Emoji.emojify(userFullInfo.bio, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onUserFullInfoReceived: {
|
||||||
|
if (foundChatListDelegate.isPrivateChat && userFullInfo["@extra"].toString() === foundChatListDelegate.foundChatInformation.type.user_id.toString()) {
|
||||||
|
foundChatListItem.tertiaryText.text = Emoji.emojify(userFullInfo.bio, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onBasicGroupFullInfoUpdated: {
|
||||||
|
if (foundChatListDelegate.isBasicGroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.basic_group_id.toString()) {
|
||||||
|
foundChatListItem.secondaryText.text = qsTr("%1 members").arg(Number(groupFullInfo.members.length).toLocaleString(Qt.locale(), "f", 0));
|
||||||
|
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onBasicGroupFullInfoReceived: {
|
||||||
|
if (foundChatListDelegate.isBasicGroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.basic_group_id.toString()) {
|
||||||
|
foundChatListItem.secondaryText.text = qsTr("%1 members").arg(Number(groupFullInfo.members.length).toLocaleString(Qt.locale(), "f", 0));
|
||||||
|
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onSupergroupFullInfoUpdated: {
|
||||||
|
if (foundChatListDelegate.isSupergroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.supergroup_id.toString()) {
|
||||||
|
if (foundChatListDelegate.relatedInformation.is_channel) {
|
||||||
|
foundChatListItem.secondaryText.text = qsTr("%1 subscribers").arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
||||||
|
} else {
|
||||||
|
foundChatListItem.secondaryText.text = qsTr("%1 members").arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
||||||
|
}
|
||||||
|
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onSupergroupFullInfoReceived: {
|
||||||
|
if (foundChatListDelegate.isSupergroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.supergroup_id.toString()) {
|
||||||
|
if (foundChatListDelegate.relatedInformation.is_channel) {
|
||||||
|
foundChatListItem.secondaryText.text = qsTr("%1 subscribers").arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
||||||
|
} else {
|
||||||
|
foundChatListItem.secondaryText.text = qsTr("%1 members").arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
||||||
|
}
|
||||||
|
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PhotoTextsListItem {
|
||||||
|
id: foundChatListItem
|
||||||
|
|
||||||
|
pictureThumbnail {
|
||||||
|
photoData: typeof foundChatInformation.photo.small !== "undefined" ? foundChatInformation.photo.small : {}
|
||||||
|
}
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
primaryText.text: Emoji.emojify(foundChatInformation.title, primaryText.font.pixelSize, "../js/emoji/")
|
||||||
|
tertiaryText.maximumLineCount: 1
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
pageStack.push(Qt.resolvedUrl("../pages/ChatPage.qml"), { "chatInformation" : foundChatInformation });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerticalScrollDecorator {}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
visible: searchChatsPage.isLoading
|
||||||
|
width: parent.width
|
||||||
|
height: loadingLabel.height + loadingBusyIndicator.height + Theme.paddingMedium
|
||||||
|
|
||||||
|
spacing: Theme.paddingMedium
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
|
InfoLabel {
|
||||||
|
id: loadingLabel
|
||||||
|
text: qsTr("Searching chats...")
|
||||||
|
}
|
||||||
|
|
||||||
|
BusyIndicator {
|
||||||
|
id: loadingBusyIndicator
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
running: searchChatsPage.isLoading
|
||||||
|
size: BusyIndicatorSize.Large
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -54,23 +54,6 @@ namespace {
|
||||||
class ChatListModel::ChatData
|
class ChatListModel::ChatData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum Role {
|
|
||||||
RoleDisplay = Qt::DisplayRole,
|
|
||||||
RoleChatId,
|
|
||||||
RoleChatType,
|
|
||||||
RoleTitle,
|
|
||||||
RolePhotoSmall,
|
|
||||||
RoleUnreadCount,
|
|
||||||
RoleLastReadInboxMessageId,
|
|
||||||
RoleLastMessageSenderId,
|
|
||||||
RoleLastMessageDate,
|
|
||||||
RoleLastMessageText,
|
|
||||||
RoleLastMessageStatus,
|
|
||||||
RoleChatMemberStatus,
|
|
||||||
RoleSecretChatState,
|
|
||||||
RoleIsVerified,
|
|
||||||
RoleIsChannel
|
|
||||||
};
|
|
||||||
|
|
||||||
ChatData(TDLibWrapper *tdLibWrapper, const QVariantMap &data);
|
ChatData(TDLibWrapper *tdLibWrapper, const QVariantMap &data);
|
||||||
|
|
||||||
|
@ -370,21 +353,22 @@ ChatListModel::~ChatListModel()
|
||||||
QHash<int,QByteArray> ChatListModel::roleNames() const
|
QHash<int,QByteArray> ChatListModel::roleNames() const
|
||||||
{
|
{
|
||||||
QHash<int,QByteArray> roles;
|
QHash<int,QByteArray> roles;
|
||||||
roles.insert(ChatData::RoleDisplay, "display");
|
roles.insert(ChatListModel::RoleDisplay, "display");
|
||||||
roles.insert(ChatData::RoleChatId, "chat_id");
|
roles.insert(ChatListModel::RoleChatId, "chat_id");
|
||||||
roles.insert(ChatData::RoleChatType, "chat_type");
|
roles.insert(ChatListModel::RoleChatType, "chat_type");
|
||||||
roles.insert(ChatData::RoleTitle, "title");
|
roles.insert(ChatListModel::RoleTitle, "title");
|
||||||
roles.insert(ChatData::RolePhotoSmall, "photo_small");
|
roles.insert(ChatListModel::RolePhotoSmall, "photo_small");
|
||||||
roles.insert(ChatData::RoleUnreadCount, "unread_count");
|
roles.insert(ChatListModel::RoleUnreadCount, "unread_count");
|
||||||
roles.insert(ChatData::RoleLastReadInboxMessageId, "last_read_inbox_message_id");
|
roles.insert(ChatListModel::RoleLastReadInboxMessageId, "last_read_inbox_message_id");
|
||||||
roles.insert(ChatData::RoleLastMessageSenderId, "last_message_sender_id");
|
roles.insert(ChatListModel::RoleLastMessageSenderId, "last_message_sender_id");
|
||||||
roles.insert(ChatData::RoleLastMessageDate, "last_message_date");
|
roles.insert(ChatListModel::RoleLastMessageDate, "last_message_date");
|
||||||
roles.insert(ChatData::RoleLastMessageText, "last_message_text");
|
roles.insert(ChatListModel::RoleLastMessageText, "last_message_text");
|
||||||
roles.insert(ChatData::RoleLastMessageStatus, "last_message_status");
|
roles.insert(ChatListModel::RoleLastMessageStatus, "last_message_status");
|
||||||
roles.insert(ChatData::RoleChatMemberStatus, "chat_member_status");
|
roles.insert(ChatListModel::RoleChatMemberStatus, "chat_member_status");
|
||||||
roles.insert(ChatData::RoleSecretChatState, "secret_chat_state");
|
roles.insert(ChatListModel::RoleSecretChatState, "secret_chat_state");
|
||||||
roles.insert(ChatData::RoleIsVerified, "is_verified");
|
roles.insert(ChatListModel::RoleIsVerified, "is_verified");
|
||||||
roles.insert(ChatData::RoleIsChannel, "is_channel");
|
roles.insert(ChatListModel::RoleIsChannel, "is_channel");
|
||||||
|
roles.insert(ChatListModel::RoleFilter, "filter");
|
||||||
return roles;
|
return roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,22 +382,23 @@ QVariant ChatListModel::data(const QModelIndex &index, int role) const
|
||||||
const int row = index.row();
|
const int row = index.row();
|
||||||
if (row >= 0 && row < chatList.size()) {
|
if (row >= 0 && row < chatList.size()) {
|
||||||
const ChatData *data = chatList.at(row);
|
const ChatData *data = chatList.at(row);
|
||||||
switch ((ChatData::Role)role) {
|
switch ((ChatListModel::Role)role) {
|
||||||
case ChatData::RoleDisplay: return data->chatData;
|
case ChatListModel::RoleDisplay: return data->chatData;
|
||||||
case ChatData::RoleChatId: return data->chatId;
|
case ChatListModel::RoleChatId: return data->chatId;
|
||||||
case ChatData::RoleChatType: return data->chatType;
|
case ChatListModel::RoleChatType: return data->chatType;
|
||||||
case ChatData::RoleTitle: return data->title();
|
case ChatListModel::RoleTitle: return data->title();
|
||||||
case ChatData::RolePhotoSmall: return data->photoSmall();
|
case ChatListModel::RolePhotoSmall: return data->photoSmall();
|
||||||
case ChatData::RoleUnreadCount: return data->unreadCount();
|
case ChatListModel::RoleUnreadCount: return data->unreadCount();
|
||||||
case ChatData::RoleLastReadInboxMessageId: return data->lastReadInboxMessageId();
|
case ChatListModel::RoleLastReadInboxMessageId: return data->lastReadInboxMessageId();
|
||||||
case ChatData::RoleLastMessageSenderId: return data->senderUserId();
|
case ChatListModel::RoleLastMessageSenderId: return data->senderUserId();
|
||||||
case ChatData::RoleLastMessageText: return data->senderMessageText();
|
case ChatListModel::RoleLastMessageText: return data->senderMessageText();
|
||||||
case ChatData::RoleLastMessageDate: return data->senderMessageDate();
|
case ChatListModel::RoleLastMessageDate: return data->senderMessageDate();
|
||||||
case ChatData::RoleLastMessageStatus: return data->senderMessageStatus();
|
case ChatListModel::RoleLastMessageStatus: return data->senderMessageStatus();
|
||||||
case ChatData::RoleChatMemberStatus: return data->memberStatus;
|
case ChatListModel::RoleChatMemberStatus: return data->memberStatus;
|
||||||
case ChatData::RoleSecretChatState: return data->secretChatState;
|
case ChatListModel::RoleSecretChatState: return data->secretChatState;
|
||||||
case ChatData::RoleIsVerified: return data->verified;
|
case ChatListModel::RoleIsVerified: return data->verified;
|
||||||
case ChatData::RoleIsChannel: return data->isChannel();
|
case ChatListModel::RoleIsChannel: return data->isChannel();
|
||||||
|
case ChatListModel::RoleFilter: return QString(data->title() + " " + data->senderMessageText()).trimmed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QVariant();
|
return QVariant();
|
||||||
|
@ -679,12 +664,12 @@ void ChatListModel::handleChatReadInboxUpdated(const QString &id, const QString
|
||||||
const int chatIndex = chatIndexMap.value(chatId);
|
const int chatIndex = chatIndexMap.value(chatId);
|
||||||
ChatData *chat = chatList.at(chatIndex);
|
ChatData *chat = chatList.at(chatIndex);
|
||||||
QVector<int> changedRoles;
|
QVector<int> changedRoles;
|
||||||
changedRoles.append(ChatData::RoleDisplay);
|
changedRoles.append(ChatListModel::RoleDisplay);
|
||||||
if (chat->updateUnreadCount(unreadCount)) {
|
if (chat->updateUnreadCount(unreadCount)) {
|
||||||
changedRoles.append(ChatData::RoleUnreadCount);
|
changedRoles.append(ChatListModel::RoleUnreadCount);
|
||||||
}
|
}
|
||||||
if (chat->updateLastReadInboxMessageId(messageId)) {
|
if (chat->updateLastReadInboxMessageId(messageId)) {
|
||||||
changedRoles.append(ChatData::RoleLastReadInboxMessageId);
|
changedRoles.append(ChatListModel::RoleLastReadInboxMessageId);
|
||||||
}
|
}
|
||||||
const QModelIndex modelIndex(index(chatIndex));
|
const QModelIndex modelIndex(index(chatIndex));
|
||||||
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
||||||
|
@ -728,7 +713,7 @@ void ChatListModel::handleChatPhotoUpdated(qlonglong chatId, const QVariantMap &
|
||||||
ChatData *chat = chatList.at(chatIndex);
|
ChatData *chat = chatList.at(chatIndex);
|
||||||
chat->chatData.insert(PHOTO, photo);
|
chat->chatData.insert(PHOTO, photo);
|
||||||
QVector<int> changedRoles;
|
QVector<int> changedRoles;
|
||||||
changedRoles.append(ChatData::RolePhotoSmall);
|
changedRoles.append(ChatListModel::RolePhotoSmall);
|
||||||
const QModelIndex modelIndex(index(chatIndex));
|
const QModelIndex modelIndex(index(chatIndex));
|
||||||
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
||||||
} else {
|
} else {
|
||||||
|
@ -817,7 +802,7 @@ void ChatListModel::handleChatTitleUpdated(const QString &chatId, const QString
|
||||||
ChatData *chat = chatList.at(chatIndex);
|
ChatData *chat = chatList.at(chatIndex);
|
||||||
chat->chatData.insert(TITLE, title);
|
chat->chatData.insert(TITLE, title);
|
||||||
QVector<int> changedRoles;
|
QVector<int> changedRoles;
|
||||||
changedRoles.append(ChatData::RoleTitle);
|
changedRoles.append(ChatListModel::RoleTitle);
|
||||||
const QModelIndex modelIndex(index(chatIndex));
|
const QModelIndex modelIndex(index(chatIndex));
|
||||||
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
||||||
} else {
|
} else {
|
||||||
|
@ -833,6 +818,6 @@ void ChatListModel::handleRelativeTimeRefreshTimer()
|
||||||
{
|
{
|
||||||
LOG("Refreshing timestamps");
|
LOG("Refreshing timestamps");
|
||||||
QVector<int> roles;
|
QVector<int> roles;
|
||||||
roles.append(ChatData::RoleLastMessageDate);
|
roles.append(ChatListModel::RoleLastMessageDate);
|
||||||
emit dataChanged(index(0), index(chatList.size() - 1), roles);
|
emit dataChanged(index(0), index(chatList.size() - 1), roles);
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,26 @@ class ChatListModel : public QAbstractListModel
|
||||||
Q_PROPERTY(bool showAllChats READ showAllChats WRITE setShowAllChats NOTIFY showAllChatsChanged)
|
Q_PROPERTY(bool showAllChats READ showAllChats WRITE setShowAllChats NOTIFY showAllChatsChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
enum Role {
|
||||||
|
RoleDisplay = Qt::DisplayRole,
|
||||||
|
RoleChatId,
|
||||||
|
RoleChatType,
|
||||||
|
RoleTitle,
|
||||||
|
RolePhotoSmall,
|
||||||
|
RoleUnreadCount,
|
||||||
|
RoleLastReadInboxMessageId,
|
||||||
|
RoleLastMessageSenderId,
|
||||||
|
RoleLastMessageDate,
|
||||||
|
RoleLastMessageText,
|
||||||
|
RoleLastMessageStatus,
|
||||||
|
RoleChatMemberStatus,
|
||||||
|
RoleSecretChatState,
|
||||||
|
RoleIsVerified,
|
||||||
|
RoleIsChannel,
|
||||||
|
RoleFilter
|
||||||
|
};
|
||||||
|
|
||||||
ChatListModel(TDLibWrapper *tdLibWrapper);
|
ChatListModel(TDLibWrapper *tdLibWrapper);
|
||||||
~ChatListModel() override;
|
~ChatListModel() override;
|
||||||
|
|
||||||
|
|
|
@ -156,11 +156,13 @@ QVariant ChatModel::data(const QModelIndex &index, int role) const
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatModel::clear()
|
void ChatModel::clear(bool contentOnly)
|
||||||
{
|
{
|
||||||
LOG("Clearing chat model");
|
LOG("Clearing chat model");
|
||||||
inReload = false;
|
inReload = false;
|
||||||
inIncrementalUpdate = false;
|
inIncrementalUpdate = false;
|
||||||
|
searchModeActive = false;
|
||||||
|
searchQuery.clear();
|
||||||
if (!messages.isEmpty()) {
|
if (!messages.isEmpty()) {
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
qDeleteAll(messages);
|
qDeleteAll(messages);
|
||||||
|
@ -168,13 +170,16 @@ void ChatModel::clear()
|
||||||
messageIndexMap.clear();
|
messageIndexMap.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
}
|
}
|
||||||
if (!chatInformation.isEmpty()) {
|
|
||||||
chatInformation.clear();
|
if (!contentOnly) {
|
||||||
emit smallPhotoChanged();
|
if (!chatInformation.isEmpty()) {
|
||||||
}
|
chatInformation.clear();
|
||||||
if (chatId) {
|
emit smallPhotoChanged();
|
||||||
chatId = 0;
|
}
|
||||||
emit chatIdChanged();
|
if (chatId) {
|
||||||
|
chatId = 0;
|
||||||
|
emit chatIdChanged();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,6 +193,7 @@ void ChatModel::initialize(const QVariantMap &chatInformation)
|
||||||
this->chatId = chatId;
|
this->chatId = chatId;
|
||||||
this->messages.clear();
|
this->messages.clear();
|
||||||
this->messageIndexMap.clear();
|
this->messageIndexMap.clear();
|
||||||
|
this->searchQuery.clear();
|
||||||
endResetModel();
|
endResetModel();
|
||||||
emit chatIdChanged();
|
emit chatIdChanged();
|
||||||
emit smallPhotoChanged();
|
emit smallPhotoChanged();
|
||||||
|
@ -197,15 +203,21 @@ void ChatModel::initialize(const QVariantMap &chatInformation)
|
||||||
void ChatModel::triggerLoadMoreHistory()
|
void ChatModel::triggerLoadMoreHistory()
|
||||||
{
|
{
|
||||||
if (!this->inIncrementalUpdate && !messages.isEmpty()) {
|
if (!this->inIncrementalUpdate && !messages.isEmpty()) {
|
||||||
LOG("Trigger loading older history...");
|
if (searchModeActive) {
|
||||||
this->inIncrementalUpdate = true;
|
LOG("Trigger loading older found messages...");
|
||||||
this->tdLibWrapper->getChatHistory(chatId, messages.first()->messageId);
|
this->inIncrementalUpdate = true;
|
||||||
|
this->tdLibWrapper->searchChatMessages(chatId, searchQuery, messages.first()->messageId);
|
||||||
|
} else {
|
||||||
|
LOG("Trigger loading older history...");
|
||||||
|
this->inIncrementalUpdate = true;
|
||||||
|
this->tdLibWrapper->getChatHistory(chatId, messages.first()->messageId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatModel::triggerLoadMoreFuture()
|
void ChatModel::triggerLoadMoreFuture()
|
||||||
{
|
{
|
||||||
if (!this->inIncrementalUpdate && !messages.isEmpty()) {
|
if (!this->inIncrementalUpdate && !messages.isEmpty() && !searchModeActive) {
|
||||||
LOG("Trigger loading newer future...");
|
LOG("Trigger loading newer future...");
|
||||||
this->inIncrementalUpdate = true;
|
this->inIncrementalUpdate = true;
|
||||||
this->tdLibWrapper->getChatHistory(chatId, messages.last()->messageId, -49);
|
this->tdLibWrapper->getChatHistory(chatId, messages.last()->messageId, -49);
|
||||||
|
@ -221,9 +233,8 @@ QVariantMap ChatModel::getMessage(int index)
|
||||||
{
|
{
|
||||||
if (index >= 0 && index < messages.size()) {
|
if (index >= 0 && index < messages.size()) {
|
||||||
return messages.at(index)->messageData;
|
return messages.at(index)->messageData;
|
||||||
} else {
|
|
||||||
return QVariantMap();
|
|
||||||
}
|
}
|
||||||
|
return QVariantMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
int ChatModel::getLastReadMessageIndex()
|
int ChatModel::getLastReadMessageIndex()
|
||||||
|
@ -247,6 +258,20 @@ int ChatModel::getLastReadMessageIndex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatModel::setSearchQuery(const QString newSearchQuery)
|
||||||
|
{
|
||||||
|
if (this->searchQuery != newSearchQuery) {
|
||||||
|
this->clear(true);
|
||||||
|
this->searchQuery = newSearchQuery;
|
||||||
|
this->searchModeActive = !this->searchQuery.isEmpty();
|
||||||
|
if (this->searchModeActive) {
|
||||||
|
this->tdLibWrapper->searchChatMessages(this->chatId, this->searchQuery);
|
||||||
|
} else {
|
||||||
|
this->tdLibWrapper->getChatHistory(chatId, this->chatInformation.value(LAST_READ_INBOX_MESSAGE_ID).toLongLong());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QVariantMap ChatModel::smallPhoto() const
|
QVariantMap ChatModel::smallPhoto() const
|
||||||
{
|
{
|
||||||
return chatInformation.value(PHOTO).toMap().value(SMALL).toMap();
|
return chatInformation.value(PHOTO).toMap().value(SMALL).toMap();
|
||||||
|
@ -260,6 +285,7 @@ qlonglong ChatModel::getChatId() const
|
||||||
void ChatModel::handleMessagesReceived(const QVariantList &messages, int totalCount)
|
void ChatModel::handleMessagesReceived(const QVariantList &messages, int totalCount)
|
||||||
{
|
{
|
||||||
LOG("Receiving new messages :)" << messages.size());
|
LOG("Receiving new messages :)" << messages.size());
|
||||||
|
LOG("Received while search mode is" << searchModeActive);
|
||||||
|
|
||||||
if (messages.size() == 0) {
|
if (messages.size() == 0) {
|
||||||
LOG("No additional messages loaded, notifying chat UI...");
|
LOG("No additional messages loaded, notifying chat UI...");
|
||||||
|
@ -276,6 +302,7 @@ void ChatModel::handleMessagesReceived(const QVariantList &messages, int totalCo
|
||||||
if (this->isMostRecentMessageLoaded() || this->inIncrementalUpdate) {
|
if (this->isMostRecentMessageLoaded() || this->inIncrementalUpdate) {
|
||||||
QList<MessageData*> messagesToBeAdded;
|
QList<MessageData*> messagesToBeAdded;
|
||||||
QListIterator<QVariant> messagesIterator(messages);
|
QListIterator<QVariant> messagesIterator(messages);
|
||||||
|
|
||||||
while (messagesIterator.hasNext()) {
|
while (messagesIterator.hasNext()) {
|
||||||
const QVariantMap messageData = messagesIterator.next().toMap();
|
const QVariantMap messageData = messagesIterator.next().toMap();
|
||||||
const qlonglong messageId = messageData.value(ID).toLongLong();
|
const qlonglong messageId = messageData.value(ID).toLongLong();
|
||||||
|
@ -295,7 +322,11 @@ void ChatModel::handleMessagesReceived(const QVariantList &messages, int totalCo
|
||||||
if (!messagesToBeAdded.isEmpty() && (messagesToBeAdded.size() + messages.size()) < 10 && !inReload) {
|
if (!messagesToBeAdded.isEmpty() && (messagesToBeAdded.size() + messages.size()) < 10 && !inReload) {
|
||||||
LOG("Only a few messages received in first call, loading more...");
|
LOG("Only a few messages received in first call, loading more...");
|
||||||
this->inReload = true;
|
this->inReload = true;
|
||||||
this->tdLibWrapper->getChatHistory(chatId, messagesToBeAdded.first()->messageId, 0);
|
if (this->searchModeActive) {
|
||||||
|
this->tdLibWrapper->searchChatMessages(chatId, searchQuery, messagesToBeAdded.first()->messageId);
|
||||||
|
} else {
|
||||||
|
this->tdLibWrapper->getChatHistory(chatId, messagesToBeAdded.first()->messageId, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
LOG("Messages loaded, notifying chat UI...");
|
LOG("Messages loaded, notifying chat UI...");
|
||||||
this->inReload = false;
|
this->inReload = false;
|
||||||
|
@ -322,7 +353,7 @@ void ChatModel::handleNewMessageReceived(qlonglong chatId, const QVariantMap &me
|
||||||
{
|
{
|
||||||
const qlonglong messageId = message.value(ID).toLongLong();
|
const qlonglong messageId = message.value(ID).toLongLong();
|
||||||
if (chatId == this->chatId && !messageIndexMap.contains(messageId)) {
|
if (chatId == this->chatId && !messageIndexMap.contains(messageId)) {
|
||||||
if (this->isMostRecentMessageLoaded()) {
|
if (this->isMostRecentMessageLoaded() && !this->searchModeActive) {
|
||||||
LOG("New message received for this chat");
|
LOG("New message received for this chat");
|
||||||
QList<MessageData*> messagesToBeAdded;
|
QList<MessageData*> messagesToBeAdded;
|
||||||
messagesToBeAdded.append(new MessageData(message, messageId));
|
messagesToBeAdded.append(new MessageData(message, messageId));
|
||||||
|
@ -449,27 +480,40 @@ void ChatModel::handleMessagesDeleted(qlonglong chatId, const QList<qlonglong> &
|
||||||
if (chatId == this->chatId) {
|
if (chatId == this->chatId) {
|
||||||
const int count = messageIds.size();
|
const int count = messageIds.size();
|
||||||
LOG(count << "messages in this chat were deleted...");
|
LOG(count << "messages in this chat were deleted...");
|
||||||
int firstDeleted = -1, lastDeleted = -2;
|
|
||||||
for (int i = 0; i < count; i++) {
|
int firstPosition = count, lastPosition = count;
|
||||||
const int pos = messageIndexMap.value(messageIds.at(i), -1);
|
for (int i = (count - 1); i > -1; i--) {
|
||||||
if (pos >= 0) {
|
const int position = messageIndexMap.value(messageIds.at(i), -1);
|
||||||
if (pos == lastDeleted + 1) {
|
if (position >= 0) {
|
||||||
lastDeleted = pos; // Extend the current range
|
// We found at least one message in our list that needs to be deleted
|
||||||
|
if (lastPosition == count) {
|
||||||
|
lastPosition = position;
|
||||||
|
}
|
||||||
|
if (firstPosition == count) {
|
||||||
|
firstPosition = position;
|
||||||
|
}
|
||||||
|
if (position < (firstPosition - 1)) {
|
||||||
|
// Some gap in between, can remove previous range and reset positions
|
||||||
|
removeRange(firstPosition, lastPosition);
|
||||||
|
firstPosition = lastPosition = position;
|
||||||
} else {
|
} else {
|
||||||
removeRange(firstDeleted, lastDeleted);
|
// No gap in between, extend the range and continue loop
|
||||||
firstDeleted = lastDeleted = pos; // Start new range
|
firstPosition = position;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Handle the last (and likely the only) range
|
// After all elements have been processed, there may be one last range to remove
|
||||||
removeRange(firstDeleted, lastDeleted);
|
// But only if we found at least one item to remove
|
||||||
|
if (firstPosition != count && lastPosition != count) {
|
||||||
|
removeRange(firstPosition, lastPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatModel::removeRange(int firstDeleted, int lastDeleted)
|
void ChatModel::removeRange(int firstDeleted, int lastDeleted)
|
||||||
{
|
{
|
||||||
if (firstDeleted >= 0 && firstDeleted <= lastDeleted) {
|
if (firstDeleted >= 0 && firstDeleted <= lastDeleted) {
|
||||||
LOG("Removing range" << firstDeleted << "..." << lastDeleted);
|
LOG("Removing range" << firstDeleted << "..." << lastDeleted << "| current messages size" << messages.size());
|
||||||
beginRemoveRows(QModelIndex(), firstDeleted, lastDeleted);
|
beginRemoveRows(QModelIndex(), firstDeleted, lastDeleted);
|
||||||
for (int i = firstDeleted; i <= lastDeleted; i++) {
|
for (int i = firstDeleted; i <= lastDeleted; i++) {
|
||||||
MessageData *message = messages.at(i);
|
MessageData *message = messages.at(i);
|
||||||
|
|
|
@ -37,13 +37,14 @@ public:
|
||||||
virtual int rowCount(const QModelIndex&) const override;
|
virtual int rowCount(const QModelIndex&) const override;
|
||||||
virtual QVariant data(const QModelIndex &index, int role) const override;
|
virtual QVariant data(const QModelIndex &index, int role) const override;
|
||||||
|
|
||||||
Q_INVOKABLE void clear();
|
Q_INVOKABLE void clear(bool contentOnly = false);
|
||||||
Q_INVOKABLE void initialize(const QVariantMap &chatInformation);
|
Q_INVOKABLE void initialize(const QVariantMap &chatInformation);
|
||||||
Q_INVOKABLE void triggerLoadMoreHistory();
|
Q_INVOKABLE void triggerLoadMoreHistory();
|
||||||
Q_INVOKABLE void triggerLoadMoreFuture();
|
Q_INVOKABLE void triggerLoadMoreFuture();
|
||||||
Q_INVOKABLE QVariantMap getChatInformation();
|
Q_INVOKABLE QVariantMap getChatInformation();
|
||||||
Q_INVOKABLE QVariantMap getMessage(int index);
|
Q_INVOKABLE QVariantMap getMessage(int index);
|
||||||
Q_INVOKABLE int getLastReadMessageIndex();
|
Q_INVOKABLE int getLastReadMessageIndex();
|
||||||
|
Q_INVOKABLE void setSearchQuery(const QString newSearchQuery);
|
||||||
|
|
||||||
QVariantMap smallPhoto() const;
|
QVariantMap smallPhoto() const;
|
||||||
qlonglong getChatId() const;
|
qlonglong getChatId() const;
|
||||||
|
@ -93,6 +94,8 @@ private:
|
||||||
qlonglong chatId;
|
qlonglong chatId;
|
||||||
bool inReload;
|
bool inReload;
|
||||||
bool inIncrementalUpdate;
|
bool inIncrementalUpdate;
|
||||||
|
bool searchModeActive;
|
||||||
|
QString searchQuery;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CHATMODEL_H
|
#endif // CHATMODEL_H
|
||||||
|
|
|
@ -88,6 +88,11 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
ChatListModel chatListModel(tdLibWrapper);
|
ChatListModel chatListModel(tdLibWrapper);
|
||||||
context->setContextProperty("chatListModel", &chatListModel);
|
context->setContextProperty("chatListModel", &chatListModel);
|
||||||
|
QSortFilterProxyModel chatListProxyModel(view.data());
|
||||||
|
chatListProxyModel.setSourceModel(&chatListModel);
|
||||||
|
chatListProxyModel.setFilterRole(ChatListModel::RoleFilter);
|
||||||
|
chatListProxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||||
|
context->setContextProperty("chatListProxyModel", &chatListProxyModel);
|
||||||
|
|
||||||
ChatModel chatModel(tdLibWrapper);
|
ChatModel chatModel(tdLibWrapper);
|
||||||
context->setContextProperty("chatModel", &chatModel);
|
context->setContextProperty("chatModel", &chatModel);
|
||||||
|
|
|
@ -74,7 +74,7 @@ signals:
|
||||||
void stickerSet(const QVariantMap &stickerSet);
|
void stickerSet(const QVariantMap &stickerSet);
|
||||||
void chatMembers(const QString &extra, const QVariantList &members, int totalMembers);
|
void chatMembers(const QString &extra, const QVariantList &members, int totalMembers);
|
||||||
void userFullInfo(const QVariantMap &userFullInfo);
|
void userFullInfo(const QVariantMap &userFullInfo);
|
||||||
void userFullInfoUpdated(const QString &userId,const QVariantMap &userFullInfo);
|
void userFullInfoUpdated(const QString &userId, const QVariantMap &userFullInfo);
|
||||||
void basicGroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo);
|
void basicGroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo);
|
||||||
void basicGroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo);
|
void basicGroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo);
|
||||||
void supergroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo);
|
void supergroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo);
|
||||||
|
|
|
@ -937,6 +937,30 @@ void TDLibWrapper::importContacts(const QVariantList &contacts)
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::searchChatMessages(const qlonglong &chatId, const QString &query, const qlonglong fromMessageId)
|
||||||
|
{
|
||||||
|
LOG("Searching for messages" << chatId << query << fromMessageId);
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "searchChatMessages");
|
||||||
|
requestObject.insert("chat_id", chatId);
|
||||||
|
requestObject.insert("query", query);
|
||||||
|
requestObject.insert("from_message_id", fromMessageId);
|
||||||
|
requestObject.insert("offset", 0);
|
||||||
|
requestObject.insert("limit", 50);
|
||||||
|
requestObject.insert(_EXTRA, "searchChatMessages");
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::searchPublicChats(const QString &query)
|
||||||
|
{
|
||||||
|
LOG("Searching public chats" << query);
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "searchPublicChats");
|
||||||
|
requestObject.insert("query", query);
|
||||||
|
requestObject.insert(_EXTRA, "searchPublicChats");
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::readAllChatMentions(qlonglong chatId)
|
void TDLibWrapper::readAllChatMentions(qlonglong chatId)
|
||||||
{
|
{
|
||||||
LOG("Read all chat mentions" << chatId);
|
LOG("Read all chat mentions" << chatId);
|
||||||
|
|
|
@ -179,6 +179,8 @@ public:
|
||||||
Q_INVOKABLE void getSecretChat(qlonglong secretChatId);
|
Q_INVOKABLE void getSecretChat(qlonglong secretChatId);
|
||||||
Q_INVOKABLE void closeSecretChat(qlonglong secretChatId);
|
Q_INVOKABLE void closeSecretChat(qlonglong secretChatId);
|
||||||
Q_INVOKABLE void importContacts(const QVariantList &contacts);
|
Q_INVOKABLE void importContacts(const QVariantList &contacts);
|
||||||
|
Q_INVOKABLE void searchChatMessages(const qlonglong &chatId, const QString &query, const qlonglong fromMessageId = 0);
|
||||||
|
Q_INVOKABLE void searchPublicChats(const QString &query);
|
||||||
Q_INVOKABLE void readAllChatMentions(qlonglong chatId);
|
Q_INVOKABLE void readAllChatMentions(qlonglong chatId);
|
||||||
|
|
||||||
// Others (candidates for extraction ;))
|
// Others (candidates for extraction ;))
|
||||||
|
|
|
@ -391,6 +391,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation>Chat schließen</translation>
|
<translation>Chat schließen</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation>Im Chat suchen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation>Im Chat suchen...</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1044,6 +1052,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>Neuer Chat</translation>
|
<translation>Neuer Chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation>Ihre Chats filtern...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation>Chats suchen</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation>Download von %1 erfolgreich.</translation>
|
<translation>Download von %1 erfolgreich.</translation>
|
||||||
|
@ -1246,6 +1262,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation>Keine Chats gefunden.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation>Suche Chats...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation>Privater Chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation>Gruppe</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation>Kanal</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 Mitglied</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 Abonnent</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation>Chats suchen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation>Einen Chat suchen...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation>Geben Sie Ihre Anfrage ein, um die Suche zu starten (mindestens 5 Zeichen benötigt)</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -391,6 +391,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation>Close Chat</translation>
|
<translation>Close Chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation>Search in Chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation>Search in chat...</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1044,6 +1052,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>New Chat</translation>
|
<translation>New Chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation>Filter your chats...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation>Search Chats</translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation>Download of %1 successful.</translation>
|
<translation>Download of %1 successful.</translation>
|
||||||
|
@ -1246,6 +1262,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation>No chats found.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation>Searching chats...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation>Private Chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation>Group</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation>Channel</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 member</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 subscriber</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation>Search Chats</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation>Search a chat...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation>Enter your query to start searching (at least 5 characters needed)</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -381,6 +381,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation>Cerrar charla</translation>
|
<translation>Cerrar charla</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1033,6 +1041,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>Nueva charla</translation>
|
<translation>Nueva charla</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished">Bajada de %1 exitosa.</translation>
|
<translation type="unfinished">Bajada de %1 exitosa.</translation>
|
||||||
|
@ -1227,6 +1243,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation type="unfinished">Privado</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 miembros</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 suscriptores</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -391,6 +391,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation>Sulje keskustelu</translation>
|
<translation>Sulje keskustelu</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1045,6 +1053,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>Uusi keskustelu</translation>
|
<translation>Uusi keskustelu</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
|
@ -1247,6 +1263,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation type="unfinished">Yksityinen keskustelu</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 jäsen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 tilaaja</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -381,6 +381,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1033,6 +1041,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished">A %1 letöltése sikerült.</translation>
|
<translation type="unfinished">A %1 letöltése sikerült.</translation>
|
||||||
|
@ -1227,6 +1243,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 tag</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 feliratkozott</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -391,6 +391,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation>Chiudi chat</translation>
|
<translation>Chiudi chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1044,6 +1052,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>Nuova chat</translation>
|
<translation>Nuova chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished">Download di %1 completato.</translation>
|
<translation type="unfinished">Download di %1 completato.</translation>
|
||||||
|
@ -1246,6 +1262,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation type="unfinished">Chat privata</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 membro</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 abbonato</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -401,6 +401,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation>Zamknij czat</translation>
|
<translation>Zamknij czat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1055,6 +1063,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>Nowy czat</translation>
|
<translation>Nowy czat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
|
@ -1265,6 +1281,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation type="unfinished">Prywatny czat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 członek</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 subskrybent</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -401,6 +401,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation>Закрыть чат</translation>
|
<translation>Закрыть чат</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1055,6 +1063,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>Новый Чат</translation>
|
<translation>Новый Чат</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished">Успешно скачано %1.</translation>
|
<translation type="unfinished">Успешно скачано %1.</translation>
|
||||||
|
@ -1265,6 +1281,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation type="unfinished">Приватный Чат</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 участников</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 подписчиков</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -391,6 +391,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation>Stäng chatten</translation>
|
<translation>Stäng chatten</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1044,6 +1052,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>Ny chatt</translation>
|
<translation>Ny chatt</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished">Nerladdning av %1 slutförd.</translation>
|
<translation type="unfinished">Nerladdning av %1 slutförd.</translation>
|
||||||
|
@ -1246,6 +1262,49 @@
|
||||||
<translation>Valt av:</translation>
|
<translation>Valt av:</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation type="unfinished">Privat chatt</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 medlem</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 prenumerant</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -381,6 +381,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation>关闭对话</translation>
|
<translation>关闭对话</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1033,6 +1041,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation>新对话</translation>
|
<translation>新对话</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation>已成功下载 %1 。</translation>
|
<translation>已成功下载 %1 。</translation>
|
||||||
|
@ -1227,6 +1243,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation type="unfinished">个人对话</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 位成员</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 位订阅者</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -391,6 +391,14 @@
|
||||||
<source>Close Chat</source>
|
<source>Close Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search in chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -1044,6 +1052,14 @@
|
||||||
<source>New Chat</source>
|
<source>New Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Filter your chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished">Download of %1 successful.</translation>
|
<translation type="unfinished">Download of %1 successful.</translation>
|
||||||
|
@ -1246,6 +1262,49 @@
|
||||||
</translation>
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>SearchChatsPage</name>
|
||||||
|
<message>
|
||||||
|
<source>No chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Searching chats...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Private Chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Group</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Channel</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 members</source>
|
||||||
|
<translation type="unfinished">%1 member</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>%1 subscribers</source>
|
||||||
|
<translation type="unfinished">%1 subscriber</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search Chats</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Search a chat...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>SettingsPage</name>
|
<name>SettingsPage</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
Loading…
Reference in a new issue