Commit 82f991c3 authored by Thomas BOUTROUE's avatar Thomas BOUTROUE

Add About, Settings, Contacts, and User Info pages

Allow including muted chats into unread count

Allow creating new private chat from user info page

Handle mentions

Cleanup in code
parent 10f9ff84
......@@ -70,10 +70,8 @@ DISTFILES += \
$$PWD/icons/108x108/$${TARGET}.png \
$$PWD/icons/128x128/$${TARGET}.png \
$$PWD/icons/172x172/$${TARGET}.png \
$$PWD/dist/telegrame.json \
$$PWD/dist/x-telegrame.im.conf \
$$PWD/dist/x-telegrame.im.fg.conf \
$$PWD/dist/TelegrameSettings.qml \
$$PWD/dist/telegrame_im.ini \
$$PWD/dist/telegrame_im_exists.ini \
$$PWD/dist/telegrame_im_fg.ini
......@@ -102,10 +100,4 @@ notificationcategories.path = /usr/share/lipstick/notificationcategories
events.files = $$PWD/dist/telegrame_im.ini $$PWD/dist/telegrame_im_exists.ini $$PWD/dist/telegrame_im_fg.ini
events.path = /usr/share/ngfd/events.d
settings_json.files = $$PWD/dist/telegrame.json
settings_json.path = /usr/share/jolla-settings/entries
settings_qml.files = $$PWD/dist/TelegrameSettings.qml
settings_qml.path = /usr/share/$${TARGET}/settings
INSTALLS += target desktop icon86 icon108 icon128 icon256 notificationcategories events settings_json settings_qml
INSTALLS += target desktop icon86 icon108 icon128 icon256 notificationcategories events
......@@ -11,5 +11,8 @@
<file>qml/components/WrapperVideoPlayer.qml</file>
<file>qml/components/WrapperAudioPlayer.qml</file>
<file>qml/components/LabelFixed.qml</file>
<file>qml/pages/PageSettings.qml</file>
<file>qml/pages/PageAbout.qml</file>
<file>qml/pages/PageContacts.qml</file>
</qresource>
</RCC>
......@@ -2,11 +2,21 @@ import QtQuick 2.6;
import QtQmlTricks 3.0;
import Sailfish.Silica 1.0;
import harbour.Telegrame 1.0;
import Nemo.Configuration 1.0;
import "../components";
CoverBackground {
id: cover;
readonly property int count : (configIncludeMutedChatsInUnreadCount.value
? TD_Global.unreadMessagesCountWithMuted
: TD_Global.unreadMessagesCount);
ConfigurationValue {
id: configIncludeMutedChatsInUnreadCount;
key: "/apps/telegrame/include_muted_chats_in_unread_count";
defaultValue: false;
}
Image {
source: "qrc:///images/Telegram_logo.svg";
height: width;
......@@ -33,15 +43,15 @@ CoverBackground {
anchors.horizontalCenter: parent.horizontalCenter;
}
LabelFixed {
text: TD_Global.unreadMessagesCount;
color: (TD_Global.unreadMessagesCount > 0 ? Theme.highlightColor : Theme.secondaryColor);
text: count;
color: (count > 0 ? Theme.highlightColor : Theme.secondaryColor);
font.pixelSize: Theme.fontSizeHuge;
anchors.horizontalCenter: parent.horizontalCenter;
}
LabelFixed {
text: qsTr ("unread messages");
color: Theme.primaryColor;
opacity: (TD_Global.unreadMessagesCount > 0 ? 1.0 : 0.35);
opacity: (count > 0 ? 1.0 : 0.35);
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
horizontalAlignment: Text.AlignHCenter;
font.pixelSize: Theme.fontSizeLarge;
......
......@@ -35,14 +35,31 @@ ApplicationWindow {
property TD_StickerSet currentStickerSet : (TD_Global.stickerSetsList.count > 0 ? TD_Global.stickerSetsList.getFirst () : null);
property alias groupImagesInAlbums : configGroupImagesInAlbum.value;
property alias groupVideosInAlbums : configGroupVideosInAlbum.value;
property alias sendTextMsgOnEnterKey : configSendTextMsgOnEnterKey.value;
property alias groupImagesInAlbums : configGroupImagesInAlbum.value;
property alias groupVideosInAlbums : configGroupVideosInAlbum.value;
property alias sendTextMsgOnEnterKey : configSendTextMsgOnEnterKey.value;
property alias includeMutedChatsInUnreadCount : configIncludeMutedChatsInUnreadCount.value;
readonly property bool active : (Qt.application.state === Qt.ApplicationActive);
readonly property bool isPortrait : (window.orientation === Orientation.Portrait || window.orientation === Orientation.PortraitInverted);
readonly property bool isLandscape : (window.orientation === Orientation.Landscape || window.orientation === Orientation.LandscapeInverted);
Connections {
target: TD_Global;
onShowChatRequested: {
if (chatItem) {
console.log ("DISPLAY REQUESTED", chatItem.id);
window.activate ();
while (pageStack.depth > 1) {
pageStack.navigateBack (PageStackAction.Immediate);
}
pageStack.push (compoPageChat, {
"currentChat" : chatItem,
},
PageStackAction.Immediate);
}
}
}
ConfigurationValue {
id: configGroupImagesInAlbum;
key: "/apps/telegrame/group_images_in_album";
......@@ -58,6 +75,11 @@ ApplicationWindow {
key: "/apps/telegrame/send_text_msg_on_enter_key";
defaultValue: false;
}
ConfigurationValue {
id: configIncludeMutedChatsInUnreadCount;
key: "/apps/telegrame/include_muted_chats_in_unread_count";
defaultValue: false;
}
Item {
rotation: {
switch (window.orientation) {
......@@ -74,6 +96,7 @@ ApplicationWindow {
MouseArea {
id: footerChat;
visible: enabled;
enabled: showInputPanel;
opacity: (enabled ? 1.0 : 0.0);
implicitHeight: (layoutFooter.height + layoutFooter.anchors.margins * 2);
......@@ -1815,11 +1838,175 @@ ApplicationWindow {
PageMain { }
}
Component {
id: compoPageContacts;
PageContacts { }
}
Component {
id: compoPageChat;
PageChat { }
}
Component {
id: compoPageSettings;
PageSettings { }
}
Component {
id: compoPageAbout;
PageAbout { }
}
Component {
id: compoPageUserInfo;
Page {
id: pageUserInfo;
allowedOrientations: Orientation.Portrait;
property TD_User userItem : null;
SilicaFlickable {
contentWidth: width;
contentHeight: (layoutUserInfo.height + layoutUserInfo.anchors.margins * 2);
anchors.fill: parent;
ColumnContainer {
id: layoutUserInfo;
spacing: Theme.paddingMedium;
ExtraAnchors.topDock: parent;
Item {
Container.forcedHeight: headerUserInfo.height;
}
DelegateDownloadableImage {
size: Theme.iconSizeExtraLarge;
fileItem: (pageUserInfo.userItem && pageUserInfo.userItem.profilePhoto ? pageUserInfo.userItem.profilePhoto.big : null);
autoDownload: true;
anchors.horizontalCenter: parent.horizontalCenter;
}
LabelFixed {
text: (pageUserInfo.userItem ? pageUserInfo.userItem.firstName : "");
color: Theme.primaryColor;
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
font.family: Theme.fontFamilyHeading;
font.pixelSize: Theme.fontSizeLarge;
anchors.horizontalCenter: parent.horizontalCenter;
}
LabelFixed {
text: (pageUserInfo.userItem ? pageUserInfo.userItem.lastName : "");
color: Theme.primaryColor;
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
font.family: Theme.fontFamilyHeading;
font.pixelSize: Theme.fontSizeLarge;
anchors.horizontalCenter: parent.horizontalCenter;
}
Item {
Container.forcedHeight: Theme.paddingLarge;
}
RowContainer {
spacing: Theme.paddingLarge;
visible: (pageUserInfo.userItem && pageUserInfo.userItem.username !== "");
anchors.margins: Theme.paddingLarge;
ExtraAnchors.horizontalFill: parent;
RectangleButton {
icon: "icon-m-link";
size: Theme.iconSizeMedium;
anchors.verticalCenter: parent.verticalCenter;
onClicked: {
Clipboard.text = pageUserInfo.userItem.username;
}
}
LabelFixed {
text: (pageUserInfo.userItem ? "@" + pageUserInfo.userItem.username : "");
color: Theme.secondaryHighlightColor;
font.underline: true;
font.pixelSize: Theme.fontSizeLarge;
anchors.verticalCenter: parent.verticalCenter;
}
}
RowContainer {
spacing: Theme.paddingLarge;
visible: (pageUserInfo.userItem && pageUserInfo.userItem.phoneNumber !== "");
anchors.margins: Theme.paddingLarge;
ExtraAnchors.horizontalFill: parent;
RectangleButton {
icon: "icon-m-answer";
size: Theme.iconSizeMedium;
anchors.verticalCenter: parent.verticalCenter;
onClicked: {
Qt.openUrlExternally ("tel:+" + pageUserInfo.userItem.phoneNumber);
}
}
LabelFixed {
text: (pageUserInfo.userItem ? "+" + pageUserInfo.userItem.phoneNumber : "");
color: Theme.secondaryHighlightColor;
font.underline: true;
font.pixelSize: Theme.fontSizeLarge;
anchors.verticalCenter: parent.verticalCenter;
}
}
Item {
Container.forcedHeight: Theme.paddingLarge;
}
MouseArea {
id: btn;
opacity: (enabled ? 1.0 : 0.35);
implicitWidth: Math.max (Theme.itemSizeSmall, lbl.width + Theme.paddingMedium * 2);
implicitHeight: Math.max (Theme.itemSizeSmall, lbl.height + Theme.paddingMedium * 2);
anchors.horizontalCenter: parent.horizontalCenter;
onClicked: {
console.log ("PRIVATE CHAT REQUESTED", pageUserInfo.userItem.id);
var chatItem = TD_Global.getChatItemById (userItem.id);
if (chatItem) {
TD_Global.showChat (chatItem);
}
else {
TD_Global.createPrivateChat (pageUserInfo.userItem);
}
}
Rectangle {
color: (parent.pressed ? Theme.highlightColor : Theme.primaryColor);
radius: Theme.paddingSmall;
opacity: 0.15;
antialiasing: true;
anchors.fill: parent;
}
LabelFixed {
id: lbl;
text: qsTr ("Open private chat");
anchors.centerIn: parent;
}
}
}
}
Rectangle {
id: headerUserInfo;
color: Qt.rgba (1.0 - Theme.primaryColor.r, 1.0 - Theme.primaryColor.g, 1.0 - Theme.primaryColor.b, 0.85);
implicitHeight: (title.height + title.anchors.margins * 2);
ExtraAnchors.topDock: parent;
LabelFixed {
id: title;
text: qsTr ("Contact info");
color: Theme.highlightColor;
font {
family: Theme.fontFamilyHeading;
pixelSize: Theme.fontSizeLarge;
}
anchors {
right: parent.right
margins: Theme.paddingLarge;
verticalCenter: parent.verticalCenter;
}
}
}
}
}
Component {
id: compoPageChatInfoPrivate;
......
import QtQuick 2.1;
import Sailfish.Silica 1.0;
import QtQmlTricks 3.0;
import "../components";
Page {
id: page;
allowedOrientations: Orientation.All;
Flickable {
id: flickerAbout;
contentWidth: width;
contentHeight: (layout.height + layout.anchors.margins * 2);
anchors.fill: parent;
ColumnContainer {
id: layout;
spacing: Theme.paddingLarge;
anchors.margins: Theme.paddingLarge;
ExtraAnchors.topDock: parent;
Item {
Container.forcedHeight: Theme.paddingMedium;
}
Image {
source: "qrc:///images/Telegram_logo.svg";
sourceSize: Qt.size (Theme.iconSizeExtraLarge, Theme.iconSizeExtraLarge);
anchors.horizontalCenter: parent.horizontalCenter;
}
LabelFixed {
text: "Telegra'me";
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
font.family: Theme.fontFamilyHeading;
font.pixelSize: Theme.fontSizeExtraLarge;
horizontalAlignment: Text.AlignHCenter;
ExtraAnchors.horizontalFill: parent;
}
LabelFixed {
text: qsTr ("An unofficial client for Telegram messaging, using TDLIB API. It aims to provide all the main features of the official apps on other platforms, while integrating nicely into Sailfish UI that we all love.");
opacity: 0.65;
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
horizontalAlignment: Text.AlignJustify;
font.family: Theme.fontFamilyHeading;
font.pixelSize: Theme.fontSizeSmall;
ExtraAnchors.horizontalFill: parent;
}
Item {
Container.forcedHeight: Theme.paddingMedium;
}
LabelFixed {
text: qsTr ("Designed and developed by Thomas BOUTROUE");
color: Theme.secondaryHighlightColor;
opacity: 0.65;
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
horizontalAlignment: Text.AlignHCenter;
font.family: Theme.fontFamilyHeading;
font.pixelSize: Theme.fontSizeMedium;
ExtraAnchors.horizontalFill: parent;
}
LabelFixed {
text: "thebootroo@gmail.com";
color: Theme.highlightColor;
opacity: 0.65;
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
horizontalAlignment: Text.AlignHCenter;
font.family: Theme.fontFamilyHeading;
font.underline: true;
font.pixelSize: Theme.fontSizeSmall;
ExtraAnchors.horizontalFill: parent;
MouseArea {
anchors.fill: parent;
anchors.margins: -Theme.paddingMedium;
onClicked: {
Qt.openUrlExternally ("mailto:" + parent.text);
}
}
}
Rectangle {
color: Theme.secondaryColor;
implicitHeight: 1;
ExtraAnchors.horizontalFill: parent;
}
LabelFixed {
text: qsTr ("The app is open-source and the code is hosted on my Gitlab instance (no account required to get sources) :");
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
horizontalAlignment: Text.AlignHCenter;
font.family: Theme.fontFamilyHeading;
font.pixelSize: Theme.fontSizeMedium;
ExtraAnchors.horizontalFill: parent;
}
LabelFixed {
text: "http://gitlab.unique-conception.org/sailfish-app/telegra-me";
color: Theme.highlightColor;
opacity: 0.65;
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
horizontalAlignment: Text.AlignHCenter;
font.family: Theme.fontFamilyHeading;
font.underline: true;
font.pixelSize: Theme.fontSizeSmall;
ExtraAnchors.horizontalFill: parent;
MouseArea {
anchors.fill: parent;
anchors.margins: -Theme.paddingMedium;
onClicked: {
Qt.openUrlExternally (parent.text);
}
}
}
Rectangle {
color: Theme.secondaryColor;
implicitHeight: 1;
ExtraAnchors.horizontalFill: parent;
}
LabelFixed {
text: qsTr ("Kudos to BlackSailer for compiling tdlib-json on Sailfish OS !");
color: Theme.highlightColor;
opacity: 0.65;
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
horizontalAlignment: Text.AlignHCenter;
font.bold: true;
font.family: Theme.fontFamilyHeading;
font.pixelSize: Theme.fontSizeMedium;
ExtraAnchors.horizontalFill: parent;
}
Rectangle {
color: Theme.secondaryColor;
implicitHeight: 1;
ExtraAnchors.horizontalFill: parent;
}
LabelFixed {
text: qsTr ("Donations are gladly accepted ;-)");
wrapMode: Text.WrapAtWordBoundaryOrAnywhere;
horizontalAlignment: Text.AlignHCenter;
font.bold: true;
font.family: Theme.fontFamilyHeading;
font.pixelSize: Theme.fontSizeMedium;
ExtraAnchors.horizontalFill: parent;
}
Item {
Container.forcedHeight: Theme.paddingLarge;
}
MouseArea {
id: btn;
opacity: (enabled ? 1.0 : 0.35);
implicitWidth: Math.max (Theme.itemSizeSmall, lbl.width + Theme.paddingMedium * 2);
implicitHeight: Math.max (Theme.itemSizeSmall, lbl.height + Theme.paddingMedium * 2);
anchors.horizontalCenter: parent.horizontalCenter;
onClicked: {
Qt.openUrlExternally ("https://paypal.me/ThomasBOUTROUE");
}
Rectangle {
color: (parent.pressed ? Theme.highlightColor : Theme.primaryColor);
radius: Theme.paddingSmall;
opacity: 0.15;
antialiasing: true;
anchors.fill: parent;
}
LabelFixed {
id: lbl;
text: qsTr ("Donate with Paypal");
anchors.centerIn: parent;
}
}
Item {
Container.forcedHeight: Theme.paddingLarge;
}
}
}
VerticalScrollDecorator {
flickable: flickerAbout;
}
}
......@@ -303,8 +303,8 @@ Page {
RemorseItem { id: remorse; }
Rectangle {
color: Theme.secondaryHighlightColor;
opacity: 0.10;
visible: (delegateMsg.messageItem.id === currentMessageId);
opacity: (delegateMsg.messageItem.containsUnreadMention ? 0.35 : 0.10);
visible: (delegateMsg.messageItem.id === currentMessageId || delegateMsg.messageItem.containsUnreadMention);
anchors.fill: parent;
}
Binding {
......
import QtQuick 2.1;
import Sailfish.Silica 1.0;
import QtQmlTricks 3.0;
import harbour.Telegrame 1.0;
import "../components";
Page {
id: page;
SilicaListView {
id: flickerContacts;
anchors.fill: parent;
model: TD_Global.sortedContactsList;
section {
property: "firstName";
criteria: ViewSection.FirstCharacter;
delegate: SectionHeader {
text: section;
}
}
header: Item {
implicitHeight: headerContacts.height;
ExtraAnchors.horizontalFill: parent;
}
delegate: ListItem {
id: delegateContact;
ExtraAnchors.horizontalFill: parent;
onClicked: {
pageStack.push (compoPageUserInfo, {
"userItem" : userItem,
});
}
readonly property TD_User userItem : modelData;
RowContainer {
id: layout;
spacing: Theme.paddingMedium;
anchors {
margins: Theme.paddingMedium;
verticalCenter: parent.verticalCenter;
}
ExtraAnchors.horizontalFill: parent;
DelegateDownloadableImage {
id: ico;
size: Theme.iconSizeMedium;
fileItem: (delegateContact.userItem && delegateContact.userItem.profilePhoto
? delegateContact.userItem.profilePhoto.big
: null);
autoDownload: true;
anchors.verticalCenter: parent.verticalCenter;
}
LabelFixed {
id: lbl;
text: (delegateContact.userItem ? delegateContact.userItem.firstName + " " + delegateContact.userItem.lastName : "");
anchors.verticalCenter: parent.verticalCenter;
Container.horizontalStretch: 1;
}
}
}
}
VerticalScrollDecorator {
flickable: flickerContacts;
}
Rectangle {
id: headerContacts;
color: Qt.rgba (1.0 - Theme.primaryColor.r, 1.0 - Theme.primaryColor.g, 1.0 - Theme.primaryColor.b, 0.85);
implicitHeight: (title.height + title.anchors.margins * 2);
ExtraAnchors.topDock: parent;
LabelFixed {
id: title;
text: qsTr ("All contacts");
color: Theme.highlightColor;
font {
family: Theme.fontFamilyHeading;
pixelSize: Theme.fontSizeLarge;
}
anchors {
right: parent.right
margins: Theme.paddingLarge;
verticalCenter: parent.verticalCenter;
}
}
}
}
......@@ -368,17 +368,15 @@ Page {
id: pulley;
MenuItem {
text: qsTr ("About [TODO]");
enabled: false;
text: qsTr ("About");
onClicked: {
// TODO
pageStack.push (compoPageAbout);
}
}
MenuItem {
text: qsTr ("Settings [TODO]");
enabled: false;
text: qsTr ("Settings");
onClicked: {
// TODO
pageStack.push (compoPageSettings);
}
}
MenuItem {
......@@ -389,10 +387,9 @@ Page {
}
}
MenuItem {
text: qsTr ("Contacts list [TODO]");
enabled: false;
text: qsTr ("Contacts list");
onClicked: {
// TODO
pageStack.push (compoPageContacts);
}
}
MenuItem {
......@@ -433,7 +430,7 @@ Page {
}
}
MenuItem {
text: (delegateChat.chatItem.notificationSettings.muteFor > 0 ? qsTr ("Un-mute notifications [TODO]") : qsTr ("Mute notifications [TODO]"));
text: (delegateChat.chatItem && delegateChat.chatItem.notificationSettings && delegateChat.chatItem.notificationSettings.muteFor > 0 ? qsTr ("Un-mute notifications [TODO]") : qsTr ("Mute notifications [TODO]"));
enabled: false;
onClicked: {
// TODO
......@@ -460,21 +457,13 @@ Page {
readonly property TD_Message lastMsgItem : (chatItem ? chatItem.getMessageItemById (chatItem.lastReceivedMessageId) : null);
readonly property TD_User lastMsgUserItem : (lastMsgItem ? TD_Global.getUserItemById (lastMsgItem.senderUserId) : null);
readonly property TD_MessageContent lastMsgContentItem : (lastMsgItem ? lastMsgItem.content : null);
readonly property int unreadCount : (chatItem.notificationSettings.muteFor === 0 ? chatItem.unreadCount : 0);
readonly property int unreadCount : (chatItem.notificationSettings && chatItem.notificationSettings.muteFor === 0 ? chatItem.unreadCount : 0);
readonly property string description : (lastMsgItem ? lastMsgItem.preview () : "");
Connections {
target: delegateChat.chatItem;
onDisplayRequested: {
console.log ("DISPLAY REQUESTED", delegateChat.chatItem.id);
window.activate ();
while (pageStack.depth > 1) {
pageStack.navigateBack (PageStackAction.Immediate);
}
pageStack.push (compoPageChat, {
"currentChat" : delegateChat.chatItem,
},
PageStackAction.Immediate);
TD_Global.showChat (delegateChat.chatItem);
}
}
RowContainer {
......
import QtQuick 2.1;
import Sailfish.Silica 1.0;
import Nemo.Configuration 1.0;
Page {
id: page;
allowedOrientations: Orientation.All;
ConfigurationValue {
id: configSendTextMsgOnEnterKey;
key: "/apps/telegrame/send_text_msg_on_enter_key";
defaultValue: false;
}
ConfigurationValue {
id: configIncludeMutedChatsInUnreadCount;
key: "/apps/telegrame/include_muted_chats_in_unread_count";
defaultValue: false;
}
Column {
spacing: Theme.paddingLarge;
anchors {
top: parent.top;
left: parent.left;
right: parent.right;
}
PageHeader {
title: qsTr ("Settings");
}
TextSwitch {
text: qsTr ("Quick sending of text messages");
description: qsTr ("Press Enter to send text messages (single-line)")
automaticCheck: true;
onCheckedChanged: {
configSendTextMsgOnEnterKey.value = checked;
}
Binding on checked { value: configSendTextMsgOnEnterKey.value; }
}
TextSwitch {
text: qsTr ("Include muted chats in unread count");
description: qsTr ("Whether unread chats should be included in cover page")
automaticCheck: true;
onCheckedChanged: {
configIncludeMutedChatsInUnreadCount.value = checked;
}
Binding on checked { value: configIncludeMutedChatsInUnreadCount.value; }
}
}
}
......@@ -14,10 +14,10 @@ Name: harbour-telegrame
%{?qtc_builddir:%define _builddir %qtc_builddir}
Summary: A native Telegram client for Sailfish OS
Version: 0.9
Release: 7
Release: 8
Group: Qt/Qt
License: LICENSE
URL: http://example.org/
License: WTFPL
URL: http://gitlab.unique-conception.org/sailfish-app/telegra-me
Source0: %{name}-%{version}.tar.bz2
Source100: harbour-telegrame.yaml
Requires: sailfishsilica-qt5 >= 0.10.9
......@@ -70,9 +70,7 @@ desktop-file-install --delete-original \
%{_bindir}
%{_datadir}/applications/%{name}.desktop
%{_datadir}/icons/hicolor/*/apps/%{name}.png
%{_datadir}/%{name}/settings/*.qml
%{_datadir}/lipstick/notificationcategories/*.conf
%{_datadir}/ngfd/events.d/*.ini
%{_datadir}/jolla-settings/entries/*.json
# >> files
# << files