Compare commits

..

2 commits

Author SHA1 Message Date
Denis Fedoseev
05238eccc8
Merge pull request #1 from savegame/aurora_os_build
Build for AuroraOS
2022-05-18 12:59:47 +03:00
sashikknox
abf2d1f565 - build for AuroraOS 2022-05-17 23:00:20 +03:00
176 changed files with 2785 additions and 20182 deletions

View file

@ -53,20 +53,20 @@ jobs:
id: build_armv7hl
uses: coderus/github-sfos-build@master
with:
release: 4.4.0.58
release: 4.2.0.21
- name: Build i486
id: build_i486
uses: coderus/github-sfos-build@master
with:
release: 4.4.0.58
release: 4.2.0.21
arch: i486
- name: Build aarch64
id: build_aarch64
uses: coderus/github-sfos-build@master
with:
release: 4.4.0.58
release: 4.2.0.21
arch: aarch64
- name: Upload build result
@ -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,17 +48,16 @@ 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.7](https://github.com/tdlib/td) 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.
In case you want to use the same codebase which was used to compile the library that is shipped with Fernschreiber, please [check out the fork](https://github.com/Wunderfitz/td), be sure to use the branch `fernschreiber` and compile these sources using the following commands (be sure to have the Sailfish OS build engine running):
- `alias sfdk=~/SailfishOS/bin/sfdk`
- `sfdk config target=SailfishOS-4.4.0.58-armv7hl` (this compiles the sources on SFOS 4.4 and ARM - the target needs to be adjusted according to the running SDK engine and the platform)
- `sfdk config target=SailfishOS-3.3.0.16-armv7hl` (this compiles the sources on SFOS 3.3 and ARM - the target needs to be adjusted according to the running SDK engine and the platform)
- `mkdir build`
- `cd build`
- `sfdk build-init`
- `sfdk build-shell cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH=../tdlib -DTD_ENABLE_LTO=ON ..` (in case of compilation issues, try removing the flag `-DTD_ENABLE_LTO=ON`)
- `sfdk build-shell cmake --build . --target install`

47
build.sh Executable file
View file

@ -0,0 +1,47 @@
engine="docker exec -w $(pwd) --user mersdk aurora-os-build-engine"
targets=`${engine} sb2-config -l|grep -v default`
version=`grep -E "Version" $(pwd)/rpm/harbour-fernschreiber.spec|sed "s/Version: \+//g"`
release=`grep -E "Release:" $(pwd)/rpm/harbour-fernschreiber.spec|sed "s/Release: \+//g"`
for each in key cert; do
if [ -f `pwd`/regular_${each}.pem ]; then
echo "Found a regular_${each}.pem file: OK"
continue;
fi
echo -n "Downloading regular_${each}.pem for singing RPM for AuroraOS: "
curl https://community.omprussia.ru/documentation/files/doc/regular_${each}.pem -o regular_${each}.pem &> /dev/null
if [ $? -eq 0 ]; then
echo "OK"
else
echo "FAIL"
echo "Cant download regular_${each}.pem: https://community.omprussia.ru/documentation/files/doc/regular_${each}.pem"
exit 1
fi
done
for target in ${targets}; do
echo "Build for ${target}"
arch=${target##*-}
echo "Detected arch: ${arch}"
${engine} mb2 -t ${target} build
[ $? -ne 0 ] && exit 1
package_name="harbour-fernschreiber-${version}-${release}.${arch}.rpm"
echo -n "Signing RPM ${package_name}: "
temp_output="$(${engine} sb2 -t ${target} rpmsign-external sign --key `pwd`/regular_key.pem --cert `pwd`/regular_cert.pem `pwd`/RPMS/${package_name} 2>&1)"
if [ $? -ne 0 ]; then
echo "FAIL"
echo "${temp_output}"
exit 1
else
echo "OK"
fi
echo -n "Validate RPM ${package_name}: "
temp_output="$( ${engine} sb2 -t ${target} rpm-validator -p regular `pwd`/RPMS/${package_name} 2>&1 )"
if [ $? -ne 0 ]; then
echo "FAIL"
echo "${temp_output}"
exit 1
else
echo "OK"
fi
done

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

@ -24,8 +24,6 @@ PhotoTextsListItem {
// message date
tertiaryText.text: showDraft ? Functions.getDateTimeElapsed(draft_message_date) : ( last_message_date ? ( last_message_date.length === 0 ? "" : Functions.getDateTimeElapsed(last_message_date) + Emoji.emojify(last_message_status, tertiaryText.font.pixelSize) ) : "" )
unreadCount: unread_count
unreadReactionCount: unread_reaction_count
unreadMentionCount: unread_mention_count
isSecret: ( chat_type === TelegramAPI.ChatTypeSecret )
isMarkedAsUnread: is_marked_as_unread
isPinned: is_pinned
@ -50,18 +48,16 @@ PhotoTextsListItem {
sourceComponent: Component {
ContextMenu {
MenuItem {
visible: unread_count > 0 || unread_reaction_count > 0 || unread_mention_count > 0
visible: unread_count > 0
onClicked: {
tdLibWrapper.viewMessage(chat_id, display.last_message.id, true);
tdLibWrapper.readAllChatMentions(chat_id);
tdLibWrapper.readAllChatReactions(chat_id);
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, false);
}
text: qsTr("Mark all messages as read")
}
MenuItem {
visible: unread_count === 0 && unread_reaction_count === 0 && unread_mention_count === 0
visible: unread_count === 0
onClicked: {
tdLibWrapper.toggleChatIsMarkedAsUnread(chat_id, !is_marked_as_unread);
}

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

@ -32,13 +32,12 @@ ListItem {
property int messageIndex
property int messageViewCount
property var myMessage
property var reactions
property bool canReplyToMessage
readonly property bool isAnonymous: myMessage.sender_id["@type"] === "messageSenderChat"
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 +46,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 +63,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 +93,6 @@ ListItem {
}
}
function getInteractionText(viewCount, reactions, size, highlightColor) {
var interactionText = "";
if (viewCount > 0) {
interactionText = Emoji.emojify("👁️ ", size) + 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)
}
}
}
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,25 +110,11 @@ ListItem {
if (messageListItem.messageReactions) {
messageListItem.messageReactions = null;
selectReactionBubble.visible = false;
} else {
selectReactionBubble.visible = !selectReactionBubble.visible;
elementSelected(index);
}
}
}
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) {
@ -193,25 +139,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
@ -312,13 +239,8 @@ ListItem {
messageListItem.messageReactions = reactions;
showItemCompletelyTimer.requestedIndex = index;
showItemCompletelyTimer.start();
} else {
messageListItem.messageReactions = null;
}
}
onReactionsUpdated: {
chatReactions = tdLibWrapper.getChatReactions(page.chatInformation.id);
}
}
Timer {
@ -331,33 +253,15 @@ 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();
@ -401,10 +305,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 +346,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 +381,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 +423,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.active = true
}
}
onPressAndHold: {
@ -552,12 +450,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 +535,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 +549,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)
}
@ -693,6 +590,7 @@ ListItem {
color: messageListItem.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor
horizontalAlignment: messageListItem.textAlign
text: getMessageStatusText(myMessage, index, chatView.lastReadSentIndex, messageDateText.useElapsed)
rightPadding: interactionLoader.active ? interactionLoader.width : 0
MouseArea {
anchors.fill: parent
enabled: !messageListItem.precalculatedValues.pageIsSelecting
@ -701,27 +599,35 @@ ListItem {
messageDateText.text = getMessageStatusText(myMessage, index, chatView.lastReadSentIndex, messageDateText.useElapsed);
}
}
}
Loader {
id: interactionLoader
width: parent.width
height: parent.height
anchors.right: parent.right
asynchronous: true
active: ( chatPage.isChannel && messageViewCount > 0 ) || reactions.length > 0
height: ( ( chatPage.isChannel && messageViewCount > 0 ) || reactions.length > 0 ) ? ( Theme.fontSizeExtraSmall + Theme.paddingSmall ) : 0
active: chatPage.isChannel && messageViewCount
sourceComponent: Component {
Label {
text: getInteractionText(messageViewCount, reactions, font.pixelSize, Theme.highlightColor)
width: parent.width
text: Functions.getShortenedCount(messageViewCount)
leftPadding: Theme.iconSizeSmall
font.pixelSize: Theme.fontSizeTiny
color: messageListItem.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor
horizontalAlignment: messageListItem.textAlign
textFormat: Text.StyledText
maximumLineCount: 1
elide: Text.ElideRight
color: Theme.secondaryColor
Icon {
anchors.verticalCenter: parent.verticalCenter
width: Theme.iconSizeExtraSmall
height: Theme.iconSizeExtraSmall
opacity: 0.6
source: "../../images/icon-s-eye.svg"
sourceSize {
width: Theme.iconSizeExtraSmall
height: Theme.iconSizeExtraSmall
}
}
}
}
}
}
}
@ -763,7 +669,7 @@ ListItem {
Image {
id: emojiPicture
source: Emoji.getEmojiPath(modelData)
width: status === Image.Ready ? Theme.fontSizeLarge : 0
width: Theme.fontSizeLarge
height: Theme.fontSizeLarge
}
@ -772,7 +678,7 @@ ListItem {
MouseArea {
anchors.fill: parent
onClicked: {
tdLibWrapper.setMessageReaction(messageListItem.chatId, messageListItem.messageId, modelData);
Debug.log("Reaction clicked: " + modelData);
messageListItem.messageReactions = null;
}
}

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
@ -12,8 +11,6 @@ ListItem {
property alias tertiaryText: tertiaryText //usually last message date
property int unreadCount: 0
property int unreadMentionCount: 0
property int unreadReactionCount: 0
property bool isSecret: false
property bool isVerified: false
property bool isMarkedAsUnread: false
@ -88,7 +85,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 +101,10 @@ ListItem {
anchors.centerIn: chatUnreadMessagesCountBackground
visible: chatListViewItem.unreadCount > 0
opacity: isMuted ? Theme.opacityHigh : 1.0
text: Functions.formatUnreadCount(chatListViewItem.unreadCount)
}
Rectangle {
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: "@"
text: chatListViewItem.unreadCount > 99 ? "99+" : chatListViewItem.unreadCount
}
}
}
}
Column {
id: contentColumn
anchors {
@ -162,9 +127,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.is_animated && 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
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
}
Behavior on height { SmoothedAnimation { duration: 200 } }
}
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: parent.enabled
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,42 +30,37 @@ 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
width: parent.width
@ -76,7 +71,6 @@ AccordionItem {
width: parent.width
color: Theme.primaryColor
horizontalAlignment: Qt.AlignHCenter
visible: activeSessionsListView.count > 0
}
delegate: ListItem {
id: activeSessionListItem
@ -117,6 +111,9 @@ AccordionItem {
font.bold: true
visible: modelData.is_current
color: Theme.highlightColor
anchors {
horizontalCenter: parent.horizontalCenter
}
}
Label {
@ -124,28 +121,53 @@ AccordionItem {
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
}
@ -154,59 +176,7 @@ AccordionItem {
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

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