Compare commits

..

No commits in common. "master" and "gemini-ui" have entirely different histories.

174 changed files with 2704 additions and 19878 deletions

View file

@ -84,7 +84,7 @@ jobs:
assets+=("-a" "$asset")
done
tag_name="${GITHUB_REF##*/}"
gh release create "$tag_name" "${assets[@]}"
hub release create "${assets[@]}" -m "$tag_name" "$tag_name"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@ -97,6 +97,6 @@ jobs:
assets+=("-a" "$asset")
done
tag_name="${GITHUB_REF##*/}"
gh release create "$tag_name" -p -n "This is a pre-release for testing purposes only. It may or may not be unstable." "${assets[@]}"
hub release create -p "${assets[@]}" -m "$tag_name" -m "This is a pre-release for testing purposes only. It may or may not be unstable." -m "Join the Telegram group to help out: https://github.com/Wunderfitz/harbour-fernschreiber/issues/162" "$tag_name"
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

3
.gitignore vendored
View file

@ -53,6 +53,3 @@ compile_commands.json
# TDLib API Secrets
tdlibsecrets.h
#Convinience scripts
*.sh

View file

@ -14,11 +14,7 @@ Fernschreiber wouldn't be the same without all the people helping in making it b
- Chat info page, performance improvements to chat page, location support, app initialization/registration with Telegram, project dependencies, emoji handling, qml/js optimizations, multi-message actions, i18n fixes, chat permission handling, code reviews, logging categories, bot support, github build: [jgibbon](https://github.com/jgibbon)
- Copy message to clipboard: [Christian Stemmle](https://github.com/chstem)
- Hide send message button if send-by-enter is switched on, focus text input on entering a chat: [santhoshmanikandan](https://github.com/santhoshmanikandan)
- Integration of logout and sesison options to settings page, search results optimization, highlight unread conversations: [Peter G.](https://github.com/nephros)
- Option to always append last message in notifications: [Johannes Bachmann](https://github.com/dscheinah)
- Option to jump to quoted message, widescreen UI adjustments: [Mikhail Barashkov](https://github.com/mbarashkov)
This list might not be complete. In case I forgot something/somebody, please let me know or create a PR, thanks! :)
- Integration of logout and sesison options to settings page: [Peter G.](https://github.com/nephros)
### Logo/Icon
- Designed by [Matteo](https://github.com/iamnomeutente), adjustments by [Slava Monich](https://github.com/monich)
@ -52,7 +48,7 @@ const char TDLIB_API_HASH[] = "1234567890abcdef1234567890abcdef";
You get the Telegram API ID and hash as soon as you've registered your own application on [https://my.telegram.org](https://my.telegram.org).
Moreover, you need to have a compiled version of [TDLib 1.8.21](https://github.com/tdlib/td) or higher in the sub-directory `tdlib`. This sub-directory must contain another sub-directory that fits to the target device architecture (e.g. armv7hl, i486). Within this directory, there needs to be a folder called `lib` that contains at least `libtdjson.so`. For armv7hl the relative path would consequently be `tdlib/armv7hl/lib`.
Moreover, you need to have a compiled version of [TDLib 1.8.3](https://github.com/tdlib/td) or higher in the sub-directory `tdlib`. This sub-directory must contain another sub-directory that fits to the target device architecture (e.g. armv7hl, i486). Within this directory, there needs to be a folder called `lib` that contains at least `libtdjson.so`. For armv7hl the relative path would consequently be `tdlib/armv7hl/lib`.
You may just want to download the [tdlib.zip from our fork](https://github.com/Wunderfitz/td/releases) to just use the exact version of the latest official Fernschreiber release. To use it, you need to extract it into your local `tdlib/` folder as described above. If so, you're done and can compile Fernschreiber using the Sailfish SDK. If you want to build TDLib for yourself, please keep on reading.

View file

@ -1,6 +1,6 @@
[Desktop Entry]
Type=Application
X-Nemo-Application-Type=silica-qt5
X-Nemo-Application-Type=generic
Icon=harbour-fernschreiber
Exec=harbour-fernschreiber
Name=Fernschreiber

View file

@ -46,7 +46,6 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/AudioPreview.qml \
qml/components/BackgroundImage.qml \
qml/components/ChatListViewItem.qml \
qml/components/ContactSync.qml \
qml/components/DocumentPreview.qml \
qml/components/GamePreview.qml \
qml/components/ImagePreview.qml \
@ -140,6 +139,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/pages/VideoPage.qml \
rpm/harbour-fernschreiber.changes \
rpm/harbour-fernschreiber.spec \
rpm/harbour-fernschreiber.yaml \
translations/*.ts \
harbour-fernschreiber.desktop

View file

@ -1,44 +0,0 @@
/*
Copyright (C) 2021 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.0
//import org.nemomobile.contacts 1.0
Item {
// signal syncError();
// function synchronize() {
// if (peopleModel.count === 0) {
// appNotification.show(qsTr("Could not synchronize your contacts with Telegram."));
// syncError();
// } else {
// contactsModel.startImportingContacts();
// for (var i = 0; i < peopleModel.count; i++ ) {
// contactsModel.importContact(peopleModel.get(i));
// }
// contactsModel.stopImportingContacts();
// }
// }
// PeopleModel {
// id: peopleModel
// requiredProperty: PeopleModel.PhoneNumberRequired
// }
}

View file

@ -40,7 +40,7 @@ Loader {
property string chatId
property string userName
property bool userNameIsValid: userName !== "" && inlineBotInformation && userName.toLowerCase() === inlineBotInformation.usernames.editable_username.toLowerCase()
property bool userNameIsValid: userName !== "" && inlineBotInformation && userName.toLowerCase() === inlineBotInformation.username.toLowerCase()
property string query
property int currentOffset: 0
property string responseExtra: chatId+"|"+userName+"|"+query+"|"+currentOffset

View file

@ -38,7 +38,7 @@ ListItem {
readonly property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender_id.user_id)
property QtObject precalculatedValues: ListView.view.precalculatedValues
readonly property color textColor: isOwnMessage ? Theme.highlightColor : Theme.primaryColor
readonly property int textAlign: Text.AlignLeft
readonly property int textAlign: isOwnMessage ? Text.AlignRight : Text.AlignLeft
readonly property Page page: precalculatedValues.page
readonly property bool isSelected: messageListItem.precalculatedValues.pageIsSelecting && page.selectedMessages.some(function(existingMessage) {
return existingMessage.id === messageId
@ -47,7 +47,6 @@ ListItem {
readonly property bool canDeleteMessage: myMessage.can_be_deleted_for_all_users || (myMessage.can_be_deleted_only_for_self && myMessage.chat_id === page.myUserId)
property bool hasContentComponent
property bool additionalOptionsOpened
property bool wasNavigatedTo: false
readonly property var additionalItemsModel: (extraContentLoader.item && ("extraContextMenuItems" in extraContentLoader.item)) ?
extraContentLoader.item.extraContextMenuItems : 0
@ -65,10 +64,9 @@ ListItem {
readonly property bool showForwardMessageMenuItem: (baseContextMenuItemCount + 2) <= maxContextMenuItemCount
// And don't count "More Options..." for "Delete Message" if "Delete Message" is the only extra option
readonly property bool haveSpaceForDeleteMessageMenuItem: (baseContextMenuItemCount + 3 - (deleteMessageIsOnlyExtraOption ? 1 : 0)) <= maxContextMenuItemCount
property var chatReactions
property var messageReactions
highlighted: (down || isSelected || additionalOptionsOpened || wasNavigatedTo) && !menuOpen
highlighted: (down || isSelected || additionalOptionsOpened) && !menuOpen
openMenuOnPressAndHold: !messageListItem.precalculatedValues.pageIsSelecting
signal replyToMessage()
@ -96,43 +94,20 @@ ListItem {
}
}
function getInteractionText(viewCount, reactions, size, highlightColor) {
function getInteractionText(viewCount, reactions) {
var interactionText = "";
if (viewCount > 0) {
interactionText = Emoji.emojify("👁️ ", size) + Functions.getShortenedCount(viewCount);
interactionText = Emoji.emojify("👁️", Theme.fontSizeTiny) + Functions.getShortenedCount(viewCount);
}
for (var i = 0; i < reactions.length; i++) {
var reaction = reactions[i]
var reactionText = reaction.reaction ? reaction.reaction : (reaction.type && reaction.type.emoji) ? reaction.type.emoji : ""
if (reactionText) {
interactionText += ( "&nbsp;" + Emoji.emojify(reactionText, size) );
if (!chatPage.isPrivateChat) {
var count = Functions.getShortenedCount(reaction.total_count)
interactionText += " "
interactionText += (reaction.is_chosen ? ( "<font color='" + highlightColor + "'><b>" + count + "</b></font>" ) : count)
}
interactionText += ( "&nbsp;" + Emoji.emojify(reactions[i].reaction, Theme.fontSizeTiny) );
if (!chatPage.isPrivateChat) {
interactionText += ( " " + Functions.getShortenedCount(reactions[i].total_count) );
}
}
return interactionText;
}
function openReactions() {
if (messageListItem.chatReactions) {
Debug.log("Using chat reactions")
messageListItem.messageReactions = chatReactions
showItemCompletelyTimer.requestedIndex = index;
showItemCompletelyTimer.start();
} else {
Debug.log("Obtaining message reactions")
tdLibWrapper.getMessageAvailableReactions(messageListItem.chatId, messageListItem.messageId);
}
selectReactionBubble.visible = false;
}
function getContentWidthMultiplier() {
return Functions.isWidescreen(appWindow) ? 0.4 : 1.0
}
onClicked: {
if (messageListItem.precalculatedValues.pageIsSelecting) {
page.toggleMessageSelection(myMessage);
@ -150,26 +125,12 @@ ListItem {
if (messageListItem.messageReactions) {
messageListItem.messageReactions = null;
selectReactionBubble.visible = false;
} else {
selectReactionBubble.visible = !selectReactionBubble.visible;
elementSelected(index);
tdLibWrapper.getMessageAvailableReactions(messageListItem.chatId, messageListItem.messageId);
}
}
}
onDoubleClicked: {
if (messageListItem.chatReactions) {
Debug.log("Using chat reactions")
messageListItem.messageReactions = chatReactions
showItemCompletelyTimer.requestedIndex = index;
showItemCompletelyTimer.start();
} else {
Debug.log("Obtaining message reactions")
tdLibWrapper.getMessageAvailableReactions(messageListItem.chatId, messageListItem.messageId);
}
}
onPressAndHold: {
if (openMenuOnPressAndHold) {
openContextMenu()
@ -193,25 +154,6 @@ ListItem {
}
}
Connections {
target: chatPage
onResetElements: {
messageListItem.messageReactions = null;
selectReactionBubble.visible = false;
}
onElementSelected: {
if (elementIndex !== index) {
selectReactionBubble.visible = false;
}
}
onNavigatedTo: {
if (targetIndex === index) {
messageListItem.wasNavigatedTo = true;
restoreNormalityTimer.start();
}
}
}
Loader {
id: contextMenuLoader
active: false
@ -316,9 +258,6 @@ ListItem {
messageListItem.messageReactions = null;
}
}
onReactionsUpdated: {
chatReactions = tdLibWrapper.getChatReactions(page.chatInformation.id);
}
}
Timer {
@ -331,34 +270,16 @@ ListItem {
interval: 200
triggeredOnStart: false
onTriggered: {
Debug.log("Show item completely timer triggered, requested index: " + requestedIndex + ", current index: " + index)
if (requestedIndex === index) {
var p = chatView.contentItem.mapFromItem(reactionsColumn, 0, 0)
if (chatView.contentY > p.y || p.y + reactionsColumn.height > chatView.contentY + chatView.height) {
Debug.log("Moving reactions for item at", requestedIndex, "info the view")
chatView.highlightMoveDuration = -1
chatView.highlightResizeDuration = -1
chatView.scrollToIndex(requestedIndex, height <= chatView.height ? ListView.Contain : ListView.End)
chatView.highlightMoveDuration = 0
chatView.highlightResizeDuration = 0
}
chatView.highlightMoveDuration = -1;
chatView.highlightResizeDuration = -1;
chatView.scrollToIndex(requestedIndex);
chatView.highlightMoveDuration = 0;
chatView.highlightResizeDuration = 0;
}
}
}
Timer {
id: restoreNormalityTimer
repeat: false
running: false
interval: 1000
triggeredOnStart: false
onTriggered: {
Debug.log("Restore normality for index " + index);
messageListItem.wasNavigatedTo = false;
}
}
Component.onCompleted: {
delegateComponentLoadingTimer.start();
if (myMessage.reply_to_message_id) {
@ -401,10 +322,8 @@ ListItem {
id: messageTextRow
spacing: Theme.paddingSmall
width: precalculatedValues.entryWidth
anchors.horizontalCenter: Functions.isWidescreen(appWindow) ? undefined : parent.horizontalCenter
anchors.left: Functions.isWidescreen(appWindow) ? parent.left : undefined
anchors.horizontalCenter: parent.horizontalCenter
y: Theme.paddingSmall
anchors.leftMargin: Functions.isWidescreen(appWindow) ? Theme.paddingMedium : undefined
Loader {
id: profileThumbnailLoader
@ -444,13 +363,13 @@ ListItem {
anchors {
left: parent.left
leftMargin: page.isPrivateChat ? (messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0) : 0 //левый марджин для собственных сообщений в приватных чатах. В остальных на полную ширину
leftMargin: messageListItem.isOwnMessage ? precalculatedValues.pageMarginDouble : 0
verticalCenter: parent.verticalCenter
}
height: messageTextColumn.height + precalculatedValues.paddingMediumDouble
width: precalculatedValues.backgroundWidth
property bool isUnread: index > chatModel.getLastReadMessageIndex() && myMessage['@type'] !== "sponsoredMessage"
color: Theme.colorScheme === Theme.LightOnDark ? (isOwnMessage ? Theme.highlightBackgroundColor : (isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor)) : (isOwnMessage ? Theme.highlightBackgroundColor : (isUnread ? Theme.backgroundGlowColor : Theme.overlayBackgroundColor))
color: Theme.colorScheme === Theme.LightOnDark ? (isUnread ? Theme.secondaryHighlightColor : Theme.secondaryColor) : (isUnread ? Theme.backgroundGlowColor : Theme.overlayBackgroundColor)
radius: parent.width / 50
opacity: isUnread ? 0.5 : 0.2
visible: appSettings.showStickersAsImages || (myMessage.content['@type'] !== "messageSticker" && myMessage.content['@type'] !== "messageAnimatedEmoji")
@ -479,7 +398,7 @@ ListItem {
truncationMode: TruncationMode.Fade
textFormat: Text.StyledText
horizontalAlignment: messageListItem.textAlign
visible: messageListItem.isOwnMessage ? false : (precalculatedValues.showUserInfo || myMessage['@type'] === "sponsoredMessage")
visible: precalculatedValues.showUserInfo || myMessage['@type'] === "sponsoredMessage"
MouseArea {
anchors.fill: parent
enabled: !(messageListItem.precalculatedValues.pageIsSelecting || messageListItem.isAnonymous)
@ -521,12 +440,8 @@ ListItem {
page.toggleMessageSelection(myMessage)
} else {
messageOptionsDrawer.open = false
if(appSettings.goToQuotedMessage) {
chatPage.showMessage(messageInReplyToRow.inReplyToMessage.id, true)
} else {
messageOverlayLoader.active = true
messageOverlayLoader.overlayMessage = messageInReplyToRow.inReplyToMessage
}
messageOverlayLoader.overlayMessage = messageInReplyToRow.inReplyToMessage
messageOverlayLoader.active = true
}
}
onPressAndHold: {
@ -552,12 +467,11 @@ ListItem {
width: parent.width
Component.onCompleted: {
var originType = myMessage.forward_info.origin["@type"]
if (originType === "messageOriginChannel" || originType === "messageForwardOriginChannel") {
if (myMessage.forward_info.origin["@type"] === "messageForwardOriginChannel") {
var otherChatInformation = tdLibWrapper.getChat(myMessage.forward_info.origin.chat_id);
forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : {};
forwardedChannelText.text = Emoji.emojify(otherChatInformation.title, Theme.fontSizeExtraSmall);
} else if (originType === "messageOriginUser" || originType === "messageForwardOriginUser") {
} else if (myMessage.forward_info.origin["@type"] === "messageForwardOriginUser") {
var otherUserInformation = tdLibWrapper.getUserInformation(myMessage.forward_info.origin.sender_user_id);
forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : {};
forwardedChannelText.text = Emoji.emojify(Functions.getUserName(otherUserInformation), Theme.fontSizeExtraSmall);
@ -638,7 +552,7 @@ ListItem {
id: webPagePreviewLoader
active: false
asynchronous: true
width: parent.width * getContentWidthMultiplier()
width: parent.width
height: (status === Loader.Ready) ? item.implicitHeight : myMessage.content.web_page ? precalculatedValues.webPagePreviewHeight : 0
sourceComponent: Component {
@ -652,7 +566,7 @@ ListItem {
Loader {
id: extraContentLoader
width: parent.width * getContentWidthMultiplier()
width: parent.width
asynchronous: true
height: item ? item.height : (messageListItem.hasContentComponent ? chatView.getContentComponentHeight(model.content_type, myMessage.content, width) : 0)
}
@ -711,7 +625,7 @@ ListItem {
height: ( ( chatPage.isChannel && messageViewCount > 0 ) || reactions.length > 0 ) ? ( Theme.fontSizeExtraSmall + Theme.paddingSmall ) : 0
sourceComponent: Component {
Label {
text: getInteractionText(messageViewCount, reactions, font.pixelSize, Theme.highlightColor)
text: getInteractionText(messageViewCount, reactions)
width: parent.width
font.pixelSize: Theme.fontSizeTiny
color: messageListItem.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor
@ -763,7 +677,7 @@ ListItem {
Image {
id: emojiPicture
source: Emoji.getEmojiPath(modelData)
width: status === Image.Ready ? Theme.fontSizeLarge : 0
width: Theme.fontSizeLarge
height: Theme.fontSizeLarge
}

View file

@ -40,11 +40,9 @@ Flickable {
function getOriginalAuthor(forwardInformation, fontSize) {
switch (forwardInformation.origin["@type"]) {
case "messageOriginChannel":
case "messageForwardOriginChannel":
var otherChatInformation = tdLibWrapper.getChat(forwardInformation.origin.chat_id);
return Emoji.emojify(otherChatInformation.title, fontSize);
case "messageOriginUser":
case "messageForwardOriginUser":
var otherUserInformation = tdLibWrapper.getUserInformation(forwardInformation.origin.sender_id.user_id);
return Emoji.emojify(Functions.getUserName(otherUserInformation), fontSize);

View file

@ -31,12 +31,12 @@ Loader {
property var botUserInformation: tdLibWrapper.getUserInformation(message.via_bot_user_id)
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeExtraSmall
text: qsTr("via %1", "message posted via bot user").arg("<a style=\"text-decoration: none; font-weight: bold; color:"+Theme.primaryColor+"\" href=\"userId://" + message.via_bot_user_id + "\">@" + Emoji.emojify(botUserInformation.usernames.editable_username, font.pixelSize)+"</a>")
text: qsTr("via %1", "message posted via bot user").arg("<a style=\"text-decoration: none; font-weight: bold; color:"+Theme.primaryColor+"\" href=\"userId://" + message.via_bot_user_id + "\">@" + Emoji.emojify(botUserInformation.username, font.pixelSize)+"</a>")
textFormat: Text.RichText
truncationMode: TruncationMode.Fade
onLinkActivated: {
if(link === "userId://" + message.via_bot_user_id && botUserInformation.type.is_inline) {
newMessageTextField.text = "@"+botUserInformation.usernames.editable_username+" "
newMessageTextField.text = "@"+botUserInformation.username+" "
newMessageTextField.cursorPosition = newMessageTextField.text.length
lostFocusTimer.start();
}

View file

@ -1,7 +1,6 @@
import QtQuick 2.6
import Sailfish.Silica 1.0
import WerkWolf.Fernschreiber 1.0
import "../js/functions.js" as Functions
ListItem {
id: chatListViewItem
@ -88,7 +87,7 @@ ListItem {
Rectangle {
id: chatUnreadMessagesCountBackground
color: isMuted ? ((Theme.colorScheme === Theme.DarkOnLight) ? "lightgray" : "dimgray") : Theme.highlightBackgroundColor
width: chatUnreadMessagesCount.width + Theme.fontSizeLarge / 2
width: Theme.fontSizeLarge
height: Theme.fontSizeLarge
anchors.right: parent.right
anchors.bottom: parent.bottom
@ -104,42 +103,31 @@ ListItem {
anchors.centerIn: chatUnreadMessagesCountBackground
visible: chatListViewItem.unreadCount > 0
opacity: isMuted ? Theme.opacityHigh : 1.0
text: Functions.formatUnreadCount(chatListViewItem.unreadCount)
text: chatListViewItem.unreadCount > 99 ? "99+" : chatListViewItem.unreadCount
}
Rectangle {
id: chatUnreadReactionCountBackground
color: isMuted ? ((Theme.colorScheme === Theme.DarkOnLight) ? "lightgray" : "dimgray") : Theme.highlightBackgroundColor
width: Theme.fontSizeLarge
height: Theme.fontSizeLarge
anchors.right: parent.right
anchors.top: parent.top
radius: parent.width / 2
visible: chatListViewItem.unreadReactionCount > 0 || chatListViewItem.unreadMentionCount > 0
Icon {
source: "image://theme/icon-s-favorite"
height: Theme.iconSizeExtraSmall
width: Theme.iconSizeExtraSmall
highlighted: chatListViewItem.highlighted
anchors.centerIn: parent
visible: chatListViewItem.unreadReactionCount > 0 && !chatListViewItem.unreadMentionCount
}
Text {
font {
pixelSize: Theme.iconSizeExtraSmall
bold: true
}
color: Theme.primaryColor
anchors.centerIn: parent
visible: chatListViewItem.unreadMentionCount > 0
opacity: isMuted ? Theme.opacityHigh : 1.0
text: "@"
}
visible: chatListViewItem.unreadReactionCount > 0
}
Icon {
source: "image://theme/icon-s-favorite"
height: Theme.iconSizeExtraSmall
width: Theme.iconSizeExtraSmall
highlighted: chatListViewItem.highlighted
anchors.centerIn: chatUnreadReactionCountBackground
visible: chatListViewItem.unreadReactionCount > 0
}
}
}
Column {
id: contentColumn
anchors {
@ -162,9 +150,6 @@ ListItem {
truncationMode: TruncationMode.Fade
anchors.verticalCenter: parent.verticalCenter
width: Math.min(contentColumn.width - (verifiedImage.visible ? (verifiedImage.width + primaryTextRow.spacing) : 0) - (mutedImage.visible ? (mutedImage.width + primaryTextRow.spacing) : 0), implicitWidth)
font.bold: appSettings.highlightUnreadConversations && ( !chatListViewItem.isMuted && (chatListViewItem.unreadCount > 0 || chatListViewItem.isMarkedAsUnread) )
font.italic: appSettings.highlightUnreadConversations && (chatListViewItem.unreadReactionCount > 0)
color: (appSettings.highlightUnreadConversations && (chatListViewItem.unreadCount > 0)) ? Theme.highlightColor : Theme.primaryColor
}
Image {

View file

@ -60,12 +60,12 @@ Column {
},
inlineKeyboardButtonTypeSwitchInline: function() {
if(modelData.type.in_current_chat) {
chatPage.setMessageText("@" + userInformation.usernames.editable_username + " "+(modelData.type.query || ""))
chatPage.setMessageText("@" + userInformation.username + " "+(modelData.type.query || ""))
} else {
pageStack.push(Qt.resolvedUrl("../pages/ChatSelectionPage.qml"), {
myUserId: chatPage.myUserId,
payload: { neededPermissions: ["can_send_other_messages"], text:"@" + userInformation.usernames.editable_username + " "+(modelData.type.query || "")},
payload: { neededPermissions: ["can_send_other_messages"], text:"@" + userInformation.username + " "+(modelData.type.query || "")},
state: "fillTextArea"
})
}

View file

@ -300,8 +300,7 @@ SilicaFlickable {
}
leftMargin: imageContainer.getEased((imageContainer.minDimension + Theme.paddingMedium), 0, imageContainer.tweenFactor) + Theme.horizontalPageMargin
title: chatInformationPage.chatInformation.title !== "" ? Emoji.emojify(chatInformationPage.chatInformation.title, Theme.fontSizeLarge) : qsTr("Unknown")
description: ((chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.privateChatUserInformation.usernames.editable_username)
? ("@"+chatInformationPage.privateChatUserInformation.usernames.editable_username) : ""
description: (chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) ? ("@"+(chatInformationPage.privateChatUserInformation.username || chatInformationPage.chatPartnerGroupId)) : ""
}
SilicaFlickable {
@ -364,27 +363,6 @@ SilicaFlickable {
height: imageContainer.hasImage ? imageContainer.maxDimension : 0
}
Label {
id: copyIdText
x: Math.max(headerItem.x + imageContainer.x - groupInfoItem.x + (imageContainer.width - width)/2, 0)
text: chatInformationPage.chatPartnerGroupId
font.pixelSize: Theme.fontSizeSmall
color: copyIdMouseArea.pressed ? Theme.secondaryHighlightColor : Theme.highlightColor
visible: text !== ""
MouseArea {
id: copyIdMouseArea
anchors {
fill: parent
margins: -Theme.paddingLarge
}
onClicked: {
Clipboard.text = copyIdText.text
appNotification.show(qsTr("ID has been copied to the clipboard."));
}
}
}
InformationEditArea {
visible: canEdit
canEdit: !(chatInformationPage.isPrivateChat || chatInformationPage.isSecretChat) && chatInformationPage.groupInformation.status && (chatInformationPage.groupInformation.status.can_change_info || chatInformationPage.groupInformation.status["@type"] === "chatMemberStatusCreator")

View file

@ -79,7 +79,7 @@ ChatInformationTabItemBase {
// chat title
primaryText.text: Emoji.emojify(Functions.getUserName(user), primaryText.font.pixelSize)
// last user
prologSecondaryText.text: "@"+(user.username ? user.username : member_id.user_id) + (member_id.user_id === chatInformationPage.myUserId ? " " + qsTr("You") : "")
prologSecondaryText.text: "@"+(user.username !== "" ? user.username : member_id.user_id) + (member_id.user_id === chatInformationPage.myUserId ? " " + qsTr("You") : "")
secondaryText {
horizontalAlignment: Text.AlignRight
property string statusText: Functions.getChatMemberStatusText(model.status["@type"])
@ -180,9 +180,6 @@ ChatInformationTabItemBase {
for(var memberIndex in members) {
var memberData = members[memberIndex];
var userInfo = tdLibWrapper.getUserInformation(memberData.member_id.user_id) || {user:{}, bot_info:{}};
if (!userInfo.username && userInfo.usernames && userInfo.usernames.active_usernames) {
userInfo.username = userInfo.usernames.active_usernames[0]
}
memberData.user = userInfo;
memberData.bot_info = memberData.bot_info || {};
pageContent.membersList.append(memberData);

View file

@ -27,7 +27,7 @@ MessageContentBase {
property var stickerData: messageListItem ? messageListItem.myMessage.content.sticker : overlayFlickable.overlayMessage.content.sticker;
readonly property bool asEmoji: appSettings.showStickersAsEmojis
readonly property bool animated: stickerData.format["@type"] === "stickerFormatTgs" && appSettings.animateStickers
readonly property bool animated: stickerData.type["@type"] === "stickerTypeAnimated" && appSettings.animateStickers
readonly property bool stickerVisible: staticStickerLoader.item ? staticStickerLoader.item.visible :
animatedStickerLoader.item ? animatedStickerLoader.item.visible : false
readonly property bool isOwnSticker : messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage

View file

@ -95,7 +95,7 @@ MessageContentBase {
tdLibWrapper.downloadFile(previewFileId);
}
} else {
placeholderImage.source = "image://theme/icon-m-video?white";
placeholderImage.source = "image://theme/icon-l-video?white";
placeholderImage.width = Theme.itemSizeLarge
placeholderImage.height = Theme.itemSizeLarge
}

View file

@ -19,10 +19,9 @@
import QtQuick 2.6
import Sailfish.Silica 1.0
import "../../js/functions.js" as Functions
Grid {
width: parent.width - ( 2 * x )
columns: Functions.isWidescreen(appWindow) ? 2 : 1
columns: (appWindow.deviceOrientation & Orientation.LandscapeMask) || Screen.sizeCategory === Screen.Large || Screen.sizeCategory === Screen.ExtraLarge ? 2 : 1
readonly property real columnWidth: width/columns
}

View file

@ -70,17 +70,6 @@ AccordionItem {
}
}
TextSwitch {
width: parent.columnWidth
checked: appSettings.highlightUnreadConversations
text: qsTr("Highlight unread messages")
description: qsTr("Highlight Conversations with unread messages")
automaticCheck: false
onClicked: {
appSettings.highlightUnreadConversations = !checked
}
}
TextSwitch {
width: parent.columnWidth
checked: appSettings.useOpenWith
@ -92,28 +81,6 @@ AccordionItem {
}
}
TextSwitch {
width: parent.columnWidth
checked: appSettings.notificationAlwaysShowPreview
text: qsTr("Always append message preview to notifications")
description: qsTr("In addition to showing the number of unread messages, the latest message will also be appended to notifications.")
automaticCheck: false
onClicked: {
appSettings.notificationAlwaysShowPreview = !checked
}
}
TextSwitch {
width: parent.columnWidth
checked: appSettings.goToQuotedMessage
text: qsTr("Go to quoted message")
description: qsTr("When tapping a quoted message, open it in chat instead of showing it in an overlay.")
automaticCheck: false
onClicked: {
appSettings.goToQuotedMessage = !checked
}
}
ComboBox {
id: feedbackComboBox
width: parent.columnWidth
@ -168,53 +135,35 @@ AccordionItem {
}
}
Item {
// Occupies one grid cell so that the column ends up under the combo box
// in the landscape layout
visible: parent.columns === 2
width: 1
height: 1
}
Column {
enabled: appSettings.notificationFeedback !== AppSettings.NotificationFeedbackNone
TextSwitch {
width: parent.columnWidth
checked: appSettings.notificationTurnsDisplayOn && enabled
text: qsTr("Notification turns on the display")
enabled: appSettings.notificationFeedback !== AppSettings.NotificationFeedbackNone
height: enabled ? implicitHeight: 0
clip: height < implicitHeight
visible: height > 0
automaticCheck: false
onClicked: {
appSettings.notificationTurnsDisplayOn = !checked
}
Behavior on height { SmoothedAnimation { duration: 200 } }
}
TextSwitch {
checked: appSettings.notificationSuppressContent && enabled
text: qsTr("Hide content in notifications")
enabled: parent.enabled
automaticCheck: false
onClicked: {
appSettings.notificationSuppressContent = !checked
}
}
TextSwitch {
checked: appSettings.notificationTurnsDisplayOn && enabled
text: qsTr("Notification turns on the display")
enabled: parent.enabled
automaticCheck: false
onClicked: {
appSettings.notificationTurnsDisplayOn = !checked
}
}
TextSwitch {
checked: appSettings.notificationSoundsEnabled && enabled
text: qsTr("Enable notification sounds")
description: qsTr("When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.")
enabled: parent.enabled
automaticCheck: false
onClicked: {
appSettings.notificationSoundsEnabled = !checked
}
TextSwitch {
width: parent.columnWidth
checked: appSettings.notificationSoundsEnabled && enabled
text: qsTr("Enable notification sounds")
description: qsTr("When sounds are enabled, Fernschreiber will use the current Sailfish OS notification sound for chats, which can be configured in the system settings.")
enabled: appSettings.notificationFeedback !== AppSettings.NotificationFeedbackNone
height: enabled ? implicitHeight: 0
clip: height < implicitHeight
visible: height > 0
automaticCheck: false
onClicked: {
appSettings.notificationSoundsEnabled = !checked
}
Behavior on height { SmoothedAnimation { duration: 200 } }
}
}
}

View file

@ -30,183 +30,153 @@ AccordionItem {
Column {
id: activeSessionsItem
bottomPadding: Theme.paddingMedium
property variant activeSessions
property int inactiveSessionsTtlDays
property variant activeSessions;
property bool loaded : false;
Component.onCompleted: {
if (!activeSessions) {
tdLibWrapper.getActiveSessions();
} else {
activeSessionsItem.loaded = true;
}
}
Connections {
target: tdLibWrapper
onSessionsReceived: {
activeSessionsItem.activeSessions = sessions
activeSessionsItem.inactiveSessionsTtlDays = inactive_session_ttl_days
activeSessionsItem.activeSessions = sessions;
activeSessionsItem.loaded = true;
}
onOkReceived: {
if (request === "terminateSession") {
appNotification.show(qsTr("Session was terminated"));
activeSessionsItem.loaded = false;
tdLibWrapper.getActiveSessions();
}
}
}
Loader {
id: sessionInformationLoader
active: tdLibWrapper.authorizationState === TelegramAPI.AuthorizationReady
width: parent.width
sourceComponent: Component {
Column {
BusyIndicator {
anchors.horizontalCenter: parent.horizontalCenter
running: !activeSessionsListView.count && !activeSessionsItem.inactiveSessionsTtlDays
size: BusyIndicatorSize.Medium
visible: opacity > 0
height: running ? implicitHeight : 0
}
SilicaListView {
id: activeSessionsListView
SilicaListView {
id: activeSessionsListView
width: parent.width
height: contentHeight
model: activeSessionsItem.activeSessions
headerPositioning: ListView.OverlayHeader
header: Separator {
width: parent.width
height: contentHeight
model: activeSessionsItem.activeSessions
headerPositioning: ListView.OverlayHeader
header: Separator {
color: Theme.primaryColor
horizontalAlignment: Qt.AlignHCenter
}
delegate: ListItem {
id: activeSessionListItem
width: parent.width
contentHeight: activeSessionColumn.height + ( 2 * Theme.paddingMedium )
menu: ContextMenu {
hasContent: !modelData.is_current
onHeightChanged: {
if (parent && flickable) {
// Make sure we are inside the screen area
var bottom = parent.mapToItem(flickable, x, y).y + height
if (bottom > flickable.height) {
flickable.contentY += bottom - flickable.height
}
}
}
MenuItem {
onClicked: {
var sessionId = modelData.id;
Remorse.itemAction(activeSessionListItem, qsTr("Terminating session"), function() { tdLibWrapper.terminateSession(sessionId); });
}
text: qsTr("Terminate Session")
}
}
Column {
id: activeSessionColumn
width: parent.width - ( 2 * Theme.horizontalPageMargin )
spacing: Theme.paddingSmall
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
Label {
width: parent.width
text: qsTr("This app")
font.pixelSize: Theme.fontSizeMedium
font.bold: true
visible: modelData.is_current
color: Theme.highlightColor
anchors {
horizontalCenter: parent.horizontalCenter
}
}
Label {
width: parent.width
text: modelData.application_name + " " + modelData.application_version
font.pixelSize: Theme.fontSizeMedium
font.bold: true
color: Theme.primaryColor
maximumLineCount: 1
elide: Text.ElideRight
anchors {
horizontalCenter: parent.horizontalCenter
}
}
Label {
width: parent.width
text: modelData.device_model + ", " + (modelData.platform + " " + modelData.system_version).trim()
font.pixelSize: Theme.fontSizeSmall
color: Theme.primaryColor
maximumLineCount: 1
truncationMode: TruncationMode.Fade
anchors {
horizontalCenter: parent.horizontalCenter
}
}
Label {
width: parent.width
text: qsTr("IP address: %1, origin: %2").arg(modelData.ip).arg(modelData.country)
font.pixelSize: Theme.fontSizeExtraSmall
color: Theme.secondaryColor
maximumLineCount: 1
truncationMode: TruncationMode.Fade
anchors {
horizontalCenter: parent.horizontalCenter
}
}
Label {
width: parent.width
text: qsTr("Active since: %1, last online: %2").arg(Functions.getDateTimeTimepoint(modelData.log_in_date)).arg(Functions.getDateTimeElapsed(modelData.last_active_date))
font.pixelSize: Theme.fontSizeExtraSmall
color: Theme.primaryColor
maximumLineCount: 1
truncationMode: TruncationMode.Fade
anchors {
horizontalCenter: parent.horizontalCenter
}
}
}
Separator {
id: separator
anchors {
bottom: parent.bottom
}
width: parent.width
color: Theme.primaryColor
horizontalAlignment: Qt.AlignHCenter
visible: activeSessionsListView.count > 0
}
delegate: ListItem {
id: activeSessionListItem
width: parent.width
contentHeight: activeSessionColumn.height + ( 2 * Theme.paddingMedium )
menu: ContextMenu {
hasContent: !modelData.is_current
onHeightChanged: {
if (parent && flickable) {
// Make sure we are inside the screen area
var bottom = parent.mapToItem(flickable, x, y).y + height
if (bottom > flickable.height) {
flickable.contentY += bottom - flickable.height
}
}
}
MenuItem {
onClicked: {
var sessionId = modelData.id;
Remorse.itemAction(activeSessionListItem, qsTr("Terminating session"), function() { tdLibWrapper.terminateSession(sessionId); });
}
text: qsTr("Terminate Session")
}
}
Column {
id: activeSessionColumn
width: parent.width - ( 2 * Theme.horizontalPageMargin )
spacing: Theme.paddingSmall
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
Label {
width: parent.width
text: qsTr("This app")
font.pixelSize: Theme.fontSizeMedium
font.bold: true
visible: modelData.is_current
color: Theme.highlightColor
}
Label {
width: parent.width
text: modelData.application_name + " " + modelData.application_version
font.pixelSize: Theme.fontSizeMedium
font.bold: true
maximumLineCount: 1
elide: Text.ElideRight
}
Label {
width: parent.width
text: modelData.device_model + ", " + (modelData.platform + " " + modelData.system_version).trim()
font.pixelSize: Theme.fontSizeSmall
maximumLineCount: 1
truncationMode: TruncationMode.Fade
}
Label {
width: parent.width
text: qsTr("Active since: %1, last online: %2").arg(Functions.getDateTimeTimepoint(modelData.log_in_date)).arg(Functions.getDateTimeElapsed(modelData.last_active_date))
font.pixelSize: Theme.fontSizeExtraSmall
maximumLineCount: 1
truncationMode: TruncationMode.Fade
}
}
Separator {
anchors {
bottom: parent.bottom
}
width: parent.width
color: Theme.primaryColor
horizontalAlignment: Qt.AlignHCenter
}
}
}
ComboBox {
readonly property int ttl: activeSessionsItem.inactiveSessionsTtlDays
label: qsTr("Session Timeout")
description: qsTr("Inactive sessions will be terminated after this timeframe")
value: (currentItem && currentItem.text) ? currentItem.text : qsTr("%1 day(s)", "", ttl).arg(ttl)
visible: ttl > 0
menu: ContextMenu {
id: ttlMenu
MenuItem {
readonly property int days: 7
text: qsTr("1 week")
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
}
MenuItem {
readonly property int days: 30
text: qsTr("1 month")
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
}
MenuItem {
readonly property int days: 90
text: qsTr("3 months")
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
}
MenuItem {
readonly property int days: 180
text: qsTr("6 months")
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
}
MenuItem {
readonly property int days: 365
text: qsTr("1 year")
onClicked: tdLibWrapper.setInactiveSessionTtl(days)
}
}
Component.onCompleted: updateSelection()
onTtlChanged: updateSelection()
function updateSelection() {
var menuItems = ttlMenu.children
var n = menuItems.length
for (var i = 0; i < n; i++) {
if (menuItems[i].days === ttl) {
currentIndex = i
return
}
}
currentIndex = -1
}
}
}
}

View file

@ -35,7 +35,6 @@ AccordionItem {
readonly property var userInformation: tdLibWrapper.getUserInformation()
property bool uploadInProgress: false
property bool contactSyncEnabled: false
Component.onCompleted: {
tdLibWrapper.getUserProfilePhotos(userInformation.id, 100, 0);
@ -143,7 +142,7 @@ AccordionItem {
visible: true
canEdit: true
headerText: qsTr("Username", "user name of the logged-in profile - header")
text: userInformation.usernames.editable_username
text: userInformation.username
width: parent.columnWidth
headerLeftAligned: true
@ -152,49 +151,6 @@ AccordionItem {
}
}
Column {
id: contactSyncItem
width: parent.width
height: syncInProgress ? ( syncContactsBusyIndicator.height + Theme.paddingMedium ) : ( syncContactsButton.height + Theme.paddingMedium )
visible: accordionContent.contactSyncEnabled
property bool syncInProgress: false
Connections {
target: contactSyncLoader.item
onSyncError: {
contactSyncItem.syncInProgress = false;
}
}
Connections {
target: tdLibWrapper
onContactsImported: {
appNotification.show(qsTr("Contacts successfully synchronized with Telegram."));
}
}
Button {
id: syncContactsButton
text: qsTr("Synchronize Contacts with Telegram")
visible: !contactSyncItem.syncInProgress
anchors {
horizontalCenter: parent.horizontalCenter
}
onClicked: {
contactSyncLoader.item.synchronize();
}
}
BusyIndicator {
id: syncContactsBusyIndicator
anchors.horizontalCenter: parent.horizontalCenter
running: contactSyncItem.syncInProgress
size: BusyIndicatorSize.Small
visible: running
}
}
}
SectionHeader {
@ -291,15 +247,6 @@ AccordionItem {
}
Loader {
id: contactSyncLoader
source: "../ContactSync.qml"
active: true
onLoaded: {
accordionContent.contactSyncEnabled = true;
}
}
Component {
id: imagePickerPage
ImagePickerPage {

0
qml/js/emoji/1f6dd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 3.1 KiB

0
qml/js/emoji/1f6de.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

0
qml/js/emoji/1f6df.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 3.4 KiB

0
qml/js/emoji/1f7f0.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 221 B

After

Width:  |  Height:  |  Size: 221 B

0
qml/js/emoji/1f91d-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1f91d-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1f91d-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1f91d-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1f91d-1f3ff.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1f979.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1f9cc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

0
qml/js/emoji/1fa7b.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 4.9 KiB

0
qml/js/emoji/1fa7c.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

0
qml/js/emoji/1faa9.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 8.4 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

0
qml/js/emoji/1faaa.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

0
qml/js/emoji/1faab.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

0
qml/js/emoji/1faac.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

0
qml/js/emoji/1fab7.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

0
qml/js/emoji/1fab8.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

0
qml/js/emoji/1fab9.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

0
qml/js/emoji/1faba.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 7.2 KiB

0
qml/js/emoji/1fac3-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac3-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac3-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac3-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac3-1f3ff.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac3.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac4-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac4-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac4-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac4-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac4-1f3ff.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac4.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

0
qml/js/emoji/1fac5-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
qml/js/emoji/1fac5-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
qml/js/emoji/1fac5-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
qml/js/emoji/1fac5-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
qml/js/emoji/1fac5-1f3ff.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
qml/js/emoji/1fac5.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
qml/js/emoji/1fad7.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
qml/js/emoji/1fad8.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
qml/js/emoji/1fad9.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

0
qml/js/emoji/1fae0.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

0
qml/js/emoji/1fae1.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

0
qml/js/emoji/1fae2.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 971 B

After

Width:  |  Height:  |  Size: 971 B

0
qml/js/emoji/1fae3.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

0
qml/js/emoji/1fae4.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 422 B

After

Width:  |  Height:  |  Size: 422 B

0
qml/js/emoji/1fae5.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

0
qml/js/emoji/1fae6.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 689 B

After

Width:  |  Height:  |  Size: 689 B

0
qml/js/emoji/1fae7.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

0
qml/js/emoji/1faf0-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

0
qml/js/emoji/1faf0-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

0
qml/js/emoji/1faf0-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

0
qml/js/emoji/1faf0-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

0
qml/js/emoji/1faf0-1f3ff.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

0
qml/js/emoji/1faf0.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1 KiB

0
qml/js/emoji/1faf1-1f3fb-200d-1faf2-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fb-200d-1faf2-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fb-200d-1faf2-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fb-200d-1faf2-1f3ff.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 741 B

After

Width:  |  Height:  |  Size: 741 B

0
qml/js/emoji/1faf1-1f3fc-200d-1faf2-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fc-200d-1faf2-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fc-200d-1faf2-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fc-200d-1faf2-1f3ff.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 741 B

After

Width:  |  Height:  |  Size: 741 B

0
qml/js/emoji/1faf1-1f3fd-200d-1faf2-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fd-200d-1faf2-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fd-200d-1faf2-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fd-200d-1faf2-1f3ff.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 741 B

After

Width:  |  Height:  |  Size: 741 B

0
qml/js/emoji/1faf1-1f3fe-200d-1faf2-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fe-200d-1faf2-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fe-200d-1faf2-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fe-200d-1faf2-1f3ff.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 741 B

After

Width:  |  Height:  |  Size: 741 B

0
qml/js/emoji/1faf1-1f3ff-200d-1faf2-1f3fb.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3ff-200d-1faf2-1f3fc.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3ff-200d-1faf2-1f3fd.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

0
qml/js/emoji/1faf1-1f3ff-200d-1faf2-1f3fe.svg Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 2.9 KiB

Some files were not shown because too many files have changed in this diff Show more