Merge branch 'master' into logout
This commit is contained in:
commit
756a96e92c
45 changed files with 2701 additions and 685 deletions
|
@ -16,7 +16,7 @@ CONFIG += sailfishapp sailfishapp_i18n
|
||||||
|
|
||||||
PKGCONFIG += nemonotifications-qt5 zlib
|
PKGCONFIG += nemonotifications-qt5 zlib
|
||||||
|
|
||||||
QT += core dbus sql
|
QT += core dbus sql multimedia positioning
|
||||||
|
|
||||||
DEFINES += QT_STATICPLUGIN
|
DEFINES += QT_STATICPLUGIN
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ DISTFILES += qml/harbour-fernschreiber.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 \
|
||||||
|
qml/components/VoiceNoteOverlay.qml \
|
||||||
qml/components/WebPagePreview.qml \
|
qml/components/WebPagePreview.qml \
|
||||||
qml/components/chatInformationPage/ChatInformationEditArea.qml \
|
qml/components/chatInformationPage/ChatInformationEditArea.qml \
|
||||||
qml/components/chatInformationPage/ChatInformationPageContent.qml \
|
qml/components/chatInformationPage/ChatInformationPageContent.qml \
|
||||||
|
|
26
images/icon-s-pin.svg
Normal file
26
images/icon-s-pin.svg
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="enable-background:new 0 0 32 32;"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
height="32px"
|
||||||
|
width="32px"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Layer_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata17"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs15" /><path
|
||||||
|
id="path4567-6-9-2-9-0"
|
||||||
|
d="M 14.774588,14.651001 2.1829034,28.267313 c -1.0611451,1.031581 0.5159425,2.608675 1.5475102,1.547514 L 17.354282,17.224652 a 8.3460333,8.3460333 0 0 1 -1.438704,-1.136457 8.3460333,8.3460333 0 0 1 -1.14099,-1.437194 z"
|
||||||
|
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.99999988;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
|
||||||
|
id="path4569-2-1-7-6-6"
|
||||||
|
d="m 27.72494,4.2773215 a 8.3460333,8.3460333 0 0 1 -2e-6,11.8030745 8.3460333,8.3460333 0 0 1 -11.803072,0 8.3460333,8.3460333 0 0 1 0,-11.8030745 8.3460333,8.3460333 0 0 1 11.803074,0 z"
|
||||||
|
style="opacity:0.6;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" /></svg>
|
After Width: | Height: | Size: 2.6 KiB |
|
@ -444,7 +444,7 @@ Item {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.bottom: positionText.top
|
anchors.bottom: positionText.top
|
||||||
minimumValue: 0
|
minimumValue: 0
|
||||||
maximumValue: messageAudio.duration ? messageAudio.duration : 0
|
maximumValue: messageAudio.duration ? messageAudio.duration : 0.1
|
||||||
stepSize: 1
|
stepSize: 1
|
||||||
value: messageAudio.position
|
value: messageAudio.position
|
||||||
enabled: messageAudio.seekable
|
enabled: messageAudio.seekable
|
||||||
|
|
|
@ -9,13 +9,14 @@ PhotoTextsListItem {
|
||||||
id: listItem
|
id: listItem
|
||||||
pictureThumbnail {
|
pictureThumbnail {
|
||||||
photoData: photo_small || ({})
|
photoData: photo_small || ({})
|
||||||
|
highlighted: listItem.highlighted && !listItem.menuOpen
|
||||||
}
|
}
|
||||||
property int ownUserId
|
property int ownUserId
|
||||||
property bool showDraft: !!draft_message_text && draft_message_date > last_message_date
|
property bool showDraft: !!draft_message_text && draft_message_date > last_message_date
|
||||||
property string previewText: showDraft ? draft_message_text : last_message_text
|
property string previewText: showDraft ? draft_message_text : last_message_text
|
||||||
|
|
||||||
// chat title
|
// chat title
|
||||||
primaryText.text: title ? Emoji.emojify(title + ( display.notification_settings.mute_for > 0 ? " 🔇" : "" ), 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)), primaryText.font.pixelSize) : qsTr("You") ) : "" ))
|
||||||
// last message
|
// last message
|
||||||
|
@ -25,6 +26,8 @@ PhotoTextsListItem {
|
||||||
unreadCount: unread_count
|
unreadCount: unread_count
|
||||||
isSecret: ( chat_type === TelegramAPI.ChatTypeSecret )
|
isSecret: ( chat_type === TelegramAPI.ChatTypeSecret )
|
||||||
isMarkedAsUnread: is_marked_as_unread
|
isMarkedAsUnread: is_marked_as_unread
|
||||||
|
isPinned: is_pinned
|
||||||
|
isMuted: display.notification_settings.mute_for > 0
|
||||||
|
|
||||||
openMenuOnPressAndHold: true//chat_id != overviewPage.ownUserId
|
openMenuOnPressAndHold: true//chat_id != overviewPage.ownUserId
|
||||||
|
|
||||||
|
@ -54,19 +57,18 @@ PhotoTextsListItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
visible: unread_count === 0 && !is_marked_as_unread
|
visible: unread_count === 0
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, true);
|
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, !is_marked_as_unread);
|
||||||
}
|
}
|
||||||
text: qsTr("Mark chat as unread")
|
text: is_marked_as_unread ? qsTr("Mark chat as read") : qsTr("Mark chat as unread")
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
visible: unread_count === 0 && is_marked_as_unread
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, false);
|
tdLibWrapper.toggleChatIsPinned(chat_id, !is_pinned);
|
||||||
}
|
}
|
||||||
text: qsTr("Mark chat as read")
|
text: is_pinned ? qsTr("Unpin chat") : qsTr("Pin chat")
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
|
@ -81,7 +83,7 @@ PhotoTextsListItem {
|
||||||
newNotificationSettings.use_default_mute_for = false;
|
newNotificationSettings.use_default_mute_for = false;
|
||||||
tdLibWrapper.setChatNotificationSettings(chat_id, newNotificationSettings);
|
tdLibWrapper.setChatNotificationSettings(chat_id, newNotificationSettings);
|
||||||
}
|
}
|
||||||
text: display.notification_settings.mute_for > 0 ? qsTr("Unmute Chat") : qsTr("Mute Chat")
|
text: display.notification_settings.mute_for > 0 ? qsTr("Unmute chat") : qsTr("Mute chat")
|
||||||
}
|
}
|
||||||
|
|
||||||
MenuItem {
|
MenuItem {
|
||||||
|
|
|
@ -41,9 +41,9 @@ Item {
|
||||||
if (documentData) {
|
if (documentData) {
|
||||||
if (documentData.document.local.is_downloading_completed) {
|
if (documentData.document.local.is_downloading_completed) {
|
||||||
downloadDocumentButton.visible = false;
|
downloadDocumentButton.visible = false;
|
||||||
openDocumentButton.visible = true;
|
openDocumentArea.visible = true;
|
||||||
} else {
|
} else {
|
||||||
openDocumentButton.visible = false;
|
openDocumentArea.visible = false;
|
||||||
downloadDocumentButton.visible = true;
|
downloadDocumentButton.visible = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ Item {
|
||||||
downloadingProgressBar.visible = false;
|
downloadingProgressBar.visible = false;
|
||||||
documentData.document = fileInformation;
|
documentData.document = fileInformation;
|
||||||
downloadDocumentButton.visible = false;
|
downloadDocumentButton.visible = false;
|
||||||
openDocumentButton.visible = true;
|
openDocumentArea.visible = true;
|
||||||
if (documentPreviewItem.openRequested) {
|
if (documentPreviewItem.openRequested) {
|
||||||
documentPreviewItem.openRequested = false;
|
documentPreviewItem.openRequested = false;
|
||||||
tdLibWrapper.openFileOnDevice(documentData.document.local.path);
|
tdLibWrapper.openFileOnDevice(documentData.document.local.path);
|
||||||
|
@ -95,17 +95,40 @@ Item {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
}
|
}
|
||||||
|
|
||||||
Button {
|
Column {
|
||||||
id: openDocumentButton
|
id: openDocumentArea
|
||||||
preferredWidth: Theme.buttonWidthMedium
|
|
||||||
anchors.centerIn: parent
|
|
||||||
text: qsTr("Open Document")
|
|
||||||
visible: false
|
visible: false
|
||||||
highlighted: documentPreviewItem.highlighted || down
|
spacing: Theme.paddingMedium
|
||||||
onClicked: {
|
width: parent.width
|
||||||
documentPreviewItem.openRequested = true;
|
|
||||||
tdLibWrapper.openFileOnDevice(documentData.document.local.path);
|
onVisibleChanged: {
|
||||||
|
visible ? (documentPreviewItem.height = openDocumentArea.height) : (documentPreviewItem.height = Theme.itemSizeLarge);
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: openDocumentButton
|
||||||
|
preferredWidth: Theme.buttonWidthMedium
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: qsTr("Open Document")
|
||||||
|
highlighted: documentPreviewItem.highlighted || down
|
||||||
|
onClicked: {
|
||||||
|
documentPreviewItem.openRequested = true;
|
||||||
|
tdLibWrapper.openFileOnDevice(documentData.document.local.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: copyDocumentButton
|
||||||
|
preferredWidth: Theme.buttonWidthMedium
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
text: qsTr("Copy Document to Downloads")
|
||||||
|
highlighted: documentPreviewItem.highlighted || down
|
||||||
|
onClicked: {
|
||||||
|
tdLibWrapper.copyFileToDownloads(documentData.document.local.path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@ ListItem {
|
||||||
contentHeight: messageBackground.height + Theme.paddingMedium
|
contentHeight: messageBackground.height + Theme.paddingMedium
|
||||||
property var chatId
|
property var chatId
|
||||||
property var messageId
|
property var messageId
|
||||||
|
property int messageIndex
|
||||||
property var myMessage
|
property var myMessage
|
||||||
property bool canReplyToMessage
|
property bool canReplyToMessage
|
||||||
readonly property bool isAnonymous: myMessage.sender["@type"] === "messageSenderChat"
|
readonly property bool isAnonymous: myMessage.sender["@type"] === "messageSenderChat"
|
||||||
|
@ -159,13 +160,6 @@ ListItem {
|
||||||
Debug.log("[ChatModel] Messages in this chat were read, new last read: ", lastReadSentIndex, ", updating description for index ", index, ", status: ", (index <= lastReadSentIndex));
|
Debug.log("[ChatModel] Messages in this chat were read, new last read: ", lastReadSentIndex, ", updating description for index ", index, ", status: ", (index <= lastReadSentIndex));
|
||||||
messageDateText.text = getMessageStatusText(myMessage, index, lastReadSentIndex, messageDateText.useElapsed);
|
messageDateText.text = getMessageStatusText(myMessage, index, lastReadSentIndex, messageDateText.useElapsed);
|
||||||
}
|
}
|
||||||
onMessageUpdated: {
|
|
||||||
if (index === modelIndex) {
|
|
||||||
Debug.log("[ChatModel] This message was updated, index ", index, ", updating content...");
|
|
||||||
messageDateText.text = getMessageStatusText(myMessage, index, chatView.lastReadSentIndex, messageDateText.useElapsed);
|
|
||||||
messageText.text = Emoji.emojify(Functions.getMessageText(myMessage, false, page.myUserId, false), messageText.font.pixelSize);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
|
@ -190,6 +184,15 @@ ListItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMyMessageChanged: {
|
||||||
|
Debug.log("[ChatModel] This message was updated, index", messageIndex, ", updating content...")
|
||||||
|
messageDateText.text = getMessageStatusText(myMessage, messageIndex, chatView.lastReadSentIndex, messageDateText.useElapsed)
|
||||||
|
messageText.text = Emoji.emojify(Functions.getMessageText(myMessage, false, page.myUserId, false), messageText.font.pixelSize)
|
||||||
|
if (webPagePreviewLoader.item) {
|
||||||
|
webPagePreviewLoader.item.webPageData = myMessage.content.web_page
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: delegateComponentLoadingTimer
|
id: delegateComponentLoadingTimer
|
||||||
interval: 500
|
interval: 500
|
||||||
|
|
|
@ -14,6 +14,8 @@ ListItem {
|
||||||
property bool isSecret: false
|
property bool isSecret: false
|
||||||
property bool isVerified: false
|
property bool isVerified: false
|
||||||
property bool isMarkedAsUnread: false
|
property bool isMarkedAsUnread: false
|
||||||
|
property bool isPinned: false
|
||||||
|
property bool isMuted: false
|
||||||
property alias pictureThumbnail: pictureThumbnail
|
property alias pictureThumbnail: pictureThumbnail
|
||||||
|
|
||||||
contentHeight: mainRow.height + separator.height + 2 * Theme.paddingMedium
|
contentHeight: mainRow.height + separator.height + 2 * Theme.paddingMedium
|
||||||
|
@ -33,15 +35,14 @@ ListItem {
|
||||||
height: contentColumn.height
|
height: contentColumn.height
|
||||||
spacing: Theme.paddingMedium
|
spacing: Theme.paddingMedium
|
||||||
|
|
||||||
Column {
|
ShaderEffectSource {
|
||||||
id: pictureColumn
|
id: pictureItem
|
||||||
width: contentColumn.height - Theme.paddingSmall
|
width: contentColumn.height - Theme.paddingSmall
|
||||||
height: contentColumn.height - Theme.paddingSmall
|
height: contentColumn.height - Theme.paddingSmall
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
sourceItem: Item {
|
||||||
Item {
|
width: pictureItem.width
|
||||||
width: parent.width
|
height: pictureItem.width
|
||||||
height: parent.width
|
|
||||||
|
|
||||||
ProfileThumbnail {
|
ProfileThumbnail {
|
||||||
id: pictureThumbnail
|
id: pictureThumbnail
|
||||||
|
@ -50,11 +51,30 @@ ListItem {
|
||||||
height: parent.width
|
height: parent.width
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: chatPinnedBackground
|
||||||
|
color: Theme.highlightBackgroundColor
|
||||||
|
width: Theme.fontSizeLarge
|
||||||
|
height: Theme.fontSizeLarge
|
||||||
|
anchors.top: parent.top
|
||||||
|
radius: parent.width / 2
|
||||||
|
visible: chatListViewItem.isPinned
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
source: "../../images/icon-s-pin.svg"
|
||||||
|
height: Theme.fontSizeSmall
|
||||||
|
width: Theme.fontSizeSmall
|
||||||
|
sourceSize: Qt.size(Theme.iconSizeSmall, Theme.iconSizeSmall)
|
||||||
|
anchors.centerIn: chatPinnedBackground
|
||||||
|
visible: chatListViewItem.isPinned
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: chatSecretBackground
|
id: chatSecretBackground
|
||||||
color: Theme.overlayBackgroundColor
|
color: Theme.highlightBackgroundColor
|
||||||
width: Theme.fontSizeExtraLarge
|
width: Theme.fontSizeLarge
|
||||||
height: Theme.fontSizeExtraLarge
|
height: Theme.fontSizeLarge
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
radius: parent.width / 2
|
radius: parent.width / 2
|
||||||
visible: chatListViewItem.isSecret
|
visible: chatListViewItem.isSecret
|
||||||
|
@ -62,8 +82,8 @@ ListItem {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
source: "image://theme/icon-s-secure"
|
source: "image://theme/icon-s-secure"
|
||||||
height: Theme.fontSizeMedium
|
height: Theme.fontSizeSmall
|
||||||
width: Theme.fontSizeMedium
|
width: Theme.fontSizeSmall
|
||||||
anchors.centerIn: chatSecretBackground
|
anchors.centerIn: chatSecretBackground
|
||||||
visible: chatListViewItem.isSecret
|
visible: chatListViewItem.isSecret
|
||||||
}
|
}
|
||||||
|
@ -93,7 +113,7 @@ ListItem {
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: contentColumn
|
id: contentColumn
|
||||||
width: mainColumn.width - pictureColumn.width - mainRow.spacing
|
width: mainColumn.width - pictureItem.width - mainRow.spacing
|
||||||
spacing: Theme.paddingSmall
|
spacing: Theme.paddingSmall
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
|
@ -106,15 +126,26 @@ ListItem {
|
||||||
font.pixelSize: Theme.fontSizeMedium
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
width: Math.min(contentColumn.width - (verifiedImage.visible ? (verifiedImage.width + primaryTextRow.spacing) : 0), implicitWidth)
|
width: Math.min(contentColumn.width - (verifiedImage.visible ? (verifiedImage.width + primaryTextRow.spacing) : 0) - (mutedImage.visible ? (mutedImage.width + primaryTextRow.spacing) : 0), implicitWidth)
|
||||||
}
|
}
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: verifiedImage
|
id: verifiedImage
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
source: chatListViewItem.isVerified ? "../../images/icon-verified.svg" : ""
|
source: chatListViewItem.isVerified ? "../../images/icon-verified.svg" : ""
|
||||||
sourceSize.width: Theme.iconSizeExtraSmall
|
sourceSize: Qt.size(Theme.iconSizeExtraSmall, Theme.iconSizeExtraSmall)
|
||||||
width: Theme.iconSizeExtraSmall
|
width: Theme.iconSizeSmall
|
||||||
|
height: Theme.iconSizeSmall
|
||||||
|
visible: status === Image.Ready
|
||||||
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
id: mutedImage
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
source: chatListViewItem.isMuted ? "../js/emoji/1f507.svg" : ""
|
||||||
|
sourceSize: Qt.size(Theme.iconSizeExtraSmall, Theme.iconSizeExtraSmall)
|
||||||
|
width: Theme.iconSizeSmall
|
||||||
|
height: Theme.iconSizeSmall
|
||||||
visible: status === Image.Ready
|
visible: status === Image.Ready
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,6 @@ import Sailfish.Silica 1.0
|
||||||
import WerkWolf.Fernschreiber 1.0
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
||||||
id: profileThumbnail
|
id: profileThumbnail
|
||||||
|
|
||||||
property alias photoData: file.fileInformation
|
property alias photoData: file.fileInformation
|
||||||
|
@ -30,6 +29,10 @@ Item {
|
||||||
property int radius: width / 2
|
property int radius: width / 2
|
||||||
property int imageStatus: -1
|
property int imageStatus: -1
|
||||||
property bool optimizeImageSize: true
|
property bool optimizeImageSize: true
|
||||||
|
property bool highlighted
|
||||||
|
|
||||||
|
layer.enabled: highlighted
|
||||||
|
layer.effect: PressEffect { source: profileThumbnail }
|
||||||
|
|
||||||
function getReplacementString() {
|
function getReplacementString() {
|
||||||
if (replacementStringHint.length > 2) {
|
if (replacementStringHint.length > 2) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ Item {
|
||||||
|
|
||||||
property ListItem messageListItem
|
property ListItem messageListItem
|
||||||
property MessageOverlayFlickable overlayFlickable
|
property MessageOverlayFlickable overlayFlickable
|
||||||
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
|
property var rawMessage: messageListItem ? messageListItem.myMessage : ( overlayFlickable ? overlayFlickable.overlayMessage : undefined )
|
||||||
|
|
||||||
property var videoData: ( rawMessage.content['@type'] === "messageVideo" ) ? rawMessage.content.video : ( ( rawMessage.content['@type'] === "messageAnimation" ) ? rawMessage.content.animation : rawMessage.content.video_note )
|
property var videoData: ( rawMessage.content['@type'] === "messageVideo" ) ? rawMessage.content.video : ( ( rawMessage.content['@type'] === "messageAnimation" ) ? rawMessage.content.animation : rawMessage.content.video_note )
|
||||||
property string videoUrl;
|
property string videoUrl;
|
||||||
|
@ -89,7 +89,7 @@ Item {
|
||||||
|
|
||||||
videoMessageComponent.videoType = videoMessageComponent.isVideoNote ? "video" : videoData['@type'];
|
videoMessageComponent.videoType = videoMessageComponent.isVideoNote ? "video" : videoData['@type'];
|
||||||
videoFileId = videoData[videoType].id;
|
videoFileId = videoData[videoType].id;
|
||||||
if (rawMessage.content['@type'] === "messageAnimation") {
|
if (typeof rawMessage !== "undefined" && rawMessage.content['@type'] === "messageAnimation") {
|
||||||
playButton.visible = true;
|
playButton.visible = true;
|
||||||
fullscreenButton.visible = !videoMessageComponent.fullscreen;
|
fullscreenButton.visible = !videoMessageComponent.fullscreen;
|
||||||
handlePlay();
|
handlePlay();
|
||||||
|
@ -294,21 +294,6 @@ Item {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
target: videoMessageComponent
|
|
||||||
onClicked: {
|
|
||||||
if (messageVideo.playbackState === MediaPlayer.PlayingState) {
|
|
||||||
enableScreensaver();
|
|
||||||
messageVideo.pause();
|
|
||||||
timeLeftItem.visible = true;
|
|
||||||
} else {
|
|
||||||
disableScreensaver();
|
|
||||||
messageVideo.play();
|
|
||||||
timeLeftTimer.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Video {
|
Video {
|
||||||
id: messageVideo
|
id: messageVideo
|
||||||
|
|
||||||
|
@ -367,7 +352,7 @@ Item {
|
||||||
height: parent.height
|
height: parent.height
|
||||||
source: videoUrl
|
source: videoUrl
|
||||||
layer.enabled: videoMessageComponent.highlighted
|
layer.enabled: videoMessageComponent.highlighted
|
||||||
layer.effect: PressEffect { source: singleImage }
|
layer.effect: PressEffect { source: messageVideo }
|
||||||
onStopped: {
|
onStopped: {
|
||||||
enableScreensaver();
|
enableScreensaver();
|
||||||
messageVideo.visible = false;
|
messageVideo.visible = false;
|
||||||
|
@ -376,6 +361,21 @@ Item {
|
||||||
videoComponentLoader.active = false;
|
videoComponentLoader.active = false;
|
||||||
fullscreenItem.visible = !videoMessageComponent.fullscreen;
|
fullscreenItem.visible = !videoMessageComponent.fullscreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
if (messageVideo.playbackState === MediaPlayer.PlayingState) {
|
||||||
|
enableScreensaver();
|
||||||
|
messageVideo.pause();
|
||||||
|
timeLeftItem.visible = true;
|
||||||
|
} else {
|
||||||
|
disableScreensaver();
|
||||||
|
messageVideo.play();
|
||||||
|
timeLeftTimer.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
|
@ -482,7 +482,7 @@ Item {
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
anchors.bottom: positionText.top
|
anchors.bottom: positionText.top
|
||||||
minimumValue: 0
|
minimumValue: 0
|
||||||
maximumValue: messageVideo.duration ? messageVideo.duration : 0
|
maximumValue: messageVideo.duration ? messageVideo.duration : 0.1
|
||||||
|
|
||||||
highlighted: videoMessageComponent.highlighted || down
|
highlighted: videoMessageComponent.highlighted || down
|
||||||
stepSize: 1
|
stepSize: 1
|
||||||
|
@ -514,7 +514,6 @@ Item {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
222
qml/components/VoiceNoteOverlay.qml
Normal file
222
qml/components/VoiceNoteOverlay.qml
Normal file
|
@ -0,0 +1,222 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import WerkWolf.Fernschreiber 1.0
|
||||||
|
import "../components"
|
||||||
|
import "../js/twemoji.js" as Emoji
|
||||||
|
import "../js/debug.js" as Debug
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: voiceNoteOverlayItem
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
property int recordingState: fernschreiberUtils.getVoiceNoteRecordingState();
|
||||||
|
property int recordingDuration: 0;
|
||||||
|
property bool recordingDone: false;
|
||||||
|
|
||||||
|
function handleRecordingState() {
|
||||||
|
switch (recordingState) {
|
||||||
|
case FernschreiberUtilities.Unavailable:
|
||||||
|
recordingStateLabel.text = qsTr("Unavailable");
|
||||||
|
break;
|
||||||
|
case FernschreiberUtilities.Ready:
|
||||||
|
recordingStateLabel.text = qsTr("Ready");
|
||||||
|
break;
|
||||||
|
case FernschreiberUtilities.Starting:
|
||||||
|
recordingStateLabel.text = qsTr("Starting");
|
||||||
|
break;
|
||||||
|
case FernschreiberUtilities.Recording:
|
||||||
|
recordingStateLabel.text = qsTr("Recording");
|
||||||
|
break;
|
||||||
|
case FernschreiberUtilities.Stopping:
|
||||||
|
recordingStateLabel.text = qsTr("Stopping");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTwoDigitString(numberToBeConverted) {
|
||||||
|
var numberString = "00";
|
||||||
|
if (numberToBeConverted > 0 && numberToBeConverted < 10) {
|
||||||
|
numberString = "0" + String(numberToBeConverted);
|
||||||
|
}
|
||||||
|
if (numberToBeConverted >= 10) {
|
||||||
|
numberString = String(numberToBeConverted);
|
||||||
|
}
|
||||||
|
return numberString;
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleRecordingDuration() {
|
||||||
|
var minutes = Math.floor(recordingDuration / 60);
|
||||||
|
var seconds = recordingDuration % 60;
|
||||||
|
recordingDurationLabel.text = getTwoDigitString(minutes) + ":" + getTwoDigitString(seconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
handleRecordingState();
|
||||||
|
handleRecordingDuration();
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: fernschreiberUtils
|
||||||
|
onVoiceNoteDurationChanged: {
|
||||||
|
Debug.log("New duration received: " + duration);
|
||||||
|
recordingDuration = Math.round(duration / 1000);
|
||||||
|
handleRecordingDuration();
|
||||||
|
}
|
||||||
|
onVoiceNoteRecordingStateChanged: {
|
||||||
|
Debug.log("New state received: " + state);
|
||||||
|
recordingState = state;
|
||||||
|
handleRecordingState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: stickerPickerOverlayBackground
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
color: Theme.overlayBackgroundColor
|
||||||
|
opacity: Theme.opacityHigh
|
||||||
|
}
|
||||||
|
|
||||||
|
Flickable {
|
||||||
|
id: voiceNoteFlickable
|
||||||
|
anchors.fill: parent
|
||||||
|
anchors.margins: Theme.paddingMedium
|
||||||
|
|
||||||
|
Behavior on opacity { NumberAnimation {} }
|
||||||
|
|
||||||
|
contentHeight: voiceNoteColumn.height
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: voiceNoteColumn
|
||||||
|
spacing: Theme.paddingMedium
|
||||||
|
width: voiceNoteFlickable.width
|
||||||
|
|
||||||
|
InfoLabel {
|
||||||
|
text: qsTr("Record a Voice Note")
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
text: qsTr("Press the button to start recording")
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
width: Theme.iconSizeExtraLarge
|
||||||
|
height: Theme.iconSizeExtraLarge
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
color: Theme.primaryColor
|
||||||
|
opacity: Theme.opacityOverlay
|
||||||
|
width: Theme.iconSizeExtraLarge
|
||||||
|
height: Theme.iconSizeExtraLarge
|
||||||
|
anchors.centerIn: parent
|
||||||
|
radius: width / 2
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: recordButton
|
||||||
|
color: "red"
|
||||||
|
width: Theme.iconSizeExtraLarge * 0.6
|
||||||
|
height: Theme.iconSizeExtraLarge * 0.6
|
||||||
|
anchors.centerIn: parent
|
||||||
|
radius: width / 2
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
recordButton.visible = false;
|
||||||
|
recordingDone = false;
|
||||||
|
recordingDuration = 0;
|
||||||
|
handleRecordingDuration();
|
||||||
|
fernschreiberUtils.startRecordingVoiceNote();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: stopButton
|
||||||
|
visible: !recordButton.visible
|
||||||
|
color: Theme.overlayBackgroundColor
|
||||||
|
width: Theme.iconSizeExtraLarge * 0.4
|
||||||
|
height: Theme.iconSizeExtraLarge * 0.4
|
||||||
|
anchors.centerIn: parent
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
recordButton.visible = true;
|
||||||
|
fernschreiberUtils.stopRecordingVoiceNote();
|
||||||
|
recordingDone = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: recordingStateLabel
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: recordingDurationLabel
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
font.pixelSize: Theme.fontSizeMedium
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
visible: recordingDone
|
||||||
|
anchors {
|
||||||
|
horizontalCenter: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
text: qsTr("Use recording")
|
||||||
|
onClicked: {
|
||||||
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
|
attachmentPreviewRow.isVoiceNote = true;
|
||||||
|
attachmentPreviewRow.attachmentDescription = qsTr("Voice Note (%1)").arg(recordingDurationLabel.text);
|
||||||
|
attachmentPreviewRow.visible = true;
|
||||||
|
controlSendButton();
|
||||||
|
voiceNoteOverlayLoader.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -33,7 +33,11 @@ Column {
|
||||||
|
|
||||||
spacing: Theme.paddingSmall
|
spacing: Theme.paddingSmall
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: updatePhoto()
|
||||||
|
|
||||||
|
onWebPageDataChanged: updatePhoto()
|
||||||
|
|
||||||
|
function updatePhoto() {
|
||||||
if (webPageData) {
|
if (webPageData) {
|
||||||
if (webPageData.photo) {
|
if (webPageData.photo) {
|
||||||
// Check first which size fits best...
|
// Check first which size fits best...
|
||||||
|
@ -134,9 +138,10 @@ Column {
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundImage {
|
BackgroundImage {
|
||||||
|
id: backgroundImage
|
||||||
visible: hasImage && singleImage.status !== Image.Ready
|
visible: hasImage && singleImage.status !== Image.Ready
|
||||||
layer.enabled: webPagePreviewColumn.highlighted
|
layer.enabled: webPagePreviewColumn.highlighted
|
||||||
layer.effect: PressEffect { source: singleImage }
|
layer.effect: PressEffect { source: backgroundImage }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,7 @@ Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
Label {
|
Label {
|
||||||
text: "Fernschreiber 0.6"
|
text: "Fernschreiber 0.7"
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
font.pixelSize: Theme.fontSizeExtraLarge
|
font.pixelSize: Theme.fontSizeExtraLarge
|
||||||
anchors {
|
anchors {
|
||||||
|
@ -178,7 +178,7 @@ Page {
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileThumbnail {
|
ProfileThumbnail {
|
||||||
photoData: aboutPage.userInformation.profile_photo.small
|
photoData: ((typeof aboutPage.userInformation.profile_photo !== "undefined") ? aboutPage.userInformation.profile_photo.small : {})
|
||||||
width: Theme.itemSizeExtraLarge
|
width: Theme.itemSizeExtraLarge
|
||||||
height: Theme.itemSizeExtraLarge
|
height: Theme.itemSizeExtraLarge
|
||||||
replacementStringHint: aboutPage.userInformation.first_name + " " + aboutPage.userInformation.last_name
|
replacementStringHint: aboutPage.userInformation.first_name + " " + aboutPage.userInformation.last_name
|
||||||
|
|
|
@ -211,14 +211,21 @@ Page {
|
||||||
attachmentPreviewRow.isPicture = false;
|
attachmentPreviewRow.isPicture = false;
|
||||||
attachmentPreviewRow.isVideo = false;
|
attachmentPreviewRow.isVideo = false;
|
||||||
attachmentPreviewRow.isDocument = false;
|
attachmentPreviewRow.isDocument = false;
|
||||||
|
attachmentPreviewRow.isVoiceNote = false;
|
||||||
|
attachmentPreviewRow.isLocation = false;
|
||||||
attachmentPreviewRow.fileProperties = {};
|
attachmentPreviewRow.fileProperties = {};
|
||||||
|
attachmentPreviewRow.locationData = {};
|
||||||
|
attachmentPreviewRow.attachmentDescription = "";
|
||||||
|
fernschreiberUtils.stopGeoLocationUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
function controlSendButton() {
|
function controlSendButton() {
|
||||||
if (newMessageTextField.text.length !== 0
|
if (newMessageTextField.text.length !== 0
|
||||||
|| attachmentPreviewRow.isPicture
|
|| attachmentPreviewRow.isPicture
|
||||||
|| attachmentPreviewRow.isDocument
|
|| attachmentPreviewRow.isDocument
|
||||||
|| attachmentPreviewRow.isVideo) {
|
|| attachmentPreviewRow.isVideo
|
||||||
|
|| attachmentPreviewRow.isVoiceNote
|
||||||
|
|| attachmentPreviewRow.isLocation) {
|
||||||
newMessageSendButton.enabled = true;
|
newMessageSendButton.enabled = true;
|
||||||
} else {
|
} else {
|
||||||
newMessageSendButton.enabled = false;
|
newMessageSendButton.enabled = false;
|
||||||
|
@ -239,14 +246,25 @@ Page {
|
||||||
if (attachmentPreviewRow.isDocument) {
|
if (attachmentPreviewRow.isDocument) {
|
||||||
tdLibWrapper.sendDocumentMessage(chatInformation.id, attachmentPreviewRow.fileProperties.filePath, newMessageTextField.text, newMessageColumn.replyToMessageId);
|
tdLibWrapper.sendDocumentMessage(chatInformation.id, attachmentPreviewRow.fileProperties.filePath, newMessageTextField.text, newMessageColumn.replyToMessageId);
|
||||||
}
|
}
|
||||||
|
if (attachmentPreviewRow.isVoiceNote) {
|
||||||
|
tdLibWrapper.sendVoiceNoteMessage(chatInformation.id, fernschreiberUtils.voiceNotePath(), newMessageTextField.text, newMessageColumn.replyToMessageId);
|
||||||
|
}
|
||||||
|
if (attachmentPreviewRow.isLocation) {
|
||||||
|
tdLibWrapper.sendLocationMessage(chatInformation.id, attachmentPreviewRow.locationData.latitude, attachmentPreviewRow.locationData.longitude, attachmentPreviewRow.locationData.horizontalAccuracy, newMessageColumn.replyToMessageId);
|
||||||
|
}
|
||||||
clearAttachmentPreviewRow();
|
clearAttachmentPreviewRow();
|
||||||
} else {
|
} else {
|
||||||
tdLibWrapper.sendTextMessage(chatInformation.id, newMessageTextField.text, newMessageColumn.replyToMessageId);
|
tdLibWrapper.sendTextMessage(chatInformation.id, newMessageTextField.text, newMessageColumn.replyToMessageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(appSettings.focusTextAreaAfterSend) {
|
||||||
|
lostFocusTimer.start();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
controlSendButton();
|
controlSendButton();
|
||||||
newMessageInReplyToRow.inReplyToMessage = null;
|
newMessageInReplyToRow.inReplyToMessage = null;
|
||||||
newMessageColumn.editMessageId = "0";
|
newMessageColumn.editMessageId = "0";
|
||||||
|
fernschreiberUtils.stopGeoLocationUpdates();
|
||||||
}
|
}
|
||||||
|
|
||||||
function getWordBoundaries(text, cursorPosition) {
|
function getWordBoundaries(text, cursorPosition) {
|
||||||
|
@ -376,6 +394,7 @@ Page {
|
||||||
if (chatPage.canSendMessages) {
|
if (chatPage.canSendMessages) {
|
||||||
tdLibWrapper.setChatDraftMessage(chatInformation.id, 0, newMessageColumn.replyToMessageId, newMessageTextField.text);
|
tdLibWrapper.setChatDraftMessage(chatInformation.id, 0, newMessageColumn.replyToMessageId, newMessageTextField.text);
|
||||||
}
|
}
|
||||||
|
fernschreiberUtils.stopGeoLocationUpdates();
|
||||||
tdLibWrapper.closeChat(chatInformation.id);
|
tdLibWrapper.closeChat(chatInformation.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,7 +474,7 @@ Page {
|
||||||
Debug.log("[ChatPage] Received pinned message");
|
Debug.log("[ChatPage] Received pinned message");
|
||||||
pinnedMessageItem.pinnedMessage = message;
|
pinnedMessageItem.pinnedMessage = message;
|
||||||
}
|
}
|
||||||
if (messageId === chatInformation.draft_message.reply_to_message_id) {
|
if (chatInformation.draft_message && messageId === chatInformation.draft_message.reply_to_message_id) {
|
||||||
newMessageInReplyToRow.inReplyToMessage = message;
|
newMessageInReplyToRow.inReplyToMessage = message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -623,7 +642,7 @@ Page {
|
||||||
contentWidth: width
|
contentWidth: width
|
||||||
|
|
||||||
PullDownMenu {
|
PullDownMenu {
|
||||||
visible: chatInformation.id !== chatPage.myUserId && !stickerPickerLoader.active && !messageOverlayLoader.active
|
visible: chatInformation.id !== chatPage.myUserId && !stickerPickerLoader.active && !voiceNoteOverlayLoader.active && !messageOverlayLoader.active
|
||||||
MenuItem {
|
MenuItem {
|
||||||
id: closeSecretChatMenuItem
|
id: closeSecretChatMenuItem
|
||||||
visible: chatPage.isSecretChat && chatPage.secretChatDetails.state["@type"] !== "secretChatStateClosed"
|
visible: chatPage.isSecretChat && chatPage.secretChatDetails.state["@type"] !== "secretChatStateClosed"
|
||||||
|
@ -730,7 +749,7 @@ Page {
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: chatSecretBackground
|
id: chatSecretBackground
|
||||||
color: Theme.overlayBackgroundColor
|
color: Theme.highlightBackgroundColor
|
||||||
width: chatPage.isPortrait ? Theme.fontSizeLarge : Theme.fontSizeMedium
|
width: chatPage.isPortrait ? Theme.fontSizeLarge : Theme.fontSizeMedium
|
||||||
height: width
|
height: width
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
@ -876,7 +895,7 @@ Page {
|
||||||
id: chatView
|
id: chatView
|
||||||
|
|
||||||
visible: !blurred
|
visible: !blurred
|
||||||
property bool blurred: messageOverlayLoader.item
|
property bool blurred: messageOverlayLoader.item || stickerPickerLoader.item || voiceNoteOverlayLoader.item
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
opacity: chatPage.loading ? 0 : 1
|
opacity: chatPage.loading ? 0 : 1
|
||||||
|
@ -1010,6 +1029,7 @@ Page {
|
||||||
chatId: chatModel.chatId
|
chatId: chatModel.chatId
|
||||||
myMessage: model.display
|
myMessage: model.display
|
||||||
messageId: model.message_id
|
messageId: model.message_id
|
||||||
|
messageIndex: model.index
|
||||||
extraContentComponentName: chatView.contentComponentNames[model.content_type] || ""
|
extraContentComponentName: chatView.contentComponentNames[model.content_type] || ""
|
||||||
canReplyToMessage: chatPage.canSendMessages
|
canReplyToMessage: chatPage.canSendMessages
|
||||||
onReplyToMessage: {
|
onReplyToMessage: {
|
||||||
|
@ -1110,7 +1130,7 @@ Page {
|
||||||
Debug.log("Sticker picked: " + stickerId);
|
Debug.log("Sticker picked: " + stickerId);
|
||||||
tdLibWrapper.sendStickerMessage(chatInformation.id, stickerId);
|
tdLibWrapper.sendStickerMessage(chatInformation.id, stickerId);
|
||||||
stickerPickerLoader.active = false;
|
stickerPickerLoader.active = false;
|
||||||
attachmentOptionsRow.isNeeded = false;
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1134,6 +1154,20 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: voiceNoteOverlayLoader
|
||||||
|
active: false
|
||||||
|
asynchronous: true
|
||||||
|
width: parent.width
|
||||||
|
height: active ? parent.height : 0
|
||||||
|
source: "../components/VoiceNoteOverlay.qml"
|
||||||
|
onActiveChanged: {
|
||||||
|
if (!active) {
|
||||||
|
fernschreiberUtils.stopRecordingVoiceNote();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
@ -1141,7 +1175,6 @@ Page {
|
||||||
spacing: Theme.paddingSmall
|
spacing: Theme.paddingSmall
|
||||||
topPadding: Theme.paddingSmall
|
topPadding: Theme.paddingSmall
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
clip: true
|
|
||||||
visible: height > 0
|
visible: height > 0
|
||||||
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
width: parent.width - ( 2 * Theme.horizontalPageMargin )
|
||||||
height: isNeeded ? implicitHeight : 0
|
height: isNeeded ? implicitHeight : 0
|
||||||
|
@ -1173,90 +1206,146 @@ Page {
|
||||||
visible: false
|
visible: false
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
Flickable {
|
||||||
id: attachmentOptionsRow
|
id: attachmentOptionsFlickable
|
||||||
|
|
||||||
property bool isNeeded: false
|
property bool isNeeded: false
|
||||||
visible: height > 0
|
width: chatPage.width
|
||||||
height: isNeeded ? implicitHeight : 0
|
x: -Theme.horizontalPageMargin
|
||||||
anchors.right: parent.right
|
height: isNeeded ? attachmentOptionsRow.height : 0
|
||||||
width: parent.width
|
|
||||||
layoutDirection: Qt.RightToLeft
|
|
||||||
spacing: Theme.paddingMedium
|
|
||||||
clip: true
|
|
||||||
Behavior on height { SmoothedAnimation { duration: 200 } }
|
Behavior on height { SmoothedAnimation { duration: 200 } }
|
||||||
IconButton {
|
visible: height > 0
|
||||||
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
contentHeight: attachmentOptionsRow.height
|
||||||
icon.source: "image://theme/icon-m-image"
|
contentWidth: Math.max(width, attachmentOptionsRow.width)
|
||||||
onClicked: {
|
property bool fadeRight: (attachmentOptionsRow.width-contentX) > width
|
||||||
var picker = pageStack.push("Sailfish.Pickers.ImagePickerPage", {
|
property bool fadeLeft: !fadeRight && contentX > 0
|
||||||
allowedOrientations: chatPage.allowedOrientations
|
layer.enabled: fadeRight || fadeLeft
|
||||||
})
|
layer.effect: OpacityRampEffectBase {
|
||||||
picker.selectedContentPropertiesChanged.connect(function(){
|
direction: attachmentOptionsFlickable.fadeRight ? OpacityRamp.LeftToRight : OpacityRamp.RightToLeft
|
||||||
attachmentOptionsRow.isNeeded = false;
|
source: attachmentOptionsFlickable
|
||||||
Debug.log("Selected document: ", picker.selectedContentProperties.filePath );
|
slope: 1 + 6 * (chatPage.width) / Screen.width
|
||||||
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
offset: 1 - 1 / slope
|
||||||
attachmentPreviewRow.isPicture = true;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Row {
|
||||||
|
id: attachmentOptionsRow
|
||||||
|
|
||||||
|
height: attachImageIconButton.height
|
||||||
|
|
||||||
|
anchors.right: parent.right
|
||||||
|
layoutDirection: Qt.RightToLeft
|
||||||
|
spacing: Theme.paddingMedium
|
||||||
|
leftPadding: Theme.horizontalPageMargin
|
||||||
|
rightPadding: Theme.horizontalPageMargin
|
||||||
|
|
||||||
|
IconButton {
|
||||||
|
id: attachImageIconButton
|
||||||
|
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
||||||
|
icon.source: "image://theme/icon-m-image"
|
||||||
|
onClicked: {
|
||||||
|
var picker = pageStack.push("Sailfish.Pickers.ImagePickerPage", {
|
||||||
|
allowedOrientations: chatPage.allowedOrientations
|
||||||
|
})
|
||||||
|
picker.selectedContentPropertiesChanged.connect(function(){
|
||||||
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
|
Debug.log("Selected document: ", picker.selectedContentProperties.filePath );
|
||||||
|
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
||||||
|
attachmentPreviewRow.isPicture = true;
|
||||||
|
attachmentPreviewRow.visible = true;
|
||||||
|
controlSendButton();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton {
|
||||||
|
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
||||||
|
icon.source: "image://theme/icon-m-video"
|
||||||
|
onClicked: {
|
||||||
|
var picker = pageStack.push("Sailfish.Pickers.VideoPickerPage", {
|
||||||
|
allowedOrientations: chatPage.allowedOrientations
|
||||||
|
})
|
||||||
|
picker.selectedContentPropertiesChanged.connect(function(){
|
||||||
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
|
Debug.log("Selected video: ", picker.selectedContentProperties.filePath );
|
||||||
|
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
||||||
|
attachmentPreviewRow.isVideo = true;
|
||||||
|
attachmentPreviewRow.visible = true;
|
||||||
|
controlSendButton();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton {
|
||||||
|
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
||||||
|
icon.source: "image://theme/icon-m-mic"
|
||||||
|
icon.sourceSize {
|
||||||
|
width: Theme.iconSizeMedium
|
||||||
|
height: Theme.iconSizeMedium
|
||||||
|
}
|
||||||
|
highlighted: down || voiceNoteOverlayLoader.active
|
||||||
|
onClicked: {
|
||||||
|
voiceNoteOverlayLoader.active = !voiceNoteOverlayLoader.active;
|
||||||
|
stickerPickerLoader.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton {
|
||||||
|
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
||||||
|
icon.source: "image://theme/icon-m-document"
|
||||||
|
onClicked: {
|
||||||
|
var picker = pageStack.push("Sailfish.Pickers.FilePickerPage", {
|
||||||
|
allowedOrientations: chatPage.allowedOrientations
|
||||||
|
})
|
||||||
|
picker.selectedContentPropertiesChanged.connect(function(){
|
||||||
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
|
Debug.log("Selected document: ", picker.selectedContentProperties.filePath );
|
||||||
|
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
||||||
|
attachmentPreviewRow.isDocument = true;
|
||||||
|
attachmentPreviewRow.visible = true;
|
||||||
|
controlSendButton();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton {
|
||||||
|
visible: chatPage.hasSendPrivilege("can_send_other_messages")
|
||||||
|
icon.source: "../../images/icon-m-sticker.svg"
|
||||||
|
icon.sourceSize {
|
||||||
|
width: Theme.iconSizeMedium
|
||||||
|
height: Theme.iconSizeMedium
|
||||||
|
}
|
||||||
|
highlighted: down || stickerPickerLoader.active
|
||||||
|
onClicked: {
|
||||||
|
stickerPickerLoader.active = !stickerPickerLoader.active;
|
||||||
|
voiceNoteOverlayLoader.active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton {
|
||||||
|
visible: !(chatPage.isPrivateChat || chatPage.isSecretChat) && chatPage.hasSendPrivilege("can_send_polls")
|
||||||
|
icon.source: "image://theme/icon-m-question"
|
||||||
|
onClicked: {
|
||||||
|
pageStack.push(Qt.resolvedUrl("../pages/PollCreationPage.qml"), { "chatId" : chatInformation.id, groupName: chatInformation.title});
|
||||||
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IconButton {
|
||||||
|
visible: fernschreiberUtils.supportsGeoLocation() && newMessageTextField.text === ""
|
||||||
|
icon.source: "image://theme/icon-m-location"
|
||||||
|
icon.sourceSize {
|
||||||
|
width: Theme.iconSizeMedium
|
||||||
|
height: Theme.iconSizeMedium
|
||||||
|
}
|
||||||
|
onClicked: {
|
||||||
|
fernschreiberUtils.startGeoLocationUpdates();
|
||||||
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
|
attachmentPreviewRow.isLocation = true;
|
||||||
|
attachmentPreviewRow.attachmentDescription = qsTr("Location: Obtaining position...");
|
||||||
attachmentPreviewRow.visible = true;
|
attachmentPreviewRow.visible = true;
|
||||||
controlSendButton();
|
controlSendButton();
|
||||||
})
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
IconButton {
|
|
||||||
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
|
||||||
icon.source: "image://theme/icon-m-video"
|
|
||||||
onClicked: {
|
|
||||||
var picker = pageStack.push("Sailfish.Pickers.VideoPickerPage", {
|
|
||||||
allowedOrientations: chatPage.allowedOrientations
|
|
||||||
})
|
|
||||||
picker.selectedContentPropertiesChanged.connect(function(){
|
|
||||||
attachmentOptionsRow.isNeeded = false;
|
|
||||||
Debug.log("Selected video: ", picker.selectedContentProperties.filePath );
|
|
||||||
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
|
||||||
attachmentPreviewRow.isVideo = true;
|
|
||||||
attachmentPreviewRow.visible = true;
|
|
||||||
controlSendButton();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IconButton {
|
|
||||||
visible: chatPage.hasSendPrivilege("can_send_media_messages")
|
|
||||||
icon.source: "image://theme/icon-m-document"
|
|
||||||
onClicked: {
|
|
||||||
var picker = pageStack.push("Sailfish.Pickers.FilePickerPage", {
|
|
||||||
allowedOrientations: chatPage.allowedOrientations
|
|
||||||
})
|
|
||||||
picker.selectedContentPropertiesChanged.connect(function(){
|
|
||||||
attachmentOptionsRow.isNeeded = false;
|
|
||||||
Debug.log("Selected document: ", picker.selectedContentProperties.filePath );
|
|
||||||
attachmentPreviewRow.fileProperties = picker.selectedContentProperties;
|
|
||||||
attachmentPreviewRow.isDocument = true;
|
|
||||||
attachmentPreviewRow.visible = true;
|
|
||||||
controlSendButton();
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IconButton {
|
|
||||||
visible: chatPage.hasSendPrivilege("can_send_other_messages")
|
|
||||||
icon.source: "../../images/icon-m-sticker.svg"
|
|
||||||
icon.sourceSize {
|
|
||||||
width: Theme.iconSizeMedium
|
|
||||||
height: Theme.iconSizeMedium
|
|
||||||
}
|
|
||||||
highlighted: down || stickerPickerLoader.active
|
|
||||||
onClicked: {
|
|
||||||
stickerPickerLoader.active = !stickerPickerLoader.active;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IconButton {
|
|
||||||
visible: !(chatPage.isPrivateChat || chatPage.isSecretChat) && chatPage.hasSendPrivilege("can_send_polls")
|
|
||||||
icon.source: "image://theme/icon-m-question"
|
|
||||||
onClicked: {
|
|
||||||
pageStack.push(Qt.resolvedUrl("../pages/PollCreationPage.qml"), { "chatId" : chatInformation.id, groupName: chatInformation.title});
|
|
||||||
attachmentOptionsRow.isNeeded = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Row {
|
Row {
|
||||||
id: attachmentPreviewRow
|
id: attachmentPreviewRow
|
||||||
visible: false
|
visible: false
|
||||||
|
@ -1268,7 +1357,21 @@ Page {
|
||||||
property bool isPicture: false;
|
property bool isPicture: false;
|
||||||
property bool isVideo: false;
|
property bool isVideo: false;
|
||||||
property bool isDocument: false;
|
property bool isDocument: false;
|
||||||
|
property bool isVoiceNote: false;
|
||||||
|
property bool isLocation: false;
|
||||||
|
property var locationData: ({});
|
||||||
property var fileProperties:({});
|
property var fileProperties:({});
|
||||||
|
property string attachmentDescription: "";
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: fernschreiberUtils
|
||||||
|
onNewPositionInformation: {
|
||||||
|
attachmentPreviewRow.locationData = positionInformation;
|
||||||
|
if (attachmentPreviewRow.isLocation) {
|
||||||
|
attachmentPreviewRow.attachmentDescription = qsTr("Location (%1/%2)").arg(attachmentPreviewRow.locationData.latitude).arg(attachmentPreviewRow.locationData.longitude);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
id: removeAttachmentsIconButton
|
id: removeAttachmentsIconButton
|
||||||
|
@ -1295,13 +1398,13 @@ Page {
|
||||||
Label {
|
Label {
|
||||||
id: attachmentPreviewText
|
id: attachmentPreviewText
|
||||||
font.pixelSize: Theme.fontSizeSmall
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
text: typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.fileName || "" : "";
|
text: ( attachmentPreviewRow.isVoiceNote || attachmentPreviewRow.isLocation ) ? attachmentPreviewRow.attachmentDescription : ( typeof attachmentPreviewRow.fileProperties !== "undefined" ? attachmentPreviewRow.fileProperties.fileName || "" : "" );
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
color: Theme.secondaryColor
|
color: Theme.secondaryColor
|
||||||
visible: attachmentPreviewRow.isDocument
|
visible: attachmentPreviewRow.isDocument || attachmentPreviewRow.isVoiceNote || attachmentPreviewRow.isLocation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1503,11 +1606,14 @@ Page {
|
||||||
labelVisible: false
|
labelVisible: false
|
||||||
textLeftMargin: 0
|
textLeftMargin: 0
|
||||||
textTopMargin: 0
|
textTopMargin: 0
|
||||||
|
enabled: !attachmentPreviewRow.isLocation
|
||||||
EnterKey.onClicked: {
|
EnterKey.onClicked: {
|
||||||
if (appSettings.sendByEnter) {
|
if (appSettings.sendByEnter) {
|
||||||
sendMessage();
|
sendMessage();
|
||||||
newMessageTextField.text = "";
|
newMessageTextField.text = "";
|
||||||
newMessageTextField.focus = false;
|
if(!appSettings.focusTextAreaAfterSend) {
|
||||||
|
newMessageTextField.focus = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1522,16 +1628,17 @@ Page {
|
||||||
|
|
||||||
IconButton {
|
IconButton {
|
||||||
id: attachmentIconButton
|
id: attachmentIconButton
|
||||||
icon.source: "image://theme/icon-m-attach?" + (attachmentOptionsRow.isNeeded ? Theme.highlightColor : Theme.primaryColor)
|
icon.source: "image://theme/icon-m-attach?" + (attachmentOptionsFlickable.isNeeded ? Theme.highlightColor : Theme.primaryColor)
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.bottomMargin: Theme.paddingSmall
|
anchors.bottomMargin: Theme.paddingSmall
|
||||||
enabled: !attachmentPreviewRow.visible
|
enabled: !attachmentPreviewRow.visible
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (attachmentOptionsRow.isNeeded) {
|
if (attachmentOptionsFlickable.isNeeded) {
|
||||||
attachmentOptionsRow.isNeeded = false;
|
attachmentOptionsFlickable.isNeeded = false;
|
||||||
stickerPickerLoader.active = false;
|
stickerPickerLoader.active = false;
|
||||||
|
voiceNoteOverlayLoader.active = false;
|
||||||
} else {
|
} else {
|
||||||
attachmentOptionsRow.isNeeded = true;
|
attachmentOptionsFlickable.isNeeded = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1546,7 +1653,9 @@ Page {
|
||||||
onClicked: {
|
onClicked: {
|
||||||
sendMessage();
|
sendMessage();
|
||||||
newMessageTextField.text = "";
|
newMessageTextField.text = "";
|
||||||
newMessageTextField.focus = false;
|
if(!appSettings.focusTextAreaAfterSend) {
|
||||||
|
newMessageTextField.focus = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,7 @@ CoverBackground {
|
||||||
coverPage.authenticated = (tdLibWrapper.getAuthorizationState() === TelegramAPI.AuthorizationReady);
|
coverPage.authenticated = (tdLibWrapper.getAuthorizationState() === TelegramAPI.AuthorizationReady);
|
||||||
coverPage.connectionState = tdLibWrapper.getConnectionState();
|
coverPage.connectionState = tdLibWrapper.getConnectionState();
|
||||||
coverPage.unreadMessages = tdLibWrapper.getUnreadMessageInformation().unread_count || 0;
|
coverPage.unreadMessages = tdLibWrapper.getUnreadMessageInformation().unread_count || 0;
|
||||||
coverPage.unreadChats = tdLibWrapper.getUnreadChatInformation().unread_count;
|
coverPage.unreadChats = tdLibWrapper.getUnreadChatInformation().unread_count || 0;
|
||||||
setUnreadInfoText();
|
setUnreadInfoText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,6 +91,15 @@ CoverBackground {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: chatListModel
|
||||||
|
onUnreadStateChanged: {
|
||||||
|
coverPage.unreadMessages = unreadMessagesCount;
|
||||||
|
coverPage.unreadChats = unreadChatsCount;
|
||||||
|
setUnreadInfoText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BackgroundImage {
|
BackgroundImage {
|
||||||
id: backgroundImage
|
id: backgroundImage
|
||||||
width: parent.height - Theme.paddingLarge
|
width: parent.height - Theme.paddingLarge
|
||||||
|
|
|
@ -67,6 +67,13 @@ Page {
|
||||||
overviewPage.chatListCreated = true;
|
overviewPage.chatListCreated = true;
|
||||||
chatListView.scrollToTop();
|
chatListView.scrollToTop();
|
||||||
updateSecondaryContentTimer.start();
|
updateSecondaryContentTimer.start();
|
||||||
|
var remainingInteractionHints = appSettings.remainingInteractionHints;
|
||||||
|
Debug.log("Remaining interaction hints: " + remainingInteractionHints);
|
||||||
|
if (remainingInteractionHints > 0) {
|
||||||
|
interactionHintTimer.start();
|
||||||
|
titleInteractionHint.opacity = 1.0;
|
||||||
|
appSettings.remainingInteractionHints = remainingInteractionHints - 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,6 +88,7 @@ Page {
|
||||||
id: updateSecondaryContentTimer
|
id: updateSecondaryContentTimer
|
||||||
interval: 600
|
interval: 600
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
|
chatListModel.calculateUnreadState();
|
||||||
tdLibWrapper.getRecentStickers();
|
tdLibWrapper.getRecentStickers();
|
||||||
tdLibWrapper.getInstalledStickerSets();
|
tdLibWrapper.getInstalledStickerSets();
|
||||||
tdLibWrapper.getContacts();
|
tdLibWrapper.getContacts();
|
||||||
|
@ -178,9 +186,8 @@ Page {
|
||||||
|
|
||||||
function resetFocus() {
|
function resetFocus() {
|
||||||
if (chatSearchField.text === "") {
|
if (chatSearchField.text === "") {
|
||||||
chatSearchField.visible = false;
|
chatSearchField.opacity = 0.0;
|
||||||
pageHeader.visible = true;
|
pageHeader.opacity = 1.0;
|
||||||
searchChatButton.visible = overviewPage.connectionState === TelegramAPI.ConnectionReady;
|
|
||||||
}
|
}
|
||||||
chatSearchField.focus = false;
|
chatSearchField.focus = false;
|
||||||
overviewPage.focus = true;
|
overviewPage.focus = true;
|
||||||
|
@ -202,11 +209,15 @@ Page {
|
||||||
onChatLastMessageUpdated: {
|
onChatLastMessageUpdated: {
|
||||||
if (!overviewPage.chatListCreated) {
|
if (!overviewPage.chatListCreated) {
|
||||||
chatListCreatedTimer.restart();
|
chatListCreatedTimer.restart();
|
||||||
|
} else {
|
||||||
|
chatListModel.calculateUnreadState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onChatOrderUpdated: {
|
onChatOrderUpdated: {
|
||||||
if (!overviewPage.chatListCreated) {
|
if (!overviewPage.chatListCreated) {
|
||||||
chatListCreatedTimer.restart();
|
chatListCreatedTimer.restart();
|
||||||
|
} else {
|
||||||
|
chatListModel.calculateUnreadState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onChatsReceived: {
|
onChatsReceived: {
|
||||||
|
@ -268,9 +279,12 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Row {
|
PageHeader {
|
||||||
id: headerRow
|
id: pageHeader
|
||||||
width: parent.width - Theme.horizontalPageMargin
|
title: qsTr("Fernschreiber")
|
||||||
|
leftMargin: Theme.itemSizeMedium
|
||||||
|
visible: opacity > 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
|
||||||
GlassItem {
|
GlassItem {
|
||||||
id: pageStatus
|
id: pageStatus
|
||||||
|
@ -282,63 +296,45 @@ Page {
|
||||||
cache: false
|
cache: false
|
||||||
}
|
}
|
||||||
|
|
||||||
PageHeader {
|
MouseArea {
|
||||||
id: pageHeader
|
anchors.fill: parent
|
||||||
title: qsTr("Fernschreiber")
|
|
||||||
width: visible ? ( parent.width - pageStatus.width - searchChatButton.width ) : 0
|
|
||||||
opacity: visible ? 1 : 0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
}
|
|
||||||
|
|
||||||
IconButton {
|
|
||||||
id: searchChatButton
|
|
||||||
width: visible ? height : 0
|
|
||||||
opacity: visible ? 1 : 0
|
|
||||||
Behavior on opacity { NumberAnimation {} }
|
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
icon {
|
|
||||||
source: "image://theme/icon-m-search?" + Theme.highlightColor
|
|
||||||
asynchronous: true
|
|
||||||
}
|
|
||||||
visible: overviewPage.connectionState === TelegramAPI.ConnectionReady
|
|
||||||
onClicked: {
|
onClicked: {
|
||||||
chatSearchField.focus = true;
|
chatSearchField.focus = true;
|
||||||
chatSearchField.visible = true;
|
chatSearchField.opacity = 1.0;
|
||||||
pageHeader.visible = false;
|
pageHeader.opacity = 0.0;
|
||||||
searchChatButton.visible = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SearchField {
|
|
||||||
id: chatSearchField
|
|
||||||
visible: false
|
|
||||||
opacity: visible ? 1 : 0
|
|
||||||
Behavior on opacity { FadeAnimation {} }
|
|
||||||
width: visible ? ( parent.width - pageStatus.width ) : 0
|
|
||||||
height: pageHeader.height
|
|
||||||
placeholderText: qsTr("Filter your chats...")
|
|
||||||
canHide: text === ""
|
|
||||||
|
|
||||||
onTextChanged: {
|
|
||||||
searchChatTimer.restart();
|
|
||||||
}
|
|
||||||
|
|
||||||
onHideClicked: {
|
|
||||||
resetFocus();
|
|
||||||
}
|
|
||||||
|
|
||||||
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
|
||||||
EnterKey.onClicked: {
|
|
||||||
resetFocus();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SearchField {
|
||||||
|
id: chatSearchField
|
||||||
|
visible: opacity > 0
|
||||||
|
opacity: 0
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
width: parent.width
|
||||||
|
height: pageHeader.height
|
||||||
|
placeholderText: qsTr("Filter your chats...")
|
||||||
|
canHide: text === ""
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
searchChatTimer.restart();
|
||||||
|
}
|
||||||
|
|
||||||
|
onHideClicked: {
|
||||||
|
resetFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterKey.iconSource: "image://theme/icon-m-enter-close"
|
||||||
|
EnterKey.onClicked: {
|
||||||
|
resetFocus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SilicaListView {
|
SilicaListView {
|
||||||
id: chatListView
|
id: chatListView
|
||||||
anchors {
|
anchors {
|
||||||
top: headerRow.bottom
|
top: pageHeader.bottom
|
||||||
bottom: parent.bottom
|
bottom: parent.bottom
|
||||||
left: parent.left
|
left: parent.left
|
||||||
right: parent.right
|
right: parent.right
|
||||||
|
@ -360,7 +356,8 @@ Page {
|
||||||
|
|
||||||
ViewPlaceholder {
|
ViewPlaceholder {
|
||||||
enabled: chatListView.count === 0
|
enabled: chatListView.count === 0
|
||||||
text: qsTr("You don't have any chats yet.")
|
text: chatSearchField.text === "" ? qsTr("You don't have any chats yet.") : qsTr("No matching chats found.")
|
||||||
|
hintText: qsTr("You can search public chats or create a new chat via the pull-down menu.")
|
||||||
}
|
}
|
||||||
|
|
||||||
VerticalScrollDecorator {}
|
VerticalScrollDecorator {}
|
||||||
|
@ -403,4 +400,24 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Timer {
|
||||||
|
id: interactionHintTimer
|
||||||
|
running: false
|
||||||
|
interval: 4000
|
||||||
|
onTriggered: {
|
||||||
|
titleInteractionHint.opacity = 0.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InteractionHintLabel {
|
||||||
|
id: titleInteractionHint
|
||||||
|
text: qsTr("Tap on the title bar to filter your chats")
|
||||||
|
visible: opacity > 0
|
||||||
|
invert: true
|
||||||
|
anchors.fill: parent
|
||||||
|
Behavior on opacity { FadeAnimation {} }
|
||||||
|
opacity: 0
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -175,13 +175,13 @@ Page {
|
||||||
|
|
||||||
onBasicGroupFullInfoUpdated: {
|
onBasicGroupFullInfoUpdated: {
|
||||||
if (foundChatListDelegate.isBasicGroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.basic_group_id.toString()) {
|
if (foundChatListDelegate.isBasicGroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.basic_group_id.toString()) {
|
||||||
foundChatListItem.secondaryText.text = qsTr("%1 members").arg(Number(groupFullInfo.members.length).toLocaleString(Qt.locale(), "f", 0));
|
foundChatListItem.secondaryText.text = qsTr("%1 members", "", groupFullInfo.members.length).arg(Number(groupFullInfo.members.length).toLocaleString(Qt.locale(), "f", 0));
|
||||||
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onBasicGroupFullInfoReceived: {
|
onBasicGroupFullInfoReceived: {
|
||||||
if (foundChatListDelegate.isBasicGroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.basic_group_id.toString()) {
|
if (foundChatListDelegate.isBasicGroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.basic_group_id.toString()) {
|
||||||
foundChatListItem.secondaryText.text = qsTr("%1 members").arg(Number(groupFullInfo.members.length).toLocaleString(Qt.locale(), "f", 0));
|
foundChatListItem.secondaryText.text = qsTr("%1 members", "", groupFullInfo.members.length).arg(Number(groupFullInfo.members.length).toLocaleString(Qt.locale(), "f", 0));
|
||||||
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -189,9 +189,9 @@ Page {
|
||||||
onSupergroupFullInfoUpdated: {
|
onSupergroupFullInfoUpdated: {
|
||||||
if (foundChatListDelegate.isSupergroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.supergroup_id.toString()) {
|
if (foundChatListDelegate.isSupergroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.supergroup_id.toString()) {
|
||||||
if (foundChatListDelegate.relatedInformation.is_channel) {
|
if (foundChatListDelegate.relatedInformation.is_channel) {
|
||||||
foundChatListItem.secondaryText.text = qsTr("%1 subscribers").arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
foundChatListItem.secondaryText.text = qsTr("%1 subscribers", "", groupFullInfo.member_count).arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
||||||
} else {
|
} else {
|
||||||
foundChatListItem.secondaryText.text = qsTr("%1 members").arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
foundChatListItem.secondaryText.text = qsTr("%1 members", "", groupFullInfo.member_count).arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
||||||
}
|
}
|
||||||
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
}
|
}
|
||||||
|
@ -199,9 +199,9 @@ Page {
|
||||||
onSupergroupFullInfoReceived: {
|
onSupergroupFullInfoReceived: {
|
||||||
if (foundChatListDelegate.isSupergroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.supergroup_id.toString()) {
|
if (foundChatListDelegate.isSupergroup && groupId.toString() === foundChatListDelegate.foundChatInformation.type.supergroup_id.toString()) {
|
||||||
if (foundChatListDelegate.relatedInformation.is_channel) {
|
if (foundChatListDelegate.relatedInformation.is_channel) {
|
||||||
foundChatListItem.secondaryText.text = qsTr("%1 subscribers").arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
foundChatListItem.secondaryText.text = qsTr("%1 subscribers", "", groupFullInfo.member_count).arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
||||||
} else {
|
} else {
|
||||||
foundChatListItem.secondaryText.text = qsTr("%1 members").arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
foundChatListItem.secondaryText.text = qsTr("%1 members", "", groupFullInfo.member_count).arg(Number(groupFullInfo.member_count).toLocaleString(Qt.locale(), "f", 0));
|
||||||
}
|
}
|
||||||
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
foundChatListItem.tertiaryText.text = Emoji.emojify(groupFullInfo.description, foundChatListItem.tertiaryText.font.pixelSize, "../js/emoji/");
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,16 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextSwitch {
|
||||||
|
checked: appSettings.focusTextAreaAfterSend
|
||||||
|
text: qsTr("Focus text input area after send")
|
||||||
|
description: qsTr("Focus the text input area after sending a message")
|
||||||
|
automaticCheck: false
|
||||||
|
onClicked: {
|
||||||
|
appSettings.focusTextAreaAfterSend = !checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
TextSwitch {
|
TextSwitch {
|
||||||
checked: appSettings.useOpenWith
|
checked: appSettings.useOpenWith
|
||||||
text: qsTr("Open-with menu integration")
|
text: qsTr("Open-with menu integration")
|
||||||
|
@ -162,6 +172,16 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TextSwitch {
|
||||||
|
checked: appSettings.onlineOnlyMode
|
||||||
|
text: qsTr("Enable online-only mode")
|
||||||
|
description: qsTr("Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.")
|
||||||
|
automaticCheck: false
|
||||||
|
onClicked: {
|
||||||
|
appSettings.onlineOnlyMode = !checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
width: 1
|
width: 1
|
||||||
height: Theme.paddingLarge // Some space at the bottom
|
height: Theme.paddingLarge // Some space at the bottom
|
||||||
|
|
|
@ -12,6 +12,38 @@
|
||||||
# * date Author's Name <author's email> version-release
|
# * date Author's Name <author's email> version-release
|
||||||
# - Summary of changes
|
# - Summary of changes
|
||||||
|
|
||||||
|
* Wed Jan 6 2021 Sebastian J. Wolf <sebastian@ygriega.de> 0.6.1
|
||||||
|
- Show indicator for pinned chats
|
||||||
|
- Use highlightBackgroundColor and align size for all chat attributes (unread messages, secret chat, pinned chat)
|
||||||
|
- Fix: Chat list order of sequence was wrong in some circumstances
|
||||||
|
- Fix: Make video (fullscreen) page work again
|
||||||
|
- Fix: Add build requirements for Qt Multimedia and Qt Positioning
|
||||||
|
- Updated translations for Finnish and Swedish - thanks to jorm1s and eson57
|
||||||
|
|
||||||
|
* Tue Jan 5 2021 Sebastian J. Wolf <sebastian@ygriega.de> 0.6
|
||||||
|
- Filter chat list (tap on title bar to open search field) - thanks to the entire dev team for the great discussion and contributions to the layout :)
|
||||||
|
- Search for public chats (see pulley menu on overview page)
|
||||||
|
- Search for chat messages (see pulley menu on chat page)
|
||||||
|
- Support sending voice notes
|
||||||
|
- Support sending locations
|
||||||
|
- Add message draft support - thanks to jgibbon
|
||||||
|
- Basic bot messages support (reply markup) - thanks to jgibbon
|
||||||
|
- Add 'Mark chat as read/unread' option
|
||||||
|
- Add download option to audio messages (voice notes, music...)
|
||||||
|
- Introduce proper text if other people added/removed a person from a chat
|
||||||
|
- Tweaks to poll layout - thanks to monich
|
||||||
|
- New option to keep message input focused after message was sent - thanks to jgibbon
|
||||||
|
- Send message button now removed if Send-message-by-enter option is enabled (and no attachment is set) - thanks to santhoshmanikandan
|
||||||
|
- Performance and code optimizations (architecture, startup, JS components) - thanks to monich and jgibbon
|
||||||
|
- Improve readability in light ambiences
|
||||||
|
- Upgrade to TDLib 1.7
|
||||||
|
- Fix: Only show reply to option for messages that can be replied to - thanks to monich
|
||||||
|
- Fix: Emoji positioning in multi-line texts - thanks to monich
|
||||||
|
- Fix: Left-over @-mention notifications when all messages in chat are read
|
||||||
|
- Fix: Occasional crashes on opening poll context menu - thanks to monich
|
||||||
|
- Fix: Don't display in-reply-to section if message wasn't found
|
||||||
|
- Several translations updated - thanks to all contributors
|
||||||
|
|
||||||
* Fri Dec 4 2020 Sebastian J. Wolf <sebastian@ygriega.de> 0.5.1
|
* Fri Dec 4 2020 Sebastian J. Wolf <sebastian@ygriega.de> 0.5.1
|
||||||
- Add verification badge to verified chats - thanks to monich
|
- Add verification badge to verified chats - thanks to monich
|
||||||
- Improve preview of wide images - thanks to monich
|
- Improve preview of wide images - thanks to monich
|
||||||
|
|
|
@ -11,7 +11,7 @@ Name: harbour-fernschreiber
|
||||||
# << macros
|
# << macros
|
||||||
|
|
||||||
Summary: Fernschreiber is a Telegram client for Sailfish OS
|
Summary: Fernschreiber is a Telegram client for Sailfish OS
|
||||||
Version: 0.6
|
Version: 0.7
|
||||||
Release: 1
|
Release: 1
|
||||||
Group: Qt/Qt
|
Group: Qt/Qt
|
||||||
License: LICENSE
|
License: LICENSE
|
||||||
|
@ -25,6 +25,8 @@ BuildRequires: pkgconfig(Qt5Qml)
|
||||||
BuildRequires: pkgconfig(Qt5Quick)
|
BuildRequires: pkgconfig(Qt5Quick)
|
||||||
BuildRequires: pkgconfig(Qt5DBus)
|
BuildRequires: pkgconfig(Qt5DBus)
|
||||||
BuildRequires: pkgconfig(Qt5Sql)
|
BuildRequires: pkgconfig(Qt5Sql)
|
||||||
|
BuildRequires: pkgconfig(Qt5Multimedia)
|
||||||
|
BuildRequires: pkgconfig(Qt5Positioning)
|
||||||
BuildRequires: pkgconfig(nemonotifications-qt5)
|
BuildRequires: pkgconfig(nemonotifications-qt5)
|
||||||
BuildRequires: pkgconfig(ngf-qt5)
|
BuildRequires: pkgconfig(ngf-qt5)
|
||||||
BuildRequires: desktop-file-utils
|
BuildRequires: desktop-file-utils
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Name: harbour-fernschreiber
|
Name: harbour-fernschreiber
|
||||||
Summary: Fernschreiber is a Telegram client for Sailfish OS
|
Summary: Fernschreiber is a Telegram client for Sailfish OS
|
||||||
Version: 0.6
|
Version: 0.7
|
||||||
Release: 1
|
Release: 1
|
||||||
# The contents of the Group field should be one of the groups listed here:
|
# The contents of the Group field should be one of the groups listed here:
|
||||||
# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
|
# https://github.com/mer-tools/spectacle/blob/master/data/GROUPS
|
||||||
|
@ -25,6 +25,8 @@ PkgConfigBR:
|
||||||
- Qt5Quick
|
- Qt5Quick
|
||||||
- Qt5DBus
|
- Qt5DBus
|
||||||
- Qt5Sql
|
- Qt5Sql
|
||||||
|
- Qt5Multimedia
|
||||||
|
- Qt5Positioning
|
||||||
- nemonotifications-qt5
|
- nemonotifications-qt5
|
||||||
- ngf-qt5
|
- ngf-qt5
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,15 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const QString KEY_SEND_BY_ENTER("sendByEnter");
|
const QString KEY_SEND_BY_ENTER("sendByEnter");
|
||||||
|
const QString KEY_FOCUS_TEXTAREA_AFTER_SEND("focusTextAreaAfterSend");
|
||||||
const QString KEY_USE_OPEN_WITH("useOpenWith");
|
const QString KEY_USE_OPEN_WITH("useOpenWith");
|
||||||
const QString KEY_SHOW_STICKERS_AS_IMAGES("showStickersAsImages");
|
const QString KEY_SHOW_STICKERS_AS_IMAGES("showStickersAsImages");
|
||||||
const QString KEY_ANIMATE_STICKERS("animateStickers");
|
const QString KEY_ANIMATE_STICKERS("animateStickers");
|
||||||
const QString KEY_NOTIFICATION_TURNS_DISPLAY_ON("notificationTurnsDisplayOn");
|
const QString KEY_NOTIFICATION_TURNS_DISPLAY_ON("notificationTurnsDisplayOn");
|
||||||
const QString KEY_NOTIFICATION_FEEDBACK("notificationFeedback");
|
const QString KEY_NOTIFICATION_FEEDBACK("notificationFeedback");
|
||||||
const QString KEY_STORAGE_OPTIMIZER("storageOptimizer");
|
const QString KEY_STORAGE_OPTIMIZER("storageOptimizer");
|
||||||
|
const QString KEY_REMAINING_INTERACTION_HINTS("remainingInteractionHints");
|
||||||
|
const QString KEY_ONLINE_ONLY_MODE("onlineOnlyMode");
|
||||||
}
|
}
|
||||||
|
|
||||||
AppSettings::AppSettings(QObject *parent) : QObject(parent), settings("harbour-fernschreiber", "settings")
|
AppSettings::AppSettings(QObject *parent) : QObject(parent), settings("harbour-fernschreiber", "settings")
|
||||||
|
@ -48,6 +51,20 @@ void AppSettings::setSendByEnter(bool sendByEnter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AppSettings::getFocusTextAreaAfterSend() const
|
||||||
|
{
|
||||||
|
return settings.value(KEY_FOCUS_TEXTAREA_AFTER_SEND, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSettings::setFocusTextAreaAfterSend(bool focusTextAreaAfterSend)
|
||||||
|
{
|
||||||
|
if (getFocusTextAreaAfterSend() != focusTextAreaAfterSend) {
|
||||||
|
LOG(KEY_FOCUS_TEXTAREA_AFTER_SEND << focusTextAreaAfterSend);
|
||||||
|
settings.setValue(KEY_FOCUS_TEXTAREA_AFTER_SEND, focusTextAreaAfterSend);
|
||||||
|
emit focusTextAreaAfterSendChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool AppSettings::getUseOpenWith() const
|
bool AppSettings::getUseOpenWith() const
|
||||||
{
|
{
|
||||||
return settings.value(KEY_USE_OPEN_WITH, true).toBool();
|
return settings.value(KEY_USE_OPEN_WITH, true).toBool();
|
||||||
|
@ -131,3 +148,31 @@ void AppSettings::setStorageOptimizer(bool enable)
|
||||||
emit storageOptimizerChanged();
|
emit storageOptimizerChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AppSettings::remainingInteractionHints() const
|
||||||
|
{
|
||||||
|
return settings.value(KEY_REMAINING_INTERACTION_HINTS, 3).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSettings::setRemainingInteractionHints(int remainingHints)
|
||||||
|
{
|
||||||
|
if (remainingInteractionHints() != remainingHints) {
|
||||||
|
LOG(KEY_REMAINING_INTERACTION_HINTS << remainingHints);
|
||||||
|
settings.setValue(KEY_REMAINING_INTERACTION_HINTS, remainingHints);
|
||||||
|
emit remainingInteractionHintsChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AppSettings::onlineOnlyMode() const
|
||||||
|
{
|
||||||
|
return settings.value(KEY_ONLINE_ONLY_MODE, false).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppSettings::setOnlineOnlyMode(bool enable)
|
||||||
|
{
|
||||||
|
if (onlineOnlyMode() != enable) {
|
||||||
|
LOG(KEY_ONLINE_ONLY_MODE << enable);
|
||||||
|
settings.setValue(KEY_ONLINE_ONLY_MODE, enable);
|
||||||
|
emit onlineOnlyModeChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -24,12 +24,15 @@
|
||||||
class AppSettings : public QObject {
|
class AppSettings : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(bool sendByEnter READ getSendByEnter WRITE setSendByEnter NOTIFY sendByEnterChanged)
|
Q_PROPERTY(bool sendByEnter READ getSendByEnter WRITE setSendByEnter NOTIFY sendByEnterChanged)
|
||||||
|
Q_PROPERTY(bool focusTextAreaAfterSend READ getFocusTextAreaAfterSend WRITE setFocusTextAreaAfterSend NOTIFY focusTextAreaAfterSendChanged)
|
||||||
Q_PROPERTY(bool useOpenWith READ getUseOpenWith WRITE setUseOpenWith NOTIFY useOpenWithChanged)
|
Q_PROPERTY(bool useOpenWith READ getUseOpenWith WRITE setUseOpenWith NOTIFY useOpenWithChanged)
|
||||||
Q_PROPERTY(bool showStickersAsImages READ showStickersAsImages WRITE setShowStickersAsImages NOTIFY showStickersAsImagesChanged)
|
Q_PROPERTY(bool showStickersAsImages READ showStickersAsImages WRITE setShowStickersAsImages NOTIFY showStickersAsImagesChanged)
|
||||||
Q_PROPERTY(bool animateStickers READ animateStickers WRITE setAnimateStickers NOTIFY animateStickersChanged)
|
Q_PROPERTY(bool animateStickers READ animateStickers WRITE setAnimateStickers NOTIFY animateStickersChanged)
|
||||||
Q_PROPERTY(bool notificationTurnsDisplayOn READ notificationTurnsDisplayOn WRITE setNotificationTurnsDisplayOn NOTIFY notificationTurnsDisplayOnChanged)
|
Q_PROPERTY(bool notificationTurnsDisplayOn READ notificationTurnsDisplayOn WRITE setNotificationTurnsDisplayOn NOTIFY notificationTurnsDisplayOnChanged)
|
||||||
Q_PROPERTY(NotificationFeedback notificationFeedback READ notificationFeedback WRITE setNotificationFeedback NOTIFY notificationFeedbackChanged)
|
Q_PROPERTY(NotificationFeedback notificationFeedback READ notificationFeedback WRITE setNotificationFeedback NOTIFY notificationFeedbackChanged)
|
||||||
Q_PROPERTY(bool storageOptimizer READ storageOptimizer WRITE setStorageOptimizer NOTIFY storageOptimizerChanged)
|
Q_PROPERTY(bool storageOptimizer READ storageOptimizer WRITE setStorageOptimizer NOTIFY storageOptimizerChanged)
|
||||||
|
Q_PROPERTY(int remainingInteractionHints READ remainingInteractionHints WRITE setRemainingInteractionHints NOTIFY remainingInteractionHintsChanged)
|
||||||
|
Q_PROPERTY(bool onlineOnlyMode READ onlineOnlyMode WRITE setOnlineOnlyMode NOTIFY onlineOnlyModeChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum NotificationFeedback {
|
enum NotificationFeedback {
|
||||||
|
@ -45,6 +48,9 @@ public:
|
||||||
bool getSendByEnter() const;
|
bool getSendByEnter() const;
|
||||||
void setSendByEnter(bool sendByEnter);
|
void setSendByEnter(bool sendByEnter);
|
||||||
|
|
||||||
|
bool getFocusTextAreaAfterSend() const;
|
||||||
|
void setFocusTextAreaAfterSend(bool focusTextAreaAfterSend);
|
||||||
|
|
||||||
bool getUseOpenWith() const;
|
bool getUseOpenWith() const;
|
||||||
void setUseOpenWith(bool useOpenWith);
|
void setUseOpenWith(bool useOpenWith);
|
||||||
|
|
||||||
|
@ -63,14 +69,23 @@ public:
|
||||||
bool storageOptimizer() const;
|
bool storageOptimizer() const;
|
||||||
void setStorageOptimizer(bool enable);
|
void setStorageOptimizer(bool enable);
|
||||||
|
|
||||||
|
int remainingInteractionHints() const;
|
||||||
|
void setRemainingInteractionHints(int remainingHints);
|
||||||
|
|
||||||
|
bool onlineOnlyMode() const;
|
||||||
|
void setOnlineOnlyMode(bool enable);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sendByEnterChanged();
|
void sendByEnterChanged();
|
||||||
|
void focusTextAreaAfterSendChanged();
|
||||||
void useOpenWithChanged();
|
void useOpenWithChanged();
|
||||||
void showStickersAsImagesChanged();
|
void showStickersAsImagesChanged();
|
||||||
void animateStickersChanged();
|
void animateStickersChanged();
|
||||||
void notificationTurnsDisplayOnChanged();
|
void notificationTurnsDisplayOnChanged();
|
||||||
void notificationFeedbackChanged();
|
void notificationFeedbackChanged();
|
||||||
void storageOptimizerChanged();
|
void storageOptimizerChanged();
|
||||||
|
void remainingInteractionHintsChanged();
|
||||||
|
void onlineOnlyModeChanged();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "chatlistmodel.h"
|
#include "chatlistmodel.h"
|
||||||
#include "fernschreiberutils.h"
|
#include "fernschreiberutils.h"
|
||||||
|
#include <QListIterator>
|
||||||
|
|
||||||
#define DEBUG_MODULE ChatListModel
|
#define DEBUG_MODULE ChatListModel
|
||||||
#include "debuglog.h"
|
#include "debuglog.h"
|
||||||
|
@ -48,6 +49,7 @@ namespace {
|
||||||
const QString IS_CHANNEL("is_channel");
|
const QString IS_CHANNEL("is_channel");
|
||||||
const QString IS_VERIFIED("is_verified");
|
const QString IS_VERIFIED("is_verified");
|
||||||
const QString IS_MARKED_AS_UNREAD("is_marked_as_unread");
|
const QString IS_MARKED_AS_UNREAD("is_marked_as_unread");
|
||||||
|
const QString IS_PINNED("is_pinned");
|
||||||
const QString PINNED_MESSAGE_ID("pinned_message_id");
|
const QString PINNED_MESSAGE_ID("pinned_message_id");
|
||||||
const QString _TYPE("@type");
|
const QString _TYPE("@type");
|
||||||
const QString SECRET_CHAT_ID("secret_chat_id");
|
const QString SECRET_CHAT_ID("secret_chat_id");
|
||||||
|
@ -77,6 +79,7 @@ public:
|
||||||
bool isChannel() const;
|
bool isChannel() const;
|
||||||
bool isHidden() const;
|
bool isHidden() const;
|
||||||
bool isMarkedAsUnread() const;
|
bool isMarkedAsUnread() const;
|
||||||
|
bool isPinned() const;
|
||||||
bool updateUnreadCount(int unreadCount);
|
bool updateUnreadCount(int unreadCount);
|
||||||
bool updateLastReadInboxMessageId(qlonglong messageId);
|
bool updateLastReadInboxMessageId(qlonglong messageId);
|
||||||
QVector<int> updateLastMessage(const QVariantMap &message);
|
QVector<int> updateLastMessage(const QVariantMap &message);
|
||||||
|
@ -272,6 +275,11 @@ bool ChatListModel::ChatData::isMarkedAsUnread() const
|
||||||
return chatData.value(IS_MARKED_AS_UNREAD).toBool();
|
return chatData.value(IS_MARKED_AS_UNREAD).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ChatListModel::ChatData::isPinned() const
|
||||||
|
{
|
||||||
|
return chatData.value(IS_PINNED).toBool();
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatListModel::ChatData::updateUnreadCount(int count)
|
bool ChatListModel::ChatData::updateUnreadCount(int count)
|
||||||
{
|
{
|
||||||
const int prevUnreadCount(unreadCount());
|
const int prevUnreadCount(unreadCount());
|
||||||
|
@ -346,9 +354,10 @@ QVector<int> ChatListModel::ChatData::updateSecretChat(const QVariantMap &secret
|
||||||
return changedRoles;
|
return changedRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) : showHiddenChats(false)
|
ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper, AppSettings *appSettings) : showHiddenChats(false)
|
||||||
{
|
{
|
||||||
this->tdLibWrapper = tdLibWrapper;
|
this->tdLibWrapper = tdLibWrapper;
|
||||||
|
this->appSettings = appSettings;
|
||||||
connect(tdLibWrapper, SIGNAL(newChatDiscovered(QString, QVariantMap)), this, SLOT(handleChatDiscovered(QString, QVariantMap)));
|
connect(tdLibWrapper, SIGNAL(newChatDiscovered(QString, QVariantMap)), this, SLOT(handleChatDiscovered(QString, QVariantMap)));
|
||||||
connect(tdLibWrapper, SIGNAL(chatLastMessageUpdated(QString, QString, QVariantMap)), this, SLOT(handleChatLastMessageUpdated(QString, QString, QVariantMap)));
|
connect(tdLibWrapper, SIGNAL(chatLastMessageUpdated(QString, QString, QVariantMap)), this, SLOT(handleChatLastMessageUpdated(QString, QString, QVariantMap)));
|
||||||
connect(tdLibWrapper, SIGNAL(chatOrderUpdated(QString, QString)), this, SLOT(handleChatOrderUpdated(QString, QString)));
|
connect(tdLibWrapper, SIGNAL(chatOrderUpdated(QString, QString)), this, SLOT(handleChatOrderUpdated(QString, QString)));
|
||||||
|
@ -364,6 +373,7 @@ ChatListModel::ChatListModel(TDLibWrapper *tdLibWrapper) : showHiddenChats(false
|
||||||
connect(tdLibWrapper, SIGNAL(secretChatReceived(qlonglong, QVariantMap)), this, SLOT(handleSecretChatUpdated(qlonglong, QVariantMap)));
|
connect(tdLibWrapper, SIGNAL(secretChatReceived(qlonglong, QVariantMap)), this, SLOT(handleSecretChatUpdated(qlonglong, QVariantMap)));
|
||||||
connect(tdLibWrapper, SIGNAL(chatTitleUpdated(QString, QString)), this, SLOT(handleChatTitleUpdated(QString, QString)));
|
connect(tdLibWrapper, SIGNAL(chatTitleUpdated(QString, QString)), this, SLOT(handleChatTitleUpdated(QString, QString)));
|
||||||
connect(tdLibWrapper, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)), this, SLOT(handleChatIsMarkedAsUnreadUpdated(qlonglong, bool)));
|
connect(tdLibWrapper, SIGNAL(chatIsMarkedAsUnreadUpdated(qlonglong, bool)), this, SLOT(handleChatIsMarkedAsUnreadUpdated(qlonglong, bool)));
|
||||||
|
connect(tdLibWrapper, SIGNAL(chatPinnedUpdated(qlonglong, bool)), this, SLOT(handleChatPinnedUpdated(qlonglong, bool)));
|
||||||
connect(tdLibWrapper, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)), this, SLOT(handleChatDraftMessageUpdated(qlonglong, QVariantMap, QString)));
|
connect(tdLibWrapper, SIGNAL(chatDraftMessageUpdated(qlonglong, QVariantMap, QString)), this, SLOT(handleChatDraftMessageUpdated(qlonglong, QVariantMap, QString)));
|
||||||
|
|
||||||
// Don't start the timer until we have at least one chat
|
// Don't start the timer until we have at least one chat
|
||||||
|
@ -405,6 +415,7 @@ QHash<int,QByteArray> ChatListModel::roleNames() const
|
||||||
roles.insert(ChatListModel::RoleIsVerified, "is_verified");
|
roles.insert(ChatListModel::RoleIsVerified, "is_verified");
|
||||||
roles.insert(ChatListModel::RoleIsChannel, "is_channel");
|
roles.insert(ChatListModel::RoleIsChannel, "is_channel");
|
||||||
roles.insert(ChatListModel::RoleIsMarkedAsUnread, "is_marked_as_unread");
|
roles.insert(ChatListModel::RoleIsMarkedAsUnread, "is_marked_as_unread");
|
||||||
|
roles.insert(ChatListModel::RoleIsPinned, "is_pinned");
|
||||||
roles.insert(ChatListModel::RoleFilter, "filter");
|
roles.insert(ChatListModel::RoleFilter, "filter");
|
||||||
roles.insert(ChatListModel::RoleDraftMessageDate, "draft_message_date");
|
roles.insert(ChatListModel::RoleDraftMessageDate, "draft_message_date");
|
||||||
roles.insert(ChatListModel::RoleDraftMessageText, "draft_message_text");
|
roles.insert(ChatListModel::RoleDraftMessageText, "draft_message_text");
|
||||||
|
@ -438,6 +449,7 @@ QVariant ChatListModel::data(const QModelIndex &index, int role) const
|
||||||
case ChatListModel::RoleIsVerified: return data->verified;
|
case ChatListModel::RoleIsVerified: return data->verified;
|
||||||
case ChatListModel::RoleIsChannel: return data->isChannel();
|
case ChatListModel::RoleIsChannel: return data->isChannel();
|
||||||
case ChatListModel::RoleIsMarkedAsUnread: return data->isMarkedAsUnread();
|
case ChatListModel::RoleIsMarkedAsUnread: return data->isMarkedAsUnread();
|
||||||
|
case ChatListModel::RoleIsPinned: return data->isPinned();
|
||||||
case ChatListModel::RoleFilter: return QString(data->title() + " " + data->senderMessageText()).trimmed();
|
case ChatListModel::RoleFilter: return QString(data->title() + " " + data->senderMessageText()).trimmed();
|
||||||
case ChatListModel::RoleDraftMessageText: return data->draftMessageText();
|
case ChatListModel::RoleDraftMessageText: return data->draftMessageText();
|
||||||
case ChatListModel::RoleDraftMessageDate: return data->draftMessageDate();
|
case ChatListModel::RoleDraftMessageDate: return data->draftMessageDate();
|
||||||
|
@ -515,6 +527,26 @@ int ChatListModel::updateChatOrder(int chatIndex)
|
||||||
return newIndex;
|
return newIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatListModel::calculateUnreadState()
|
||||||
|
{
|
||||||
|
if (this->appSettings->onlineOnlyMode()) {
|
||||||
|
LOG("Online-only mode: Calculating unread state on my own...");
|
||||||
|
int unreadMessages = 0;
|
||||||
|
int unreadChats = 0;
|
||||||
|
QListIterator<ChatData*> chatIterator(this->chatList);
|
||||||
|
while (chatIterator.hasNext()) {
|
||||||
|
ChatData *currentChat = chatIterator.next();
|
||||||
|
int unreadCount = currentChat->unreadCount();
|
||||||
|
if (unreadCount > 0) {
|
||||||
|
unreadChats++;
|
||||||
|
unreadMessages += unreadCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LOG("Online-only mode: New unread state:" << unreadMessages << unreadChats);
|
||||||
|
emit unreadStateChanged(unreadMessages, unreadChats);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChatListModel::addVisibleChat(ChatData *chat)
|
void ChatListModel::addVisibleChat(ChatData *chat)
|
||||||
{
|
{
|
||||||
const int n = chatList.size();
|
const int n = chatList.size();
|
||||||
|
@ -715,6 +747,7 @@ void ChatListModel::handleChatReadInboxUpdated(const QString &id, const QString
|
||||||
}
|
}
|
||||||
const QModelIndex modelIndex(index(chatIndex));
|
const QModelIndex modelIndex(index(chatIndex));
|
||||||
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
||||||
|
this->calculateUnreadState();
|
||||||
} else {
|
} else {
|
||||||
ChatData *chat = hiddenChats.value(chatId);
|
ChatData *chat = hiddenChats.value(chatId);
|
||||||
if (chat) {
|
if (chat) {
|
||||||
|
@ -856,6 +889,26 @@ void ChatListModel::handleChatTitleUpdated(const QString &chatId, const QString
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatListModel::handleChatPinnedUpdated(qlonglong chatId, bool chatIsPinned)
|
||||||
|
{
|
||||||
|
if (chatIndexMap.contains(chatId)) {
|
||||||
|
LOG("Updating chat is pinned for" << chatId << chatIsPinned);
|
||||||
|
const int chatIndex = chatIndexMap.value(chatId);
|
||||||
|
ChatData *chat = chatList.at(chatIndex);
|
||||||
|
chat->chatData.insert(IS_PINNED, chatIsPinned);
|
||||||
|
QVector<int> changedRoles;
|
||||||
|
changedRoles.append(ChatListModel::RoleIsPinned);
|
||||||
|
const QModelIndex modelIndex(index(chatIndex));
|
||||||
|
emit dataChanged(modelIndex, modelIndex, changedRoles);
|
||||||
|
} else {
|
||||||
|
ChatData *chat = hiddenChats.value(chatId);
|
||||||
|
if (chat) {
|
||||||
|
LOG("Updating chat is pinned for hidden chat" << chatId);
|
||||||
|
chat->chatData.insert(IS_PINNED, chatIsPinned);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChatListModel::handleChatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread)
|
void ChatListModel::handleChatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread)
|
||||||
{
|
{
|
||||||
if (chatIndexMap.contains(chatId)) {
|
if (chatIndexMap.contains(chatId)) {
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
#include <QAbstractListModel>
|
||||||
#include "tdlibwrapper.h"
|
#include "tdlibwrapper.h"
|
||||||
|
#include "appsettings.h"
|
||||||
|
|
||||||
class ChatListModel : public QAbstractListModel
|
class ChatListModel : public QAbstractListModel
|
||||||
{
|
{
|
||||||
|
@ -47,12 +48,13 @@ public:
|
||||||
RoleIsVerified,
|
RoleIsVerified,
|
||||||
RoleIsChannel,
|
RoleIsChannel,
|
||||||
RoleIsMarkedAsUnread,
|
RoleIsMarkedAsUnread,
|
||||||
|
RoleIsPinned,
|
||||||
RoleFilter,
|
RoleFilter,
|
||||||
RoleDraftMessageText,
|
RoleDraftMessageText,
|
||||||
RoleDraftMessageDate
|
RoleDraftMessageDate
|
||||||
};
|
};
|
||||||
|
|
||||||
ChatListModel(TDLibWrapper *tdLibWrapper);
|
ChatListModel(TDLibWrapper *tdLibWrapper, AppSettings *appSettings);
|
||||||
~ChatListModel() override;
|
~ChatListModel() override;
|
||||||
|
|
||||||
virtual QHash<int,QByteArray> roleNames() const override;
|
virtual QHash<int,QByteArray> roleNames() const override;
|
||||||
|
@ -64,6 +66,7 @@ public:
|
||||||
Q_INVOKABLE QVariantMap getById(qlonglong chatId);
|
Q_INVOKABLE QVariantMap getById(qlonglong chatId);
|
||||||
Q_INVOKABLE void reset();
|
Q_INVOKABLE void reset();
|
||||||
|
|
||||||
|
Q_INVOKABLE void calculateUnreadState();
|
||||||
|
|
||||||
bool showAllChats() const;
|
bool showAllChats() const;
|
||||||
void setShowAllChats(bool showAll);
|
void setShowAllChats(bool showAll);
|
||||||
|
@ -81,6 +84,7 @@ private slots:
|
||||||
void handleGroupUpdated(qlonglong groupId);
|
void handleGroupUpdated(qlonglong groupId);
|
||||||
void handleSecretChatUpdated(qlonglong secretChatId, const QVariantMap &secretChat);
|
void handleSecretChatUpdated(qlonglong secretChatId, const QVariantMap &secretChat);
|
||||||
void handleChatTitleUpdated(const QString &chatId, const QString &title);
|
void handleChatTitleUpdated(const QString &chatId, const QString &title);
|
||||||
|
void handleChatPinnedUpdated(qlonglong chatId, bool chatIsPinned);
|
||||||
void handleChatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
|
void handleChatIsMarkedAsUnreadUpdated(qlonglong chatId, bool chatIsMarkedAsUnread);
|
||||||
void handleChatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
|
void handleChatDraftMessageUpdated(qlonglong chatId, const QVariantMap &draftMessage, const QString &order);
|
||||||
void handleRelativeTimeRefreshTimer();
|
void handleRelativeTimeRefreshTimer();
|
||||||
|
@ -89,6 +93,7 @@ signals:
|
||||||
void showAllChatsChanged();
|
void showAllChatsChanged();
|
||||||
void chatChanged(const qlonglong &changedChatId);
|
void chatChanged(const qlonglong &changedChatId);
|
||||||
void chatJoined(const qlonglong &chatId, const QString &chatTitle);
|
void chatJoined(const qlonglong &chatId, const QString &chatTitle);
|
||||||
|
void unreadStateChanged(int unreadMessagesCount, int unreadChatsCount);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class ChatData;
|
class ChatData;
|
||||||
|
@ -99,6 +104,7 @@ private:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TDLibWrapper *tdLibWrapper;
|
TDLibWrapper *tdLibWrapper;
|
||||||
|
AppSettings *appSettings;
|
||||||
QTimer *relativeTimeRefreshTimer;
|
QTimer *relativeTimeRefreshTimer;
|
||||||
QList<ChatData*> chatList;
|
QList<ChatData*> chatList;
|
||||||
QHash<qlonglong,int> chatIndexMap;
|
QHash<qlonglong,int> chatIndexMap;
|
||||||
|
|
|
@ -54,8 +54,10 @@ public:
|
||||||
MessageData(const QVariantMap &data, qlonglong msgid);
|
MessageData(const QVariantMap &data, qlonglong msgid);
|
||||||
|
|
||||||
static bool lessThan(const MessageData *message1, const MessageData *message2);
|
static bool lessThan(const MessageData *message1, const MessageData *message2);
|
||||||
void setContent(const QVariantMap &content);
|
QVector<int> diff(const MessageData *message) const;
|
||||||
void setReplyMarkup(const QVariantMap &replyMarkup);
|
QVector<int> setMessageData(const QVariantMap &data);
|
||||||
|
QVector<int> setContent(const QVariantMap &content);
|
||||||
|
QVector<int> setReplyMarkup(const QVariantMap &replyMarkup);
|
||||||
int senderUserId() const;
|
int senderUserId() const;
|
||||||
qlonglong senderChatId() const;
|
qlonglong senderChatId() const;
|
||||||
bool senderIsChat() const;
|
bool senderIsChat() const;
|
||||||
|
@ -63,7 +65,7 @@ public:
|
||||||
public:
|
public:
|
||||||
QVariantMap messageData;
|
QVariantMap messageData;
|
||||||
const qlonglong messageId;
|
const qlonglong messageId;
|
||||||
const QString messageContentType;
|
QString messageContentType;
|
||||||
};
|
};
|
||||||
|
|
||||||
ChatModel::MessageData::MessageData(const QVariantMap &data, qlonglong msgid) :
|
ChatModel::MessageData::MessageData(const QVariantMap &data, qlonglong msgid) :
|
||||||
|
@ -88,13 +90,48 @@ bool ChatModel::MessageData::senderIsChat() const
|
||||||
return messageData.value(SENDER).toMap().value(_TYPE).toString() == "messageSenderChat";
|
return messageData.value(SENDER).toMap().value(_TYPE).toString() == "messageSenderChat";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatModel::MessageData::setContent(const QVariantMap &content)
|
QVector<int> ChatModel::MessageData::diff(const MessageData *message) const
|
||||||
{
|
{
|
||||||
messageData.insert(CONTENT, content);
|
QVector<int> roles;
|
||||||
|
if (message != this) {
|
||||||
|
roles.append(RoleDisplay);
|
||||||
|
if (message->messageId != messageId) {
|
||||||
|
roles.append(RoleMessageId);
|
||||||
|
}
|
||||||
|
if (message->messageContentType != messageContentType) {
|
||||||
|
roles.append(RoleMessageContentType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return roles;
|
||||||
}
|
}
|
||||||
void ChatModel::MessageData::setReplyMarkup(const QVariantMap &replyMarkup)
|
|
||||||
|
QVector<int> ChatModel::MessageData::setMessageData(const QVariantMap &data)
|
||||||
|
{
|
||||||
|
messageData = data;
|
||||||
|
QVector<int> changedRoles;
|
||||||
|
changedRoles.append(RoleDisplay);
|
||||||
|
return changedRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<int> ChatModel::MessageData::setContent(const QVariantMap &content)
|
||||||
|
{
|
||||||
|
const QString oldContentType(messageContentType);
|
||||||
|
messageData.insert(CONTENT, content);
|
||||||
|
messageContentType = content.value(_TYPE).toString();
|
||||||
|
QVector<int> changedRoles;
|
||||||
|
if (oldContentType != messageContentType) {
|
||||||
|
changedRoles.append(RoleMessageContentType);
|
||||||
|
}
|
||||||
|
changedRoles.append(RoleDisplay);
|
||||||
|
return changedRoles;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<int> ChatModel::MessageData::setReplyMarkup(const QVariantMap &replyMarkup)
|
||||||
{
|
{
|
||||||
messageData.insert(REPLY_MARKUP, replyMarkup);
|
messageData.insert(REPLY_MARKUP, replyMarkup);
|
||||||
|
QVector<int> changedRoles;
|
||||||
|
changedRoles.append(RoleDisplay);
|
||||||
|
return changedRoles;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChatModel::MessageData::lessThan(const MessageData *message1, const MessageData *message2)
|
bool ChatModel::MessageData::lessThan(const MessageData *message1, const MessageData *message2)
|
||||||
|
@ -105,7 +142,8 @@ bool ChatModel::MessageData::lessThan(const MessageData *message1, const Message
|
||||||
ChatModel::ChatModel(TDLibWrapper *tdLibWrapper) :
|
ChatModel::ChatModel(TDLibWrapper *tdLibWrapper) :
|
||||||
chatId(0),
|
chatId(0),
|
||||||
inReload(false),
|
inReload(false),
|
||||||
inIncrementalUpdate(false)
|
inIncrementalUpdate(false),
|
||||||
|
searchModeActive(false)
|
||||||
{
|
{
|
||||||
this->tdLibWrapper = tdLibWrapper;
|
this->tdLibWrapper = tdLibWrapper;
|
||||||
connect(this->tdLibWrapper, SIGNAL(messagesReceived(QVariantList, int)), this, SLOT(handleMessagesReceived(QVariantList, int)));
|
connect(this->tdLibWrapper, SIGNAL(messagesReceived(QVariantList, int)), this, SLOT(handleMessagesReceived(QVariantList, int)));
|
||||||
|
@ -370,11 +408,10 @@ void ChatModel::handleMessageReceived(qlonglong chatId, qlonglong messageId, con
|
||||||
if (chatId == this->chatId && messageIndexMap.contains(messageId)) {
|
if (chatId == this->chatId && messageIndexMap.contains(messageId)) {
|
||||||
LOG("Received a message that we already know, let's update it!");
|
LOG("Received a message that we already know, let's update it!");
|
||||||
const int position = messageIndexMap.value(messageId);
|
const int position = messageIndexMap.value(messageId);
|
||||||
MessageData *messageData = messages.at(position);
|
const QVector<int> changedRoles(messages.at(position)->setMessageData(message));
|
||||||
messageData->messageData = message;
|
|
||||||
LOG("Message was updated at index" << position);
|
LOG("Message was updated at index" << position);
|
||||||
const QModelIndex messageIndex(index(position));
|
const QModelIndex messageIndex(index(position));
|
||||||
emit dataChanged(messageIndex, messageIndex);
|
emit dataChanged(messageIndex, messageIndex, changedRoles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,11 +442,14 @@ void ChatModel::handleMessageSendSucceeded(qlonglong messageId, qlonglong oldMes
|
||||||
if (this->messageIndexMap.contains(oldMessageId)) {
|
if (this->messageIndexMap.contains(oldMessageId)) {
|
||||||
LOG("Message was successfully sent" << oldMessageId);
|
LOG("Message was successfully sent" << oldMessageId);
|
||||||
const int pos = messageIndexMap.take(oldMessageId);
|
const int pos = messageIndexMap.take(oldMessageId);
|
||||||
delete messages.at(pos);
|
MessageData* oldMessage = messages.at(pos);
|
||||||
messages.replace(pos, new MessageData(message, messageId));
|
MessageData* newMessage = new MessageData(message, messageId);
|
||||||
|
messages.replace(pos, newMessage);
|
||||||
|
const QVector<int> changedRoles(newMessage->diff(oldMessage));
|
||||||
|
delete oldMessage;
|
||||||
LOG("Message was replaced at index" << pos);
|
LOG("Message was replaced at index" << pos);
|
||||||
const QModelIndex messageIndex(index(pos));
|
const QModelIndex messageIndex(index(pos));
|
||||||
emit dataChanged(messageIndex, messageIndex);
|
emit dataChanged(messageIndex, messageIndex, changedRoles);
|
||||||
emit lastReadSentMessageUpdated(calculateLastReadSentMessageId());
|
emit lastReadSentMessageUpdated(calculateLastReadSentMessageId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,10 +488,10 @@ void ChatModel::handleMessageContentUpdated(qlonglong chatId, qlonglong messageI
|
||||||
LOG("We know the message that was updated" << messageId);
|
LOG("We know the message that was updated" << messageId);
|
||||||
const int pos = messageIndexMap.value(messageId, -1);
|
const int pos = messageIndexMap.value(messageId, -1);
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
messages.at(pos)->setContent(newContent);
|
const QVector<int> changedRoles(messages.at(pos)->setContent(newContent));
|
||||||
LOG("Message was replaced at index" << pos);
|
LOG("Message was updated at index" << pos);
|
||||||
const QModelIndex messageIndex(index(pos));
|
const QModelIndex messageIndex(index(pos));
|
||||||
emit dataChanged(messageIndex, messageIndex);
|
emit dataChanged(messageIndex, messageIndex, changedRoles);
|
||||||
emit messageUpdated(pos);
|
emit messageUpdated(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -464,10 +504,10 @@ void ChatModel::handleMessageEditedUpdated(qlonglong chatId, qlonglong messageId
|
||||||
LOG("We know the message that was updated" << messageId);
|
LOG("We know the message that was updated" << messageId);
|
||||||
const int pos = messageIndexMap.value(messageId, -1);
|
const int pos = messageIndexMap.value(messageId, -1);
|
||||||
if (pos >= 0) {
|
if (pos >= 0) {
|
||||||
messages.at(pos)->setReplyMarkup(replyMarkup);
|
const QVector<int> changedRoles(messages.at(pos)->setReplyMarkup(replyMarkup));
|
||||||
LOG("Message was edited at index" << pos);
|
LOG("Message was edited at index" << pos);
|
||||||
const QModelIndex messageIndex(index(pos));
|
const QModelIndex messageIndex(index(pos));
|
||||||
emit dataChanged(messageIndex, messageIndex);
|
emit dataChanged(messageIndex, messageIndex, changedRoles);
|
||||||
emit messageUpdated(pos);
|
emit messageUpdated(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,74 @@
|
||||||
#include "fernschreiberutils.h"
|
/*
|
||||||
|
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "fernschreiberutils.h"
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QVariant>
|
#include <QVariant>
|
||||||
|
#include <QAudioEncoderSettings>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QDirIterator>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QGeoCoordinate>
|
||||||
|
#include <QGeoLocation>
|
||||||
|
|
||||||
|
#define DEBUG_MODULE FernschreiberUtils
|
||||||
|
#include "debuglog.h"
|
||||||
|
|
||||||
FernschreiberUtils::FernschreiberUtils(QObject *parent) : QObject(parent)
|
FernschreiberUtils::FernschreiberUtils(QObject *parent) : QObject(parent)
|
||||||
{
|
{
|
||||||
|
LOG("Initializing audio recorder...");
|
||||||
|
|
||||||
|
QString temporaryDirectoryPath = this->getTemporaryDirectoryPath();
|
||||||
|
QDir temporaryDirectory(temporaryDirectoryPath);
|
||||||
|
if (!temporaryDirectory.exists()) {
|
||||||
|
temporaryDirectory.mkpath(temporaryDirectoryPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
QAudioEncoderSettings encoderSettings;
|
||||||
|
encoderSettings.setCodec("audio/vorbis");
|
||||||
|
encoderSettings.setChannelCount(1);
|
||||||
|
encoderSettings.setQuality(QMultimedia::LowQuality);
|
||||||
|
this->audioRecorder.setEncodingSettings(encoderSettings);
|
||||||
|
this->audioRecorder.setContainerFormat("ogg");
|
||||||
|
|
||||||
|
QMediaRecorder::Status audioRecorderStatus = this->audioRecorder.status();
|
||||||
|
this->handleAudioRecorderStatusChanged(audioRecorderStatus);
|
||||||
|
|
||||||
|
connect(&audioRecorder, SIGNAL(durationChanged(qlonglong)), this, SIGNAL(voiceNoteDurationChanged(qlonglong)));
|
||||||
|
connect(&audioRecorder, SIGNAL(statusChanged(QMediaRecorder::Status)), this, SLOT(handleAudioRecorderStatusChanged(QMediaRecorder::Status)));
|
||||||
|
|
||||||
|
this->geoPositionInfoSource = QGeoPositionInfoSource::createDefaultSource(this);
|
||||||
|
if (this->geoPositionInfoSource) {
|
||||||
|
LOG("Geolocation successfully initialized...");
|
||||||
|
this->geoPositionInfoSource->setUpdateInterval(5000);
|
||||||
|
connect(geoPositionInfoSource, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(handleGeoPositionUpdated(QGeoPositionInfo)));
|
||||||
|
} else {
|
||||||
|
LOG("Unable to initialize geolocation!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FernschreiberUtils::~FernschreiberUtils()
|
||||||
|
{
|
||||||
|
this->cleanUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString FernschreiberUtils::getMessageShortText(TDLibWrapper *tdLibWrapper, const QVariantMap &messageContent, const bool isChannel, const qlonglong currentUserId, const QVariantMap &messageSender)
|
QString FernschreiberUtils::getMessageShortText(TDLibWrapper *tdLibWrapper, const QVariantMap &messageContent, const bool isChannel, const qlonglong currentUserId, const QVariantMap &messageSender)
|
||||||
|
@ -128,3 +191,117 @@ QString FernschreiberUtils::getUserName(const QVariantMap &userInformation)
|
||||||
const QString lastName = userInformation.value("last_name").toString();
|
const QString lastName = userInformation.value("last_name").toString();
|
||||||
return QString(firstName + " " + lastName).trimmed();
|
return QString(firstName + " " + lastName).trimmed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FernschreiberUtils::startRecordingVoiceNote()
|
||||||
|
{
|
||||||
|
LOG("Start recording voice note...");
|
||||||
|
QDateTime thisIsNow = QDateTime::currentDateTime();
|
||||||
|
this->audioRecorder.setOutputLocation(QUrl::fromLocalFile(this->getTemporaryDirectoryPath() + "/voicenote-" + thisIsNow.toString("yyyy-MM-dd-HH-mm-ss") + ".ogg"));
|
||||||
|
this->audioRecorder.setVolume(1);
|
||||||
|
this->audioRecorder.record();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FernschreiberUtils::stopRecordingVoiceNote()
|
||||||
|
{
|
||||||
|
LOG("Stop recording voice note...");
|
||||||
|
this->audioRecorder.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FernschreiberUtils::voiceNotePath()
|
||||||
|
{
|
||||||
|
return this->audioRecorder.outputLocation().toLocalFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
FernschreiberUtils::VoiceNoteRecordingState FernschreiberUtils::getVoiceNoteRecordingState()
|
||||||
|
{
|
||||||
|
return this->voiceNoteRecordingState;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FernschreiberUtils::startGeoLocationUpdates()
|
||||||
|
{
|
||||||
|
if (this->geoPositionInfoSource) {
|
||||||
|
this->geoPositionInfoSource->startUpdates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void FernschreiberUtils::stopGeoLocationUpdates()
|
||||||
|
{
|
||||||
|
if (this->geoPositionInfoSource) {
|
||||||
|
this->geoPositionInfoSource->stopUpdates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FernschreiberUtils::supportsGeoLocation()
|
||||||
|
{
|
||||||
|
return this->geoPositionInfoSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FernschreiberUtils::handleAudioRecorderStatusChanged(QMediaRecorder::Status status)
|
||||||
|
{
|
||||||
|
LOG("Audio recorder status changed:" << status);
|
||||||
|
switch (status) {
|
||||||
|
case QMediaRecorder::UnavailableStatus:
|
||||||
|
case QMediaRecorder::UnloadedStatus:
|
||||||
|
case QMediaRecorder::LoadingStatus:
|
||||||
|
this->voiceNoteRecordingState = VoiceNoteRecordingState::Unavailable;
|
||||||
|
break;
|
||||||
|
case QMediaRecorder::LoadedStatus:
|
||||||
|
case QMediaRecorder::PausedStatus:
|
||||||
|
this->voiceNoteRecordingState = VoiceNoteRecordingState::Ready;
|
||||||
|
break;
|
||||||
|
case QMediaRecorder::StartingStatus:
|
||||||
|
this->voiceNoteRecordingState = VoiceNoteRecordingState::Starting;
|
||||||
|
break;
|
||||||
|
case QMediaRecorder::FinalizingStatus:
|
||||||
|
this->voiceNoteRecordingState = VoiceNoteRecordingState::Stopping;
|
||||||
|
break;
|
||||||
|
case QMediaRecorder::RecordingStatus:
|
||||||
|
this->voiceNoteRecordingState = VoiceNoteRecordingState::Recording;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
emit voiceNoteRecordingStateChanged(this->voiceNoteRecordingState);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FernschreiberUtils::handleGeoPositionUpdated(const QGeoPositionInfo &info)
|
||||||
|
{
|
||||||
|
LOG("Geo position was updated");
|
||||||
|
QVariantMap positionInformation;
|
||||||
|
if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) {
|
||||||
|
positionInformation.insert("horizontalAccuracy", info.attribute(QGeoPositionInfo::HorizontalAccuracy));
|
||||||
|
} else {
|
||||||
|
positionInformation.insert("horizontalAccuracy", 0);
|
||||||
|
}
|
||||||
|
if (info.hasAttribute(QGeoPositionInfo::VerticalAccuracy)) {
|
||||||
|
positionInformation.insert("verticalAccuracy", info.attribute(QGeoPositionInfo::VerticalAccuracy));
|
||||||
|
} else {
|
||||||
|
positionInformation.insert("verticalAccuracy", 0);
|
||||||
|
}
|
||||||
|
QGeoCoordinate geoCoordinate = info.coordinate();
|
||||||
|
positionInformation.insert("latitude", geoCoordinate.latitude());
|
||||||
|
positionInformation.insert("longitude", geoCoordinate.longitude());
|
||||||
|
|
||||||
|
|
||||||
|
emit newPositionInformation(positionInformation);
|
||||||
|
}
|
||||||
|
|
||||||
|
void FernschreiberUtils::cleanUp()
|
||||||
|
{
|
||||||
|
if (this->geoPositionInfoSource) {
|
||||||
|
this->geoPositionInfoSource->stopUpdates();
|
||||||
|
}
|
||||||
|
QString temporaryDirectoryPath = this->getTemporaryDirectoryPath();
|
||||||
|
QDirIterator temporaryDirectoryIterator(temporaryDirectoryPath, QDir::Files | QDir::NoDotAndDotDot | QDir::NoSymLinks, QDirIterator::Subdirectories);
|
||||||
|
while (temporaryDirectoryIterator.hasNext()) {
|
||||||
|
QString nextFilePath = temporaryDirectoryIterator.next();
|
||||||
|
if (QFile::remove(nextFilePath)) {
|
||||||
|
LOG("Temporary file removed " << nextFilePath);
|
||||||
|
} else {
|
||||||
|
LOG("Error removing temporary file " << nextFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString FernschreiberUtils::getTemporaryDirectoryPath()
|
||||||
|
{
|
||||||
|
return QStandardPaths::writableLocation(QStandardPaths::TempLocation) + + "/harbour-fernschreiber";
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,29 @@
|
||||||
|
/*
|
||||||
|
Copyright (C) 2020-21 Sebastian J. Wolf and other contributors
|
||||||
|
|
||||||
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
Fernschreiber is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
Fernschreiber is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with Fernschreiber. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef FERNSCHREIBERUTILS_H
|
#ifndef FERNSCHREIBERUTILS_H
|
||||||
#define FERNSCHREIBERUTILS_H
|
#define FERNSCHREIBERUTILS_H
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QAudioRecorder>
|
||||||
|
#include <QGeoPositionInfo>
|
||||||
|
#include <QGeoPositionInfoSource>
|
||||||
#include "tdlibwrapper.h"
|
#include "tdlibwrapper.h"
|
||||||
|
|
||||||
class FernschreiberUtils : public QObject
|
class FernschreiberUtils : public QObject
|
||||||
|
@ -9,13 +31,46 @@ class FernschreiberUtils : public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit FernschreiberUtils(QObject *parent = nullptr);
|
explicit FernschreiberUtils(QObject *parent = nullptr);
|
||||||
|
~FernschreiberUtils();
|
||||||
|
|
||||||
|
enum VoiceNoteRecordingState {
|
||||||
|
Unavailable,
|
||||||
|
Ready,
|
||||||
|
Starting,
|
||||||
|
Recording,
|
||||||
|
Stopping
|
||||||
|
};
|
||||||
|
Q_ENUM(VoiceNoteRecordingState)
|
||||||
|
|
||||||
static QString getMessageShortText(TDLibWrapper *tdLibWrapper, const QVariantMap &messageContent, const bool isChannel, const qlonglong currentUserId, const QVariantMap &messageSender);
|
static QString getMessageShortText(TDLibWrapper *tdLibWrapper, const QVariantMap &messageContent, const bool isChannel, const qlonglong currentUserId, const QVariantMap &messageSender);
|
||||||
static QString getUserName(const QVariantMap &userInformation);
|
static QString getUserName(const QVariantMap &userInformation);
|
||||||
|
|
||||||
signals:
|
Q_INVOKABLE void startRecordingVoiceNote();
|
||||||
|
Q_INVOKABLE void stopRecordingVoiceNote();
|
||||||
|
Q_INVOKABLE QString voiceNotePath();
|
||||||
|
Q_INVOKABLE VoiceNoteRecordingState getVoiceNoteRecordingState();
|
||||||
|
Q_INVOKABLE void startGeoLocationUpdates();
|
||||||
|
Q_INVOKABLE void stopGeoLocationUpdates();
|
||||||
|
Q_INVOKABLE bool supportsGeoLocation();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void voiceNoteDurationChanged(qlonglong duration);
|
||||||
|
void voiceNoteRecordingStateChanged(VoiceNoteRecordingState state);
|
||||||
|
void newPositionInformation(const QVariantMap &positionInformation);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void handleAudioRecorderStatusChanged(QMediaRecorder::Status status);
|
||||||
|
void handleGeoPositionUpdated(const QGeoPositionInfo &info);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QAudioRecorder audioRecorder;
|
||||||
|
VoiceNoteRecordingState voiceNoteRecordingState;
|
||||||
|
|
||||||
|
QGeoPositionInfoSource *geoPositionInfoSource;
|
||||||
|
|
||||||
|
void cleanUp();
|
||||||
|
QString getTemporaryDirectoryPath();
|
||||||
|
|
||||||
public slots:
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FERNSCHREIBERUTILS_H
|
#endif // FERNSCHREIBERUTILS_H
|
||||||
|
|
|
@ -82,11 +82,12 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
FernschreiberUtils *fernschreiberUtils = new FernschreiberUtils(view.data());
|
FernschreiberUtils *fernschreiberUtils = new FernschreiberUtils(view.data());
|
||||||
context->setContextProperty("fernschreiberUtils", fernschreiberUtils);
|
context->setContextProperty("fernschreiberUtils", fernschreiberUtils);
|
||||||
|
qmlRegisterUncreatableType<FernschreiberUtils>(uri, 1, 0, "FernschreiberUtilities", QString());
|
||||||
|
|
||||||
DBusAdaptor *dBusAdaptor = tdLibWrapper->getDBusAdaptor();
|
DBusAdaptor *dBusAdaptor = tdLibWrapper->getDBusAdaptor();
|
||||||
context->setContextProperty("dBusAdaptor", dBusAdaptor);
|
context->setContextProperty("dBusAdaptor", dBusAdaptor);
|
||||||
|
|
||||||
ChatListModel chatListModel(tdLibWrapper);
|
ChatListModel chatListModel(tdLibWrapper, appSettings);
|
||||||
context->setContextProperty("chatListModel", &chatListModel);
|
context->setContextProperty("chatListModel", &chatListModel);
|
||||||
QSortFilterProxyModel chatListProxyModel(view.data());
|
QSortFilterProxyModel chatListProxyModel(view.data());
|
||||||
chatListProxyModel.setSourceModel(&chatListModel);
|
chatListProxyModel.setSourceModel(&chatListModel);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2020 Slava Monich at al.
|
Copyright (C) 2020-2021 Slava Monich at al.
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
@ -107,6 +107,7 @@ void TDLibFile::init()
|
||||||
queuedSignals = 0;
|
queuedSignals = 0;
|
||||||
firstQueuedSignal = SignalCount;
|
firstQueuedSignal = SignalCount;
|
||||||
autoLoad = false;
|
autoLoad = false;
|
||||||
|
downloadHoldOffTimer = 0;
|
||||||
id = 0;
|
id = 0;
|
||||||
expected_size = 0;
|
expected_size = 0;
|
||||||
size = 0;
|
size = 0;
|
||||||
|
@ -174,7 +175,7 @@ void TDLibFile::updateTDLibWrapper(TDLibWrapper* tdlib)
|
||||||
if (tdlib) {
|
if (tdlib) {
|
||||||
connect(tdlib, SIGNAL(fileUpdated(int,QVariantMap)), SLOT(handleFileUpdated(int,QVariantMap)));
|
connect(tdlib, SIGNAL(fileUpdated(int,QVariantMap)), SLOT(handleFileUpdated(int,QVariantMap)));
|
||||||
if (autoLoad) {
|
if (autoLoad) {
|
||||||
load();
|
downloadFile();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
queueSignal(SignalTdLibChanged);
|
queueSignal(SignalTdLibChanged);
|
||||||
|
@ -187,7 +188,7 @@ void TDLibFile::setAutoLoad(bool enableAutoLoad)
|
||||||
autoLoad = enableAutoLoad;
|
autoLoad = enableAutoLoad;
|
||||||
queueSignal(SignalAutoLoadChanged);
|
queueSignal(SignalAutoLoadChanged);
|
||||||
if (autoLoad) {
|
if (autoLoad) {
|
||||||
load();
|
downloadFile();
|
||||||
}
|
}
|
||||||
emitQueuedSignals();
|
emitQueuedSignals();
|
||||||
}
|
}
|
||||||
|
@ -195,7 +196,19 @@ void TDLibFile::setAutoLoad(bool enableAutoLoad)
|
||||||
|
|
||||||
bool TDLibFile::load()
|
bool TDLibFile::load()
|
||||||
{
|
{
|
||||||
if (id && tdLibWrapper && !is_downloading_active && !is_downloading_completed && can_be_downloaded) {
|
// Manual load ignores hold-off timer
|
||||||
|
if (downloadHoldOffTimer) {
|
||||||
|
killTimer(downloadHoldOffTimer);
|
||||||
|
downloadHoldOffTimer = 0;
|
||||||
|
}
|
||||||
|
return downloadFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TDLibFile::downloadFile()
|
||||||
|
{
|
||||||
|
if (id && tdLibWrapper && !downloadHoldOffTimer &&
|
||||||
|
!is_downloading_active && !is_downloading_completed && can_be_downloaded) {
|
||||||
|
downloadHoldOffTimer = startTimer(DownloadHoldOffMs);
|
||||||
tdLibWrapper->downloadFile(id);
|
tdLibWrapper->downloadFile(id);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -205,12 +218,26 @@ bool TDLibFile::load()
|
||||||
void TDLibFile::setFileInfo(const QVariantMap &fileInfo)
|
void TDLibFile::setFileInfo(const QVariantMap &fileInfo)
|
||||||
{
|
{
|
||||||
updateFileInfo(fileInfo);
|
updateFileInfo(fileInfo);
|
||||||
|
if (is_downloading_completed && downloadHoldOffTimer) {
|
||||||
|
// Don't need this timer anymore
|
||||||
|
killTimer(downloadHoldOffTimer);
|
||||||
|
downloadHoldOffTimer = 0;
|
||||||
|
}
|
||||||
if (autoLoad) {
|
if (autoLoad) {
|
||||||
load();
|
downloadFile();
|
||||||
}
|
}
|
||||||
emitQueuedSignals();
|
emitQueuedSignals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibFile::timerEvent(QTimerEvent *)
|
||||||
|
{
|
||||||
|
killTimer(downloadHoldOffTimer);
|
||||||
|
downloadHoldOffTimer = 0;
|
||||||
|
if (autoLoad) {
|
||||||
|
downloadFile();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibFile::handleFileUpdated(int fileId, const QVariantMap &fileInfo)
|
void TDLibFile::handleFileUpdated(int fileId, const QVariantMap &fileInfo)
|
||||||
{
|
{
|
||||||
if (id == fileId) {
|
if (id == fileId) {
|
||||||
|
@ -256,6 +283,7 @@ void TDLibFile::updateFileInfo(const QVariantMap &file)
|
||||||
bool b, fileChanged = false;
|
bool b, fileChanged = false;
|
||||||
int i = file.value(ID).toInt();
|
int i = file.value(ID).toInt();
|
||||||
if (id != i) {
|
if (id != i) {
|
||||||
|
LOG("File id has changed" << id << "=>" << i);
|
||||||
id = i;
|
id = i;
|
||||||
fileChanged = true;
|
fileChanged = true;
|
||||||
queueSignal(SignalIdChanged);
|
queueSignal(SignalIdChanged);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright (C) 2020 Slava Monich at al.
|
Copyright (C) 2020-2021 Slava Monich at al.
|
||||||
|
|
||||||
This file is part of Fernschreiber.
|
This file is part of Fernschreiber.
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ class TDLibFile : public QObject
|
||||||
Q_PROPERTY(bool isUploadingActive READ isUploadingActive NOTIFY uploadingActiveChanged)
|
Q_PROPERTY(bool isUploadingActive READ isUploadingActive NOTIFY uploadingActiveChanged)
|
||||||
Q_PROPERTY(bool isUploadingCompleted READ isUploadingCompleted NOTIFY uploadingCompletedChanged)
|
Q_PROPERTY(bool isUploadingCompleted READ isUploadingCompleted NOTIFY uploadingCompletedChanged)
|
||||||
|
|
||||||
|
enum { DownloadHoldOffMs = 1000 };
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TDLibFile();
|
TDLibFile();
|
||||||
TDLibFile(TDLibWrapper *tdlib);
|
TDLibFile(TDLibWrapper *tdlib);
|
||||||
|
@ -102,10 +104,14 @@ signals:
|
||||||
private slots:
|
private slots:
|
||||||
void handleFileUpdated(int fileId, const QVariantMap &fileInfo);
|
void handleFileUpdated(int fileId, const QVariantMap &fileInfo);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void timerEvent(QTimerEvent *event) Q_DECL_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
void updateTDLibWrapper(TDLibWrapper* tdlib);
|
void updateTDLibWrapper(TDLibWrapper* tdlib);
|
||||||
void updateFileInfo(const QVariantMap &fileInfo);
|
void updateFileInfo(const QVariantMap &fileInfo);
|
||||||
|
bool downloadFile();
|
||||||
void queueSignal(uint signal);
|
void queueSignal(uint signal);
|
||||||
void emitQueuedSignals();
|
void emitQueuedSignals();
|
||||||
|
|
||||||
|
@ -114,6 +120,7 @@ private:
|
||||||
uint queuedSignals;
|
uint queuedSignals;
|
||||||
uint firstQueuedSignal;
|
uint firstQueuedSignal;
|
||||||
bool autoLoad;
|
bool autoLoad;
|
||||||
|
int downloadHoldOffTimer;
|
||||||
// file
|
// file
|
||||||
QVariantMap infoMap;
|
QVariantMap infoMap;
|
||||||
int id;
|
int id;
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace {
|
||||||
const QString POSITIONS("positions");
|
const QString POSITIONS("positions");
|
||||||
const QString PHOTO("photo");
|
const QString PHOTO("photo");
|
||||||
const QString ORDER("order");
|
const QString ORDER("order");
|
||||||
|
const QString IS_PINNED("is_pinned");
|
||||||
const QString BASIC_GROUP("basic_group");
|
const QString BASIC_GROUP("basic_group");
|
||||||
const QString SUPERGROUP("supergroup");
|
const QString SUPERGROUP("supergroup");
|
||||||
const QString LAST_MESSAGE("last_message");
|
const QString LAST_MESSAGE("last_message");
|
||||||
|
@ -287,9 +288,20 @@ void TDLibReceiver::processUpdateChatOrder(const QVariantMap &receivedInformatio
|
||||||
void TDLibReceiver::processUpdateChatPosition(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processUpdateChatPosition(const QVariantMap &receivedInformation)
|
||||||
{
|
{
|
||||||
const QString chat_id(receivedInformation.value(CHAT_ID).toString());
|
const QString chat_id(receivedInformation.value(CHAT_ID).toString());
|
||||||
const QString order(receivedInformation.value(POSITION).toMap().value(ORDER).toString());
|
QVariantMap positionMap = receivedInformation.value(POSITION).toMap();
|
||||||
LOG("Chat position updated for ID" << chat_id << "new order" << order);
|
|
||||||
emit chatOrderUpdated(chat_id, order);
|
QString updateForChatList = positionMap.value(LIST).toMap().value(TYPE).toString();
|
||||||
|
const QString order(positionMap.value(ORDER).toString());
|
||||||
|
bool is_pinned = positionMap.value(IS_PINNED).toBool();
|
||||||
|
|
||||||
|
// We are only processing main chat list updates at the moment...
|
||||||
|
if (updateForChatList == "chatListMain") {
|
||||||
|
LOG("Chat position updated for ID" << chat_id << "new order" << order << "is pinned" << is_pinned);
|
||||||
|
emit chatOrderUpdated(chat_id, order);
|
||||||
|
emit chatPinnedUpdated(chat_id.toLongLong(), is_pinned);
|
||||||
|
} else {
|
||||||
|
LOG("Received chat position update for uninteresting list" << updateForChatList << "ID" << chat_id << "new order" << order << "is pinned" << is_pinned);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processUpdateChatReadInbox(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processUpdateChatReadInbox(const QVariantMap &receivedInformation)
|
||||||
|
|
|
@ -49,6 +49,7 @@ signals:
|
||||||
void unreadChatCountUpdated(const QVariantMap &chatCountInformation);
|
void unreadChatCountUpdated(const QVariantMap &chatCountInformation);
|
||||||
void chatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage);
|
void chatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage);
|
||||||
void chatOrderUpdated(const QString &chatId, const QString &order);
|
void chatOrderUpdated(const QString &chatId, const QString &order);
|
||||||
|
void chatPinnedUpdated(qlonglong chatId, bool isPinned);
|
||||||
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 basicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
void basicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
|
||||||
|
|
|
@ -47,8 +47,10 @@ namespace {
|
||||||
const QString USERNAME("username");
|
const QString USERNAME("username");
|
||||||
const QString THREAD_ID("thread_id");
|
const QString THREAD_ID("thread_id");
|
||||||
const QString VALUE("value");
|
const QString VALUE("value");
|
||||||
|
const QString CHAT_LIST_TYPE("chat_list_type");
|
||||||
const QString _TYPE("@type");
|
const QString _TYPE("@type");
|
||||||
const QString _EXTRA("@extra");
|
const QString _EXTRA("@extra");
|
||||||
|
const QString CHAT_LIST_MAIN("chatListMain");
|
||||||
}
|
}
|
||||||
|
|
||||||
TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface, QObject *parent) : QObject(parent), joinChatRequested(false)
|
TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface, QObject *parent) : QObject(parent), joinChatRequested(false)
|
||||||
|
@ -145,6 +147,7 @@ void TDLibWrapper::initializeTDLibReciever() {
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatPermissionsUpdated(QString, QVariantMap)), this, SIGNAL(chatPermissionsUpdated(QString, QVariantMap)));
|
connect(this->tdLibReceiver, SIGNAL(chatPermissionsUpdated(QString, QVariantMap)), this, SIGNAL(chatPermissionsUpdated(QString, QVariantMap)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatPhotoUpdated(qlonglong, QVariantMap)), this, SIGNAL(chatPhotoUpdated(qlonglong, QVariantMap)));
|
connect(this->tdLibReceiver, SIGNAL(chatPhotoUpdated(qlonglong, QVariantMap)), this, SIGNAL(chatPhotoUpdated(qlonglong, QVariantMap)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatTitleUpdated(QString, QString)), this, SIGNAL(chatTitleUpdated(QString, QString)));
|
connect(this->tdLibReceiver, SIGNAL(chatTitleUpdated(QString, QString)), this, SIGNAL(chatTitleUpdated(QString, QString)));
|
||||||
|
connect(this->tdLibReceiver, SIGNAL(chatPinnedUpdated(qlonglong, bool)), this, SIGNAL(chatPinnedUpdated(qlonglong, bool)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)), this, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)));
|
connect(this->tdLibReceiver, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)), this, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(messageIsPinnedUpdated(qlonglong, qlonglong, bool)), this, SLOT(handleMessageIsPinnedUpdated(qlonglong, qlonglong, bool)));
|
connect(this->tdLibReceiver, SIGNAL(messageIsPinnedUpdated(qlonglong, qlonglong, bool)), this, SLOT(handleMessageIsPinnedUpdated(qlonglong, qlonglong, bool)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
|
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
|
||||||
|
@ -491,6 +494,56 @@ void TDLibWrapper::sendDocumentMessage(const QString &chatId, const QString &fil
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::sendVoiceNoteMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId)
|
||||||
|
{
|
||||||
|
LOG("Sending voice note message" << chatId << filePath << message << replyToMessageId);
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "sendMessage");
|
||||||
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
|
if (replyToMessageId != "0") {
|
||||||
|
requestObject.insert("reply_to_message_id", replyToMessageId);
|
||||||
|
}
|
||||||
|
QVariantMap inputMessageContent;
|
||||||
|
inputMessageContent.insert(_TYPE, "inputMessageVoiceNote");
|
||||||
|
QVariantMap formattedText;
|
||||||
|
formattedText.insert("text", message);
|
||||||
|
formattedText.insert(_TYPE, "formattedText");
|
||||||
|
inputMessageContent.insert("caption", formattedText);
|
||||||
|
QVariantMap documentInputFile;
|
||||||
|
documentInputFile.insert(_TYPE, "inputFileLocal");
|
||||||
|
documentInputFile.insert("path", filePath);
|
||||||
|
inputMessageContent.insert("voice_note", documentInputFile);
|
||||||
|
|
||||||
|
requestObject.insert("input_message_content", inputMessageContent);
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::sendLocationMessage(const QString &chatId, double latitude, double longitude, double horizontalAccuracy, const QString &replyToMessageId)
|
||||||
|
{
|
||||||
|
LOG("Sending location message" << chatId << latitude << longitude << horizontalAccuracy << replyToMessageId);
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "sendMessage");
|
||||||
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
|
if (replyToMessageId != "0") {
|
||||||
|
requestObject.insert("reply_to_message_id", replyToMessageId);
|
||||||
|
}
|
||||||
|
QVariantMap inputMessageContent;
|
||||||
|
inputMessageContent.insert(_TYPE, "inputMessageLocation");
|
||||||
|
QVariantMap location;
|
||||||
|
location.insert("latitude", latitude);
|
||||||
|
location.insert("longitude", longitude);
|
||||||
|
location.insert("horizontal_accuracy", horizontalAccuracy);
|
||||||
|
location.insert(_TYPE, "location");
|
||||||
|
inputMessageContent.insert("location", location);
|
||||||
|
|
||||||
|
inputMessageContent.insert("live_period", 0);
|
||||||
|
inputMessageContent.insert("heading", 0);
|
||||||
|
inputMessageContent.insert("proximity_alert_radius", 0);
|
||||||
|
|
||||||
|
requestObject.insert("input_message_content", inputMessageContent);
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::sendStickerMessage(const QString &chatId, const QString &fileId, const QString &replyToMessageId)
|
void TDLibWrapper::sendStickerMessage(const QString &chatId, const QString &fileId, const QString &replyToMessageId)
|
||||||
{
|
{
|
||||||
LOG("Sending sticker message" << chatId << fileId << replyToMessageId);
|
LOG("Sending sticker message" << chatId << fileId << replyToMessageId);
|
||||||
|
@ -1002,6 +1055,20 @@ void TDLibWrapper::toggleChatIsMarkedAsUnread(qlonglong chatId, bool isMarkedAsU
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::toggleChatIsPinned(qlonglong chatId, bool isPinned)
|
||||||
|
{
|
||||||
|
LOG("Toggle chat is pinned" << chatId << isPinned);
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "toggleChatIsPinned");
|
||||||
|
QVariantMap chatListMap;
|
||||||
|
chatListMap.insert(_TYPE, CHAT_LIST_MAIN);
|
||||||
|
requestObject.insert("chat_list", chatListMap);
|
||||||
|
requestObject.insert(CHAT_ID, chatId);
|
||||||
|
requestObject.insert("is_pinned", isPinned);
|
||||||
|
requestObject.insert("is_marked_as_unread", isPinned);
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::setChatDraftMessage(qlonglong chatId, qlonglong threadId, qlonglong replyToMessageId, const QString &draft)
|
void TDLibWrapper::setChatDraftMessage(qlonglong chatId, qlonglong threadId, qlonglong replyToMessageId, const QString &draft)
|
||||||
{
|
{
|
||||||
LOG("Set Draft Message" << chatId);
|
LOG("Set Draft Message" << chatId);
|
||||||
|
@ -1334,7 +1401,7 @@ void TDLibWrapper::handleChatReceived(const QVariantMap &chatInformation)
|
||||||
|
|
||||||
void TDLibWrapper::handleUnreadMessageCountUpdated(const QVariantMap &messageCountInformation)
|
void TDLibWrapper::handleUnreadMessageCountUpdated(const QVariantMap &messageCountInformation)
|
||||||
{
|
{
|
||||||
if (messageCountInformation.value("chat_list_type").toString() == "chatListMain") {
|
if (messageCountInformation.value(CHAT_LIST_TYPE).toString() == CHAT_LIST_MAIN) {
|
||||||
this->unreadMessageInformation = messageCountInformation;
|
this->unreadMessageInformation = messageCountInformation;
|
||||||
emit unreadMessageCountUpdated(messageCountInformation);
|
emit unreadMessageCountUpdated(messageCountInformation);
|
||||||
}
|
}
|
||||||
|
@ -1342,7 +1409,7 @@ void TDLibWrapper::handleUnreadMessageCountUpdated(const QVariantMap &messageCou
|
||||||
|
|
||||||
void TDLibWrapper::handleUnreadChatCountUpdated(const QVariantMap &chatCountInformation)
|
void TDLibWrapper::handleUnreadChatCountUpdated(const QVariantMap &chatCountInformation)
|
||||||
{
|
{
|
||||||
if (chatCountInformation.value("chat_list_type").toString() == "chatListMain") {
|
if (chatCountInformation.value(CHAT_LIST_TYPE).toString() == CHAT_LIST_MAIN) {
|
||||||
this->unreadChatInformation = chatCountInformation;
|
this->unreadChatInformation = chatCountInformation;
|
||||||
emit unreadChatCountUpdated(chatCountInformation);
|
emit unreadChatCountUpdated(chatCountInformation);
|
||||||
}
|
}
|
||||||
|
@ -1449,15 +1516,16 @@ void TDLibWrapper::setInitialParameters()
|
||||||
initialParameters.insert("api_id", TDLIB_API_ID);
|
initialParameters.insert("api_id", TDLIB_API_ID);
|
||||||
initialParameters.insert("api_hash", TDLIB_API_HASH);
|
initialParameters.insert("api_hash", TDLIB_API_HASH);
|
||||||
initialParameters.insert("database_directory", QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tdlib");
|
initialParameters.insert("database_directory", QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/tdlib");
|
||||||
initialParameters.insert("use_file_database", true);
|
bool onlineOnlyMode = this->appSettings->onlineOnlyMode();
|
||||||
initialParameters.insert("use_chat_info_database", true);
|
initialParameters.insert("use_file_database", !onlineOnlyMode);
|
||||||
initialParameters.insert("use_message_database", true);
|
initialParameters.insert("use_chat_info_database", !onlineOnlyMode);
|
||||||
|
initialParameters.insert("use_message_database", !onlineOnlyMode);
|
||||||
initialParameters.insert("use_secret_chats", true);
|
initialParameters.insert("use_secret_chats", true);
|
||||||
initialParameters.insert("system_language_code", QLocale::system().name());
|
initialParameters.insert("system_language_code", QLocale::system().name());
|
||||||
QSettings hardwareSettings("/etc/hw-release", QSettings::NativeFormat);
|
QSettings hardwareSettings("/etc/hw-release", QSettings::NativeFormat);
|
||||||
initialParameters.insert("device_model", hardwareSettings.value("NAME", "Unknown Mobile Device").toString());
|
initialParameters.insert("device_model", hardwareSettings.value("NAME", "Unknown Mobile Device").toString());
|
||||||
initialParameters.insert("system_version", QSysInfo::prettyProductName());
|
initialParameters.insert("system_version", QSysInfo::prettyProductName());
|
||||||
initialParameters.insert("application_version", "0.6");
|
initialParameters.insert("application_version", "0.7");
|
||||||
initialParameters.insert("enable_storage_optimizer", appSettings->storageOptimizer());
|
initialParameters.insert("enable_storage_optimizer", appSettings->storageOptimizer());
|
||||||
// initialParameters.insert("use_test_dc", true);
|
// initialParameters.insert("use_test_dc", true);
|
||||||
requestObject.insert("parameters", initialParameters);
|
requestObject.insert("parameters", initialParameters);
|
||||||
|
|
|
@ -142,6 +142,8 @@ public:
|
||||||
Q_INVOKABLE void sendPhotoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendPhotoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
||||||
Q_INVOKABLE void sendVideoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendVideoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
||||||
Q_INVOKABLE void sendDocumentMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendDocumentMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
||||||
|
Q_INVOKABLE void sendVoiceNoteMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
|
||||||
|
Q_INVOKABLE void sendLocationMessage(const QString &chatId, double latitude, double longitude, double horizontalAccuracy, const QString &replyToMessageId = "0");
|
||||||
Q_INVOKABLE void sendStickerMessage(const QString &chatId, const QString &fileId, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendStickerMessage(const QString &chatId, const QString &fileId, const QString &replyToMessageId = "0");
|
||||||
Q_INVOKABLE void sendPollMessage(const QString &chatId, const QString &question, const QVariantList &options, bool anonymous, int correctOption, bool multiple, const QString &replyToMessageId = "0");
|
Q_INVOKABLE void sendPollMessage(const QString &chatId, const QString &question, const QVariantList &options, bool anonymous, int correctOption, bool multiple, const QString &replyToMessageId = "0");
|
||||||
Q_INVOKABLE void forwardMessages(const QString &chatId, const QString &fromChatId, const QVariantList &messageIds, bool sendCopy, bool removeCaption);
|
Q_INVOKABLE void forwardMessages(const QString &chatId, const QString &fromChatId, const QVariantList &messageIds, bool sendCopy, bool removeCaption);
|
||||||
|
@ -186,6 +188,7 @@ public:
|
||||||
Q_INVOKABLE void searchPublicChats(const QString &query);
|
Q_INVOKABLE void searchPublicChats(const QString &query);
|
||||||
Q_INVOKABLE void readAllChatMentions(qlonglong chatId);
|
Q_INVOKABLE void readAllChatMentions(qlonglong chatId);
|
||||||
Q_INVOKABLE void toggleChatIsMarkedAsUnread(qlonglong chatId, bool isMarkedAsUnread);
|
Q_INVOKABLE void toggleChatIsMarkedAsUnread(qlonglong chatId, bool isMarkedAsUnread);
|
||||||
|
Q_INVOKABLE void toggleChatIsPinned(qlonglong chatId, bool isPinned);
|
||||||
Q_INVOKABLE void setChatDraftMessage(qlonglong chatId, qlonglong threadId, qlonglong replyToMessageId, const QString &draft);
|
Q_INVOKABLE void setChatDraftMessage(qlonglong chatId, qlonglong threadId, qlonglong replyToMessageId, const QString &draft);
|
||||||
|
|
||||||
// Others (candidates for extraction ;))
|
// Others (candidates for extraction ;))
|
||||||
|
@ -211,6 +214,7 @@ signals:
|
||||||
void unreadChatCountUpdated(const QVariantMap &chatCountInformation);
|
void unreadChatCountUpdated(const QVariantMap &chatCountInformation);
|
||||||
void chatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage);
|
void chatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage);
|
||||||
void chatOrderUpdated(const QString &chatId, const QString &order);
|
void chatOrderUpdated(const QString &chatId, const QString &order);
|
||||||
|
void chatPinnedUpdated(qlonglong chatId, bool isPinned);
|
||||||
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);
|
||||||
|
|
|
@ -131,14 +131,6 @@
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation>Verlasse Chat</translation>
|
<translation>Verlasse Chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Stummschaltung des Chats aufheben</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Chat stummschalten</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation>Unbekannt</translation>
|
<translation>Unbekannt</translation>
|
||||||
|
@ -191,6 +183,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation>Neuer geheimer Chat</translation>
|
<translation>Neuer geheimer Chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>Stummschaltung des Chats aufheben</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>Chat stummschalten</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -248,14 +248,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Sie</translation>
|
<translation>Sie</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Stummschaltung des Chats aufheben</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Chat stummschalten</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>Benutzerinfos</translation>
|
<translation>Benutzerinfos</translation>
|
||||||
|
@ -284,6 +276,22 @@
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation>Entwurf</translation>
|
<translation>Entwurf</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
|
<translation>Chat losheften</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation>Chat anheften</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>Stummschaltung des Chats aufheben</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>Chat stummschalten</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -419,6 +427,14 @@
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation>Im Chat suchen...</translation>
|
<translation>Im Chat suchen...</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation>Standort: Erlange Position...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation>Standort (%1/%2)</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -484,6 +500,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Dokument öffnen</translation>
|
<translation>Dokument öffnen</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation>Dokument zu Downloads kopieren</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -1085,8 +1105,16 @@
|
||||||
<translation>Download fehlgeschlagen.</translation>
|
<translation>Download fehlgeschlagen.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
<translation type="unfinished">Verbinde zum Netzwerk...</translation>
|
<translation>Tippen Sie auf die Titelleiste, um Ihre Chats zu filtern</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation>Keine passenden Chats gefunden.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation>Sie können über das Pull-Down-Menü öffentliche Chats finden oder einen Neuen erstellen.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Logging out</source>
|
<source>Logging out</source>
|
||||||
|
@ -1308,13 +1336,19 @@
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation>Kanal</translation>
|
<translation>Kanal</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 Mitglied</translation>
|
<translation>
|
||||||
|
<numerusform>%1 Mitglied</numerusform>
|
||||||
|
<numerusform>%1 Mitglieder</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 Abonnent</translation>
|
<translation>
|
||||||
|
<numerusform>%1 Abonnent</numerusform>
|
||||||
|
<numerusform>%1 Abonnenten</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
|
@ -1403,6 +1437,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>Speicheroptimierer einschalten</translation>
|
<translation>Speicheroptimierer einschalten</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation>Texteingabe nach Senden fokussieren</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation>Fokussiert die Texteingabe nach Senden einer Nachricht</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation>Nur-Online-Modus einschalten</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation>Schaltet das Offline-Caching aus. Bestimmte Features können in diesem Modus eingeschränkt sein oder fehlen. Änderungen erfordern einen Neustart von Fernschreiber, um in Kraft zu treten.</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1430,6 +1480,45 @@
|
||||||
<translation>Download fehlgeschlagen.</translation>
|
<translation>Download fehlgeschlagen.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation>Eine Sprachnachricht aufzeichnen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation>Drücken Sie den Knopf, um die Aufzeichnung zu starten</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation>Nicht verfügbar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation>Bereit</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation>Startet</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation>Zeichnet auf</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation>Stoppt</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation>Aufzeichnung verwenden</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation>Sprachnachricht (%1)</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -131,14 +131,6 @@
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation>Leaving chat</translation>
|
<translation>Leaving chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Unmute Chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Mute Chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation>Unknown</translation>
|
<translation>Unknown</translation>
|
||||||
|
@ -191,6 +183,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation>New Secret Chat</translation>
|
<translation>New Secret Chat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>Unmute Chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>Mute Chat</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -248,14 +248,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>You</translation>
|
<translation>You</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Unmute Chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Mute Chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>User Info</translation>
|
<translation>User Info</translation>
|
||||||
|
@ -284,6 +276,22 @@
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation>Draft</translation>
|
<translation>Draft</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
|
<translation>Unpin chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation>Pin chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>Unmute chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>Mute chat</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -419,6 +427,14 @@
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation>Search in chat...</translation>
|
<translation>Search in chat...</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation>Location: Obtaining position...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation>Location (%1/%2)</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -484,6 +500,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Open Document</translation>
|
<translation>Open Document</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation>Copy Document to Downloads</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -1085,12 +1105,20 @@
|
||||||
<translation>Download failed.</translation>
|
<translation>Download failed.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
<translation type="unfinished">Connecting to network...</translation>
|
<translation>Tap on the title bar to filter your chats</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation>No matching chats found.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation>You can search public chats or create a new chat via the pull-down menu.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Logging out</source>
|
<source>Logging out</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation >Logging out</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1308,13 +1336,19 @@
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation>Channel</translation>
|
<translation>Channel</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 member</translation>
|
<translation>
|
||||||
|
<numerusform>%1 member</numerusform>
|
||||||
|
<numerusform>%1 members</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 subscriber</translation>
|
<translation>
|
||||||
|
<numerusform>%1 subscriber</numerusform>
|
||||||
|
<numerusform>%1 subscribers</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
|
@ -1403,6 +1437,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>Enable storage optimizer</translation>
|
<translation>Enable storage optimizer</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation>Focus text input area after send</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation>Focus the text input area after sending a message</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation>Enable online-only mode</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1430,6 +1480,45 @@
|
||||||
<translation>Download failed.</translation>
|
<translation>Download failed.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation>Record a Voice Note</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation>Press the button to start recording</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation>Unavailable</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation>Starting</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation>Recording</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation>Stopping</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation>Use recording</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation>Voice Note (%1)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation>Ready</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1815,21 +1904,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished">has added %1 to the chat</translation>
|
<translation>has added %1 to the chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished">has removed %1 from the chat</translation>
|
<translation>has removed %1 from the chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished">have added %1 to the chat</translation>
|
<translation>have added %1 to the chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished">have removed %1 from the chat</translation>
|
<translation>have removed %1 from the chat</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -129,14 +129,6 @@
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation>Saliendo de la charla</translation>
|
<translation>Saliendo de la charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Notificar</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>No notificar</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation>Desconocido</translation>
|
<translation>Desconocido</translation>
|
||||||
|
@ -188,6 +180,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation>Charla secreta</translation>
|
<translation>Charla secreta</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>Notificar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>No notificar</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -245,14 +245,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Usted</translation>
|
<translation>Usted</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Notificar</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>No notificar</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>Usuario</translation>
|
<translation>Usuario</translation>
|
||||||
|
@ -271,16 +263,32 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as unread</source>
|
<source>Mark chat as unread</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Marcar como no leído</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Borrador</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as read</source>
|
<source>Mark chat as read</source>
|
||||||
|
<translation>Marcar como leído</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>Notificar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>No notificar</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -403,11 +411,19 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in Chat</source>
|
<source>Search in Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Buscar en charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Buscar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation>Ubicación: Recibiendo posición ...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation>Ubicación (%1/%2)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -474,6 +490,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Abrir Documento</translation>
|
<translation>Abrir Documento</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -785,21 +805,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha añadido %1 a charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha quitado %1 de charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha añadido %1 a la charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha quitado %1 de charla</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -836,7 +856,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Please enter your phone number to continue.</source>
|
<source>Please enter your phone number to continue.</source>
|
||||||
<translation>Marcar número de teléfono para continuar.</translation>
|
<translation>Marcar el número de teléfono para continuar.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Continue</source>
|
<source>Continue</source>
|
||||||
|
@ -884,7 +904,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Use the international format, e.g. %1</source>
|
<source>Use the international format, e.g. %1</source>
|
||||||
<translation>Usar el formato internacional %1</translation>
|
<translation>Usa el formato internacional %1</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>About Fernschreiber</source>
|
<source>About Fernschreiber</source>
|
||||||
|
@ -910,7 +930,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Copy Message to Clipboard</source>
|
<source>Copy Message to Clipboard</source>
|
||||||
<translation>Copiar mensaje</translation>
|
<translation>Copiar</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Message deleted</source>
|
<source>Message deleted</source>
|
||||||
|
@ -930,7 +950,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Select Message</source>
|
<source>Select Message</source>
|
||||||
<translation>Seleccionar mensaje</translation>
|
<translation>Seleccionar</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Pin Message</source>
|
<source>Pin Message</source>
|
||||||
|
@ -938,11 +958,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Message unpinned</source>
|
<source>Message unpinned</source>
|
||||||
<translation type="unfinished">Desanclar mensaje</translation>
|
<translation>Mensaje desanclado</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unpin Message</source>
|
<source>Unpin Message</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Desanclar mensaje</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1059,19 +1079,31 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Filter your chats...</source>
|
<source>Filter your chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Filtrar las charlas...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Buscar charlas</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished">Bajada de %1 exitosa.</translation>
|
<translation>Bajada de %1 exitosa.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download failed.</source>
|
<source>Download failed.</source>
|
||||||
<translation type="unfinished">Error al bajar</translation>
|
<translation>Error al bajar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
|
<translation>Tocar la barra de título para filtrar las charlas</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation>No hay coincidencias.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation>Puede buscar charlas públicas o crear un nueva charla a través de la polea de opciones.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Connecting to network...</source>
|
||||||
|
@ -1094,7 +1126,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Message unpinned</source>
|
<source>Message unpinned</source>
|
||||||
<translation>Desanclar mensaje</translation>
|
<translation>Mensaje desanclado</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1271,43 +1303,47 @@
|
||||||
<name>SearchChatsPage</name>
|
<name>SearchChatsPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>No chats found.</source>
|
<source>No chats found.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>No se han encontrado charlas.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Searching chats...</source>
|
<source>Searching chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Buscando charlas...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Private Chat</source>
|
<source>Private Chat</source>
|
||||||
<translation type="unfinished">Privado</translation>
|
<translation>Privado</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Group</source>
|
<source>Group</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Grupo</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Canal</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 miembros</translation>
|
<translation>
|
||||||
|
<numerusform>%1 miembros</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 suscriptores</translation>
|
<translation>
|
||||||
|
<numerusform>%1 suscriptores</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Buscar charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search a chat...</source>
|
<source>Search a chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>A b c</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Para iniciar la búsqueda se necesitan al menos 5 caracteres</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1342,15 +1378,15 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Notification feedback</source>
|
<source>Notification feedback</source>
|
||||||
<translation>Notificaciones</translation>
|
<translation>Notificar en </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>All events</source>
|
<source>All events</source>
|
||||||
<translation>Todos los eventos</translation>
|
<translation>Eventos</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Only new events</source>
|
<source>Only new events</source>
|
||||||
<translation>Sólo nuevos eventos</translation>
|
<translation>Nuevos eventos</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>None</source>
|
<source>None</source>
|
||||||
|
@ -1384,6 +1420,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>Optimizador de almacenamiento</translation>
|
<translation>Optimizador de almacenamiento</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation>Enfocar área de entrada de texto</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation>Enfoca el área de entrada de texto después de enviar un mensaje</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1411,6 +1463,45 @@
|
||||||
<translation>Error al bajar</translation>
|
<translation>Error al bajar</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation>Nota de voz</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation>Presionar el botón para iniciar a grabar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation>No diponible</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation>Iniciando</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation>Grabando</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation>Deteniendo</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation>Usar grabación</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation>Nota de voz (%1)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation>Listo</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1796,21 +1887,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha añadido %1 a la charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha quitado %1 de la charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha añadido %1 a la charla</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha añadido %1 de la charla</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -131,14 +131,6 @@
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation>Poistutaan keskustelusta</translation>
|
<translation>Poistutaan keskustelusta</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Poista keskustelun vaimennus</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Vaimenna keskustelu</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation>Tuntematon</translation>
|
<translation>Tuntematon</translation>
|
||||||
|
@ -191,6 +183,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation>Uusi salattu keskustelu</translation>
|
<translation>Uusi salattu keskustelu</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>Poista keskustelun vaimennus</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>Vaimenna keskustelu</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -248,14 +248,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Sinä</translation>
|
<translation>Sinä</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Poista keskustelun vaimennus</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Vaimenna keskustelu</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>Käyttäjän tiedot</translation>
|
<translation>Käyttäjän tiedot</translation>
|
||||||
|
@ -274,16 +266,32 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as unread</source>
|
<source>Mark chat as unread</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Merkitse keskustelu lukemattomaksi</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Luonnos</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as read</source>
|
<source>Mark chat as read</source>
|
||||||
|
<translation>Merkitse keskustelu luetuksi</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>Poista keskustelun vaimennus</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>Vaimenna keskustelu</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -413,11 +421,19 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in Chat</source>
|
<source>Search in Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Etsi keskustelusta</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Etsi keskustelusta...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation>Sijainti: Paikannetaan...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation>Sijainti (%1/%2)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -485,6 +501,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Avaa dokumentti</translation>
|
<translation>Avaa dokumentti</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -796,21 +816,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>lisäsi käyttäjän %1 keskusteluun</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>posit käyttäjän %1 keskustelusta</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>lisäsit käyttäjän %1 keskusteluun</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>poistit käyttäjän %1 keskustelusta</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -949,11 +969,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Message unpinned</source>
|
<source>Message unpinned</source>
|
||||||
<translation type="unfinished">Viestin kiinnitys poistettu</translation>
|
<translation>Viestin kiinnitys poistettu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unpin Message</source>
|
<source>Unpin Message</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Poista viestin kiinnitys</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1071,19 +1091,31 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Filter your chats...</source>
|
<source>Filter your chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Suodata keskustelujasi...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Etsi keskusteluista</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Tiedoston %1 lataus onnistui.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download failed.</source>
|
<source>Download failed.</source>
|
||||||
<translation type="unfinished">Lataus epäonnistui.</translation>
|
<translation>Lataus epäonnistui.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
|
<translation>Kosketa otsikkopalkkia suodattaaksesi keskusteluja</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation>Hakua vastaavia keskusteluja ei löytynyt,</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation>Voit etsiä julkisia keskusteluja tai luoda uuden keskustelun alasvetovalikosta.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Connecting to network...</source>
|
||||||
|
@ -1291,43 +1323,49 @@
|
||||||
<name>SearchChatsPage</name>
|
<name>SearchChatsPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>No chats found.</source>
|
<source>No chats found.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Keskusteluja ei löytynyt</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Searching chats...</source>
|
<source>Searching chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Etsitään keskusteluja...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Private Chat</source>
|
<source>Private Chat</source>
|
||||||
<translation type="unfinished">Yksityinen keskustelu</translation>
|
<translation>Yksityinen keskustelu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Group</source>
|
<source>Group</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Ryhmä</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Kanava</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 jäsen</translation>
|
<translation>
|
||||||
|
<numerusform>%1 jäsen</numerusform>
|
||||||
|
<numerusform>%1 jäsentä</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 tilaaja</translation>
|
<translation>
|
||||||
|
<numerusform>%1 tilaaja</numerusform>
|
||||||
|
<numerusform>%1 tilaajaa</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Etsi keskusteluja</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search a chat...</source>
|
<source>Search a chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Etsi keskustelua...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Syötä hakusanasi etsiäksesi (vähintään 5 merkkiä tarvitaan)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1404,6 +1442,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>Käytä tallennustilan optimointia</translation>
|
<translation>Käytä tallennustilan optimointia</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation>Kohdista tekstinsyöttökenttä lähetyksen jälkeen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation>Kohdista tekstinsyöttökenttä viestin lähetyksen jälkeen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1431,6 +1485,45 @@
|
||||||
<translation>Lataus epäonnistui.</translation>
|
<translation>Lataus epäonnistui.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation>Nauhoita ääniviesti</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation>Paina nappia aloittaaksesi nauhoituksen</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation>Ei saatavilla</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation>Aloitetaan</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation>Nauhoitetaan</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation>Lopetetaan</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation>Käytä nauhoitusta</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation>Ääniviesti (%1)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation>Valmis</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1816,21 +1909,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>lisäsi käyttäjä %1 keskusteluun</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>posit käyttäjän %1 keskustelusta</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>lisäsit käyttäjän %1 keskusteluun</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>poistit käyttäjän %1 keskustelusta</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -129,14 +129,6 @@
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation type="unfinished">Csevegés némítás feloldása</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation type="unfinished">Csevegés némítása</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation type="unfinished">Ismeretlen</translation>
|
<translation type="unfinished">Ismeretlen</translation>
|
||||||
|
@ -188,6 +180,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>Csevegés némítás feloldása</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>Csevegés némítása</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -245,14 +245,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation type="unfinished">Te</translation>
|
<translation type="unfinished">Te</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation type="unfinished">Csevegés némítás feloldása</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation type="unfinished">Csevegés némítása</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
|
@ -281,6 +273,22 @@
|
||||||
<source>Mark chat as read</source>
|
<source>Mark chat as read</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>Csevegés némítás feloldása</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>Csevegés némítása</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -409,6 +417,14 @@
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -474,6 +490,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Dokumentum megyitása</translation>
|
<translation>Dokumentum megyitása</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -1074,8 +1094,16 @@
|
||||||
<translation type="unfinished">A letöltés nem sikerült.</translation>
|
<translation type="unfinished">A letöltés nem sikerült.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
<translation type="unfinished">Csatlakozás a hálózathoz...</translation>
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Logging out</source>
|
<source>Logging out</source>
|
||||||
|
@ -1289,13 +1317,17 @@
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 tag</translation>
|
<translation type="unfinished">
|
||||||
|
<numerusform>%1 tag</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 feliratkozott</translation>
|
<translation type="unfinished">
|
||||||
|
<numerusform>%1 feliratkozott</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
|
@ -1384,6 +1416,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1411,6 +1459,45 @@
|
||||||
<translation>A letöltés nem sikerült.</translation>
|
<translation>A letöltés nem sikerült.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -131,14 +131,6 @@
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation>Lascia chat</translation>
|
<translation>Lascia chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Riattiva suoni chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Silenzia chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation>Sconosciuto</translation>
|
<translation>Sconosciuto</translation>
|
||||||
|
@ -191,6 +183,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation>Nuova chat segreta</translation>
|
<translation>Nuova chat segreta</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>Riattiva suoni chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>Silenzia chat</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -248,14 +248,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Tu</translation>
|
<translation>Tu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Riattiva suoni chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Silenzia chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>Info utente</translation>
|
<translation>Info utente</translation>
|
||||||
|
@ -274,15 +266,31 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as unread</source>
|
<source>Mark chat as unread</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Segna chat come non letta</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Bozza</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as read</source>
|
<source>Mark chat as read</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Segna chat come letta</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
|
<translation>Togli chat in evidenza</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation>Metti chat in evidenza</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>Riattiva suoni chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>Silenzia chat</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -413,11 +421,19 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in Chat</source>
|
<source>Search in Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Cerca nella chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Cerca nella chat...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation>Posizione: ottengo posizione...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation>Posizione(%1/%2)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -484,6 +500,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Apri documento</translation>
|
<translation>Apri documento</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -795,21 +815,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha aggiunto %1 alla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha rimosso %1 dalla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>hai aggiunto %1 alla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>hai rimosso %1 dalla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -948,11 +968,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Message unpinned</source>
|
<source>Message unpinned</source>
|
||||||
<translation type="unfinished">Messaggio non più in evidenza</translation>
|
<translation>Messaggio non più in evidenza</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unpin Message</source>
|
<source>Unpin Message</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Togli messaggio in evidenza</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1070,19 +1090,31 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Filter your chats...</source>
|
<source>Filter your chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Filtra le chat...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Ricerca chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished">Download di %1 completato.</translation>
|
<translation>Download di %1 completato.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download failed.</source>
|
<source>Download failed.</source>
|
||||||
<translation type="unfinished">Download non riuscito.</translation>
|
<translation>Download non riuscito.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
|
<translation>Clicca sulla barra del titolo per filtrare le tue chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation>Nessuna chat corrispondente.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation>Puoi creare una nuova chat o cercare chat pubbliche dal menu a trascinamento.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Connecting to network...</source>
|
||||||
|
@ -1290,43 +1322,49 @@
|
||||||
<name>SearchChatsPage</name>
|
<name>SearchChatsPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>No chats found.</source>
|
<source>No chats found.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Nessuna chat trovata.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Searching chats...</source>
|
<source>Searching chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Ricerca chat...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Private Chat</source>
|
<source>Private Chat</source>
|
||||||
<translation type="unfinished">Chat privata</translation>
|
<translation>Chat privata</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Group</source>
|
<source>Group</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Gruppo</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Canale</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 membro</translation>
|
<translation>
|
||||||
|
<numerusform>%1 membro</numerusform>
|
||||||
|
<numerusform>%1 membri</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 abbonato</translation>
|
<translation>
|
||||||
|
<numerusform>%1 abbonato</numerusform>
|
||||||
|
<numerusform>%1 abbonati</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Cerca chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search a chat...</source>
|
<source>Search a chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Cerca chat...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Scrivi il testo che vuoi cercare (almeno 5 caratteri)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1403,6 +1441,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>Abilita ottimizzazione memoria</translation>
|
<translation>Abilita ottimizzazione memoria</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation>Tastiera in primo piano dopo invio</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation>Mantieni la tastiera in primo piano dopo aver inviato un messaggio</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1430,6 +1484,45 @@
|
||||||
<translation>Download non riuscito.</translation>
|
<translation>Download non riuscito.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation>Registra una nota vocale</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation>Premi il pulsante per iniziare la registrazione</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation>Non disponibile</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation>Inizia</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation>In registrazione</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation>Stop</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation>Usa registrazione</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation>Nota vocale (%1)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation>Pronto</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1815,21 +1908,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha aggiunto %1 alla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>ha rimosso %1 dalla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>hai aggiunto %1 alla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>hai rimosso %1 dalla chat</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -105,14 +105,6 @@
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationPageContent</name>
|
<name>ChatInformationPageContent</name>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Wyłącz wyciszenie czatu</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Wycisz czat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation>Nieznany</translation>
|
<translation>Nieznany</translation>
|
||||||
|
@ -194,6 +186,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation>Nowy tajny czat</translation>
|
<translation>Nowy tajny czat</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>Wyłącz wyciszenie czatu</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>Wycisz czat</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -251,14 +251,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Ty</translation>
|
<translation>Ty</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Wyłącz wyciszenie czatu</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Wycisz czat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>Informacje o użytkowniku</translation>
|
<translation>Informacje o użytkowniku</translation>
|
||||||
|
@ -277,16 +269,32 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as unread</source>
|
<source>Mark chat as unread</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Oznacz czat jako nieprzeczytany</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Kopia robocza</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as read</source>
|
<source>Mark chat as read</source>
|
||||||
|
<translation>Oznacz czat jako przeczytany</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>Wyłącz wyciszenie czatu</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>Wycisz czat</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -423,11 +431,19 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in Chat</source>
|
<source>Search in Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Wyszukaj w czacie</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Wyszukaj w czacie</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation>Lokalizacja: Uzyskanie pozycji ...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation>Lokalizacja (%1/%2)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -494,6 +510,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Otwórz dokument</translation>
|
<translation>Otwórz dokument</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -805,21 +825,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>dodał %1 do czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>usunął %1 z czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>dodsałem %1 do czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>usunąłem %1 z czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -958,11 +978,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Message unpinned</source>
|
<source>Message unpinned</source>
|
||||||
<translation type="unfinished">Wiadomość opięta</translation>
|
<translation>Wiadomość odpięta</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unpin Message</source>
|
<source>Unpin Message</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Odepnij wiadomość</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1081,19 +1101,31 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Filter your chats...</source>
|
<source>Filter your chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Filtruj swoje czaty...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Wyszukaj czaty</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Pobieranie %1 zakończone sukcesem</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download failed.</source>
|
<source>Download failed.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Nieudane pobranie</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
|
<translation>Dotknij paska tytułowego, aby filtrować swoje czaty</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation>Brak pasujących czatów</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation>Możesz przeszukiwać czaty publiczne lub utworzyć nowy czat za pomocą menu rozwijanego z góry.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Connecting to network...</source>
|
||||||
|
@ -1309,43 +1341,51 @@
|
||||||
<name>SearchChatsPage</name>
|
<name>SearchChatsPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>No chats found.</source>
|
<source>No chats found.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Brak pasujących czatów</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Searching chats...</source>
|
<source>Searching chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Wyszukiwanie czatów...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Private Chat</source>
|
<source>Private Chat</source>
|
||||||
<translation type="unfinished">Prywatny czat</translation>
|
<translation>Prywatny czat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Group</source>
|
<source>Group</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Grupa</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Kanał</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 członek</translation>
|
<translation>
|
||||||
|
<numerusform>%1 członek</numerusform>
|
||||||
|
<numerusform>%1 członków</numerusform>
|
||||||
|
<numerusform>%1 członków</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 subskrybent</translation>
|
<translation>
|
||||||
|
<numerusform>%1 subskrybent</numerusform>
|
||||||
|
<numerusform>%1 subskrybentów</numerusform>
|
||||||
|
<numerusform>%1 subskrybentów</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Wyszukaj czaty</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search a chat...</source>
|
<source>Search a chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Wyszukaj czat...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Wprowadź zapytanie aby zacząć wyszukiwanie (minimum 5 znaków)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1422,6 +1462,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>Włącz optymalizację pamięci</translation>
|
<translation>Włącz optymalizację pamięci</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation>Po wysłaniu zaznacz pole wprowadzania tekstu</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation>Po wysłaniu wiadomości zaznacz pole wprowadzania tekstu</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1449,6 +1505,45 @@
|
||||||
<translation>Nieudane pobieranie</translation>
|
<translation>Nieudane pobieranie</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation>Nagraj notatkę głosową</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation>Naciśnij przycisk, aby zacząć nagrywać</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation>Niedostepne</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation>Uruchamianie</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation>Nagrywanie</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation>Zatrzymywanie</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation>Użyj nagrywania</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation>Notatka głosowa (%1)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation>Gotowy</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1834,21 +1929,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>dodał %1 do czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>usunął %1 z czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>dodałem %1 do czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>usunąłem %1 z czatu</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -123,59 +123,51 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Leave Chat</source>
|
<source>Leave Chat</source>
|
||||||
<translation type="unfinished">Выйти из чата</translation>
|
<translation>Выйти из чата</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Join Chat</source>
|
<source>Join Chat</source>
|
||||||
<translation type="unfinished">Зайти в чат</translation>
|
<translation>Зайти в чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation type="unfinished">Выход из чата</translation>
|
<translation>Выход из чата</translation>
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation type="unfinished">Включить уведомления</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation type="unfinished">Выключить уведомления</translation>
|
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation type="unfinished">Неизвестный</translation>
|
<translation>Неизвестный</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Chat Title</source>
|
<source>Chat Title</source>
|
||||||
<comment>group title header</comment>
|
<comment>group title header</comment>
|
||||||
<translation type="unfinished">Заголовок чата</translation>
|
<translation>Заголовок чата</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enter 1-128 characters</source>
|
<source>Enter 1-128 characters</source>
|
||||||
<translation type="unfinished">Введите 1-128 символов</translation>
|
<translation>Введите 1-128 символов</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>There is no information text available, yet.</source>
|
<source>There is no information text available, yet.</source>
|
||||||
<translation type="unfinished">Информация отсутствует</translation>
|
<translation>Информация отсутствует</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Info</source>
|
<source>Info</source>
|
||||||
<comment>group or user infotext header</comment>
|
<comment>group or user infotext header</comment>
|
||||||
<translation type="unfinished">Информация</translation>
|
<translation>Информация</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Phone Number</source>
|
<source>Phone Number</source>
|
||||||
<comment>user phone number header</comment>
|
<comment>user phone number header</comment>
|
||||||
<translation type="unfinished">Номер телефона</translation>
|
<translation>Номер телефона</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Invite Link</source>
|
<source>Invite Link</source>
|
||||||
<comment>header</comment>
|
<comment>header</comment>
|
||||||
<translation type="unfinished">Ссылка для приглашения</translation>
|
<translation>Ссылка для приглашения</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>The Invite Link has been copied to the clipboard.</source>
|
<source>The Invite Link has been copied to the clipboard.</source>
|
||||||
<translation type="unfinished">Ссылка для приглашения скопирована в буффер обмена</translation>
|
<translation>Ссылка для приглашения скопирована в буффер обмена</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>%1, %2</source>
|
<source>%1, %2</source>
|
||||||
|
@ -194,6 +186,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation>Новый секретный чат</translation>
|
<translation>Новый секретный чат</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>Включить уведомления</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>Выключить уведомления</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -228,17 +228,17 @@
|
||||||
<message>
|
<message>
|
||||||
<source>Groups</source>
|
<source>Groups</source>
|
||||||
<comment>Button: groups in common (short)</comment>
|
<comment>Button: groups in common (short)</comment>
|
||||||
<translation type="unfinished">Группы</translation>
|
<translation>Группы</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Members</source>
|
<source>Members</source>
|
||||||
<comment>Button: Group Members</comment>
|
<comment>Button: Group Members</comment>
|
||||||
<translation type="unfinished">Участники группы</translation>
|
<translation>Участники группы</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Settings</source>
|
<source>Settings</source>
|
||||||
<comment>Button: Chat Settings</comment>
|
<comment>Button: Chat Settings</comment>
|
||||||
<translation type="unfinished">Настройки</translation>
|
<translation>Настройки</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -251,14 +251,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Вы</translation>
|
<translation>Вы</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Включить уведомления</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Выключить уведомления</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>Информация о пользователе</translation>
|
<translation>Информация о пользователе</translation>
|
||||||
|
@ -277,16 +269,32 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as unread</source>
|
<source>Mark chat as unread</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Отметить чат как непрочитанный</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Черновик</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as read</source>
|
<source>Mark chat as read</source>
|
||||||
|
<translation>Отметить чат как прочитанный</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>Включить уведомления</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>Выключить уведомления</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -423,11 +431,19 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in Chat</source>
|
<source>Search in Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Найти в Чате</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Поиск...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation type="unfinished">Определение координат...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation type="unfinished">Местоположение (%1/%2)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -438,18 +454,18 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>You don't have any chats yet.</source>
|
<source>You don't have any chats yet.</source>
|
||||||
<translation type="unfinished">Тут пока ничего нет</translation>
|
<translation>Тут пока ничего нет</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>unread message</source>
|
<source>unread message</source>
|
||||||
<translation>непрочитанное сообщение</translation>
|
<translation>сообщение</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>unread messages</source>
|
<source>unread messages</source>
|
||||||
<translation>непрочитанных сообщений</translation>
|
<translation>сообщений</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>in</source>
|
<source>in</source>
|
||||||
|
@ -469,7 +485,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connected</source>
|
<source>Connected</source>
|
||||||
<translation>Подключен</translation>
|
<translation>В сети</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Updating content...</source>
|
<source>Updating content...</source>
|
||||||
|
@ -477,11 +493,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>chat</source>
|
<source>chat</source>
|
||||||
<translation>чат</translation>
|
<translation>чате</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>chats</source>
|
<source>chats</source>
|
||||||
<translation>чаты</translation>
|
<translation>чатах</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -494,6 +510,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Открыть документ</translation>
|
<translation>Открыть документ</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -805,21 +825,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">%1 добавлен в чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">%1 удалён из чата</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">%1 добавлены в чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">%1 удалены из чата</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -958,11 +978,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Message unpinned</source>
|
<source>Message unpinned</source>
|
||||||
<translation type="unfinished">Сообщение откреплено</translation>
|
<translation>Сообщение откреплено</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Unpin Message</source>
|
<source>Unpin Message</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">Открепить сообщение</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -991,7 +1011,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>You don't have any contacts.</source>
|
<source>You don't have any contacts.</source>
|
||||||
<translation type="unfinished">У вас нет никаких контактов.</translation>
|
<translation>У вас нет никаких контактов.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Private Chat</source>
|
<source>Private Chat</source>
|
||||||
|
@ -1081,19 +1101,31 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Filter your chats...</source>
|
<source>Filter your chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Выбрать чат...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Найти Чаты</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
<translation type="unfinished">Успешно скачано %1.</translation>
|
<translation>Успешно скачано %1.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download failed.</source>
|
<source>Download failed.</source>
|
||||||
<translation type="unfinished">Ошибка скачивания.</translation>
|
<translation>Ошибка скачивания.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
|
<translation>Коснитесь строки заголовка, чтобы отфильтровать ваши чаты</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation type="unfinished">Совпадающих чатов не найдено.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation>Вы можете искать публичные чаты или создать новый чат с помощью выпадающего меню</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Connecting to network...</source>
|
||||||
|
@ -1309,43 +1341,51 @@
|
||||||
<name>SearchChatsPage</name>
|
<name>SearchChatsPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>No chats found.</source>
|
<source>No chats found.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Чаты не найдены</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Searching chats...</source>
|
<source>Searching chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Идёт поиск чатов...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Private Chat</source>
|
<source>Private Chat</source>
|
||||||
<translation type="unfinished">Приватный Чат</translation>
|
<translation>Приватный Чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Group</source>
|
<source>Group</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Группа</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Канал</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 участников</translation>
|
<translation type="unfinished">
|
||||||
|
<numerusform>%1 участников</numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 подписчиков</translation>
|
<translation type="unfinished">
|
||||||
|
<numerusform>%1 подписчиков</numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Найти Чаты</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search a chat...</source>
|
<source>Search a chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Поиск...</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Введите не менее 5 символов, чтобы начать поиск</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1422,6 +1462,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>Включить оптимизацию хранилища</translation>
|
<translation>Включить оптимизацию хранилища</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation>Приоритет фокусировки при разговоре в чате</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation>Сфокусироваться на поле ввода текста после отправки сообщения</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1449,6 +1505,45 @@
|
||||||
<translation>Ошибка скачивания.</translation>
|
<translation>Ошибка скачивания.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation>Голосовое сообщение</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation>Коснитесь кнопки для записи</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation>Недоступно</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation>Пуск</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation>Запись</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation>Стоп</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation>Использовать запись</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation>Аудиозаметка (%1)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation>Готов</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1834,21 +1929,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">%1 добавлен в чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">%1 удалён из чата</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">%1 добавлены в чат</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished">%1 удалены из чата</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -131,14 +131,6 @@
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation>Lämnar chatten</translation>
|
<translation>Lämnar chatten</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Slå på chatten</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Stäng av chatten</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation>Okänd</translation>
|
<translation>Okänd</translation>
|
||||||
|
@ -191,6 +183,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation>Ny hemlig chatt</translation>
|
<translation>Ny hemlig chatt</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>Slå på chatten</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>Stäng av chatten</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -248,14 +248,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>Du</translation>
|
<translation>Du</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Slå på chatten</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Stäng av chatten</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>Användarinfo</translation>
|
<translation>Användarinfo</translation>
|
||||||
|
@ -278,12 +270,28 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>Utkast</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as read</source>
|
<source>Mark chat as read</source>
|
||||||
<translation>Markera chatten som läst</translation>
|
<translation>Markera chatten som läst</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>Slå på chatten</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>Stäng av chatten</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -419,6 +427,14 @@
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation>Sök i chatten...</translation>
|
<translation>Sök i chatten...</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation>Plats: Hämtar position...</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation>Plats (%1/%2)</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -484,6 +500,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Öppna dokument</translation>
|
<translation>Öppna dokument</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -1085,8 +1105,16 @@
|
||||||
<translation>Nerladdning misslyckades.</translation>
|
<translation>Nerladdning misslyckades.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
<translation type="unfinished">Ansluter till nätverket...</translation>
|
<translation>Tryck på titelfältet för att filtrera dina chattar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation>Ingen passande chatt hittades.</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation>Du kan söka efter allmänna chattar eller skapa en ny chatt via toppmenyn.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Logging out</source>
|
<source>Logging out</source>
|
||||||
|
@ -1308,13 +1336,19 @@
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation>Kanal</translation>
|
<translation>Kanal</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation>%1 medlemmar</translation>
|
<translation>
|
||||||
|
<numerusform>%1 medlem</numerusform>
|
||||||
|
<numerusform>%1 medlemmar</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation>%1 prenumeranter</translation>
|
<translation>
|
||||||
|
<numerusform>%1 prenumerant</numerusform>
|
||||||
|
<numerusform>%1 prenumeranter</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
|
@ -1403,6 +1437,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>Aktivera lagringsoptimering</translation>
|
<translation>Aktivera lagringsoptimering</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation>Fokusera textinmatningsfältet efter sändning</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation>Fokusera textinmatningsfältet efter att ett meddelande skickats</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1430,6 +1480,45 @@
|
||||||
<translation>Nerladdning misslyckades.</translation>
|
<translation>Nerladdning misslyckades.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation>Spela in ett röstmeddelande</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation>Tryck på knappen för att starta inspelning</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation>Ej tillgänglig</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation>Startar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation>Spelar in</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation>Stoppar</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation>Använd inspelning</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation>Röstmeddelande (%1)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation>Klar</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
|
@ -129,14 +129,6 @@
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation>正在离开对话</translation>
|
<translation>正在离开对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>取消对话静音</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>静音对话</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation>未知</translation>
|
<translation>未知</translation>
|
||||||
|
@ -188,6 +180,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation>新加密对话</translation>
|
<translation>新加密对话</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation>取消对话静音</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation>静音对话</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -245,14 +245,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>你</translation>
|
<translation>你</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>取消对话静音</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>静音对话</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>用户信息</translation>
|
<translation>用户信息</translation>
|
||||||
|
@ -271,16 +263,32 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as unread</source>
|
<source>Mark chat as unread</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>标记此对话为未读</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>草稿</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Mark chat as read</source>
|
<source>Mark chat as read</source>
|
||||||
|
<translation>标记为已读</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation>取消对话静音</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation>静音对话</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -403,11 +411,19 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in Chat</source>
|
<source>Search in Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>对话内搜索</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>正在搜索对话内容…</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation>位置:正在获取位置…</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation>位置 (%1/%2)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -425,7 +441,8 @@
|
||||||
<name>CoverPage</name>
|
<name>CoverPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>unread message</source>
|
<source>unread message</source>
|
||||||
<translation>未读消息</translation>
|
<translation>未读
|
||||||
|
消息</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>unread messages</source>
|
<source>unread messages</source>
|
||||||
|
@ -474,6 +491,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>打开文档</translation>
|
<translation>打开文档</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -574,7 +595,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>sent a voice note</source>
|
<source>sent a voice note</source>
|
||||||
<translation>发送语言消息</translation>
|
<translation>发送语音消息</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>sent a document</source>
|
<source>sent a document</source>
|
||||||
|
@ -785,21 +806,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>已加入 %1 到此对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>已从此对话移除 %1</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>已加入 %1 到此对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>已从此对话移除 %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1059,11 +1080,11 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Filter your chats...</source>
|
<source>Filter your chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>筛选你的对话…</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>搜索对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Download of %1 successful.</source>
|
<source>Download of %1 successful.</source>
|
||||||
|
@ -1074,8 +1095,16 @@
|
||||||
<translation>下载失败。</translation>
|
<translation>下载失败。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
<translation type="unfinished">正在连接到网络…</translation>
|
<translation>点击顶部状态栏即可筛选你的对话</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation>没有找到匹配的对话。</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation>你可以搜索公共对话或通过下拉菜单创建新对话。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Logging out</source>
|
<source>Logging out</source>
|
||||||
|
@ -1271,43 +1300,47 @@
|
||||||
<name>SearchChatsPage</name>
|
<name>SearchChatsPage</name>
|
||||||
<message>
|
<message>
|
||||||
<source>No chats found.</source>
|
<source>No chats found.</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>没有找到对话。</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Searching chats...</source>
|
<source>Searching chats...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>正在搜索对话…</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Private Chat</source>
|
<source>Private Chat</source>
|
||||||
<translation type="unfinished">个人对话</translation>
|
<translation>个人对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Group</source>
|
<source>Group</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>群组</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>频道</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 位成员</translation>
|
<translation>
|
||||||
|
<numerusform>%1 位成员</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 位订阅者</translation>
|
<translation>
|
||||||
|
<numerusform>%1 位订阅者</numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>搜索对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search a chat...</source>
|
<source>Search a chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>搜索对话…</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
<source>Enter your query to start searching (at least 5 characters needed)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>输入你要搜索的内容(至少需要输入5个字符)</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
|
@ -1384,6 +1417,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation>启用储存加速器</translation>
|
<translation>启用储存加速器</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation>发送后聚焦文本输入区域</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation>发送消息后聚焦文本输入区域</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1411,6 +1460,45 @@
|
||||||
<translation>下载失败</translation>
|
<translation>下载失败</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation>录制语音消息</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation>按下按钮即可开始录音</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation>不可用</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation>正在启动</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation>正在录音</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation>正在停止</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation>使用录音</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation>语音消息 (%1)</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation>就绪</translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
@ -1788,7 +1876,7 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Closed!</source>
|
<source>Closed!</source>
|
||||||
<translation>已关闭!</translation>
|
<translation>已关闭!</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Pending acknowledgement</source>
|
<source>Pending acknowledgement</source>
|
||||||
|
@ -1796,21 +1884,21 @@
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has added %1 to the chat</source>
|
<source>has added %1 to the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>已加入 %1 到此对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>has removed %1 from the chat</source>
|
<source>has removed %1 from the chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation>已从此对话移除 %1</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have added %1 to the chat</source>
|
<source>have added %1 to the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>已加入 %1 到此对话</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>have removed %1 from the chat</source>
|
<source>have removed %1 from the chat</source>
|
||||||
<comment>myself</comment>
|
<comment>myself</comment>
|
||||||
<translation type="unfinished"></translation>
|
<translation>已从此对话移除 %1</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
</TS>
|
</TS>
|
||||||
|
|
|
@ -131,14 +131,6 @@
|
||||||
<source>Leaving chat</source>
|
<source>Leaving chat</source>
|
||||||
<translation>Leaving chat</translation>
|
<translation>Leaving chat</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Unmute Chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Mute Chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>Unknown</source>
|
<source>Unknown</source>
|
||||||
<translation>Unknown</translation>
|
<translation>Unknown</translation>
|
||||||
|
@ -191,6 +183,14 @@
|
||||||
<source>New Secret Chat</source>
|
<source>New Secret Chat</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute Chat</source>
|
||||||
|
<translation type="unfinished">Unmute Chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute Chat</source>
|
||||||
|
<translation type="unfinished">Mute Chat</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatInformationTabItemMembersGroups</name>
|
<name>ChatInformationTabItemMembersGroups</name>
|
||||||
|
@ -248,14 +248,6 @@
|
||||||
<source>You</source>
|
<source>You</source>
|
||||||
<translation>You</translation>
|
<translation>You</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
|
||||||
<source>Unmute Chat</source>
|
|
||||||
<translation>Unmute Chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
|
||||||
<source>Mute Chat</source>
|
|
||||||
<translation>Mute Chat</translation>
|
|
||||||
</message>
|
|
||||||
<message>
|
<message>
|
||||||
<source>User Info</source>
|
<source>User Info</source>
|
||||||
<translation>User Info</translation>
|
<translation>User Info</translation>
|
||||||
|
@ -284,6 +276,22 @@
|
||||||
<source>Draft</source>
|
<source>Draft</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unpin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Pin chat</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unmute chat</source>
|
||||||
|
<translation type="unfinished">Unmute chat</translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Mute chat</source>
|
||||||
|
<translation type="unfinished">Mute chat</translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatPage</name>
|
<name>ChatPage</name>
|
||||||
|
@ -419,6 +427,14 @@
|
||||||
<source>Search in chat...</source>
|
<source>Search in chat...</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location: Obtaining position...</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Location (%1/%2)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>ChatSelectionPage</name>
|
<name>ChatSelectionPage</name>
|
||||||
|
@ -484,6 +500,10 @@
|
||||||
<source>Open Document</source>
|
<source>Open Document</source>
|
||||||
<translation>Open Document</translation>
|
<translation>Open Document</translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Copy Document to Downloads</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>EditGroupChatPermissionsColumn</name>
|
<name>EditGroupChatPermissionsColumn</name>
|
||||||
|
@ -1085,8 +1105,16 @@
|
||||||
<translation type="unfinished">Download failed.</translation>
|
<translation type="unfinished">Download failed.</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Connecting to network...</source>
|
<source>Tap on the title bar to filter your chats</source>
|
||||||
<translation type="unfinished">Connecting to network...</translation>
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>No matching chats found.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>You can search public chats or create a new chat via the pull-down menu.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Logging out</source>
|
<source>Logging out</source>
|
||||||
|
@ -1308,13 +1336,19 @@
|
||||||
<source>Channel</source>
|
<source>Channel</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 members</source>
|
<source>%1 members</source>
|
||||||
<translation type="unfinished">%1 member</translation>
|
<translation type="unfinished">
|
||||||
|
<numerusform>%1 member</numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message numerus="yes">
|
||||||
<source>%1 subscribers</source>
|
<source>%1 subscribers</source>
|
||||||
<translation type="unfinished">%1 subscriber</translation>
|
<translation type="unfinished">
|
||||||
|
<numerusform>%1 subscriber</numerusform>
|
||||||
|
<numerusform></numerusform>
|
||||||
|
</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<source>Search Chats</source>
|
<source>Search Chats</source>
|
||||||
|
@ -1403,6 +1437,22 @@
|
||||||
<source>Enable storage optimizer</source>
|
<source>Enable storage optimizer</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus text input area after send</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Focus the text input area after sending a message</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Enable online-only mode</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Disables offline caching. Certain features may be limited or missing in this mode. Changes require a restart of Fernschreiber to take effect.</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
</context>
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>StickerPicker</name>
|
<name>StickerPicker</name>
|
||||||
|
@ -1430,6 +1480,45 @@
|
||||||
<translation>Download failed.</translation>
|
<translation>Download failed.</translation>
|
||||||
</message>
|
</message>
|
||||||
</context>
|
</context>
|
||||||
|
<context>
|
||||||
|
<name>VoiceNoteOverlay</name>
|
||||||
|
<message>
|
||||||
|
<source>Record a Voice Note</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Press the button to start recording</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Unavailable</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Starting</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Recording</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Stopping</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Use recording</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Voice Note (%1)</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<source>Ready</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
</context>
|
||||||
<context>
|
<context>
|
||||||
<name>WebPagePreview</name>
|
<name>WebPagePreview</name>
|
||||||
<message>
|
<message>
|
||||||
|
|
Loading…
Reference in a new issue