From aeed051afd535f466821c2e6bcdb6bd2df4b391a Mon Sep 17 00:00:00 2001 From: iamnomeutente <72705765+iamnomeutente@users.noreply.github.com> Date: Tue, 27 Oct 2020 15:57:56 +0100 Subject: [PATCH 1/7] Update harbour-fernschreiber-it.ts and README.md --- README.md | 2 +- translations/harbour-fernschreiber-it.ts | 188 +++++++++++------------ 2 files changed, 95 insertions(+), 95 deletions(-) diff --git a/README.md b/README.md index b9b2a0c..566daa2 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,7 @@ Fernschreiber wouldn't be the same without all the people helping in making it b - Polish: [atlochowski](https://github.com/atlochowski) - Russian: [Rustem Abzalov](https://github.com/arustg) and [Slava Monich](https://github.com/monich) - Spanish: [carlosgonz](https://github.com/GNUuser) +- Swedish: [Åke Engelbrektson](https://github.com/eson57) ## License Licensed under GNU GPLv3 @@ -50,4 +51,3 @@ This project uses - Emoji parsing and artwork by [Twitter Emoji (Twemoji)](http://twitter.github.io/twemoji/), copyright 2018 Twitter, Inc and other contributors, Code licensed under the [MIT License](http://opensource.org/licenses/MIT), Graphics licensed under [CC-BY 4.0](https://creativecommons.org/licenses/by/4.0/) Fernschreiber was translated to several languages. Thanks to all contributors! - diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts index 5fc459c..73aa1d1 100644 --- a/translations/harbour-fernschreiber-it.ts +++ b/translations/harbour-fernschreiber-it.ts @@ -1,6 +1,6 @@ - + AboutPage @@ -61,7 +61,7 @@ Phone number: +%1 - Numero di telefono: +%1 + Telefono: +%1 This project uses twemoji. Copyright 2018 Twitter, Inc. and other contributors. Thanks for making it available under the conditions of the MIT License (coding) and CC-BY 4.0 (graphics)! @@ -151,7 +151,7 @@ Enter 1-128 characters - Inserisci 1-128 caratteri + Inserisci da 1 a 128 caratteri @@ -185,11 +185,11 @@ Loading common chats… chats you have in common with a user - + Carica chat in comune… Loading group members… - + Carica membri del gruppo… @@ -262,8 +262,8 @@ Tu - Loading messages... - Carica messaggi... + Loading messages… + Carica messaggi… Unmute Chat @@ -290,8 +290,8 @@ Cancella messaggio - Uploading... - Carica... + Uploading… + Carica… Forwarded Message @@ -299,42 +299,42 @@ This chat is empty. - Questa chat è vuota + Questa chat è vuota. CoverPage unread message - Messaggio non letto + messaggio non letto unread messages - Messaggi non letti + messaggi non letti in in - Waiting for network... - Attendo la rete... + Waiting for network… + Attendo la rete… - Connecting to network... - Connetto alla rete... + Connecting to network… + Connetto alla rete… - Connecting to proxy... - Connetto al proxy... + Connecting to proxy… + Connetto al proxy… Connected Connesso - Updating content... - Aggiorna contenuti... + Updating content… + Aggiorna contenuti… chat @@ -396,7 +396,7 @@ Pin Messages member permission - Metti in evidenza un messaggio + Metti i messaggi in evidenza New Members @@ -536,29 +536,29 @@ changed the chat title myself - Hanno modificato il titolo della chat + hanno modificato il titolo della chat changed the chat title - Ha modificato il titolo della chat + ha modificato il titolo della chat sent a poll myself - + hanno inviato un sondaggio sent a poll - + ha inviato un sondaggio sent a quiz myself - + hanno inviato un quiz sent a quiz - + ha inviato un quiz @@ -606,8 +606,8 @@ Inserisci il codice che hai ricevuto: - Loading... - Carica... + Loading… + Carica… Unable to authenticate you with the entered code. @@ -671,28 +671,28 @@ Fernschreiber - Waiting for network... - Attendo la rete... + Waiting for network… + Attendo la rete… - Connecting to network... - Connetto alla rete... + Connecting to network… + Connetto alla rete… - Connecting to proxy... - Connetto al proxy... + Connecting to proxy… + Connetto al proxy… - Updating content... - Aggiorna contenuti... + Updating content… + Aggiorna contenuti… Unknown Sconosciuto - Loading chat list... - Carica lista chat... + Loading chat list… + Carica lista chat… Settings @@ -707,85 +707,85 @@ PollCreationPage All answers have to contain 1-100 characters. - + Le risposte devono avere da 1 a 100 caratteri. To send a quiz, you have to specify the right answer. - + Per inviare un quiz devi indicare una risposta esatta. You have to enter a question. - + Devi inserire una domanda. The question has to be shorter than 256 characters. - + La domanda non deve superare 255 caratteri. A poll requires 2-10 answers. - + Un sondaggio richiede tra 2 e 10 risposte. Create a Poll Dialog Header - + Crea un sondaggio in %1 After dialog header… Create a Poll in [group name] - + in %1 Enter your question here - + Scrivi la tua domanda Question (%n1 characters left) - - - + + Domanda (%n1 carattere rimanente) + Domanda (%n1 caratteri rimanenti) Answers Section header - + Risposte Enter an answer here - + Scrivi una risposta Answer (%n1 characters left) - - - + + Risposta (%n1 carattere rimanente) + Risposta (%n1 caratteri rimanenti) Add an answer - + Aggiungi una risposta Poll Options Section header - + Opzioni sondaggio Anonymous answers - + Risposte anonime Multiple answers allowed - + Risposte multiple consentite Quiz Mode - + Modalità quiz Quizzes have one correct answer. Participants can't revoke their responses. - + I quiz hanno una sola risposta corretta. I partecipanti non possono revocare le risposte. @@ -793,85 +793,85 @@ %L1% % of votes for option - + %L1% Final Result: - + Risultato: Multiple Answers are allowed. - + Risposte multiple consentite %L1 vote(s) total number of total votes - - - + + %L1 voto in totale + %L1 voti in totale Close Poll - + Termina sondaggio Reset Answer - + Annulla risposta PollResultsPage Quiz Results - + Risultati quiz Poll Results - + Risultati sondaggio %L1 vote(s) total number of total votes - - - + + %L1 voto in totale + %L1 voti in totale Question section header - + Domdanda Results section header - + Risultati %L1 vote(s) number of votes for option - - - + + %L1 voto + %L1 voti %L1% % of votes for option - + %L1% Chosen by: This answer has been chosen by the following users - + Scelta da: %L1 vote(s) including yours number of votes for option - - - + + %L1 voto incluso il tuo + %L1 voti incluso il tuo @@ -933,8 +933,8 @@ Usati di recente - Loading stickers... - Carica sticker... + Loading stickers… + Carica sticker… @@ -1157,38 +1157,38 @@ sent a poll myself - + hanno inviato un sondaggio sent a poll - + ha inviato un sondaggio sent an anonymous quiz myself - + hanno inviato un quiz anonimo sent an anonymous quiz - + ha inviato un quiz anonimo sent a quiz myself - + hanno inviato un quiz sent a quiz - + ha inviato un quiz sent an anonymous poll myself - + hanno inviato un sondaggio anonimo sent an anonymous poll - + ha inviato un sondaggio anonimo From 1fa719272895e78efc3c1b3563ed0eaa3245629b Mon Sep 17 00:00:00 2001 From: John Gibbon Date: Fri, 30 Oct 2020 20:36:32 +0100 Subject: [PATCH 2/7] Reduce ChatPage.qml jit compile time MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit First of all: Take all measurements I mention with a grain of salt – all of them are rough and not necessarily measured more than a few times. All times were measured on an Xperia X run via SDK. Visiting a chat page can take a long time, especially before the qml is cached by the engine. When opening it for the first time after application launch, it sometimes takes >1000ms from onClicked (OverviewPage) to Component.OnCompleted (Chatpage). Subsequent activations take roughly 470-480ms. With these changes, I was able to reduce these times to ~450ms for the first, ~100ms for subsequent activations of the ChatPage on my test device. Things changed: - The components for displaying extra content to a message are (mostly) gone and replaced by a single Loader. This Loader does not use sourceComponent to trade the initial compilation boost for a neglegible bit of runtime penalty. - Connections were consolidated - I was surprised how costly the inclusion of the RemorseItem was (compiling ~75ms, initializing up to ~20ms for every delegate). So I traded a bit for a compromise. deleteMessageRemorseItem is now defined on the appWindow level, where it gets a bit mitigated by the animations at application start. Also, only one deletion at a time is now possible. We can easily revert this change, but I thought it worthwhile despite its drawbacks. - profileThumbnailComponent is now defined directly as sourceComponent, removing the need for its id. Probably didn't do anything. - InReplyToRow had width: parent.width, so I removed horizontalCenter. Also probably didn't change compilation time at all. - Another compromise I was willing to take – your opinion may differ: The PickerPages took ages (~200ms) to just parse/compile inside those Components, so I replaced them with the "string notation" of pageStack.push. Drawback: The first time a picker gets activated, you'll see how slow it is. Subsequent activations aren't that bad – also for the other pickers. --- qml/components/AudioPreview.qml | 9 +- qml/components/DocumentPreview.qml | 5 +- qml/components/ImagePreview.qml | 7 +- qml/components/LocationPreview.qml | 11 +- qml/components/PollPreview.qml | 23 +- qml/components/StickerPreview.qml | 6 +- qml/components/VideoPreview.qml | 9 +- qml/harbour-fernschreiber.qml | 4 + qml/pages/ChatPage.qml | 365 +++++++++-------------------- 9 files changed, 159 insertions(+), 280 deletions(-) diff --git a/qml/components/AudioPreview.qml b/qml/components/AudioPreview.qml index 3b37e55..0b59911 100644 --- a/qml/components/AudioPreview.qml +++ b/qml/components/AudioPreview.qml @@ -24,15 +24,18 @@ import "../js/functions.js" as Functions Item { id: audioMessageComponent - property variant audioData; + property ListItem messageListItem + property variant rawMessage: messageListItem.myMessage + + property variant audioData: ( rawMessage.content['@type'] === "messageVoiceNote" ) ? rawMessage.content.voice_note : ( ( rawMessage.content['@type'] === "messageAudio" ) ? rawMessage.content.audio : ""); property string audioUrl; property int previewFileId; property int audioFileId; - property bool onScreen; + property bool onScreen: messageListItem.page.status === PageStatus.Active property string audioType : "voiceNote"; width: parent.width - height: parent.height + height: width / 2 function getTimeString(rawSeconds) { var minutes = Math.floor( rawSeconds / 60 ); diff --git a/qml/components/DocumentPreview.qml b/qml/components/DocumentPreview.qml index 9f46a09..2b656a0 100644 --- a/qml/components/DocumentPreview.qml +++ b/qml/components/DocumentPreview.qml @@ -26,7 +26,10 @@ Item { width: parent.width height: Theme.itemSizeLarge - property variant documentData; + property ListItem messageListItem + property variant rawMessage: messageListItem.myMessage + + property variant documentData: rawMessage.content.document property bool openRequested: false; Component.onCompleted: { diff --git a/qml/components/ImagePreview.qml b/qml/components/ImagePreview.qml index ea8571d..8156762 100644 --- a/qml/components/ImagePreview.qml +++ b/qml/components/ImagePreview.qml @@ -24,9 +24,14 @@ Item { id: imagePreviewItem - property variant photoData; + property ListItem messageListItem + property variant rawMessage: messageListItem.myMessage + property variant photoData: rawMessage.content.photo; property variant pictureFileInformation; + width: parent.width + height: width * 2 / 3 + Component.onCompleted: { updatePicture(); } diff --git a/qml/components/LocationPreview.qml b/qml/components/LocationPreview.qml index 6964340..ecffa23 100644 --- a/qml/components/LocationPreview.qml +++ b/qml/components/LocationPreview.qml @@ -23,9 +23,16 @@ import Sailfish.Silica 1.0 Item { id: imagePreviewItem - property variant locationData; - property int chatId; + + property ListItem messageListItem + property variant rawMessage: messageListItem.myMessage + + property variant locationData : ( rawMessage.content['@type'] === "messageLocation" ) ? rawMessage.content.location : ( ( rawMessage.content['@type'] === "messageVenue" ) ? rawMessage.content.venue.location : "" ) + + property string chatId: messageListItem.page.chatInformation.id property variant pictureFileInformation; + width: parent.width + height: width / 2 Component.onCompleted: { updatePicture(); diff --git a/qml/components/PollPreview.qml b/qml/components/PollPreview.qml index c4261e2..00d3101 100644 --- a/qml/components/PollPreview.qml +++ b/qml/components/PollPreview.qml @@ -27,13 +27,16 @@ import "../js/twemoji.js" as Emoji Item { id: pollMessageComponent - property string chatId - property var message:({}) - property bool isOwnMessage - property string messageId: message.id - property bool canEdit: message.can_be_edited - property var pollData: message.content.poll + property ListItem messageListItem + property variant rawMessage: messageListItem.myMessage + property string chatId: messageListItem.page.chatInformation.id + + property bool isOwnMessage: messageListItem.isOwnMessage + + property string messageId: rawMessage.id + property bool canEdit: rawMessage.can_be_edited + property var pollData: rawMessage.content.poll property var chosenPollData:({}) property var chosenIndexes: [] property bool hasAnswered: { @@ -43,7 +46,7 @@ Item { } property bool canAnswer: !hasAnswered && !pollData.is_closed property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz" - property Item messageItem + width: parent.width height: pollColumn.height opacity: 0 Behavior on opacity { FadeAnimation {} } @@ -286,9 +289,9 @@ Item { Component.onCompleted: { opacity = 1; - if(messageItem && messageItem.menu ) { // workaround to add menu entries - closePollMenuItemComponent.createObject(messageItem.menu._contentColumn); - resetAnswerMenuItemComponent.createObject(messageItem.menu._contentColumn); + if(messageListItem && messageListItem.menu ) { // workaround to add menu entries + closePollMenuItemComponent.createObject(messageListItem.menu._contentColumn); + resetAnswerMenuItemComponent.createObject(messageListItem.menu._contentColumn); } } } diff --git a/qml/components/StickerPreview.qml b/qml/components/StickerPreview.qml index 070f668..9049671 100644 --- a/qml/components/StickerPreview.qml +++ b/qml/components/StickerPreview.qml @@ -20,7 +20,11 @@ import QtQuick 2.5 import Sailfish.Silica 1.0 Item { - property variant stickerData; + + property ListItem messageListItem + property variant rawMessage: messageListItem.myMessage + + property variant stickerData: rawMessage.content.sticker; property int usedFileId; width: stickerData.width diff --git a/qml/components/VideoPreview.qml b/qml/components/VideoPreview.qml index 6646d8e..a7fe357 100644 --- a/qml/components/VideoPreview.qml +++ b/qml/components/VideoPreview.qml @@ -24,17 +24,20 @@ import "../js/functions.js" as Functions Item { id: videoMessageComponent - property variant videoData; + property ListItem messageListItem + property variant rawMessage: messageListItem.myMessage + + property variant videoData: ( rawMessage.content['@type'] === "messageVideo" ) ? rawMessage.content.video : ( ( rawMessage.content['@type'] === "messageAnimation" ) ? rawMessage.content.animation : "") property string videoUrl; property int previewFileId; property int videoFileId; property bool fullscreen : false; - property bool onScreen; + property bool onScreen: messageListItem.page.status === PageStatus.Active; property string videoType : "video"; property bool playRequested: false; width: parent.width - height: parent.height + height: Functions.getVideoHeight(width, videoData) Timer { id: screensaverTimer diff --git a/qml/harbour-fernschreiber.qml b/qml/harbour-fernschreiber.qml index 8c756cd..42bdf31 100644 --- a/qml/harbour-fernschreiber.qml +++ b/qml/harbour-fernschreiber.qml @@ -28,6 +28,10 @@ ApplicationWindow cover: Qt.resolvedUrl("pages/CoverPage.qml") allowedOrientations: defaultAllowedOrientations + RemorseItem { + id: deleteMessageRemorseItem + } + Connections { target: dBusAdaptor onPleaseOpenMessage: { diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml index ce8ff10..7ebb21f 100644 --- a/qml/pages/ChatPage.qml +++ b/qml/pages/ChatPage.qml @@ -225,8 +225,6 @@ Page { chatPage.isInitialized = true; } break; -// case PageStatus.Deactivating: -// tdLibWrapper.closeChat(chatInformation.id); } } @@ -314,6 +312,10 @@ Page { chatView.lastReadSentIndex = lastReadSentIndex; chatViewCooldownTimer.start(); } + onNotificationSettingsUpdated: { + chatInformation = chatModel.getChatInformation(); + muteChatMenuItem.text = chatInformation.notification_settings.mute_for > 0 ? qsTr("Unmute Chat") : qsTr("Mute Chat"); + } } Timer { @@ -348,9 +350,9 @@ Page { SilicaFlickable { id: chatContainer - contentHeight: parent.height - contentWidth: parent.width anchors.fill: parent + contentHeight: height + contentWidth: width PullDownMenu { visible: chatInformation.id !== chatPage.myUserId && !stickerPickerLoader.active @@ -369,13 +371,6 @@ Page { } } - Connections { - target: chatModel - onNotificationSettingsUpdated: { - chatInformation = chatModel.getChatInformation(); - muteChatMenuItem.text = chatInformation.notification_settings.mute_for > 0 ? qsTr("Unmute Chat") : qsTr("Mute Chat"); - } - } BackgroundItem { id: headerMouseArea height: headerRow.height @@ -463,16 +458,6 @@ Page { previousHeight = height; } - Timer { - id: chatViewLoadingTimer - interval: 100 - repeat: false - running: false - onTriggered: { - chatPage.loading = false; - } - } - Timer { id: chatViewCooldownTimer interval: 2000 @@ -484,6 +469,7 @@ Page { } } + SilicaListView { id: chatView @@ -519,24 +505,28 @@ Page { } model: chatModel + property variant contentComponentNames: ({ + messageSticker: "StickerPreview", + messagePhoto: "ImagePreview", + messageVideo: "VideoPreview", + messageAnimation: "VideoPreview", + messageAudio: "AudioPreview", + messageVoiceNote: "AudioPreview", + messageDocument: "DocumentPreview", + messageLocation: "LocationPreview", + messageVenue: "LocationPreview", + messagePoll: "PollPreview" + }) delegate: ListItem { - id: messageListItem contentHeight: messageBackground.height + Theme.paddingMedium contentWidth: parent.width property variant myMessage: display property variant userInformation: tdLibWrapper.getUserInformation(display.sender_user_id) + property Page page: chatPage + property bool isOwnMessage: chatPage.myUserId === display.sender_user_id - property bool isForwarded: typeof display.forward_info !== "undefined" - property bool containsImage: display.content['@type'] === "messagePhoto" - property bool containsSticker: display.content['@type'] === "messageSticker" - property bool containsWebPage: typeof display.content.web_page !== "undefined" - property bool containsVideo: (( display.content['@type'] === "messageVideo" ) || ( display.content['@type'] === "messageAnimation" )); - property bool containsAudio: (( display.content['@type'] === "messageVoiceNote" ) || ( display.content['@type'] === "messageAudio" )); - property bool containsDocument: ( display.content['@type'] === "messageDocument" ) - property bool containsLocation: ( display.content['@type'] === "messageLocation" || ( display.content['@type'] === "messageVenue" )) - property bool containsPoll: display.content['@type'] === "messagePoll" menu: ContextMenu { MenuItem { @@ -556,6 +546,7 @@ Page { visible: display.can_be_edited } MenuItem { + enabled: !deleteMessageRemorseItem.pending onClicked: { deleteMessageRemorseItem.execute(messageListItem, qsTr("Deleting message"), function() { tdLibWrapper.deleteMessages(chatInformation.id, [ display.id ]); } ); } @@ -574,6 +565,32 @@ Page { messageBackground.color = index > ( chatView.count - chatInformation.unreadCount - 1 ) ? Theme.secondaryHighlightColor : Theme.secondaryColor; messageBackground.opacity = index > ( chatView.count - chatInformation.unreadCount - 1 ) ? 0.5 : 0.2; } + + onLastReadSentMessageUpdated: { + console.log("[ChatModel] Messages in this chat were read, new last read: " + lastReadSentIndex + ", updating description for index " + index + ", status: " + (index <= lastReadSentIndex)); + messageDateText.text = getMessageStatusText(display, index, lastReadSentIndex); + } + onMessageUpdated: { + if (index === modelIndex) { + console.log("[ChatModel] This message was updated, index " + index + ", updating content..."); + messageDateText.text = getMessageStatusText(display, index, chatView.lastReadSentIndex); + messageText.text = Emoji.emojify(Functions.getMessageText(display, false, messageListItem.isOwnMessage), messageText.font.pixelSize); + if(locationPreviewLoader.active && locationPreviewLoader.status === Loader.Ready) { + locationPreviewLoader.item.locationData = display.content.location; + locationPreviewLoader.item.updatePicture() + } + } + } + } + + Connections { + target: tdLibWrapper + onReceivedMessage: { + if (messageId === display.reply_to_message_id.toString()) { + messageInReplyToRow.inReplyToMessage = message; + messageInReplyToRow.visible = true; + } + } } Component.onCompleted: { @@ -587,22 +604,21 @@ Page { running: false onTriggered: { if (typeof display.content !== "undefined") { - webPagePreviewLoader.active = messageListItem.containsWebPage; - imagePreviewLoader.active = messageListItem.containsImage; - stickerPreviewLoader.active = messageListItem.containsSticker; - videoPreviewLoader.active = messageListItem.containsVideo; - audioPreviewLoader.active = messageListItem.containsAudio; - documentPreviewLoader.active = messageListItem.containsDocument; - locationPreviewLoader.active = messageListItem.containsLocation; - pollPreviewLoader.active = messageListItem.containsPoll; - forwardedInformationLoader.active = messageListItem.isForwarded; + if(chatView.contentComponentNames.hasOwnProperty(display.content['@type'])) { + extraContentLoader.setSource( + "../components/" +chatView.contentComponentNames[display.content['@type']] +".qml", + { + messageListItem: messageListItem + }) + } else { + if(typeof display.content.web_page !== "undefined") { // only in messageText + webPagePreviewLoader.active = true; + } + } } } } - RemorseItem { - id: deleteMessageRemorseItem - } Row { id: messageTextRow @@ -611,18 +627,6 @@ Page { anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter - Component { - id: profileThumbnailComponent - ProfileThumbnail { - id: messagePictureThumbnail - photoData: (typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : "" - replacementStringHint: userText.text - width: visible ? Theme.itemSizeSmall : 0 - height: visible ? Theme.itemSizeSmall : 0 - visible: ( chatPage.isBasicGroup || chatPage.isSuperGroup ) && !chatPage.isChannel - } - } - Loader { id: profileThumbnailLoader active: (( chatPage.isBasicGroup || chatPage.isSuperGroup ) && !chatPage.isChannel) @@ -631,7 +635,16 @@ Page { height: active ? Theme.itemSizeSmall : 0 anchors.bottom: parent.bottom anchors.bottomMargin: Theme.paddingSmall - sourceComponent: profileThumbnailComponent + sourceComponent: Component { + ProfileThumbnail { + id: messagePictureThumbnail + photoData: (typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : "" + replacementStringHint: userText.text + width: visible ? Theme.itemSizeSmall : 0 + height: visible ? Theme.itemSizeSmall : 0 + visible: ( chatPage.isBasicGroup || chatPage.isSuperGroup ) && !chatPage.isChannel + } + } } Item { @@ -654,7 +667,7 @@ Page { color: index > ( chatView.count - chatInformation.unread_count - 1 ) ? Theme.secondaryHighlightColor : Theme.secondaryColor radius: parent.width / 50 opacity: index > ( chatView.count - chatInformation.unread_count - 1 ) ? 0.5 : 0.2 - visible: appSettings.showStickersAsImages || !messageListItem.containsSticker + visible: appSettings.showStickersAsImages || display.content['@type'] !== "messageSticker" } Column { @@ -671,15 +684,6 @@ Page { } } - Connections { - target: tdLibWrapper - onReceivedMessage: { - if (messageId === display.reply_to_message_id.toString()) { - messageInReplyToRow.inReplyToMessage = message; - messageInReplyToRow.visible = true; - } - } - } Text { id: userText @@ -704,10 +708,10 @@ Page { Loader { id: forwardedInformationLoader - active: false + active: typeof display.forward_info !== "undefined" asynchronous: true width: parent.width - height: messageListItem.isForwarded ? ( item ? item.height : Theme.itemSizeExtraSmall ) : 0 +// height: active ? ( item ? item.height : Theme.itemSizeExtraSmall ) : 0 sourceComponent: Component { Row { id: forwardedMessageInformationRow @@ -817,128 +821,10 @@ Page { } } } - Loader { - id: imagePreviewLoader - active: false - asynchronous: true + id: extraContentLoader width: parent.width - height: messageListItem.containsImage ? (item ? item.height : (parent.width * 2 / 3)) : 0 - sourceComponent: Component { - id: imagePreviewComponent - ImagePreview { - id: messageImagePreview - photoData: messageListItem.containsImage ? display.content.photo : "" - width: parent.width - height: parent.width * 2 / 3 - } - } - } - - Loader - { - id: stickerPreviewLoader - active: false asynchronous: true - x: messageListItem.isOwnMessage ? (parent.width - width) : 0 - width: (appSettings.showStickersAsImages || !item) ? parent.width : item.width - height: messageListItem.containsSticker ? display.content.sticker.height : 0 - - sourceComponent: Component { - id: stickerPreviewComponent - StickerPreview { - id: messageStickerPreview - stickerData: messageListItem.containsSticker ? display.content.sticker : "" - } - } - } - - Loader { - id: videoPreviewLoader - active: false - asynchronous: true - width: parent.width - height: messageListItem.containsVideo ? Functions.getVideoHeight(width, ( display.content['@type'] === "messageVideo" ) ? display.content.video : display.content.animation) : 0 - sourceComponent: Component { - id: videoPreviewComponent - VideoPreview { - id: messageVideoPreview - videoData: ( display.content['@type'] === "messageVideo" ) ? display.content.video : ( ( display.content['@type'] === "messageAnimation" ) ? display.content.animation : "") - width: parent.width - height: Functions.getVideoHeight(width, ( display.content['@type'] === "messageVideo" ) ? display.content.video : display.content.animation) - onScreen: chatPage.status === PageStatus.Active - } - } - } - - Loader { - id: audioPreviewLoader - active: false - asynchronous: true - width: parent.width - height: messageListItem.containsAudio ? (parent.width / 2) : 0 - sourceComponent: Component { - id: audioPreviewComponent - AudioPreview { - id: messageAudioPreview - audioData: ( display.content['@type'] === "messageVoiceNote" ) ? display.content.voice_note : ( ( display.content['@type'] === "messageAudio" ) ? display.content.audio : "") - width: parent.width - height: parent.width / 2 - onScreen: chatPage.status === PageStatus.Active - } - } - } - - Loader { - id: documentPreviewLoader - active: false - asynchronous: true - width: parent.width - height: messageListItem.containsDocument ? (item ? item.height : Theme.itemSizeSmall) : 0 - sourceComponent: Component { - id: documentPreviewComponent - DocumentPreview { - id: messageDocumentPreview - documentData: messageListItem.containsDocument ? display.content.document : "" - } - } - } - - Loader { - id: locationPreviewLoader - active: false - asynchronous: true - width: parent.width - height: messageListItem.containsLocation ? (item ? item.height : (parent.width * 2 / 3)) : 0 - sourceComponent: Component { - id: locationPreviewComponent - LocationPreview { - id: messageLocationPreview - width: parent.width - height: parent.width * 2 / 3 - chatId: display.id - locationData: ( display.content['@type'] === "messageLocation" ) ? display.content.location : ( ( display.content['@type'] === "messageVenue" ) ? display.content.venue.location : "" ) - } - } - } - - Loader { - id: pollPreviewLoader - active: false - asynchronous: true - width: parent.width -// height: messageListItem.containsLocation ? (item ? item.height : (parent.width * 2 / 3)) : 0 - sourceComponent: Component { - id: pollPreviewComponent - PollPreview { - id: messageLocationPreview - width: parent.width - chatId: chatInformation.id - isOwnMessage: messageListItem.isOwnMessage - message: display - messageItem: messageListItem - } - } } Timer { @@ -951,24 +837,6 @@ Page { } } - Connections { - target: chatModel - onLastReadSentMessageUpdated: { - console.log("[ChatModel] Messages in this chat were read, new last read: " + lastReadSentIndex + ", updating description for index " + index + ", status: " + (index <= lastReadSentIndex)); - messageDateText.text = getMessageStatusText(display, index, lastReadSentIndex); - } - onMessageUpdated: { - if (index === modelIndex) { - console.log("[ChatModel] This message was updated, index " + index + ", updating content..."); - messageDateText.text = getMessageStatusText(display, index, chatView.lastReadSentIndex); - messageText.text = Emoji.emojify(Functions.getMessageText(display, false, messageListItem.isOwnMessage), messageText.font.pixelSize); - if(locationPreviewLoader.active && locationPreviewLoader.status === Loader.Ready) { - locationPreviewLoader.item.locationData = display.content.location; - locationPreviewLoader.item.updatePicture() - } - } - } - } Text { width: parent.width @@ -1003,7 +871,7 @@ Page { anchors.verticalCenter: parent.verticalCenter opacity: chatPage.loading ? 1 : 0 - Behavior on opacity { NumberAnimation {} } + Behavior on opacity { FadeAnimation {} } visible: chatPage.loading InfoLabel { @@ -1066,6 +934,7 @@ Page { Column { id: newMessageColumn spacing: Theme.paddingSmall + width: parent.width - ( 2 * Theme.horizontalPageMargin ) anchors.horizontalCenter: parent.horizontalCenter visible: !chatPage.isChannel @@ -1073,48 +942,6 @@ Page { property string replyToMessageId: "0"; property string editMessageId: "0"; - Component { - id: imagePickerPage - ImagePickerPage { - onSelectedContentPropertiesChanged: { - attachmentOptionsRow.visible = false; - console.log("Selected photo: " + selectedContentProperties.filePath ); - attachmentPreviewRow.fileProperties = selectedContentProperties; - attachmentPreviewRow.isPicture = true; - attachmentPreviewRow.visible = true; - controlSendButton(); - } - } - } - - Component { - id: videoPickerPage - VideoPickerPage { - onSelectedContentPropertiesChanged: { - attachmentOptionsRow.visible = false; - console.log("Selected video: " + selectedContentProperties.filePath ); - attachmentPreviewRow.fileProperties = selectedContentProperties; - attachmentPreviewRow.isVideo = true; - attachmentPreviewRow.visible = true; - controlSendButton(); - } - } - } - - Component { - id: documentPickerPage - DocumentPickerPage { - onSelectedContentPropertiesChanged: { - attachmentOptionsRow.visible = false; - console.log("Selected document: " + selectedContentProperties.filePath ); - attachmentPreviewRow.fileProperties = selectedContentProperties; - attachmentPreviewRow.isDocument = true; - attachmentPreviewRow.visible = true; - controlSendButton(); - } - } - } - InReplyToRow { onInReplyToMessageChanged: { if (inReplyToMessage) { @@ -1134,7 +961,6 @@ Page { id: newMessageInReplyToRow myUserId: chatPage.myUserId - anchors.horizontalCenter: parent.horizontalCenter visible: false } @@ -1149,21 +975,45 @@ Page { id: imageAttachmentButton icon.source: "image://theme/icon-m-image" onClicked: { - pageStack.push(imagePickerPage); + var picker = pageStack.push("Sailfish.Pickers.ImagePickerPage"); + picker.selectedContentPropertiesChanged.connect(function(){ + attachmentOptionsRow.visible = false; + console.log("Selected document: " + picker.selectedContentProperties.filePath ); + attachmentPreviewRow.fileProperties = picker.selectedContentProperties; + attachmentPreviewRow.isDocument = true; + attachmentPreviewRow.visible = true; + controlSendButton(); + }) } } IconButton { id: videoAttachmentButton icon.source: "image://theme/icon-m-video" onClicked: { - pageStack.push(videoPickerPage); + var picker = pageStack.push("Sailfish.Pickers.VideoPickerPage"); + picker.selectedContentPropertiesChanged.connect(function(){ + attachmentOptionsRow.visible = false; + console.log("Selected video: " + picker.selectedContentProperties.filePath ); + attachmentPreviewRow.fileProperties = picker.selectedContentProperties; + attachmentPreviewRow.isVideo = true; + attachmentPreviewRow.visible = true; + controlSendButton(); + }) } } IconButton { id: documentAttachmentButton icon.source: "image://theme/icon-m-document" onClicked: { - pageStack.push(documentPickerPage); + var picker = pageStack.push("Sailfish.Pickers.DocumentPicker"); + picker.selectedContentPropertiesChanged.connect(function(){ + attachmentOptionsRow.visible = false; + console.log("Selected document: " + picker.selectedContentProperties.filePath ); + attachmentPreviewRow.fileProperties = picker.selectedContentProperties; + attachmentPreviewRow.isDocument = true; + attachmentPreviewRow.visible = true; + controlSendButton(); + }) } } @@ -1180,7 +1030,7 @@ Page { } } IconButton { - visible: !chatPage.isPrivateChat && + visible: !chatPage.isPrivateChat && chatGroupInformation && (chatGroupInformation.status["@type"] === "chatMemberStatusCreator" || chatGroupInformation.status["@type"] === "chatMemberStatusAdministrator" || (chatGroupInformation.status["@type"] === "chatMemberStatusMember" && chatInformation.permissions.can_send_polls)) @@ -1222,15 +1072,15 @@ Page { sourceSize.height: height fillMode: Thumbnail.PreserveAspectCrop - mimeType: typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.mimeType : "" - source: typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.url : "" + mimeType: typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.mimeType || "" : "" + source: typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.url || "" : "" visible: attachmentPreviewRow.isPicture || attachmentPreviewRow.isVideo } Text { id: attachmentPreviewText font.pixelSize: Theme.fontSizeSmall - text: typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.fileName : ""; + text: typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.fileName || "" : ""; anchors.verticalCenter: parent.verticalCenter maximumLineCount: 1 @@ -1407,11 +1257,8 @@ Page { newMessageTextField.focus = false; } } - } - } - } } From a8afc6e60e8c6a07c3bc0c5bcec20da16298076d Mon Sep 17 00:00:00 2001 From: iamnomeutente <72705765+iamnomeutente@users.noreply.github.com> Date: Sat, 31 Oct 2020 09:51:09 +0100 Subject: [PATCH 3/7] Update harbour-fernschreiber-it.ts --- translations/harbour-fernschreiber-it.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts index 794a756..9a1e2ba 100644 --- a/translations/harbour-fernschreiber-it.ts +++ b/translations/harbour-fernschreiber-it.ts @@ -531,7 +531,7 @@ sent a venue - ha inviato la posizione + ha inviato un luogo changed the chat title @@ -1192,19 +1192,19 @@ Anonymous Quiz - + Quiz anonimo Quiz - + Quiz Anonymous Poll - + Sondaggio anonimo Poll - + Sondaggio From 46f1b144a765fd3dd3440e35ca0986d5dde2bec4 Mon Sep 17 00:00:00 2001 From: iamnomeutente <72705765+iamnomeutente@users.noreply.github.com> Date: Sat, 31 Oct 2020 09:54:47 +0100 Subject: [PATCH 4/7] Update harbour-fernschreiber-it.ts --- translations/harbour-fernschreiber-it.ts | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts index 9a1e2ba..acd0de6 100644 --- a/translations/harbour-fernschreiber-it.ts +++ b/translations/harbour-fernschreiber-it.ts @@ -333,12 +333,12 @@ Attendo la rete... - Connecting to network… - Connetto alla rete… + Connecting to network... + Connetto alla rete... - Connecting to proxy… - Connetto al proxy… + Connecting to proxy... + Connetto al proxy... Updating content... @@ -687,16 +687,16 @@ Attendo la rete... - Connecting to network… - Connetto alla rete… + Connecting to network... + Connetto alla rete... - Connecting to proxy… - Connetto al proxy… + Connecting to proxy... + Connetto al proxy... - Updating content… - Aggiorna contenuti… + Updating content... + Aggiorna contenuti... Loading chat list... @@ -933,8 +933,8 @@ Usati di recente - Loading stickers… - Carica sticker… + Loading stickers... + Carica sticker... From fb5cf0d38280a28810d8639bd652291330884506 Mon Sep 17 00:00:00 2001 From: John Gibbon Date: Sat, 31 Oct 2020 20:02:18 +0100 Subject: [PATCH 5/7] Remorse.itemAction; content Loader height preset --- qml/harbour-fernschreiber.qml | 4 --- qml/pages/ChatPage.qml | 32 +++++++++++++++++---- translations/harbour-fernschreiber-de.ts | 8 +++--- translations/harbour-fernschreiber-es.ts | 8 +++--- translations/harbour-fernschreiber-fi.ts | 8 +++--- translations/harbour-fernschreiber-hu.ts | 8 +++--- translations/harbour-fernschreiber-it.ts | 8 +++--- translations/harbour-fernschreiber-pl.ts | 8 +++--- translations/harbour-fernschreiber-ru.ts | 8 +++--- translations/harbour-fernschreiber-sv.ts | 8 +++--- translations/harbour-fernschreiber-zh_CN.ts | 8 +++--- translations/harbour-fernschreiber.ts | 8 +++--- 12 files changed, 67 insertions(+), 49 deletions(-) diff --git a/qml/harbour-fernschreiber.qml b/qml/harbour-fernschreiber.qml index 42bdf31..8c756cd 100644 --- a/qml/harbour-fernschreiber.qml +++ b/qml/harbour-fernschreiber.qml @@ -28,10 +28,6 @@ ApplicationWindow cover: Qt.resolvedUrl("pages/CoverPage.qml") allowedOrientations: defaultAllowedOrientations - RemorseItem { - id: deleteMessageRemorseItem - } - Connections { target: dBusAdaptor onPleaseOpenMessage: { diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml index 7ebb21f..346e602 100644 --- a/qml/pages/ChatPage.qml +++ b/qml/pages/ChatPage.qml @@ -517,6 +517,23 @@ Page { messageVenue: "LocationPreview", messagePoll: "PollPreview" }) + function getContentComponentHeight(componentName, content, parentWidth) { + switch(componentName) { + case "StickerPreview": return content.sticker.height; + case "ImagePreview": + case "LocationPreview": + return parentWidth * 0.66666666; // 2 / 3; + case "VideoPreview": + return Functions.getVideoHeight(parentWidth, ( content['@type'] === "messageVideo" ) ? content.video : content.animation); + case "AudioPreview": + return parentWidth / 2; + case "DocumentPreview": + return Theme.itemSizeSmall; + case "PollPreview": + return Theme.itemSizeSmall * (4 + content.poll.options); + } + } + delegate: ListItem { id: messageListItem contentHeight: messageBackground.height + Theme.paddingMedium @@ -527,7 +544,9 @@ Page { property Page page: chatPage property bool isOwnMessage: chatPage.myUserId === display.sender_user_id - + property string extraContentComponentName: typeof display.content !== "undefined" + && chatView.contentComponentNames.hasOwnProperty(display.content['@type']) ? + chatView.contentComponentNames[display.content['@type']] : "" menu: ContextMenu { MenuItem { onClicked: { @@ -546,9 +565,10 @@ Page { visible: display.can_be_edited } MenuItem { - enabled: !deleteMessageRemorseItem.pending onClicked: { - deleteMessageRemorseItem.execute(messageListItem, qsTr("Deleting message"), function() { tdLibWrapper.deleteMessages(chatInformation.id, [ display.id ]); } ); + var chatId = chatInformation.id; + var messageId = display.id; + Remorse.itemAction(messageListItem, qsTr("Message deleted"), function() { tdLibWrapper.deleteMessages(chatId, [ messageId]); }) } text: qsTr("Delete Message") visible: display.can_be_deleted_for_all_users || (display.can_be_deleted_only_for_self && display.chat_id === chatPage.myUserId) @@ -604,9 +624,9 @@ Page { running: false onTriggered: { if (typeof display.content !== "undefined") { - if(chatView.contentComponentNames.hasOwnProperty(display.content['@type'])) { + if(messageListItem.extraContentComponentName !== "") { extraContentLoader.setSource( - "../components/" +chatView.contentComponentNames[display.content['@type']] +".qml", + "../components/" +messageListItem.extraContentComponentName +".qml", { messageListItem: messageListItem }) @@ -825,6 +845,8 @@ Page { id: extraContentLoader width: parent.width asynchronous: true + property int heightPreset: messageListItem.extraContentComponentName !== "" ? chatView.getContentComponentHeight(messageListItem.extraContentComponentName, display.content, width) : 0 + height: item ? item.height : heightPreset } Timer { diff --git a/translations/harbour-fernschreiber-de.ts b/translations/harbour-fernschreiber-de.ts index 88e665b..7ecbc1f 100644 --- a/translations/harbour-fernschreiber-de.ts +++ b/translations/harbour-fernschreiber-de.ts @@ -281,10 +281,6 @@ edited bearbeitet - - Deleting message - Lösche Nachricht - Delete Message Nachricht löschen @@ -301,6 +297,10 @@ This chat is empty. Dieser Chat ist leer. + + Message deleted + Nachricht gelöscht + CoverPage diff --git a/translations/harbour-fernschreiber-es.ts b/translations/harbour-fernschreiber-es.ts index abf9faa..212bb0d 100644 --- a/translations/harbour-fernschreiber-es.ts +++ b/translations/harbour-fernschreiber-es.ts @@ -281,10 +281,6 @@ edited editado - - Deleting message - Borrando mensaje - Delete Message Borrar @@ -301,6 +297,10 @@ This chat is empty. Esta charla está vacía. + + Message deleted + + CoverPage diff --git a/translations/harbour-fernschreiber-fi.ts b/translations/harbour-fernschreiber-fi.ts index 081cfa2..ffe02e1 100644 --- a/translations/harbour-fernschreiber-fi.ts +++ b/translations/harbour-fernschreiber-fi.ts @@ -281,10 +281,6 @@ edited muokattu - - Deleting message - Poistetaan viestiä - Delete Message Poista viesti @@ -301,6 +297,10 @@ This chat is empty. Tämä keskustelu on tyhjä. + + Message deleted + + CoverPage diff --git a/translations/harbour-fernschreiber-hu.ts b/translations/harbour-fernschreiber-hu.ts index 7116eeb..abff168 100644 --- a/translations/harbour-fernschreiber-hu.ts +++ b/translations/harbour-fernschreiber-hu.ts @@ -281,10 +281,6 @@ edited Szerkesztett - - Deleting message - Üzenet törlése - Delete Message Üzenet törlése @@ -301,6 +297,10 @@ This chat is empty. + + Message deleted + + CoverPage diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts index 93b854e..f8b3240 100644 --- a/translations/harbour-fernschreiber-it.ts +++ b/translations/harbour-fernschreiber-it.ts @@ -277,10 +277,6 @@ edited modificato - - Deleting message - Cancellazione del messaggio - Delete Message Cancella messaggio @@ -301,6 +297,10 @@ Uploading... Carica... + + Message deleted + + CoverPage diff --git a/translations/harbour-fernschreiber-pl.ts b/translations/harbour-fernschreiber-pl.ts index 289adc5..a495ab5 100644 --- a/translations/harbour-fernschreiber-pl.ts +++ b/translations/harbour-fernschreiber-pl.ts @@ -281,10 +281,6 @@ edited edytowana - - Deleting message - Usuwanie wiadomości - Delete Message Usuń wiadomość @@ -301,6 +297,10 @@ This chat is empty. + + Message deleted + + CoverPage diff --git a/translations/harbour-fernschreiber-ru.ts b/translations/harbour-fernschreiber-ru.ts index 47be5ba..6d558c3 100644 --- a/translations/harbour-fernschreiber-ru.ts +++ b/translations/harbour-fernschreiber-ru.ts @@ -281,10 +281,6 @@ edited изменено - - Deleting message - Удаление сообщения - Delete Message Удалить @@ -301,6 +297,10 @@ This chat is empty. + + Message deleted + + CoverPage diff --git a/translations/harbour-fernschreiber-sv.ts b/translations/harbour-fernschreiber-sv.ts index 90b83f4..0881f58 100644 --- a/translations/harbour-fernschreiber-sv.ts +++ b/translations/harbour-fernschreiber-sv.ts @@ -281,10 +281,6 @@ edited redigerade - - Deleting message - Tar bort meddelande - Delete Message Ta bort meddelandet @@ -301,6 +297,10 @@ This chat is empty. Denna chatt är tom. + + Message deleted + + CoverPage diff --git a/translations/harbour-fernschreiber-zh_CN.ts b/translations/harbour-fernschreiber-zh_CN.ts index 7085c5f..7544f23 100644 --- a/translations/harbour-fernschreiber-zh_CN.ts +++ b/translations/harbour-fernschreiber-zh_CN.ts @@ -281,10 +281,6 @@ edited 已编辑 - - Deleting message - 正在删除消息 - Delete Message 删除消息 @@ -301,6 +297,10 @@ This chat is empty. + + Message deleted + + CoverPage diff --git a/translations/harbour-fernschreiber.ts b/translations/harbour-fernschreiber.ts index 3c5dd70..1211452 100644 --- a/translations/harbour-fernschreiber.ts +++ b/translations/harbour-fernschreiber.ts @@ -281,10 +281,6 @@ edited - - Deleting message - - Delete Message @@ -301,6 +297,10 @@ This chat is empty. + + Message deleted + + CoverPage From 30decc8f84169056bb0c7cd41b3dfdde06bba77d Mon Sep 17 00:00:00 2001 From: Sebastian Wolf Date: Sun, 1 Nov 2020 17:54:00 +0100 Subject: [PATCH 6/7] Make document picker work again, fix image picker --- qml/pages/ChatPage.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml index 346e602..e6b8108 100644 --- a/qml/pages/ChatPage.qml +++ b/qml/pages/ChatPage.qml @@ -1002,7 +1002,7 @@ Page { attachmentOptionsRow.visible = false; console.log("Selected document: " + picker.selectedContentProperties.filePath ); attachmentPreviewRow.fileProperties = picker.selectedContentProperties; - attachmentPreviewRow.isDocument = true; + attachmentPreviewRow.isPicture = true; attachmentPreviewRow.visible = true; controlSendButton(); }) @@ -1027,7 +1027,7 @@ Page { id: documentAttachmentButton icon.source: "image://theme/icon-m-document" onClicked: { - var picker = pageStack.push("Sailfish.Pickers.DocumentPicker"); + var picker = pageStack.push("Sailfish.Pickers.DocumentPickerPage"); picker.selectedContentPropertiesChanged.connect(function(){ attachmentOptionsRow.visible = false; console.log("Selected document: " + picker.selectedContentProperties.filePath ); From 09256d8ed95e0c659ba0c7e835a6a201c51ad2cc Mon Sep 17 00:00:00 2001 From: Sebastian Wolf Date: Sun, 1 Nov 2020 18:56:09 +0100 Subject: [PATCH 7/7] Update README after latest changes to chat page --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 566daa2..7430298 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Fernschreiber wouldn't be the same without all the people helping in making it b ### Code (Features, Bugfixes, Optimizations etc.) - Chat list model, TDLib receiver, project dependencies: [Slava Monich](https://github.com/monich) -- Chat info page, location support, app initialization/registration with Telegram, project dependencies: [jgibbon](https://github.com/jgibbon) +- Chat info page, performance improvements to chat page, location support, app initialization/registration with Telegram, project dependencies: [jgibbon](https://github.com/jgibbon) ### Logo/Icon - Designed by [Matteo](https://github.com/iamnomeutente)