Improvements after feedback round

This commit is contained in:
Sebastian Wolf 2020-11-28 19:11:51 +01:00
parent de945c7846
commit 48b5e14335
22 changed files with 161 additions and 107 deletions

View file

@ -13,7 +13,7 @@ PhotoTextsListItem {
property int ownUserId
// chat title
primaryText.text: title ? Emoji.emojify((listItem.isSecret ? "🔒 " : "" ) + title + ( display.notification_settings.mute_for > 0 ? " 🔇" : "" ), Theme.fontSizeMedium) : qsTr("Unknown")
primaryText.text: title ? Emoji.emojify(title + ( display.notification_settings.mute_for > 0 ? " 🔇" : "" ), Theme.fontSizeMedium) : qsTr("Unknown")
// last user
prologSecondaryText.text: is_channel ? "" : ( last_message_sender_id ? ( last_message_sender_id !== ownUserId ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(last_message_sender_id)), primaryText.font.pixelSize) : qsTr("You") ) : "" )
// last message

View file

@ -11,7 +11,7 @@ ListItem {
property alias secondaryText: secondaryText //usually last message
property alias tertiaryText: tertiaryText //usually last message date
property int unreadCount
property int unreadCount: 0
property bool isSecret: false
property alias pictureThumbnail: pictureThumbnail
@ -58,14 +58,12 @@ ListItem {
color: Theme.overlayBackgroundColor
width: Theme.fontSizeExtraLarge
height: Theme.fontSizeExtraLarge
anchors.left: parent.left
anchors.bottom: parent.bottom
radius: parent.width / 2
visible: chatListViewItem.isSecret
}
Image {
id: chatSecretImage
source: "image://theme/icon-s-secure"
height: Theme.fontSizeMedium
width: Theme.fontSizeMedium
@ -73,7 +71,6 @@ ListItem {
visible: chatListViewItem.isSecret
}
Rectangle {
id: chatUnreadMessagesCountBackground
color: Theme.highlightBackgroundColor

View file

@ -41,6 +41,15 @@ SilicaFlickable {
tdLibWrapper.getUserFullInfo(chatInformationPage.chatPartnerGroupId);
tdLibWrapper.getUserProfilePhotos(chatInformationPage.chatPartnerGroupId, 100, 0);
break;
case "chatTypeSecret":
chatInformationPage.isSecretChat = true;
chatInformationPage.chatPartnerGroupId = chatInformationPage.chatInformation.type.user_id.toString();
if(!chatInformationPage.privateChatUserInformation.id) {
chatInformationPage.privateChatUserInformation = tdLibWrapper.getUserInformation(chatInformationPage.chatPartnerGroupId);
}
tdLibWrapper.getUserFullInfo(chatInformationPage.chatPartnerGroupId);
tdLibWrapper.getUserProfilePhotos(chatInformationPage.chatPartnerGroupId, 100, 0);
break;
case "chatTypeBasicGroup":
chatInformationPage.isBasicGroup = true;
chatInformationPage.chatPartnerGroupId = chatInformation.type.basic_group_id.toString();
@ -60,8 +69,8 @@ SilicaFlickable {
chatInformationPage.isChannel = chatInformationPage.groupInformation.is_channel;
break;
}
Debug.log("is set up", chatInformationPage.isPrivateChat, chatInformationPage.isBasicGroup, chatInformationPage.isSuperGroup, chatInformationPage.chatPartnerGroupId)
if(!chatInformationPage.isPrivateChat) {
Debug.log("is set up", chatInformationPage.isPrivateChat, chatInformationPage.isSecretChat, chatInformationPage.isBasicGroup, chatInformationPage.isSuperGroup, chatInformationPage.chatPartnerGroupId)
if(!(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat)) {
updateGroupStatusText();
}
@ -147,18 +156,18 @@ SilicaFlickable {
}
}
onUserFullInfoReceived: {
if(chatInformationPage.isPrivateChat && userFullInfo["@extra"] === chatInformationPage.chatPartnerGroupId) {
if((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && userFullInfo["@extra"] === chatInformationPage.chatPartnerGroupId) {
chatInformationPage.chatPartnerFullInformation = userFullInfo;
}
}
onUserFullInfoUpdated: {
if(chatInformationPage.isPrivateChat && userId === chatInformationPage.chatPartnerGroupId) {
if((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && userId === chatInformationPage.chatPartnerGroupId) {
chatInformationPage.chatPartnerFullInformation = userFullInfo;
}
}
onUserProfilePhotosReceived: {
if(chatInformationPage.isPrivateChat && extra === chatInformationPage.chatPartnerGroupId) {
if((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && extra === chatInformationPage.chatPartnerGroupId) {
chatInformationPage.chatPartnerProfilePhotos = photos;
}
}
@ -180,14 +189,10 @@ SilicaFlickable {
}
}
Component.onCompleted: {7
Component.onCompleted: {
initializePage();
}
ListModel {
id: membersList
}
@ -227,13 +232,13 @@ SilicaFlickable {
}
text: chatInformation.notification_settings.mute_for > 0 ? qsTr("Unmute Chat") : qsTr("Mute Chat")
}
// MenuItem { //TODO Implement
// visible: !userIsMember
// onClicked: {
// tdLibWrapper.joinChat(chatInformationPage.chatInformation.id);
// }
// text: qsTr("Join Chat")
// }
MenuItem {
visible: chatInformationPage.isPrivateChat
onClicked: {
tdLibWrapper.createNewSecretChat(chatInformationPage.chatPartnerGroupId);
}
text: qsTr("New Secret Chat")
}
}
// header
PageHeader {
@ -278,14 +283,14 @@ SilicaFlickable {
active: imageContainer.hasImage
asynchronous: true
anchors.fill: chatPictureThumbnail
source: chatInformationPage.isPrivateChat
source: ( chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat)
? "ChatInformationProfilePictureList.qml"
: "ChatInformationProfilePicture.qml"
}
}
leftMargin: imageContainer.getEased((imageContainer.minDimension + Theme.paddingMedium), 0, imageContainer.tweenFactor) + Theme.horizontalPageMargin
title: chatInformationPage.chatInformation.title !== "" ? Emoji.emojify(chatInformationPage.chatInformation.title, Theme.fontSizeLarge) : qsTr("Unknown")
description: chatInformationPage.isPrivateChat ? ("@"+(chatInformationPage.privateChatUserInformation.username || chatInformationPage.chatPartnerGroupId)) : ""
description: (chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? ("@"+(chatInformationPage.privateChatUserInformation.username || chatInformationPage.chatPartnerGroupId)) : ""
}
SilicaFlickable {
@ -350,7 +355,7 @@ SilicaFlickable {
ChatInformationEditArea {
visible: canEdit
canEdit: !chatInformationPage.isPrivateChat && chatInformationPage.groupInformation.status && (chatInformationPage.groupInformation.status.can_change_info || chatInformationPage.groupInformation.status["@type"] === "chatMemberStatusCreator")
canEdit: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.groupInformation.status && (chatInformationPage.groupInformation.status.can_change_info || chatInformationPage.groupInformation.status["@type"] === "chatMemberStatusCreator")
headerText: qsTr("Chat Title", "group title header")
text: chatInformationPage.chatInformation.title
@ -375,13 +380,13 @@ SilicaFlickable {
}
}
ChatInformationEditArea {
canEdit: (chatInformationPage.isPrivateChat && chatInformationPage.privateChatUserInformation.id === chatInformationPage.myUserId) || ((chatInformationPage.isBasicGroup || chatInformationPage.isSuperGroup) && chatInformationPage.groupInformation && (chatInformationPage.groupInformation.status.can_change_info || chatInformationPage.groupInformation.status["@type"] === "chatMemberStatusCreator"))
canEdit: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.id === chatInformationPage.myUserId) || ((chatInformationPage.isBasicGroup || chatInformationPage.isSuperGroup) && chatInformationPage.groupInformation && (chatInformationPage.groupInformation.status.can_change_info || chatInformationPage.groupInformation.status["@type"] === "chatMemberStatusCreator"))
emptyPlaceholderText: qsTr("There is no information text available, yet.")
headerText: qsTr("Info", "group or user infotext header")
multiLine: true
text: (chatInformationPage.isPrivateChat ? chatInformationPage.chatPartnerFullInformation.bio : chatInformationPage.groupFullInformation.description) || ""
text: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? chatInformationPage.chatPartnerFullInformation.bio : chatInformationPage.groupFullInformation.description) || ""
onSaveButtonClicked: {
if(chatInformationPage.isPrivateChat) { // own bio
if ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat)) { // own bio
tdLibWrapper.setBio(textValue);
} else { // group info
tdLibWrapper.setChatDescription(chatInformationPage.chatInformation.id, textValue);
@ -391,7 +396,7 @@ SilicaFlickable {
ChatInformationTextItem {
headerText: qsTr("Phone Number", "user phone number header")
text: (chatInformationPage.isPrivateChat && chatInformationPage.privateChatUserInformation.phone_number ? "+"+chatInformationPage.privateChatUserInformation.phone_number : "") || ""
text: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.phone_number ? "+"+chatInformationPage.privateChatUserInformation.phone_number : "") || ""
isLinkedLabel: true
}
@ -408,7 +413,7 @@ SilicaFlickable {
visible: !!inviteLinkItem.text
ChatInformationTextItem {
id: inviteLinkItem
text: !isPrivateChat ? chatInformationPage.groupFullInformation.invite_link : ""
text: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? chatInformationPage.groupFullInformation.invite_link : ""
width: parent.width - inviteLinkButton.width
}
IconButton {

View file

@ -27,15 +27,15 @@ import "../../js/functions.js" as Functions
ChatInformationTabItemBase {
id: tabBase
loadingText: isPrivateChat ? qsTr("Loading common chats…", "chats you have in common with a user") : qsTr("Loading group members…")
loading: ( chatInformationPage.isSuperGroup || chatInformationPage.isPrivateChat) && !chatInformationPage.isChannel
loadingText: (isPrivateChat || isSecretChat) ? qsTr("Loading common chats…", "chats you have in common with a user") : qsTr("Loading group members…")
loading: ( chatInformationPage.isSuperGroup || chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && !chatInformationPage.isChannel
loadingVisible: loading && membersView.count === 0
property var chatPartnerCommonGroupsIds: ([]);
SilicaListView {
id: membersView
model: chatInformationPage.isPrivateChat ? (chatPartnerCommonGroupsIds.length > 0 ? delegateModel : null) : pageContent.membersList
model: (chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? (chatPartnerCommonGroupsIds.length > 0 ? delegateModel : null) : pageContent.membersList
clip: true
height: tabBase.height
width: tabBase.width
@ -68,7 +68,7 @@ ChatInformationTabItemBase {
ViewPlaceholder {
y: Theme.paddingLarge
enabled: membersView.count === 0
text: chatInformationPage.isPrivateChat ? qsTr("You don't have any groups in common with this user.") : ( chatInformationPage.isChannel ? qsTr("Channel members are anonymous.") : qsTr("This group is empty.") )
text: (chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? qsTr("You don't have any groups in common with this user.") : ( chatInformationPage.isChannel ? qsTr("Channel members are anonymous.") : qsTr("This group is empty.") )
}
delegate: PhotoTextsListItem {
pictureThumbnail {
@ -204,7 +204,7 @@ ChatInformationTabItemBase {
}
}
onChatsReceived: {// common chats with user
if(isPrivateChat && chats["@extra"] === chatInformationPage.chatPartnerGroupId) {
if((isPrivateChat || isSecretChat) && chats["@extra"] === chatInformationPage.chatPartnerGroupId) {
tabBase.chatPartnerCommonGroupsIds = chats.chat_ids;
delegateModel.applyFilter();
// if we set it directly, the views start scrolling
@ -221,7 +221,7 @@ ChatInformationTabItemBase {
}
Component.onCompleted: {
if(chatInformationPage.isPrivateChat) {
if(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) {
tdLibWrapper.getGroupsInCommon(chatInformationPage.chatPartnerGroupId, 200, 0); // we only use the first 200
} else if(chatInformationPage.isSuperGroup) {
fetchMoreMembersTimer.start();

View file

@ -124,14 +124,14 @@ Item {
}
}
Component.onCompleted: {
if(!(isPrivateChat && chatPartnerGroupId === myUserId.toString())) {
if(!((isPrivateChat || isSecretChat) && chatPartnerGroupId === myUserId.toString())) {
tabModel.append({
tab:"ChatInformationTabItemMembersGroups",
title: chatInformationPage.isPrivateChat ? qsTr("Groups", "Button: groups in common (short)") : qsTr("Members", "Button: Group Members"),
title: ( chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat ) ? qsTr("Groups", "Button: groups in common (short)") : qsTr("Members", "Button: Group Members"),
image: "image://theme/icon-m-people"
});
}
if(!isPrivateChat && (groupInformation.status.can_restrict_members || groupInformation.status["@type"] === "chatMemberStatusCreator")) {
if(!(isPrivateChat || isSecretChat) && (groupInformation.status.can_restrict_members || groupInformation.status["@type"] === "chatMemberStatusCreator")) {
tabModel.append({
tab:"ChatInformationTabItemSettings",
title: qsTr("Settings", "Button: Chat Settings"),

View file

@ -34,13 +34,14 @@ Page {
property int myUserId: tdLibWrapper.getUserInformation().id;
property bool isPrivateChat: false
property bool isSecretChat: false
property bool isBasicGroup: false
property bool isSuperGroup: false
property bool isChannel: false
property string chatPartnerGroupId
property bool userIsMember: (isPrivateChat && chatInformation["@type"]) || // should be optimized
property bool userIsMember: ((isPrivateChat || isSecretChat ) && chatInformation["@type"]) || // should be optimized
(isBasicGroup || isSuperGroup) && (
(groupInformation.status["@type"] === "chatMemberStatusMember")
|| (groupInformation.status["@type"] === "chatMemberStatusAdministrator")

View file

@ -429,7 +429,7 @@ Page {
}
}
onSecretChatReceived: {
if (secretChatId.toString() === chatInformation.type.secret_chat_id.toString()) {
if (secretChatId === chatInformation.type.secret_chat_id) {
Debug.log("[ChatPage] Received detailed information about this secret chat");
chatPage.secretChatDetails = secretChat;
updateChatPartnerStatusText();
@ -706,7 +706,7 @@ Page {
id: chatNameText
width: Math.min(implicitWidth, parent.width)
anchors.right: parent.right
text: chatInformation.title !== "" ? Emoji.emojify((chatPage.isSecretChat ? "🔒 " : "" ) + chatInformation.title, font.pixelSize) : qsTr("Unknown")
text: chatInformation.title !== "" ? Emoji.emojify(chatInformation.title, font.pixelSize) : qsTr("Unknown")
textFormat: Text.StyledText
font.pixelSize: chatPage.isPortrait ? Theme.fontSizeLarge : Theme.fontSizeMedium
font.family: Theme.fontFamilyHeading

View file

@ -35,7 +35,7 @@ Page {
function reloadContacts() {
contactsModel.hydrateContacts();
contactsListView.model = contactsModel;
contactsListView.model = contactsProxyModel;
newChatPage.isLoading = false;
}
@ -46,14 +46,6 @@ Page {
}
}
Connections {
target: contactsModel
onErrorSynchronizingContacts: {
reloadContacts();
appNotification.show(qsTr("Could not synchronize your contacts with Telegram."));
}
}
Connections {
target: tdLibWrapper
onContactsImported: {
@ -72,7 +64,11 @@ Page {
MenuItem {
onClicked: {
newChatPage.isLoading = true;
contactsModel.synchronizeContacts();
if (!contactsModel.synchronizeContacts()) {
reloadContacts();
appNotification.show(qsTr("Could not synchronize your contacts with Telegram."));
}
// Success message is not fired before TDLib returned "Contacts imported" (see above)
}
text: qsTr("Synchronize Contacts with Telegram")
}
@ -103,7 +99,11 @@ Page {
width: parent.width
placeholderText: qsTr("Search a contact...")
active: !newChatPage.isLoading
onTextChanged: contactsModel.applyFilter(text);
onTextChanged: {
contactsProxyModel.setFilterWildcard("*" + text + "*");
}
EnterKey.iconSource: "image://theme/icon-m-enter-close"
EnterKey.onClicked: {
resetFocus();
@ -140,15 +140,15 @@ Page {
Behavior on opacity { FadeAnimation {} }
pictureThumbnail {
photoData: (typeof display.profile_photo !== "undefined") ? display.profile_photo.small : {}
photoData: typeof photo_small !== "undefined" ? photo_small : {}
}
width: parent.width
primaryText.text: Emoji.emojify(Functions.getUserName(display), primaryText.font.pixelSize, "../js/emoji/")
prologSecondaryText.text: "@" + ( display.username !== "" ? display.username : display.id )
primaryText.text: Emoji.emojify(title, primaryText.font.pixelSize, "../js/emoji/")
prologSecondaryText.text: "@" + ( username !== "" ? username : user_id )
tertiaryText {
maximumLineCount: 1
text: Functions.getChatPartnerStatusText(display.status["@type"], display.status.was_online);
text: Functions.getChatPartnerStatusText(user_status, user_last_online);
}
onClicked: {
@ -191,22 +191,20 @@ Page {
Rectangle {
anchors.fill: parent
opacity: 0.3
opacity: Theme.opacityLow
color: Theme.overlayBackgroundColor
}
Item {
id: privateChatItem
height: parent.height
width: parent.width / 2 // - ( Theme.horizontalPageMargin / 2 )
anchors.left: parent.left
anchors.top: parent.top
width: parent.width / 2
Rectangle {
id: privateChatHighlightBackground
anchors.fill: parent
color: Theme.highlightBackgroundColor
opacity: 0.5
opacity: Theme.opacityHigh
visible: false
}
@ -273,7 +271,7 @@ Page {
Item {
id: secretChatItem
height: parent.height
width: parent.width / 2 //+ ( Theme.horizontalPageMargin / 2 )
width: parent.width / 2
anchors.left: privateChatItem.right
anchors.top: parent.top
@ -281,7 +279,7 @@ Page {
id: secretChatHighlightBackground
anchors.fill: parent
color: Theme.highlightBackgroundColor
opacity: 0.5
opacity: Theme.opacityHigh
visible: false
}
@ -297,7 +295,7 @@ Page {
icon.source: "image://theme/icon-m-device-lock"
anchors.verticalCenter: parent.verticalCenter
onClicked: {
console.log("SECRET CHAT!");
tdLibWrapper.createNewSecretChat(display.id);
}
}

View file

@ -51,15 +51,39 @@ ContactsModel::ContactsModel(TDLibWrapper *tdLibWrapper, QObject *parent)
}
}
QHash<int, QByteArray> ContactsModel::roleNames() const
{
QHash<int,QByteArray> roles;
roles.insert(ContactRole::RoleDisplay, "display");
roles.insert(ContactRole::RoleTitle, "title");
roles.insert(ContactRole::RoleUserId, "user_id");
roles.insert(ContactRole::RoleUsername, "username");
roles.insert(ContactRole::RolePhotoSmall, "photo_small");
roles.insert(ContactRole::RoleUserStatus, "user_status");
roles.insert(ContactRole::RoleUserLastOnline, "user_last_online");
roles.insert(ContactRole::RoleFilter, "filter");
return roles;
}
int ContactsModel::rowCount(const QModelIndex &) const
{
return this->filter.isEmpty() ? this->contacts.size() : this->filteredContacts.size();
return this->contacts.size();
}
QVariant ContactsModel::data(const QModelIndex &index, int role) const
{
if (index.isValid() && role == Qt::DisplayRole) {
return this->filter.isEmpty() ? QVariant(contacts.value(index.row())) : QVariant(filteredContacts.value(index.row())) ;
if (index.isValid()) {
QVariantMap requestedContact = contacts.value(index.row()).toMap();
switch (static_cast<ContactRole>(role)) {
case ContactRole::RoleDisplay: return requestedContact;
case ContactRole::RoleTitle: return QString(requestedContact.value("first_name").toString() + " " + requestedContact.value("last_name").toString()).trimmed();
case ContactRole::RoleUserId: return requestedContact.value("id");
case ContactRole::RoleUsername: return requestedContact.value("username");
case ContactRole::RolePhotoSmall: return requestedContact.value("profile_photo").toMap().value("small");
case ContactRole::RoleUserStatus: return requestedContact.value("status").toMap().value("@type");
case ContactRole::RoleUserLastOnline: return requestedContact.value("status").toMap().value("was_online");
case ContactRole::RoleFilter: return QString(requestedContact.value("first_name").toString() + " " + requestedContact.value("last_name").toString() + " " + requestedContact.value("username").toString()).trimmed();
}
}
return QVariant();
}
@ -126,34 +150,7 @@ void ContactsModel::hydrateContacts()
std::sort(this->contacts.begin(), this->contacts.end(), compareUsers);
}
void ContactsModel::applyFilter(const QString &filter)
{
LOG("Applying filter:" << filter);
beginResetModel();
this->filter = filter;
this->filteredContacts.clear();
if (!this->filter.isEmpty()) {
QListIterator<QVariant> contactIterator(this->contacts);
while (contactIterator.hasNext()) {
QVariantMap contact = contactIterator.next().toMap();
if (contact.value(LAST_NAME).toString().contains(this->filter, Qt::CaseInsensitive)) {
this->filteredContacts.append(contact);
continue;
}
if (contact.value(FIRST_NAME).toString().contains(this->filter, Qt::CaseInsensitive)) {
this->filteredContacts.append(contact);
continue;
}
if (contact.value(USERNAME).toString().contains(this->filter, Qt::CaseInsensitive)) {
this->filteredContacts.append(contact);
continue;
}
}
}
endResetModel();
}
void ContactsModel::synchronizeContacts()
bool ContactsModel::synchronizeContacts()
{
LOG("Synchronizing device contacts");
QVariantList deviceContacts;
@ -173,10 +170,10 @@ void ContactsModel::synchronizeContacts()
LOG("Importing found contacts" << deviceContacts.size());
this->tdLibWrapper->importContacts(deviceContacts);
}
emit contactsSynchronized();
return true;
} else {
LOG("Error selecting contacts from database!");
emit errorSynchronizingContacts();
return false;
}
}

View file

@ -31,27 +31,34 @@ class ContactsModel : public QAbstractListModel
{
Q_OBJECT
public:
enum ContactRole {
RoleDisplay = Qt::DisplayRole,
RolePhotoSmall,
RoleTitle,
RoleUserId,
RoleUsername,
RoleUserStatus,
RoleUserLastOnline,
RoleFilter
};
ContactsModel(TDLibWrapper *tdLibWrapper, QObject *parent = nullptr);
virtual int rowCount(const QModelIndex &) const;
virtual QVariant data(const QModelIndex &index, int role) const;
virtual QHash<int,QByteArray> roleNames() const override;
virtual int rowCount(const QModelIndex &) const override;
virtual QVariant data(const QModelIndex &index, int role) const override;
Q_INVOKABLE void hydrateContacts();
Q_INVOKABLE void applyFilter(const QString &filter);
Q_INVOKABLE void synchronizeContacts();
Q_INVOKABLE bool synchronizeContacts();
Q_INVOKABLE bool canSynchronizeContacts();
signals:
void contactsSynchronized();
void errorSynchronizingContacts();
public slots:
void handleUsersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
private:
TDLibWrapper *tdLibWrapper;
QVariantList contacts;
QVariantList filteredContacts;
QList<QString> contactIds;
QString filter;
QSqlDatabase deviceContactsDatabase;

View file

@ -99,6 +99,11 @@ int main(int argc, char *argv[])
ContactsModel contactsModel(tdLibWrapper, view.data());
context->setContextProperty("contactsModel", &contactsModel);
QSortFilterProxyModel contactsProxyModel(view.data());
contactsProxyModel.setSourceModel(&contactsModel);
contactsProxyModel.setFilterRole(ContactsModel::RoleFilter);
contactsProxyModel.setFilterCaseSensitivity(Qt::CaseInsensitive);
context->setContextProperty("contactsProxyModel", &contactsProxyModel);
view->setSource(SailfishApp::pathTo("qml/harbour-fernschreiber.qml"));
view->show();

View file

@ -179,6 +179,10 @@
<numerusform>%1 online</numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation>Neuer geheimer Chat</translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -179,6 +179,10 @@
<numerusform>%1 online</numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation>New Secret Chat</translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -176,6 +176,10 @@
<numerusform>%1 en línea</numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -179,6 +179,10 @@
<numerusform>%1 paikalla</numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -176,6 +176,10 @@
<numerusform></numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -179,6 +179,10 @@
<numerusform>%1 online</numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -182,6 +182,10 @@
<numerusform>%1 online</numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -182,6 +182,10 @@
<numerusform></numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -179,6 +179,10 @@
<numerusform>%1 online</numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -176,6 +176,10 @@
<numerusform>%1 线</numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>

View file

@ -179,6 +179,10 @@
<numerusform>%1 online</numerusform>
</translation>
</message>
<message>
<source>New Secret Chat</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>ChatInformationTabItemMembersGroups</name>