Merge pull request #340 from Wunderfitz/userPreferences

User profile and privacy settings
This commit is contained in:
Sebastian Wolf 2021-01-28 21:58:56 +01:00 committed by GitHub
commit fe4d3c79d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 2063 additions and 40 deletions

View file

@ -47,6 +47,8 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/DocumentPreview.qml \ qml/components/DocumentPreview.qml \
qml/components/GamePreview.qml \ qml/components/GamePreview.qml \
qml/components/ImagePreview.qml \ qml/components/ImagePreview.qml \
qml/components/InformationEditArea.qml \
qml/components/InformationTextItem.qml \
qml/components/InReplyToRow.qml \ qml/components/InReplyToRow.qml \
qml/components/InlineQuery.qml \ qml/components/InlineQuery.qml \
qml/components/LocationPreview.qml \ qml/components/LocationPreview.qml \
@ -58,6 +60,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/PinnedMessageItem.qml \ qml/components/PinnedMessageItem.qml \
qml/components/PollPreview.qml \ qml/components/PollPreview.qml \
qml/components/PressEffect.qml \ qml/components/PressEffect.qml \
qml/components/ProfilePictureList.qml \
qml/components/ReplyMarkupButtons.qml \ qml/components/ReplyMarkupButtons.qml \
qml/components/StickerPicker.qml \ qml/components/StickerPicker.qml \
qml/components/PhotoTextsListItem.qml \ qml/components/PhotoTextsListItem.qml \
@ -66,16 +69,13 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/TDLibPhoto.qml \ qml/components/TDLibPhoto.qml \
qml/components/TDLibThumbnail.qml \ qml/components/TDLibThumbnail.qml \
qml/components/VoiceNoteOverlay.qml \ qml/components/VoiceNoteOverlay.qml \
qml/components/chatInformationPage/ChatInformationEditArea.qml \
qml/components/chatInformationPage/ChatInformationPageContent.qml \ qml/components/chatInformationPage/ChatInformationPageContent.qml \
qml/components/chatInformationPage/ChatInformationProfilePicture.qml \ qml/components/chatInformationPage/ChatInformationProfilePicture.qml \
qml/components/chatInformationPage/ChatInformationProfilePictureList.qml \
qml/components/chatInformationPage/ChatInformationTabItemBase.qml \ qml/components/chatInformationPage/ChatInformationTabItemBase.qml \
qml/components/chatInformationPage/ChatInformationTabItemDebug.qml \ qml/components/chatInformationPage/ChatInformationTabItemDebug.qml \
qml/components/chatInformationPage/ChatInformationTabItemMembersGroups.qml \ qml/components/chatInformationPage/ChatInformationTabItemMembersGroups.qml \
qml/components/chatInformationPage/ChatInformationTabItemSettings.qml \ qml/components/chatInformationPage/ChatInformationTabItemSettings.qml \
qml/components/chatInformationPage/ChatInformationTabView.qml \ qml/components/chatInformationPage/ChatInformationTabView.qml \
qml/components/chatInformationPage/ChatInformationTextItem.qml \
qml/components/chatInformationPage/EditGroupChatPermissionsColumn.qml \ qml/components/chatInformationPage/EditGroupChatPermissionsColumn.qml \
qml/components/chatInformationPage/EditSuperGroupSlowModeColumn.qml \ qml/components/chatInformationPage/EditSuperGroupSlowModeColumn.qml \
qml/components/inlineQueryResults/InlineQueryResult.qml \ qml/components/inlineQueryResults/InlineQueryResult.qml \

View file

@ -18,7 +18,7 @@ PhotoTextsListItem {
// chat title // chat title
primaryText.text: title ? Emoji.emojify(title, Theme.fontSizeMedium) : qsTr("Unknown") primaryText.text: title ? Emoji.emojify(title, Theme.fontSizeMedium) : qsTr("Unknown")
// last user // last user
prologSecondaryText.text: showDraft ? "<i>"+qsTr("Draft")+"</i>" : (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") ) : "" )) prologSecondaryText.text: showDraft ? "<i>"+qsTr("Draft")+"</i>" : (is_channel ? "" : ( last_message_sender_id ? ( last_message_sender_id !== ownUserId ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(last_message_sender_id)), Theme.fontSizeExtraSmall) : qsTr("You") ) : "" ))
// last message // last message
secondaryText.text: previewText ? Emoji.emojify(Functions.enhanceHtmlEntities(previewText), Theme.fontSizeExtraSmall) : "<i>" + qsTr("No message in this chat.") + "</i>" secondaryText.text: previewText ? Emoji.emojify(Functions.enhanceHtmlEntities(previewText), Theme.fontSizeExtraSmall) : "<i>" + qsTr("No message in this chat.") + "</i>"
// message date // message date

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2020 Sebastian J. Wolf and other contributors Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber. This file is part of Fernschreiber.
@ -16,6 +16,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>. along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
*/ */
import QtQuick 2.6 import QtQuick 2.6
import Sailfish.Silica 1.0 import Sailfish.Silica 1.0
@ -27,6 +28,7 @@ Column {
property string emptyPlaceholderText property string emptyPlaceholderText
property string text property string text
property bool multiLine property bool multiLine
property bool headerLeftAligned
property bool isEditing property bool isEditing
property Item editItem: multiLine ? editAreaTextArea : editAreaTextField property Item editItem: multiLine ? editAreaTextArea : editAreaTextField
@ -41,6 +43,7 @@ Column {
id: editAreaHeader id: editAreaHeader
height: parent.visible && text !== "" ? Theme.itemSizeExtraSmall : 0 height: parent.visible && text !== "" ? Theme.itemSizeExtraSmall : 0
x: 0 x: 0
horizontalAlignment: headerLeftAligned ? Text.AlignLeft : Text.AlignRight
} }
Row { Row {
id: editAreaTextRow id: editAreaTextRow
@ -50,25 +53,30 @@ Column {
id: editAreaTextArea id: editAreaTextArea
visible: editAreaColumn.isEditing && editAreaColumn.multiLine visible: editAreaColumn.isEditing && editAreaColumn.multiLine
width: parent.width - editAreaButton.width width: parent.width - editAreaButton.width
textLeftMargin: 0
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
font.pixelSize: Theme.fontSizeMedium
} }
TextField { TextField {
id: editAreaTextField id: editAreaTextField
visible: editAreaColumn.isEditing && !editAreaColumn.multiLine visible: editAreaColumn.isEditing && !editAreaColumn.multiLine
width: parent.width - editAreaButton.width width: parent.width - editAreaButton.width
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
textLeftMargin: 0
EnterKey.onClicked: { EnterKey.onClicked: {
editAreaColumn.isEditing = false; editAreaColumn.isEditing = false;
editAreaColumn.saveButtonClicked(editAreaColumn.editItem.text); editAreaColumn.saveButtonClicked(editAreaColumn.editItem.text);
} }
EnterKey.iconSource: editAreaButton.icon.source EnterKey.iconSource: editAreaButton.icon.source
font.pixelSize: Theme.fontSizeMedium
} }
ChatInformationTextItem { InformationTextItem {
id: editAreaTextItem id: editAreaTextItem
visible: !editAreaColumn.isEditing visible: !editAreaColumn.isEditing
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: editAreaColumn.text || editAreaColumn.emptyPlaceholderText text: editAreaColumn.text || editAreaColumn.emptyPlaceholderText
width: parent.width - editAreaButton.width width: parent.width - editAreaButton.width
height: !editAreaColumn.multiLine ? implicitHeight : editAreaTextField.height
} }
IconButton { IconButton {
id: editAreaButton id: editAreaButton

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2020 Sebastian J. Wolf and other contributors Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber. This file is part of Fernschreiber.
@ -16,11 +16,12 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>. along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
*/ */
import QtQuick 2.6 import QtQuick 2.6
import Sailfish.Silica 1.0 import Sailfish.Silica 1.0
import "../../js/twemoji.js" as Emoji import "../js/twemoji.js" as Emoji
import "../../js/functions.js" as Functions import "../js/functions.js" as Functions
Column { Column {
id: textItem id: textItem
@ -47,7 +48,7 @@ Column {
id: labelComponent id: labelComponent
Label { Label {
wrapMode: Text.WrapAtWordBoundaryOrAnywhere wrapMode: Text.WrapAtWordBoundaryOrAnywhere
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeMedium
textFormat: Text.StyledText textFormat: Text.StyledText
color: Theme.primaryColor color: Theme.primaryColor
text: Emoji.emojify( Functions.replaceUrlsWithLinks(textItem.text).replace(/\n/g, "<br>"), Theme.fontSizeExtraSmall) text: Emoji.emojify( Functions.replaceUrlsWithLinks(textItem.text).replace(/\n/g, "<br>"), Theme.fontSizeExtraSmall)

View file

@ -186,11 +186,11 @@ ListItem {
} }
onMyMessageChanged: { onMyMessageChanged: {
Debug.log("[ChatModel] This message was updated, index", messageIndex, ", updating content...") Debug.log("[ChatModel] This message was updated, index", messageIndex, ", updating content...");
messageDateText.text = getMessageStatusText(myMessage, messageIndex, chatView.lastReadSentIndex, messageDateText.useElapsed) messageDateText.text = getMessageStatusText(myMessage, messageIndex, chatView.lastReadSentIndex, messageDateText.useElapsed);
messageText.text = Emoji.emojify(Functions.getMessageText(myMessage, false, page.myUserId, false), messageText.font.pixelSize) messageText.text = Emoji.emojify(Functions.getMessageText(myMessage, false, page.myUserId, false), Theme.fontSizeSmall);
if (webPagePreviewLoader.item) { if (webPagePreviewLoader.item) {
webPagePreviewLoader.item.webPageData = myMessage.content.web_page webPagePreviewLoader.item.webPageData = myMessage.content.web_page;
} }
} }
@ -399,7 +399,7 @@ ListItem {
Text { Text {
id: messageText id: messageText
width: parent.width width: parent.width
text: Emoji.emojify(Functions.getMessageText(myMessage, false, page.myUserId, false), font.pixelSize) text: Emoji.emojify(Functions.getMessageText(myMessage, false, page.myUserId, false), Theme.fontSizeMedium)
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
color: messageListItem.textColor color: messageListItem.textColor
wrapMode: Text.Wrap wrapMode: Text.Wrap

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2020 Sebastian J. Wolf and other contributors Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
This file is part of Fernschreiber. This file is part of Fernschreiber.
@ -18,25 +18,25 @@
*/ */
import QtQuick 2.6 import QtQuick 2.6
import Sailfish.Silica 1.0 import Sailfish.Silica 1.0
import "../"
Item { Item {
visible: imageContainer.tweenFactor > 0.8 && bigProfilePictureList.count > 0 id: profilePictureListItem
property bool isActive: imageContainer.tweenFactor === 1.0 visible: imageContainer.thumbnailVisible && bigProfilePictureList.count > 0
property bool isActive: imageContainer.thumbnailActive
readonly property int currentPictureIndex: bigProfilePictureList.currentIndex
opacity: isActive ? 1.0 : 0.0 opacity: isActive ? 1.0 : 0.0
Behavior on opacity { FadeAnimation {} } Behavior on opacity { FadeAnimation {} }
SlideshowView { SlideshowView {
id: bigProfilePictureList id: bigProfilePictureList
property bool isActive: imageContainer.tweenFactor === 1.0
width: parent.width width: parent.width
height: parent.height height: parent.height
clip: true clip: true
itemWidth: width itemWidth: width
itemHeight: height itemHeight: height
interactive: parent.isActive interactive: parent.isActive
model: chatInformationPage.chatPartnerProfilePhotos model: imageContainer.thumbnailModel
delegate: Item { delegate: Item {
width: bigProfilePictureList.itemWidth width: bigProfilePictureList.itemWidth
height: bigProfilePictureList.itemHeight height: bigProfilePictureList.itemHeight
@ -44,13 +44,13 @@ Item {
id: chatPictureDetail id: chatPictureDetail
photoData: modelData.sizes[modelData.sizes.length - 1].photo photoData: modelData.sizes[modelData.sizes.length - 1].photo
replacementStringHint: "" replacementStringHint: ""
radius: chatPictureThumbnail.radius radius: imageContainer.thumbnailRadius
anchors.fill: parent anchors.fill: parent
} }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
pageStack.push(Qt.resolvedUrl("../../pages/ImagePage.qml"), { "photoData" : modelData }); pageStack.push(Qt.resolvedUrl("../pages/ImagePage.qml"), { "photoData" : modelData });
} }
} }
} }
@ -58,16 +58,18 @@ Item {
Text { Text {
visible: bigProfilePictureList.count > 1 visible: bigProfilePictureList.count > 1
width: parent.width width: parent.width - Theme.paddingSmall
anchors { anchors {
bottomMargin: Theme.paddingSmall bottomMargin: Theme.paddingSmall
bottom: parent.bottom bottom: parent.bottom
} }
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
property var baseString: new Array(bigProfilePictureList.count+1).join(" ○ ") property var baseString: new Array(bigProfilePictureList.count+1).join(" ○ ")
text: baseString.substring(0,bigProfilePictureList.currentIndex*3) + " ● " + baseString.substring((bigProfilePictureList.currentIndex+1)*3) text: (baseString.substring(0,bigProfilePictureList.currentIndex*3) + " ● " + baseString.substring((bigProfilePictureList.currentIndex+1)*3)).trim()
font.pixelSize: Theme.fontSizeTiny
color: Theme.primaryColor color: Theme.primaryColor
style: Text.Raised style: Text.Raised
styleColor: Theme.highlightDimmerColor styleColor: Theme.highlightDimmerColor
} }
} }

View file

@ -256,6 +256,10 @@ SilicaFlickable {
} }
return 1 - Math.max(0, Math.min(1, contentFlickable.contentY / maxDimension)) return 1 - Math.max(0, Math.min(1, contentFlickable.contentY / maxDimension))
} }
property bool thumbnailVisible: imageContainer.tweenFactor > 0.8
property bool thumbnailActive: imageContainer.tweenFactor === 1.0
property var thumbnailModel: chatInformationPage.chatPartnerProfilePhotos
property int thumbnailRadius: imageContainer.minDimension / 2
function getEased(min,max,factor) { function getEased(min,max,factor) {
return min + (max-min)*factor return min + (max-min)*factor
@ -271,17 +275,18 @@ SilicaFlickable {
replacementStringHint: headerItem.title replacementStringHint: headerItem.title
width: parent.width width: parent.width
height: width height: width
radius: imageContainer.minDimension / 2 radius: imageContainer.thumbnailRadius
opacity: profilePictureLoader.status !== Loader.Ready || profilePictureLoader.item.opacity < 1 ? 1.0 : 0.0 opacity: profilePictureLoader.status !== Loader.Ready || profilePictureLoader.item.opacity < 1 ? 1.0 : 0.0
optimizeImageSize: false optimizeImageSize: false
} }
Loader { Loader {
id: profilePictureLoader id: profilePictureLoader
active: imageContainer.hasImage active: imageContainer.hasImage
asynchronous: true asynchronous: true
anchors.fill: chatPictureThumbnail anchors.fill: chatPictureThumbnail
source: ( chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) source: ( chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat)
? "ChatInformationProfilePictureList.qml" ? "../ProfilePictureList.qml"
: "ChatInformationProfilePicture.qml" : "ChatInformationProfilePicture.qml"
} }
} }
@ -350,7 +355,7 @@ SilicaFlickable {
height: imageContainer.hasImage ? imageContainer.maxDimension : 0 height: imageContainer.hasImage ? imageContainer.maxDimension : 0
} }
ChatInformationEditArea { InformationEditArea {
visible: canEdit visible: canEdit
canEdit: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && 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") headerText: qsTr("Chat Title", "group title header")
@ -376,7 +381,7 @@ SilicaFlickable {
} }
} }
} }
ChatInformationEditArea { InformationEditArea {
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")) 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.") emptyPlaceholderText: qsTr("There is no information text available, yet.")
headerText: qsTr("Info", "group or user infotext header") headerText: qsTr("Info", "group or user infotext header")
@ -391,7 +396,7 @@ SilicaFlickable {
} }
} }
ChatInformationTextItem { InformationTextItem {
headerText: qsTr("Phone Number", "user phone number header") headerText: qsTr("Phone Number", "user phone number header")
text: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.phone_number ? "+"+chatInformationPage.privateChatUserInformation.phone_number : "") || "" text: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.phone_number ? "+"+chatInformationPage.privateChatUserInformation.phone_number : "") || ""
isLinkedLabel: true isLinkedLabel: true
@ -408,7 +413,7 @@ SilicaFlickable {
Row { Row {
width: parent.width width: parent.width
visible: !!inviteLinkItem.text visible: !!inviteLinkItem.text
ChatInformationTextItem { InformationTextItem {
id: inviteLinkItem id: inviteLinkItem
text: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? chatInformationPage.groupFullInformation.invite_link : "" text: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? chatInformationPage.groupFullInformation.invite_link : ""
width: parent.width - inviteLinkButton.width width: parent.width - inviteLinkButton.width

View file

@ -22,8 +22,8 @@ import Sailfish.Silica 1.0
import "../" import "../"
Item { Item {
visible: imageContainer.tweenFactor > 0.8 && chatPictureDetail.imageStatus === Image.Ready visible: parent.thumbnailVisible && chatPictureDetail.imageStatus === Image.Ready
property bool isActive: imageContainer.tweenFactor === 1.0 property bool isActive: parent.thumbnailActive
opacity: isActive ? 1.0 : 0.0 opacity: isActive ? 1.0 : 0.0
Behavior on opacity { FadeAnimation {} } Behavior on opacity { FadeAnimation {} }
ProfileThumbnail { ProfileThumbnail {

View file

@ -38,18 +38,18 @@ ChatInformationTabItemBase {
width: tabBase.width - Theme.horizontalPageMargin * 2 width: tabBase.width - Theme.horizontalPageMargin * 2
x: Theme.horizontalPageMargin x: Theme.horizontalPageMargin
ChatInformationTextItem { InformationTextItem {
headerText: "chatInformation" headerText: "chatInformation"
text:chatInformationPage.chatInformation ? JSON.stringify(chatInformationPage.chatInformation, null, 2) : "" text:chatInformationPage.chatInformation ? JSON.stringify(chatInformationPage.chatInformation, null, 2) : ""
isLinkedLabel: true isLinkedLabel: true
} }
ChatInformationTextItem { InformationTextItem {
headerText: "groupInformation" headerText: "groupInformation"
text: chatInformationPage.groupInformation ? JSON.stringify(chatInformationPage.groupInformation, null, 2) : "" text: chatInformationPage.groupInformation ? JSON.stringify(chatInformationPage.groupInformation, null, 2) : ""
isLinkedLabel: true isLinkedLabel: true
} }
ChatInformationTextItem { InformationTextItem {
headerText: "groupFullInformation" headerText: "groupFullInformation"
text: chatInformationPage.groupFullInformation ? JSON.stringify(chatInformationPage.groupFullInformation, null, 2) : "" text: chatInformationPage.groupFullInformation ? JSON.stringify(chatInformationPage.groupFullInformation, null, 2) : ""
isLinkedLabel: true isLinkedLabel: true

View file

@ -92,6 +92,12 @@ Page {
tdLibWrapper.getRecentStickers(); tdLibWrapper.getRecentStickers();
tdLibWrapper.getInstalledStickerSets(); tdLibWrapper.getInstalledStickerSets();
tdLibWrapper.getContacts(); tdLibWrapper.getContacts();
tdLibWrapper.getUserPrivacySettingRules(TelegramAPI.SettingAllowChatInvites);
tdLibWrapper.getUserPrivacySettingRules(TelegramAPI.SettingAllowFindingByPhoneNumber);
tdLibWrapper.getUserPrivacySettingRules(TelegramAPI.SettingShowLinkInForwardedMessages);
tdLibWrapper.getUserPrivacySettingRules(TelegramAPI.SettingShowPhoneNumber);
tdLibWrapper.getUserPrivacySettingRules(TelegramAPI.SettingShowProfilePhoto);
tdLibWrapper.getUserPrivacySettingRules(TelegramAPI.SettingShowStatus);
} }
} }

View file

@ -18,14 +18,59 @@
*/ */
import QtQuick 2.6 import QtQuick 2.6
import Sailfish.Silica 1.0 import Sailfish.Silica 1.0
import Sailfish.Pickers 1.0
import WerkWolf.Fernschreiber 1.0 import WerkWolf.Fernschreiber 1.0
import "../components"
import "../js/functions.js" as Functions import "../js/functions.js" as Functions
import "../js/debug.js" as Debug
Page { Page {
id: settingsPage id: settingsPage
allowedOrientations: Orientation.All allowedOrientations: Orientation.All
readonly property bool landscapeLayout: (width > height && Screen.sizeCategory > Screen.Small) || Screen.sizeCategory > Screen.Medium readonly property bool landscapeLayout: (width > height && Screen.sizeCategory > Screen.Small) || Screen.sizeCategory > Screen.Medium
readonly property var userInformation: tdLibWrapper.getUserInformation()
property bool uploadInProgress: false
onStatusChanged: {
if (status === PageStatus.Active) {
tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
}
}
Connections {
target: tdLibWrapper
onOwnUserUpdated: {
firstNameEditArea.text = userInformation.first_name;
lastNameEditArea.text = userInformation.last_name;
userNameEditArea.text = userInformation.username;
}
onUserProfilePhotosReceived: {
if (extra === userInformation.id.toString()) {
imageContainer.thumbnailModel = photos;
}
}
onFileUpdated: {
if (uploadInProgress) {
profilePictureButtonColumn.visible = !fileInformation.remote.is_uploading_active;
uploadInProgress = fileInformation.remote.is_uploading_active;
if (!fileInformation.remote.is_uploading_active) {
uploadInProgress = false;
tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
}
}
}
onOkReceived: {
if (request === "deleteProfilePhoto") {
tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
}
if (request === "setProfilePhoto") {
tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
profilePictureButtonColumn.visible = true;
uploadInProgress = false;
}
}
}
SilicaFlickable { SilicaFlickable {
id: settingsContainer id: settingsContainer
@ -40,6 +85,427 @@ Page {
title: qsTr("Settings") title: qsTr("Settings")
} }
SectionHeader {
text: qsTr("User Profile")
}
Grid {
width: parent.width - ( 2 * Theme.horizontalPageMargin )
columns: landscapeLayout ? 2 : 1
columnSpacing: Theme.horizontalPageMargin
anchors.horizontalCenter: parent.horizontalCenter
readonly property real columnWidth: width/columns
InformationEditArea {
id: firstNameEditArea
visible: true
canEdit: true
headerText: qsTr("First Name", "first name of the logged-in profile - header")
text: userInformation.first_name
width: parent.columnWidth
headerLeftAligned: true
onSaveButtonClicked: {
if(!editItem.errorHighlight) {
tdLibWrapper.setName(textValue, lastNameEditArea.text);
} else {
isEditing = true;
}
}
onTextEdited: {
if(textValue.length > 0 && textValue.length < 65) {
editItem.errorHighlight = false;
editItem.label = "";
editItem.placeholderText = "";
} else {
editItem.label = qsTr("Enter 1-64 characters");
editItem.placeholderText = editItem.label;
editItem.errorHighlight = true;
}
}
}
InformationEditArea {
id: lastNameEditArea
visible: true
canEdit: true
headerText: qsTr("Last Name", "last name of the logged-in profile - header")
text: userInformation.last_name
width: parent.columnWidth
headerLeftAligned: true
onSaveButtonClicked: {
if(!editItem.errorHighlight) {
tdLibWrapper.setName(firstNameEditArea.text, textValue);
} else {
isEditing = true;
}
}
onTextEdited: {
if(textValue.length >= 0 && textValue.length < 65) {
editItem.errorHighlight = false;
editItem.label = "";
editItem.placeholderText = "";
} else {
editItem.label = qsTr("Enter 0-64 characters");
editItem.placeholderText = editItem.label;
editItem.errorHighlight = true;
}
}
}
InformationEditArea {
id: userNameEditArea
visible: true
canEdit: true
headerText: qsTr("Username", "user name of the logged-in profile - header")
text: userInformation.username
width: parent.columnWidth
headerLeftAligned: true
onSaveButtonClicked: {
tdLibWrapper.setUsername(textValue);
}
}
}
SectionHeader {
horizontalAlignment: Text.AlignLeft
text: qsTr("Profile Pictures")
}
Row {
width: parent.width - ( 2 * Theme.horizontalPageMargin )
spacing: Theme.paddingMedium
Item {
id: imageContainer
anchors.verticalCenter: parent.verticalCenter
width: parent.width / 2
height: profilePictureLoader.height
property var thumbnailModel: ({})
property bool thumbnailVisible: true
property bool thumbnailActive: thumbnailModel.length > 0
property int thumbnailRadius: imageContainer.width / 2
Loader {
id: profilePictureLoader
active: imageContainer.thumbnailActive
asynchronous: true
width: Theme.itemSizeExtraLarge
height: Theme.itemSizeExtraLarge
anchors.horizontalCenter: parent.horizontalCenter
source: "../components/ProfilePictureList.qml"
}
ProfileThumbnail {
id: chatPictureReplacement
visible: !profilePictureLoader.active
replacementStringHint: Functions.getUserName(settingsPage.userInformation)
radius: imageContainer.thumbnailRadius
anchors.horizontalCenter: parent.horizontalCenter
width: Theme.itemSizeExtraLarge
height: Theme.itemSizeExtraLarge
}
}
Column {
id: profilePictureButtonColumn
spacing: Theme.paddingSmall
width: parent.width / 2
Button {
id: addProfilePictureButton
text: qsTr("Add Picture")
anchors {
horizontalCenter: parent.horizontalCenter
}
onClicked: {
pageStack.push(imagePickerPage);
}
}
Button {
id: removeProfilePictureButton
text: qsTr("Delete Picture")
anchors {
horizontalCenter: parent.horizontalCenter
}
onClicked: {
var pictureIdForDeletion = imageContainer.thumbnailModel[profilePictureLoader.item.currentPictureIndex].id;
Remorse.popupAction(settingsPage, qsTr("Deleting profile picture"), function() { tdLibWrapper.deleteProfilePhoto(pictureIdForDeletion) });
}
}
}
Column {
id: uploadStatusColumn
visible: !profilePictureButtonColumn.visible
spacing: Theme.paddingMedium
width: parent.width / 2
Text {
id: uploadingText
font.pixelSize: Theme.fontSizeSmall
text: qsTr("Uploading...")
horizontalAlignment: Text.AlignHCenter
color: Theme.secondaryColor
width: parent.width
}
BusyIndicator {
anchors.horizontalCenter: parent.horizontalCenter
running: uploadStatusColumn.visible
size: BusyIndicatorSize.Medium
}
}
}
Component {
id: imagePickerPage
ImagePickerPage {
onSelectedContentPropertiesChanged: {
profilePictureButtonColumn.visible = false;
uploadInProgress = true;
tdLibWrapper.setProfilePhoto(selectedContentProperties.filePath);
}
}
}
SectionHeader {
horizontalAlignment: Text.AlignLeft
text: qsTr("Privacy")
}
Grid {
width: parent.width
columns: landscapeLayout ? 2 : 1
columnSpacing: Theme.horizontalPageMargin
anchors.horizontalCenter: parent.horizontalCenter
readonly property real columnWidth: width/columns
Connections {
target: tdLibWrapper
onUserPrivacySettingUpdated: {
Debug.log("Received updated privacy setting: " + setting + ":" + rule);
switch (setting) {
case TelegramAPI.SettingAllowChatInvites:
allowChatInvitesComboBox.currentIndex = rule;
break;
case TelegramAPI.SettingAllowFindingByPhoneNumber:
allowFindingByPhoneNumberComboBox.currentIndex = rule;
break;
case TelegramAPI.SettingShowLinkInForwardedMessages:
showLinkInForwardedMessagesComboBox.currentIndex = rule;
break;
case TelegramAPI.SettingShowPhoneNumber:
showPhoneNumberComboBox.currentIndex = rule;
break;
case TelegramAPI.SettingShowProfilePhoto:
showProfilePhotoComboBox.currentIndex = rule;
break;
case TelegramAPI.SettingShowStatus:
showStatusComboBox.currentIndex = rule;
break;
}
}
}
ComboBox {
id: allowChatInvitesComboBox
width: parent.columnWidth
label: qsTr("Allow chat invites")
description: qsTr("Privacy setting for managing whether you can be invited to chats.")
menu: ContextMenu {
MenuItem {
text: qsTr("Yes")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleAllowAll);
}
}
MenuItem {
text: qsTr("Your contacts only")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleAllowContacts);
}
}
MenuItem {
text: qsTr("No")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites, TelegramAPI.RuleRestrictAll);
}
}
}
Component.onCompleted: {
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingAllowChatInvites);
}
}
ComboBox {
id: allowFindingByPhoneNumberComboBox
width: parent.columnWidth
label: qsTr("Allow finding by phone number")
description: qsTr("Privacy setting for managing whether you can be found by your phone number.")
menu: ContextMenu {
MenuItem {
text: qsTr("Yes")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber, TelegramAPI.RuleAllowAll);
}
}
MenuItem {
text: qsTr("Your contacts only")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber, TelegramAPI.RuleAllowContacts);
}
}
}
Component.onCompleted: {
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingAllowFindingByPhoneNumber);
}
}
ComboBox {
id: showLinkInForwardedMessagesComboBox
width: parent.columnWidth
label: qsTr("Show link in forwarded messages")
description: qsTr("Privacy setting for managing whether a link to your account is included in forwarded messages.")
menu: ContextMenu {
MenuItem {
text: qsTr("Yes")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleAllowAll);
}
}
MenuItem {
text: qsTr("Your contacts only")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleAllowContacts);
}
}
MenuItem {
text: qsTr("No")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages, TelegramAPI.RuleRestrictAll);
}
}
}
Component.onCompleted: {
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowLinkInForwardedMessages);
}
}
ComboBox {
id: showPhoneNumberComboBox
width: parent.columnWidth
label: qsTr("Show phone number")
description: qsTr("Privacy setting for managing whether your phone number is visible.")
menu: ContextMenu {
MenuItem {
text: qsTr("Yes")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleAllowAll);
}
}
MenuItem {
text: qsTr("Your contacts only")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleAllowContacts);
}
}
MenuItem {
text: qsTr("No")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber, TelegramAPI.RuleRestrictAll);
}
}
}
Component.onCompleted: {
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowPhoneNumber);
}
}
ComboBox {
id: showProfilePhotoComboBox
width: parent.columnWidth
label: qsTr("Show profile photo")
description: qsTr("Privacy setting for managing whether your profile photo is visible.")
menu: ContextMenu {
MenuItem {
text: qsTr("Yes")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleAllowAll);
}
}
MenuItem {
text: qsTr("Your contacts only")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleAllowContacts);
}
}
MenuItem {
text: qsTr("No")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto, TelegramAPI.RuleRestrictAll);
}
}
}
Component.onCompleted: {
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowProfilePhoto);
}
}
ComboBox {
id: showStatusComboBox
width: parent.columnWidth
label: qsTr("Show status")
description: qsTr("Privacy setting for managing whether your online status is visible.")
menu: ContextMenu {
MenuItem {
text: qsTr("Yes")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleAllowAll);
}
}
MenuItem {
text: qsTr("Your contacts only")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleAllowContacts);
}
}
MenuItem {
text: qsTr("No")
onClicked: {
tdLibWrapper.setUserPrivacySettingRule(TelegramAPI.SettingShowStatus, TelegramAPI.RuleRestrictAll);
}
}
}
Component.onCompleted: {
currentIndex = tdLibWrapper.getUserPrivacySettingRule(TelegramAPI.SettingShowStatus);
}
}
}
SectionHeader { SectionHeader {
text: qsTr("Behavior") text: qsTr("Behavior")
} }

View file

@ -139,6 +139,8 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
handlers.insert("updateChatDraftMessage", &TDLibReceiver::processUpdateChatDraftMessage); handlers.insert("updateChatDraftMessage", &TDLibReceiver::processUpdateChatDraftMessage);
handlers.insert("inlineQueryResults", &TDLibReceiver::processInlineQueryResults); handlers.insert("inlineQueryResults", &TDLibReceiver::processInlineQueryResults);
handlers.insert("callbackQueryAnswer", &TDLibReceiver::processCallbackQueryAnswer); handlers.insert("callbackQueryAnswer", &TDLibReceiver::processCallbackQueryAnswer);
handlers.insert("userPrivacySettingRules", &TDLibReceiver::processUserPrivacySettingRules);
handlers.insert("updateUserPrivacySettingRules", &TDLibReceiver::processUpdateUserPrivacySettingRules);
} }
void TDLibReceiver::setActive(bool active) void TDLibReceiver::setActive(bool active)
@ -556,8 +558,12 @@ void TDLibReceiver::processError(const QVariantMap &receivedInformation)
emit errorReceived(receivedInformation.value("code").toInt(), receivedInformation.value(MESSAGE).toString(), receivedInformation.value(EXTRA).toString()); emit errorReceived(receivedInformation.value("code").toInt(), receivedInformation.value(MESSAGE).toString(), receivedInformation.value(EXTRA).toString());
} }
void TDLibReceiver::nop(const QVariantMap &) void TDLibReceiver::nop(const QVariantMap &receivedInformation)
{ {
LOG("Received an OK");
if (receivedInformation.contains(EXTRA)) {
emit okReceived(receivedInformation.value(EXTRA).toString());
}
} }
void TDLibReceiver::processSecretChat(const QVariantMap &receivedInformation) void TDLibReceiver::processSecretChat(const QVariantMap &receivedInformation)
@ -607,7 +613,18 @@ void TDLibReceiver::processInlineQueryResults(const QVariantMap &receivedInforma
void TDLibReceiver::processCallbackQueryAnswer(const QVariantMap &receivedInformation) void TDLibReceiver::processCallbackQueryAnswer(const QVariantMap &receivedInformation)
{ {
LOG("Callback Query answer"); LOG("Callback Query answer");
emit callbackQueryAnswer(receivedInformation.value(TEXT).toString(), receivedInformation.value("alert").toBool(), receivedInformation.value("url").toString()); emit callbackQueryAnswer(receivedInformation.value(TEXT).toString(), receivedInformation.value("alert").toBool(), receivedInformation.value("url").toString());
} }
void TDLibReceiver::processUserPrivacySettingRules(const QVariantMap &receivedInformation)
{
LOG("User privacy setting rules");
emit userPrivacySettingRules(receivedInformation);
}
void TDLibReceiver::processUpdateUserPrivacySettingRules(const QVariantMap &receivedInformation)
{
LOG("User privacy setting rules updated");
emit userPrivacySettingRulesUpdated(receivedInformation);
}

View file

@ -95,6 +95,9 @@ signals:
void chatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order); void chatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
void inlineQueryResults(const QString &inlineQueryId, const QString &nextOffset, const QVariantList &results, const QString &switchPmText, const QString &switchPmParameter, const QString &extra); void inlineQueryResults(const QString &inlineQueryId, const QString &nextOffset, const QVariantList &results, const QString &switchPmText, const QString &switchPmParameter, const QString &extra);
void callbackQueryAnswer(const QString &text, bool alert, const QString &url); void callbackQueryAnswer(const QString &text, bool alert, const QString &url);
void userPrivacySettingRules(const QVariantMap &rules);
void userPrivacySettingRulesUpdated(const QVariantMap &updatedRules);
void okReceived(const QString &request);
private: private:
typedef void (TDLibReceiver::*Handler)(const QVariantMap &); typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
@ -164,6 +167,8 @@ private:
void processUpdateChatDraftMessage(const QVariantMap &receivedInformation); void processUpdateChatDraftMessage(const QVariantMap &receivedInformation);
void processInlineQueryResults(const QVariantMap &receivedInformation); void processInlineQueryResults(const QVariantMap &receivedInformation);
void processCallbackQueryAnswer(const QVariantMap &receivedInformation); void processCallbackQueryAnswer(const QVariantMap &receivedInformation);
void processUserPrivacySettingRules(const QVariantMap &receivedInformation);
void processUpdateUserPrivacySettingRules(const QVariantMap &receivedInformation);
}; };
#endif // TDLIBRECEIVER_H #endif // TDLIBRECEIVER_H

View file

@ -158,6 +158,9 @@ void TDLibWrapper::initializeTDLibReciever() {
connect(this->tdLibReceiver, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)), this, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString))); connect(this->tdLibReceiver, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)), this, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)));
connect(this->tdLibReceiver, SIGNAL(inlineQueryResults(QString, QString, QVariantList, QString, QString, QString)), this, SIGNAL(inlineQueryResults(QString, QString, QVariantList, QString, QString, QString))); connect(this->tdLibReceiver, SIGNAL(inlineQueryResults(QString, QString, QVariantList, QString, QString, QString)), this, SIGNAL(inlineQueryResults(QString, QString, QVariantList, QString, QString, QString)));
connect(this->tdLibReceiver, SIGNAL(callbackQueryAnswer(QString, bool, QString)), this, SIGNAL(callbackQueryAnswer(QString, bool, QString))); connect(this->tdLibReceiver, SIGNAL(callbackQueryAnswer(QString, bool, QString)), this, SIGNAL(callbackQueryAnswer(QString, bool, QString)));
connect(this->tdLibReceiver, SIGNAL(userPrivacySettingRules(QVariantMap)), this, SLOT(handleUserPrivacySettingRules(QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(userPrivacySettingRulesUpdated(QVariantMap)), this, SLOT(handleUpdatedUserPrivacySettingRules(QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(okReceived(QString)), this, SIGNAL(okReceived(QString)));
this->tdLibReceiver->start(); this->tdLibReceiver->start();
} }
@ -1182,6 +1185,146 @@ void TDLibWrapper::deleteFile(int fileId)
this->sendRequest(requestObject); this->sendRequest(requestObject);
} }
void TDLibWrapper::setName(const QString &firstName, const QString &lastName)
{
LOG("Set name of current user" << firstName << lastName);
QVariantMap requestObject;
requestObject.insert(_TYPE, "setName");
requestObject.insert("first_name", firstName);
requestObject.insert("last_name", lastName);
this->sendRequest(requestObject);
}
void TDLibWrapper::setUsername(const QString &userName)
{
LOG("Set username of current user" << userName);
QVariantMap requestObject;
requestObject.insert(_TYPE, "setUsername");
requestObject.insert("username", userName);
this->sendRequest(requestObject);
}
void TDLibWrapper::setUserPrivacySettingRule(TDLibWrapper::UserPrivacySetting setting, TDLibWrapper::UserPrivacySettingRule rule)
{
LOG("Set user privacy setting rule of current user" << setting << rule);
QVariantMap requestObject;
requestObject.insert(_TYPE, "setUserPrivacySettingRules");
QVariantMap settingMap;
switch (setting) {
case SettingShowStatus:
settingMap.insert(_TYPE, "userPrivacySettingShowStatus");
break;
case SettingShowPhoneNumber:
settingMap.insert(_TYPE, "userPrivacySettingShowPhoneNumber");
break;
case SettingAllowChatInvites:
settingMap.insert(_TYPE, "userPrivacySettingAllowChatInvites");
break;
case SettingShowProfilePhoto:
settingMap.insert(_TYPE, "userPrivacySettingShowProfilePhoto");
break;
case SettingAllowFindingByPhoneNumber:
settingMap.insert(_TYPE, "userPrivacySettingAllowFindingByPhoneNumber");
break;
case SettingShowLinkInForwardedMessages:
settingMap.insert(_TYPE, "userPrivacySettingShowLinkInForwardedMessages");
break;
case SettingUnknown:
return;
}
requestObject.insert("setting", settingMap);
QVariantMap ruleMap;
switch (rule) {
case RuleAllowAll:
ruleMap.insert(_TYPE, "userPrivacySettingRuleAllowAll");
break;
case RuleAllowContacts:
ruleMap.insert(_TYPE, "userPrivacySettingRuleAllowContacts");
break;
case RuleRestrictAll:
ruleMap.insert(_TYPE, "userPrivacySettingRuleRestrictAll");
break;
}
QVariantList ruleMaps;
ruleMaps.append(ruleMap);
QVariantMap encapsulatedRules;
encapsulatedRules.insert(_TYPE, "userPrivacySettingRules");
encapsulatedRules.insert("rules", ruleMaps);
requestObject.insert("rules", encapsulatedRules);
this->sendRequest(requestObject);
}
void TDLibWrapper::getUserPrivacySettingRules(TDLibWrapper::UserPrivacySetting setting)
{
LOG("Getting user privacy setting rules of current user" << setting);
QVariantMap requestObject;
requestObject.insert(_TYPE, "getUserPrivacySettingRules");
requestObject.insert(_EXTRA, setting);
QVariantMap settingMap;
switch (setting) {
case SettingShowStatus:
settingMap.insert(_TYPE, "userPrivacySettingShowStatus");
break;
case SettingShowPhoneNumber:
settingMap.insert(_TYPE, "userPrivacySettingShowPhoneNumber");
break;
case SettingAllowChatInvites:
settingMap.insert(_TYPE, "userPrivacySettingAllowChatInvites");
break;
case SettingShowProfilePhoto:
settingMap.insert(_TYPE, "userPrivacySettingShowProfilePhoto");
break;
case SettingAllowFindingByPhoneNumber:
settingMap.insert(_TYPE, "userPrivacySettingAllowFindingByPhoneNumber");
break;
case SettingShowLinkInForwardedMessages:
settingMap.insert(_TYPE, "userPrivacySettingShowLinkInForwardedMessages");
break;
case SettingUnknown:
return;
}
requestObject.insert("setting", settingMap);
this->sendRequest(requestObject);
}
void TDLibWrapper::setProfilePhoto(const QString &filePath)
{
LOG("Set a profile photo" << filePath);
QVariantMap requestObject;
requestObject.insert(_TYPE, "setProfilePhoto");
requestObject.insert(_EXTRA, "setProfilePhoto");
QVariantMap inputChatPhoto;
inputChatPhoto.insert(_TYPE, "inputChatPhotoStatic");
QVariantMap inputFile;
inputFile.insert(_TYPE, "inputFileLocal");
inputFile.insert("path", filePath);
inputChatPhoto.insert("photo", inputFile);
requestObject.insert("photo", inputChatPhoto);
this->sendRequest(requestObject);
}
void TDLibWrapper::deleteProfilePhoto(const QString &profilePhotoId)
{
LOG("Delete a profile photo" << profilePhotoId);
QVariantMap requestObject;
requestObject.insert(_TYPE, "deleteProfilePhoto");
requestObject.insert(_EXTRA, "deleteProfilePhoto");
requestObject.insert("profile_photo_id", profilePhotoId);
this->sendRequest(requestObject);
}
void TDLibWrapper::searchEmoji(const QString &queryString) void TDLibWrapper::searchEmoji(const QString &queryString)
{ {
LOG("Searching emoji" << queryString); LOG("Searching emoji" << queryString);
@ -1213,6 +1356,11 @@ QVariantMap TDLibWrapper::getUserInformationByName(const QString &userName)
return this->allUserNames.value(userName).toMap(); return this->allUserNames.value(userName).toMap();
} }
TDLibWrapper::UserPrivacySettingRule TDLibWrapper::getUserPrivacySettingRule(TDLibWrapper::UserPrivacySetting userPrivacySetting)
{
return this->userPrivacySettingRules.value(userPrivacySetting, UserPrivacySettingRule::RuleAllowAll);
}
QVariantMap TDLibWrapper::getUnreadMessageInformation() QVariantMap TDLibWrapper::getUnreadMessageInformation()
{ {
return this->unreadMessageInformation; return this->unreadMessageInformation;
@ -1436,6 +1584,7 @@ void TDLibWrapper::handleUserUpdated(const QVariantMap &userInformation)
if (updatedUserId == this->options.value("my_id").toString()) { if (updatedUserId == this->options.value("my_id").toString()) {
LOG("Own user information updated :)"); LOG("Own user information updated :)");
this->userInformation = userInformation; this->userInformation = userInformation;
emit ownUserUpdated(userInformation);
} }
LOG("User information updated:" << userInformation.value(USERNAME).toString() << userInformation.value(FIRST_NAME).toString() << userInformation.value(LAST_NAME).toString()); LOG("User information updated:" << userInformation.value(USERNAME).toString() << userInformation.value(FIRST_NAME).toString() << userInformation.value(LAST_NAME).toString());
this->allUsers.insert(updatedUserId, userInformation); this->allUsers.insert(updatedUserId, userInformation);
@ -1596,6 +1745,55 @@ void TDLibWrapper::handleMessageIsPinnedUpdated(qlonglong chatId, qlonglong mess
} }
} }
void TDLibWrapper::handleUserPrivacySettingRules(const QVariantMap &rules)
{
QVariantList newGivenRules = rules.value("rules").toList();
// If nothing (or something unsupported is sent out) it is considered to be restricted completely
UserPrivacySettingRule newAppliedRule = UserPrivacySettingRule::RuleRestrictAll;
QListIterator<QVariant> givenRulesIterator(newGivenRules);
while (givenRulesIterator.hasNext()) {
QString givenRule = givenRulesIterator.next().toMap().value(_TYPE).toString();
if (givenRule == "userPrivacySettingRuleAllowContacts") {
newAppliedRule = UserPrivacySettingRule::RuleAllowContacts;
}
if (givenRule == "userPrivacySettingRuleAllowAll") {
newAppliedRule = UserPrivacySettingRule::RuleAllowAll;
}
}
UserPrivacySetting usedSetting = static_cast<UserPrivacySetting>(rules.value(_EXTRA).toInt());
this->userPrivacySettingRules.insert(usedSetting, newAppliedRule);
emit userPrivacySettingUpdated(usedSetting, newAppliedRule);
}
void TDLibWrapper::handleUpdatedUserPrivacySettingRules(const QVariantMap &updatedRules)
{
QString rawSetting = updatedRules.value("setting").toMap().value(_TYPE).toString();
UserPrivacySetting usedSetting = UserPrivacySetting::SettingUnknown;
if (rawSetting == "userPrivacySettingAllowChatInvites") {
usedSetting = UserPrivacySetting::SettingAllowChatInvites;
}
if (rawSetting == "userPrivacySettingAllowFindingByPhoneNumber") {
usedSetting = UserPrivacySetting::SettingAllowFindingByPhoneNumber;
}
if (rawSetting == "userPrivacySettingShowLinkInForwardedMessages") {
usedSetting = UserPrivacySetting::SettingShowLinkInForwardedMessages;
}
if (rawSetting == "userPrivacySettingShowPhoneNumber") {
usedSetting = UserPrivacySetting::SettingShowPhoneNumber;
}
if (rawSetting == "userPrivacySettingShowProfilePhoto") {
usedSetting = UserPrivacySetting::SettingShowProfilePhoto;
}
if (rawSetting == "userPrivacySettingShowStatus") {
usedSetting = UserPrivacySetting::SettingShowStatus;
}
if (usedSetting != UserPrivacySetting::SettingUnknown) {
QVariantMap rawRules = updatedRules.value("rules").toMap();
rawRules.insert(_EXTRA, usedSetting);
this->handleUserPrivacySettingRules(rawRules);
}
}
void TDLibWrapper::setInitialParameters() void TDLibWrapper::setInitialParameters()
{ {
LOG("Sending initial parameters to TD Lib"); LOG("Sending initial parameters to TD Lib");

View file

@ -89,6 +89,24 @@ public:
}; };
Q_ENUM(SecretChatState) Q_ENUM(SecretChatState)
enum UserPrivacySetting {
SettingAllowChatInvites,
SettingAllowFindingByPhoneNumber,
SettingShowLinkInForwardedMessages,
SettingShowPhoneNumber,
SettingShowProfilePhoto,
SettingShowStatus,
SettingUnknown
};
Q_ENUM(UserPrivacySetting)
enum UserPrivacySettingRule {
RuleAllowAll,
RuleAllowContacts,
RuleRestrictAll
};
Q_ENUM(UserPrivacySettingRule)
class Group { class Group {
public: public:
Group(qlonglong id) : groupId(id) { } Group(qlonglong id) : groupId(id) { }
@ -106,6 +124,7 @@ public:
Q_INVOKABLE QVariantMap getUserInformation(const QString &userId); Q_INVOKABLE QVariantMap getUserInformation(const QString &userId);
Q_INVOKABLE bool hasUserInformation(const QString &userId); Q_INVOKABLE bool hasUserInformation(const QString &userId);
Q_INVOKABLE QVariantMap getUserInformationByName(const QString &userName); Q_INVOKABLE QVariantMap getUserInformationByName(const QString &userName);
Q_INVOKABLE UserPrivacySettingRule getUserPrivacySettingRule(UserPrivacySetting userPrivacySetting);
Q_INVOKABLE QVariantMap getUnreadMessageInformation(); Q_INVOKABLE QVariantMap getUnreadMessageInformation();
Q_INVOKABLE QVariantMap getUnreadChatInformation(); Q_INVOKABLE QVariantMap getUnreadChatInformation();
Q_INVOKABLE QVariantMap getBasicGroup(qlonglong groupId) const; Q_INVOKABLE QVariantMap getBasicGroup(qlonglong groupId) const;
@ -196,6 +215,12 @@ public:
Q_INVOKABLE void cancelDownloadFile(int fileId); Q_INVOKABLE void cancelDownloadFile(int fileId);
Q_INVOKABLE void cancelUploadFile(int fileId); Q_INVOKABLE void cancelUploadFile(int fileId);
Q_INVOKABLE void deleteFile(int fileId); Q_INVOKABLE void deleteFile(int fileId);
Q_INVOKABLE void setName(const QString &firstName, const QString &lastName);
Q_INVOKABLE void setUsername(const QString &userName);
Q_INVOKABLE void setUserPrivacySettingRule(UserPrivacySetting setting, UserPrivacySettingRule rule);
Q_INVOKABLE void getUserPrivacySettingRules(UserPrivacySetting setting);
Q_INVOKABLE void setProfilePhoto(const QString &filePath);
Q_INVOKABLE void deleteProfilePhoto(const QString &profilePhotoId);
// Others (candidates for extraction ;)) // Others (candidates for extraction ;))
Q_INVOKABLE void searchEmoji(const QString &queryString); Q_INVOKABLE void searchEmoji(const QString &queryString);
@ -224,6 +249,7 @@ signals:
void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount); void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount);
void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId); void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId);
void userUpdated(const QString &userId, const QVariantMap &userInformation); void userUpdated(const QString &userId, const QVariantMap &userInformation);
void ownUserUpdated(const QVariantMap &userInformation);
void basicGroupUpdated(qlonglong groupId); void basicGroupUpdated(qlonglong groupId);
void superGroupUpdated(qlonglong groupId); void superGroupUpdated(qlonglong groupId);
void chatOnlineMemberCountUpdated(const QString &chatId, int onlineMemberCount); void chatOnlineMemberCountUpdated(const QString &chatId, int onlineMemberCount);
@ -270,6 +296,8 @@ signals:
void chatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order); void chatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
void inlineQueryResults(const QString &inlineQueryId, const QString &nextOffset, const QVariantList &results, const QString &switchPmText, const QString &switchPmParameter, const QString &extra); void inlineQueryResults(const QString &inlineQueryId, const QString &nextOffset, const QVariantList &results, const QString &switchPmText, const QString &switchPmParameter, const QString &extra);
void callbackQueryAnswer(const QString &text, bool alert, const QString &url); void callbackQueryAnswer(const QString &text, bool alert, const QString &url);
void userPrivacySettingUpdated(UserPrivacySetting setting, UserPrivacySettingRule rule);
void okReceived(const QString &request);
public slots: public slots:
void handleVersionDetected(const QString &version); void handleVersionDetected(const QString &version);
@ -294,6 +322,8 @@ public slots:
void handleErrorReceived(int code, const QString &message, const QString &extra); void handleErrorReceived(int code, const QString &message, const QString &extra);
void handleMessageInformation(qlonglong chatId, qlonglong messageId, const QVariantMap &receivedInformation); void handleMessageInformation(qlonglong chatId, qlonglong messageId, const QVariantMap &receivedInformation);
void handleMessageIsPinnedUpdated(qlonglong chatId, qlonglong messageId, bool isPinned); void handleMessageIsPinnedUpdated(qlonglong chatId, qlonglong messageId, bool isPinned);
void handleUserPrivacySettingRules(const QVariantMap &rules);
void handleUpdatedUserPrivacySettingRules(const QVariantMap &updatedRules);
private: private:
void setOption(const QString &name, const QString &type, const QVariant &value); void setOption(const QString &name, const QString &type, const QVariant &value);
@ -315,6 +345,7 @@ private:
TDLibWrapper::ConnectionState connectionState; TDLibWrapper::ConnectionState connectionState;
QVariantMap options; QVariantMap options;
QVariantMap userInformation; QVariantMap userInformation;
QMap<UserPrivacySetting, UserPrivacySettingRule> userPrivacySettingRules;
QVariantMap allUsers; QVariantMap allUsers;
QVariantMap allUserNames; QVariantMap allUserNames;
QVariantMap chats; QVariantMap chats;

View file

@ -1529,6 +1529,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation>Einige Inline-Bots fragen bei Nutzung Standortdaten an</translation> <translation>Einige Inline-Bots fragen bei Nutzung Standortdaten an</translation>
</message> </message>
<message>
<source>User Profile</source>
<translation>Nutzungsprofil</translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation>Vorname</translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation>Geben Sie 1-64 Zeichen ein</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation>Nachname</translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation>Geben Sie 0-64 Zeichen ein</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation>Benutzername</translation>
</message>
<message>
<source>Allow chat invites</source>
<translation>Chateinladungen erlauben</translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation>Privatsphären-Einstellung zur Regelung, ob Sie zu Chats eingeladen werden können.</translation>
</message>
<message>
<source>Yes</source>
<translation>Ja</translation>
</message>
<message>
<source>Your contacts only</source>
<translation>Nur Ihre Kontakte</translation>
</message>
<message>
<source>No</source>
<translation>Nein</translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation>Auffinden per Telefonnummer erlauben</translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation>Privatsphären-Einstellung zur Regelung, ob Sie per Telefonnummer gefunden werden können.</translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation>Link in weitergeleiteten Nachrichten anzeigen</translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation>Privatsphären-Einstellung zur Regelung, ob ein Link zu Ihrem Profil in weitergeleiteten Nachrichten eingebettet wird.</translation>
</message>
<message>
<source>Show phone number</source>
<translation>Telefonnummer anzeigen</translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation>Privatsphären-Einstellung zur Regelung, ob Ihre Telefonnummer sichtbar ist.</translation>
</message>
<message>
<source>Show profile photo</source>
<translation>Profilfoto anzeigen</translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation>Privatsphären-Einstellung zur Regelung, ob Ihr Profilfoto sichtbar ist.</translation>
</message>
<message>
<source>Show status</source>
<translation>Status anzeigen</translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation>Privatsphären-Einstellung zur Regelung, ob Ihr Onlinestatus sichtbar ist.</translation>
</message>
<message>
<source>Add Picture</source>
<translation>Bild hinzufügen</translation>
</message>
<message>
<source>Profile Pictures</source>
<translation>Profilbilder</translation>
</message>
<message>
<source>Delete Picture</source>
<translation>Bild löschen</translation>
</message>
<message>
<source>Uploading...</source>
<translation>Lade hoch...</translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation>Lösche Profilbild</translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1529,6 +1529,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation>Some inline bots request location data when using them</translation> <translation>Some inline bots request location data when using them</translation>
</message> </message>
<message>
<source>User Profile</source>
<translation>User Profile</translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation>First Name</translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation>Enter 1-64 characters</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation>Last Name</translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation>Enter 0-64 characters</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation>Username</translation>
</message>
<message>
<source>Allow chat invites</source>
<translation>Allow chat invites</translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation>Privacy setting for managing whether you can be invited to chats.</translation>
</message>
<message>
<source>Yes</source>
<translation>Yes</translation>
</message>
<message>
<source>Your contacts only</source>
<translation>Your contacts only</translation>
</message>
<message>
<source>No</source>
<translation>No</translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation>Allow finding by phone number</translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation>Privacy setting for managing whether you can be found by your phone number.</translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation>Show link in forwarded messages</translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation>Privacy setting for managing whether a link to your account is included in forwarded messages.</translation>
</message>
<message>
<source>Show phone number</source>
<translation>Show phone number</translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation>Privacy setting for managing whether your phone number is visible.</translation>
</message>
<message>
<source>Show profile photo</source>
<translation>Show profile photo</translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation>Privacy setting for managing whether your profile photo is visible.</translation>
</message>
<message>
<source>Show status</source>
<translation>Show status</translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation>Privacy setting for managing whether your online status is visible.</translation>
</message>
<message>
<source>Add Picture</source>
<translation>Add Picture</translation>
</message>
<message>
<source>Profile Pictures</source>
<translation>Profile Pictures</translation>
</message>
<message>
<source>Delete Picture</source>
<translation>Delete Picture</translation>
</message>
<message>
<source>Uploading...</source>
<translation>Uploading...</translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation>Deleting profile picture</translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1529,6 +1529,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished">Marcar caracteres 1-128 {1-64 ?}</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished">Marcar caracteres 1-128 {0-64 ?}</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished">Subiendo...</translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1530,6 +1530,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation>Jotkin viestinsyöttöriville upotetut botit pyytävät sijaintitietoja niitä käytettäessä</translation> <translation>Jotkin viestinsyöttöriville upotetut botit pyytävät sijaintitietoja niitä käytettäessä</translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished">Syötä 1-128 merkkiä {1-64 ?}</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished">Syötä 1-128 merkkiä {0-64 ?}</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished">Lähetetään...</translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1504,6 +1504,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1529,6 +1529,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished">Inserisci da 1 a 128 caratteri {1-64 ?}</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished">Inserisci da 1 a 128 caratteri {0-64 ?}</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished">Carica...</translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1554,6 +1554,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished">Wprowadź znaki 1-128 {1-64 ?}</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished">Wprowadź znaki 1-128 {0-64 ?}</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished">Przesyłanie...</translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1554,6 +1554,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation type="unfinished">Некоторые инлайн-боты просят отправить координаты местоположения при обращении к ним</translation> <translation type="unfinished">Некоторые инлайн-боты просят отправить координаты местоположения при обращении к ним</translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished">Введите 1-128 символов {1-64 ?}</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished">Введите 1-128 символов {0-64 ?}</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished">Отправка...</translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>
@ -2033,11 +2140,11 @@
<message> <message>
<source>sent a game</source> <source>sent a game</source>
<comment>myself</comment> <comment>myself</comment>
<translation type="unfinished"></translation> <translation type="unfinished">отправлена игра</translation>
</message> </message>
<message> <message>
<source>sent a game</source> <source>sent a game</source>
<translation type="unfinished"></translation> <translation type="unfinished">отправлена игра</translation>
</message> </message>
</context> </context>
</TS> </TS>

View file

@ -1554,6 +1554,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation>Niektorí inline roboti požadujú údaje o polohe ak ich používajú</translation> <translation>Niektorí inline roboti požadujú údaje o polohe ak ich používajú</translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished">Zadať 1-128 znakov {1-64 ?}</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished">Zadať 1-128 znakov {0-64 ?}</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished">Zapisovanie...</translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1529,6 +1529,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation>Vissa infogade robotar begär platsdata när de används</translation> <translation>Vissa infogade robotar begär platsdata när de används</translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished">Ange 1-128 tecken {1-64 ?}</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished">Ange 1-128 tecken {0-64 ?}</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished">Ladda upp...</translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1504,6 +1504,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation>使</translation> <translation>使</translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished"> 1-128 {1-64 ?}</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished"> 1-128 {0-64 ?}</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>

View file

@ -1529,6 +1529,113 @@
<source>Some inline bots request location data when using them</source> <source>Some inline bots request location data when using them</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>User Profile</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>First Name</source>
<comment>first name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 1-64 characters</source>
<translation type="unfinished">Enter 1-128 characters {1-64 ?}</translation>
</message>
<message>
<source>Last Name</source>
<comment>last name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Enter 0-64 characters</source>
<translation type="unfinished">Enter 1-128 characters {0-64 ?}</translation>
</message>
<message>
<source>Username</source>
<comment>user name of the logged-in profile - header</comment>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow chat invites</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be invited to chats.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Yes</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Your contacts only</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>No</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Allow finding by phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether you can be found by your phone number.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show link in forwarded messages</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether a link to your account is included in forwarded messages.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show phone number</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your phone number is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show profile photo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your profile photo is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Show status</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Privacy setting for managing whether your online status is visible.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Add Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Profile Pictures</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete Picture</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Uploading...</source>
<translation type="unfinished">Uploading...</translation>
</message>
<message>
<source>Deleting profile picture</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>StickerPicker</name> <name>StickerPicker</name>