1
0
Fork 0
mirror of https://git.jami.net/savoirfairelinux/jami-client-qt.git synced 2025-09-10 12:03:18 +02:00

welcomeview: implement new design

GitLab: #767
Change-Id: Ia2ae77e8e9d3d5abe560ced0a84d828057824845
This commit is contained in:
Sébastien Blin 2022-07-28 13:22:47 -04:00
parent ef7323cf06
commit 2077041c04
22 changed files with 743 additions and 161 deletions

View file

@ -181,7 +181,8 @@ set(COMMON_SOURCES
${APP_SRC_DIR}/currentaccount.cpp
${APP_SRC_DIR}/videodevices.cpp
${APP_SRC_DIR}/videoprovider.cpp
${APP_SRC_DIR}/callparticipantsmodel.cpp)
${APP_SRC_DIR}/callparticipantsmodel.cpp
${APP_SRC_DIR}/tipsmodel.cpp)
set(COMMON_HEADERS
${APP_SRC_DIR}/avatarimageprovider.h
@ -236,7 +237,8 @@ set(COMMON_HEADERS
${APP_SRC_DIR}/currentaccount.h
${APP_SRC_DIR}/videodevices.h
${APP_SRC_DIR}/videoprovider.h
${APP_SRC_DIR}/callparticipantsmodel.h)
${APP_SRC_DIR}/callparticipantsmodel.h
${APP_SRC_DIR}/tipsmodel.h)
if(WITH_WEBENGINE)
list(APPEND COMMON_SOURCES

View file

@ -195,5 +195,6 @@
<file>src/app/wizardview/components/NoUsernamePopup.qml</file>
<file>src/app/wizardview/components/AdvancedAccountSettings.qml</file>
<file>src/app/commoncomponents/InfoBox.qml</file>
<file>src/app/mainview/components/TipBox.qml</file>
</qresource>
</RCC>

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><path d="M20 5H4c-1.1 0-1.99.9-1.99 2L2 17c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm-9 3h2v2h-2V8zm0 3h2v2h-2v-2zM8 8h2v2H8V8zm0 3h2v2H8v-2zm-1 2H5v-2h2v2zm0-3H5V8h2v2zm9 7H8v-2h8v2zm0-4h-2v-2h2v2zm0-3h-2V8h2v2zm3 3h-2v-2h2v2zm0-3h-2V8h2v2z"/><path d="M0 0h24v24H0zm0 0h24v24H0z" fill="none"/></svg>

After

Width:  |  Height:  |  Size: 410 B

View file

@ -39,6 +39,7 @@ import "commoncomponents"
ApplicationWindow {
id: root
flags: Qt.WA_TranslucentBackground
enum LoadedSource {
WizardView = 0,

View file

@ -50,6 +50,7 @@ extern const QString defaultDownloadPath;
X(StartMinimized, false) \
X(ShowChatviewHorizontally, true) \
X(NeverShowMeAgain, false) \
X(HiddenTips, QStringList()) \
X(WindowGeometry, QRectF(qQNaN(), qQNaN(), 0., 0.)) \
X(WindowState, QWindow::AutomaticVisibility) \
X(LANG, "SYSTEM")

View file

@ -263,9 +263,7 @@ Item {
duration: JamiTheme.longFadeDuration
}
}
}
}
@ -303,4 +301,10 @@ Item {
}
}
onFocusChanged: function(focus) {
if (focus)
lineEdit.forceActiveFocus();
}
}

View file

@ -173,7 +173,7 @@ AbstractButton {
Layout.alignment: Qt.AlignHCenter
text: root.text
font.weight: Font.Medium
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter

View file

@ -31,6 +31,7 @@ Item {
id: root
property alias imageId: avatar.imageId
property alias cancelButton: cancelButton.visible
property bool newItem: false
property bool readOnly: false
@ -61,6 +62,8 @@ Item {
onVisibleChanged: {
if (!visible) {
imageLayer.visible = true
buttonsRowLayout.visible = false
stopBooth()
}
}
@ -192,6 +195,8 @@ Item {
height: buttonSize
width: buttonSize
imageContainerWidth: buttonSize
imageContainerHeight: buttonSize
radius: height / 2
border.width: 2
border.color: darkTheme ? "white" : JamiTheme.buttonTintedBlue
@ -245,6 +250,8 @@ Item {
height: buttonSize
width: buttonSize
imageContainerWidth: buttonSize
imageContainerHeight: buttonSize
radius: height / 2
border.width: 2
border.color: darkTheme ? "white" : JamiTheme.buttonTintedBlue
@ -286,6 +293,8 @@ Item {
height: buttonSize
width: buttonSize
imageContainerWidth: buttonSize
imageContainerHeight: buttonSize
radius: height / 2
border.width: 2
border.color: darkTheme ? "white" : JamiTheme.buttonTintedBlue
@ -331,6 +340,7 @@ Item {
PushButton {
id: cancelButton
visible: true
preferredSize: 18
width: 18
height: 18

View file

@ -62,8 +62,9 @@ SBSMessageBase {
height: implicitHeight
wrapMode: Label.WrapAtWordBoundaryOrAnywhere
selectByMouse: true
font.pixelSize: JamiTheme.chatviewFontSize
font.family: 'Ubuntu'
font.hintingPreference: Font.PreferNoHinting
renderType: Text.NativeRendering
textFormat: Text.MarkdownText

View file

@ -253,6 +253,7 @@ Item {
// LineEditContextMenu
property string copy: qsTr("Copy")
property string share: qsTr("Share")
property string cut: qsTr("Cut")
property string paste: qsTr("Paste")
@ -487,6 +488,7 @@ Item {
// KeyboardShortCutTable
property string keyboardShortcutTableWindowTitle: qsTr("Keyboard Shortcut Table")
property string keyboardShortcuts: qsTr("Keyboard Shortcuts")
property string generalKeyboardShortcuts: qsTr("General")
property string conversationKeyboardShortcuts: qsTr("Conversation")
property string callKeyboardShortcuts: qsTr("Call")
@ -651,10 +653,9 @@ Item {
property string introductionJami: qsTr("Share, freely and privately with Jami")
property string alreadyHaveAccount: qsTr("I already have an account")
property string useExistingAccount: qsTr("Use existing Jami account")
property string recommendationMessage: qsTr("Here are some recommendations to improve your experience on Jami")
property string noRecommendations: qsTr("Never show recommendations again")
property string welcomeToJami: qsTr("Welcome to Jami")
property string identifierDescription: qsTr("Share this Jami identifier to be contacted on this account!")
property string hereIsIdentifier: qsTr("Here is your Jami identifier, don't hesitate to share it in order to be contacted more easily!")
// SmartList
property string clearText: qsTr("Clear Text")
@ -751,5 +752,6 @@ Item {
property string tips: qsTr("Tips")
property string customizeText: qsTr("Add a picture and a nickname to complete your profile")
property string customizationDescription: qsTr("This profile is only shared with this account’s contacts")
property string customizationDescription2: qsTr("Your profile is only shared with your contacts")
property string whySaveAccount: qsTr("Why should I save my account ?")
}

View file

@ -426,6 +426,11 @@ Item {
property real infoBoxTitleFontSize: calcSize(13)
property real infoBoxDescFontSize: calcSize(12)
//Tipbox
property real tipBoxTitleFontSize: calcSize(13)
property real tipBoxContentFontSize: calcSize(12)
// MaterialLineEdit
property real materialLineEditPointSize: calcSize(10 + fontSizeOffset)

View file

@ -328,7 +328,7 @@ void
MainApplication::setApplicationFont()
{
QFont font;
font.setFamily("Segoe UI");
font.setFamily("Ubuntu");
setFont(font);
QFontDatabase::addApplicationFont(":/fonts/FontAwesome.otf");
}

View file

@ -25,28 +25,37 @@ import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import "../../commoncomponents"
import "../../settingsview/components"
Rectangle {
id: root
NameRegistrationDialog {
id : nameRegistrationDialog
onAccepted: jamiRegisteredNameText.nameRegistrationState =
UsernameLineEdit.NameRegistrationState.BLANK
}
property bool editable: false
property bool editing: false
radius: 20
Layout.bottomMargin: JamiTheme.jamiIdMargins
Layout.leftMargin: JamiTheme.jamiIdMargins
height: 91
color: JamiTheme.whiteColor
property var minWidth: mainRectangle.width + secondLine.implicitWidth
width: Math.max(minWidth, jamiRegisteredNameText.width + 2 * JamiTheme.preferredMarginSize)
height: component.implicitHeight
color: JamiTheme.secondaryBackgroundColor
ColumnLayout {
anchors.fill: parent
id: component
RowLayout {
id: firstLine
Layout.preferredWidth: parent.width
Layout.alignment: Qt.AlignTop
Layout.preferredWidth: root.width
Rectangle {
id: mainRectangle
@ -58,13 +67,11 @@ Rectangle {
Rectangle {
id: rectForRadius
anchors.bottom: parent.bottom
width: 20
height: 20
color: JamiTheme.mainColor
}
ResponsiveImage {
@ -81,25 +88,49 @@ Rectangle {
}
RowLayout {
id: secondLine
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
Layout.fillWidth: true
PushButton {
id: btnEdit
imageColor: JamiTheme.buttonTintedBlue
imageColor: enabled ? JamiTheme.buttonTintedBlue : JamiTheme.buttonTintedBlack
normalColor: JamiTheme.transparentColor
Layout.topMargin: JamiTheme.pushButtonMargin
hoverEnabled: false
preferredSize : 30
imageContainerWidth: JamiTheme.pushButtonSize
imageContainerHeight: JamiTheme.pushButtonSize
visible: false //(editable) Not visible for the moment
border.color: JamiTheme.buttonTintedBlue
visible: editable && CurrentAccount.registeredName === ""
border.color: enabled ? JamiTheme.buttonTintedBlue : JamiTheme.buttonTintedBlack
enabled: {
switch(jamiRegisteredNameText.nameRegistrationState) {
case UsernameLineEdit.NameRegistrationState.BLANK:
case UsernameLineEdit.NameRegistrationState.FREE:
return true
case UsernameLineEdit.NameRegistrationState.SEARCHING:
case UsernameLineEdit.NameRegistrationState.INVALID:
case UsernameLineEdit.NameRegistrationState.TAKEN:
return false
}
}
source: JamiResources.round_edit_24dp_svg
onClicked: { }
onClicked: {
if (!root.editing) {
root.editing = !root.editing
source = JamiResources.check_black_24dp_svg
jamiRegisteredNameText.text = ""
jamiRegisteredNameText.forceActiveFocus()
} else {
root.editing = !root.editing
source = JamiResources.round_edit_24dp_svg
jamiRegisteredNameText.accepted()
jamiRegisteredNameText.focus = false
}
}
}
PushButton {
@ -107,21 +138,19 @@ Rectangle {
imageColor: JamiTheme.buttonTintedBlue
normalColor: JamiTheme.transparentColor
hoveredColor: JamiTheme.transparentColor
Layout.topMargin: JamiTheme.pushButtonMargin
preferredSize : 30
imageContainerWidth: JamiTheme.pushButtonSize
imageContainerHeight: JamiTheme.pushButtonSize
hoverEnabled: false
border.color: JamiTheme.tintedBlue
source: JamiResources.content_copy_24dp_svg
toolTipText: JamiStrings.copy
onClicked: {
UtilsAdapter.setClipboardText(CurrentAccount.bestId)
}
onClicked: UtilsAdapter.setClipboardText(CurrentAccount.bestId)
}
PushButton {
@ -129,34 +158,48 @@ Rectangle {
imageColor: JamiTheme.buttonTintedBlue
normalColor: JamiTheme.transparentColor
hoveredColor: JamiTheme.transparentColor
Layout.topMargin: JamiTheme.pushButtonMargin
Layout.rightMargin: JamiTheme.pushButtonMargin
preferredSize : 30
imageContainerWidth: JamiTheme.pushButtonSize
imageContainerHeight: JamiTheme.pushButtonSize
hoverEnabled: false
border.color: JamiTheme.buttonTintedBlue
source: JamiResources.share_24dp_svg
toolTipText: JamiStrings.share
onClicked: { qrDialog.open() }
onClicked: qrDialog.open()
}
}
}
ElidedTextLabel {
UsernameLineEdit {
id: jamiRegisteredNameText
readOnly: !root.editing
Layout.preferredWidth: 330
Layout.alignment: Qt.AlignBottom | Qt.AlignCenter
Layout.bottomMargin: JamiTheme.preferredMarginSize
horizontalAlignment: Qt.AlignHCenter
Layout.leftMargin: JamiTheme.preferredMarginSize
Layout.rightMargin: JamiTheme.preferredMarginSize
backgroundColor: JamiTheme.secondaryBackgroundColor
font.pointSize: JamiTheme.textFontSize + 1
text: CurrentAccount.bestId
color: JamiTheme.blackColor
color: JamiTheme.textColor
onAccepted: {
if (!btnEdit.enabled)
return
if (text.length === 0) {
text = CurrentAccount.bestId
} else {
nameRegistrationDialog.openNameRegistrationDialog(text)
}
}
}
}

View file

@ -0,0 +1,219 @@
/*
* Copyright (C) 2020-2022 Savoir-faire Linux Inc.
* Author: Fadi Shehadeh <fadi.shehadeh@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
*/
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import Qt5Compat.GraphicalEffects
import "../../commoncomponents"
Item {
id: root
property var title: ""
property var description: ""
property int tipId: 0
property bool isTip : true
property bool hovered: false
property bool clicked : false
property bool opened : false
property string alias: ""
width: 200
height: tipColumnLayout.implicitHeight + 2 * JamiTheme.preferredMarginSize
signal ignoreClicked
Rectangle {
id: rect
anchors.fill: parent
color: JamiTheme.secondaryBackgroundColor
border.color: opened || hovered ? "transparent" : Qt.rgba(0, 0.34,0.6,0.16)
radius: 20
ColumnLayout {
id: tipColumnLayout
anchors.top: parent.top
width: parent.width
anchors.topMargin: 10
RowLayout {
Layout.leftMargin: 15
Layout.alignment: Qt.AlignLeft
ResponsiveImage {
id: icon
visible: !opened
Layout.alignment: Qt.AlignLeft
Layout.topMargin: 5
Layout.preferredWidth: 26
Layout.preferredHeight: 26
containerHeight: Layout.preferredHeight
containerWidth: Layout.preferredWidth
source: !isTip ? JamiResources.noun_paint_svg : JamiResources.glasses_tips_svg
color: "#005699"
}
Label {
text: root.isTip ? JamiStrings.tips : JamiStrings.customize
color: JamiTheme.textColor
font.weight: Font.Medium
Layout.topMargin: 5
visible: !opened
Layout.alignment: Qt.AlignLeft
Layout.leftMargin: isTip ? 8 : 5
font.pixelSize: JamiTheme.tipBoxTitleFontSize
}
}
Text {
Layout.preferredWidth: root.isTip ? opened ? 140 : 150 : 170
Layout.leftMargin: 20
Layout.topMargin: root.isTip && opened ? 0 : 8
Layout.bottomMargin: 15
font.pixelSize: JamiTheme.tipBoxContentFontSize
visible: !opened || root.isTip
wrapMode: Text.WordWrap
font.weight: root.isTip && opened ? Font.Medium : Font.Normal
text: !isTip ? JamiStrings.customizeText : root.title
color: JamiTheme.textColor
}
PhotoboothView {
id: setAvatarWidget
Layout.preferredWidth: JamiTheme.accountListAvatarSize
Layout.preferredHeight: JamiTheme.accountListAvatarSize
Layout.topMargin: 10
Layout.alignment: Qt.AlignHCenter
darkTheme: UtilsAdapter.luma(JamiTheme.primaryBackgroundColor)
visible: opened &&! isTip
enabled: true
buttonSize: 35
imageId: CurrentAccount.id
avatarSize: 53
cancelButton: false
}
EditableLineEdit {
id: displayNameLineEdit
visible: !isTip && opened
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: root.width - 32
text: CurrentAccount.alias
placeholderText: JamiStrings.enterNickname
color: JamiTheme.textColor
fontSize: JamiTheme.tipBoxContentFontSize
onEditingFinished: root.alias = text
}
Text {
Layout.preferredWidth: root.width - 32
Layout.leftMargin: 20
Layout.topMargin: 6
font.pixelSize: JamiTheme.tipBoxContentFontSize
visible: opened && !isTip
wrapMode: Text.WordWrap
text: JamiStrings.customizationDescription2
color: JamiTheme.textColor
}
Text {
Layout.preferredWidth: root.width - 32
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
font.pixelSize: JamiTheme.tipBoxContentFontSize
visible: opened && isTip
wrapMode: Text.WordWrap
text: root.description
color: JamiTheme.textColor
}
}
}
HoverHandler {
target : rect
onHoveredChanged: root.hovered = hovered
cursorShape: Qt.PointingHandCursor
}
TapHandler {
target: rect
onTapped: opened = !opened
}
DropShadow {
z: -1
visible: hovered || opened
width: root.width
height: root.height
horizontalOffset: 3.0
verticalOffset: 3.0
radius: 16
color: Qt.rgba(0, 0.34,0.6,0.16)
source: rect
transparentBorder: true
}
PushButton {
id: btnClose
width: 20
height: 20
imageContainerWidth: 20
imageContainerHeight : 20
anchors.margins: 14
anchors.top: parent.top
anchors.right: parent.right
visible: opened
circled: true
imageColor: Qt.rgba(0, 86/255, 153/255, 1)
normalColor: "transparent"
source: JamiResources.round_close_24dp_svg
onClicked: root.ignoreClicked()
}
}

View file

@ -20,155 +20,204 @@ import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import net.jami.Models 1.1
import net.jami.Adapters 1.1
import net.jami.Constants 1.1
import net.jami.Enums 1.1
import net.jami.Models 1.1
import Qt.labs.lottieqt
import "../../commoncomponents"
import "../js/keyboardshortcuttablecreation.js" as KeyboardShortcutTableCreation
Rectangle {
id: root
id: root
color: JamiTheme.secondaryBackgroundColor
ColumnLayout {
id: welcomePageColumnLayout
anchors.centerIn: parent
width: Math.max(mainViewStackPreferredWidth, root.width - 100)
height: parent.height
ColumnLayout {
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: welcomePageColumnLayout.width
Layout.preferredHeight: implicitHeight
Layout.topMargin: JamiTheme.preferredMarginSize
ResponsiveImage {
id: jamiLogoImage
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: Math.min(welcomePageColumnLayout.width, 330)
Layout.preferredHeight: Math.min(welcomePageColumnLayout.width / 3, 110)
Layout.bottomMargin: 10
source: JamiTheme.darkTheme ?
JamiResources.logo_jami_standard_coul_white_svg :
JamiResources.logo_jami_standard_coul_svg
JamiFlickable {
id: welcomeView
MouseArea {
anchors.fill: parent
enabled: visible
onClicked: {
for (var c in flow.children) {
flow.children[c].opened = false
}
}
}
Label {
id: jamiIntroText
anchors.fill: root
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: welcomePageColumnLayout.width
Layout.preferredHeight: 80
Layout.bottomMargin: 5
contentHeight: Math.max(root.height, welcomePageLayout.implicitHeight)
contentWidth: Math.max(300, root.width)
wrapMode: Text.WordWrap
font.pointSize: JamiTheme.textFontSize + 1
Item {
id: welcomePageLayout
width: Math.max(300, root.width)
height: parent.height
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
Item {
anchors.centerIn: parent
height: childrenRect.height
text: JamiStrings.description
color: JamiTheme.textColor
}
Rectangle {
id: welcomeInfo
Label {
id: jamiShareWithFriendText
radius: 30
color: JamiTheme.rectColor
anchors.topMargin: 25
anchors.horizontalCenter: parent.horizontalCenter
width: identifier.width + 2 * JamiTheme.preferredMarginSize + (welcomeLogo.visible ? welcomeLogo.width : 0)
height: childrenRect.height
opacity:1
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: welcomePageColumnLayout.width
Layout.preferredHeight: 50
wrapMode: Text.WordWrap
font.pointSize: JamiTheme.textFontSize
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
visible: LRCInstance.currentAccountType === Profile.Type.JAMI
text: JamiStrings.shareInvite
color: JamiTheme.faddedFontColor
}
Rectangle {
id: jamiRegisteredNameRect
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: welcomePageColumnLayout.width
Layout.preferredHeight: 65
color: JamiTheme.secondaryBackgroundColor
visible: LRCInstance.currentAccountType === Profile.Type.JAMI
ColumnLayout {
id: jamiRegisteredNameRectColumnLayout
spacing: 0
Text {
id: jamiRegisteredNameText
Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: welcomePageColumnLayout.width
Layout.preferredHeight: 30
font.pointSize: JamiTheme.textFontSize + 1
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
text: textMetricsjamiRegisteredNameText.elidedText
color: JamiTheme.textColor
TextMetrics {
id: textMetricsjamiRegisteredNameText
font: jamiRegisteredNameText.font
text: UtilsAdapter.getBestId(LRCInstance.currentAccountId)
elideWidth: welcomePageColumnLayout.width
elide: Qt.ElideMiddle
}
Behavior on width {
NumberAnimation { duration: JamiTheme.shortFadeDuration }
}
PushButton {
id: copyRegisterednameButton
Layout.alignment: Qt.AlignCenter
Label {
id: welcome
preferredSize: 34
imagePadding: 4
imageColor: JamiTheme.textColor
anchors.top: parent.top
anchors.left: parent.left
anchors.topMargin: JamiTheme.preferredMarginSize
anchors.leftMargin: JamiTheme.preferredMarginSize
width: 300
source: JamiResources.content_copy_24dp_svg
font.pixelSize: JamiTheme.bigFontSize
onClicked: {
UtilsAdapter.setClipboardText(
textMetricsjamiRegisteredNameText.text)
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
text: JamiStrings.welcomeToJami
color: JamiTheme.textColor
}
Label {
id: identifierDescription
anchors.top: welcome.bottom
anchors.left: parent.left
anchors.topMargin: JamiTheme.preferredMarginSize
anchors.leftMargin: JamiTheme.preferredMarginSize
width: 300
font.pixelSize: JamiTheme.headerFontSize
wrapMode: Text.WordWrap
text: JamiStrings.hereIsIdentifier
color: JamiTheme.textColor
}
JamiIdentifier {
id: identifier
editable: true
anchors.top: identifierDescription.bottom
anchors.left: parent.left
anchors.margins: JamiTheme.preferredMarginSize
}
Image {
id: welcomeLogo
visible: root.width > 630
width: 212
height: 244
anchors.top: parent.top
anchors.left: identifier.right
anchors.margins: JamiTheme.preferredMarginSize
anchors.topMargin: -20
opacity: visible
source: JamiResources.welcome_illustration_2_svg
Behavior on opacity {
NumberAnimation { duration: JamiTheme.shortFadeDuration }
}
}
}
JamiFlickable {
id: tipsFlow
anchors.top: welcomeInfo.bottom
anchors.topMargin: JamiTheme.preferredMarginSize * 2
anchors.horizontalCenter: parent.horizontalCenter
width: welcomeInfo.width + JamiTheme.preferredMarginSize * 2
height: flow.height + JamiTheme.preferredMarginSize * 2
clip: true
Flow {
id: flow
spacing: 12
Repeater {
model: TipsModel
Layout.alignment: Qt.AlignCenter
delegate: TipBox {
tipId: TipId
title: Title
description: Description
isTip: IsTip
visible: index < 3
onIgnoreClicked: TipsModel.remove(TipId)
}
}
}
}
}
}
MaterialButton {
id: btnAboutPopUp
Item {
id: bottomRow
width: Math.max(300, root.width)
height: aboutJami.height + JamiTheme.preferredMarginSize
anchors.bottom: parent.bottom
Layout.alignment: Qt.AlignBottom | Qt.AlignHCenter
Layout.bottomMargin: JamiTheme.preferredMarginSize
MaterialButton {
id: aboutJami
tertiary: true
preferredWidth: JamiTheme.aboutButtonPreferredWidth
anchors.horizontalCenter: parent.horizontalCenter
preferredWidth: JamiTheme.aboutButtonPreferredWidthth
text: JamiStrings.aboutJami
color: JamiTheme.buttonTintedBlack
hoveredColor: JamiTheme.buttonTintedBlackHovered
pressedColor: JamiTheme.buttonTintedBlackPressed
secondary: true
onClicked: aboutPopUpDialog.open()
}
text: JamiStrings.aboutJami
PushButton {
id: btnKeyboard
onClicked: aboutPopUpDialog.open()
imageColor: JamiTheme.buttonTintedBlue
normalColor: JamiTheme.transparentColor
hoveredColor: JamiTheme.transparentColor
anchors.right: parent.right
anchors.rightMargin: JamiTheme.preferredMarginSize
preferredSize : 30
imageContainerWidth: JamiTheme.pushButtonSize
imageContainerHeight: JamiTheme.pushButtonSize
border.color: JamiTheme.buttonTintedBlue
source: JamiResources.keyboard_black_24dp_svg
toolTipText: JamiStrings.keyboardShortcuts
onClicked: {
KeyboardShortcutTableCreation.createKeyboardShortcutTableWindowObject()
KeyboardShortcutTableCreation.showKeyboardShortcutTableWindow()
}
}
}
}
}
@ -180,4 +229,6 @@ Rectangle {
bBorderwidth: 0
borderColor: JamiTheme.tabbarBorderColor
}
}

View file

@ -24,6 +24,7 @@
#include "contactadapter.h"
#include "pluginadapter.h"
#include "messagesadapter.h"
#include "tipsmodel.h"
#include "previewengine.h"
#include "utilsadapter.h"
#include "conversationsadapter.h"
@ -117,11 +118,13 @@ registerTypes(QQmlEngine* engine,
auto pluginAdapter = new PluginAdapter(lrcInstance, parent);
auto currentConversation = new CurrentConversation(lrcInstance, parent);
auto currentAccount = new CurrentAccount(lrcInstance, settingsManager, parent);
auto tipsModel = new TipsModel(settingsManager, parent);
auto videoDevices = new VideoDevices(lrcInstance, parent);
auto currentAccountToMigrate = new CurrentAccountToMigrate(lrcInstance, parent);
// qml adapter registration
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, callAdapter, "CallAdapter");
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, tipsModel, "TipsModel");
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, messagesAdapter, "MessagesAdapter");
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, conversationsAdapter, "ConversationsAdapter");
QML_REGISTERSINGLETONTYPE_POBJECT(NS_ADAPTERS, avAdapter, "AvAdapter");

167
src/app/tipsmodel.cpp Normal file
View file

@ -0,0 +1,167 @@
/*
* Copyright (C) 2022 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "tipsmodel.h"
TipsModel::TipsModel(AppSettingsManager* settingsManager, QObject* parent)
: QAbstractListModel(parent)
, settingsManager_(settingsManager)
{
tips_.append({{"id", "0"}, {"title", tr("Customize")}, {"desc", ""}, {"isTip", "false"}});
tips_.append({{"id", "1"},
{"title", tr("What does Jami mean?")},
{"desc",
tr("The choice of the name Jami was inspired by the Swahili word jamii which "
"means community as a noun and together as an adverb.")},
{"isTip", "true"}});
tips_.append({{"id", "2"},
{"title", tr("What is the green dot next to my account?")},
{"desc",
tr("A red dot means that your account is disconnected from the network, it "
"turns green when its connected")},
{"isTip", "true"}});
tips_.append({{"id", "3"},
{"title", tr("Why should I backup my account?")},
{"desc",
tr("Jami is distributed and you're account is only stored on your device. If "
"you loose your password, or your datas you can't recover it")},
{"isTip", "true"}});
tips_.append(
{{"id", "4"},
{"title", tr("Can I make a conference call?")},
{"desc", tr("In a call, you can click on \"Add participants\" to add a contact to a call")},
{"isTip", "true"}});
tips_.append({{"id", "5"},
{"title", tr("Does Jami have group chats?")},
{"desc", tr("In the settings, you can enabled support for groups (experimental)")},
{"isTip", "true"}});
tips_.append({{"id", "6"},
{"title", tr("What is a Jami account?")},
{"desc",
tr("A Jami account is an asymmetric encryption key. Your account is identified "
"by a Jami ID, which is a fingerprint of your public key.")},
{"isTip", "true"}});
tips_.append({{"id", "7"},
{"title", tr("What information do I need to provide to create a Jami account?")},
{"desc",
tr("When you create a new Jami account, you don’t have to provide any private "
"information like an email, address, or phone number.")},
{"isTip", "true"}});
tips_.append({{"id", "8"},
{"title", tr("Why don't I have to use a password?")},
{"desc",
tr("With Jami, your account is stored in a folder on your device. The password "
"is only used to encrypt your account in order to protect you from someone "
"who has physical access to your device.")},
{"isTip", "true"}});
tips_.append(
{{"id", "9"},
{"title", tr("Why don't I have to register a username?")},
{"desc",
tr("The most permanent, secure identifier is your Jami ID, but since these are difficult "
"to use for some people, you also have the option of registering a username.")},
{"isTip", "true"}});
tips_.append(
{{"id", "10"},
{"title", tr("How can I back up my account?")},
{"desc", tr("In the account settings, a button is available to backup your account.")},
{"isTip", "true"}});
tips_.append({{"id", "11"},
{"title", tr("What happens when I delete my account?")},
{"desc",
tr("Your account is only stored on your own devices. If you delete your account "
"from each device, the account is gone and you cannot get it back.")},
{"isTip", "true"}});
tips_.append({{"id", "12"},
{"title", tr("Can I use my account on multiple device?")},
{"desc",
tr("Yes, you can link your account from the settings, or you can import your "
"back-up on another device.")},
{"isTip", "true"}});
QStringList hiddenIds = settingsManager_->getValue(Settings::Key::HiddenTips).toStringList();
auto it = tips_.begin();
while (it != tips_.end()) {
if (hiddenIds.contains((*it)["id"]))
it = tips_.erase(it);
else
it++;
}
}
int
TipsModel::rowCount(const QModelIndex& parent) const
{
if (parent.isValid())
return 0;
return tips_.size();
}
QVariant
TipsModel::data(const QModelIndex& index, int role) const
{
if (!index.isValid())
return QVariant();
auto tip = tips_.at(index.row());
switch (role) {
case Tips::Role::TipId:
return QVariant::fromValue(tip["id"].toInt());
case Tips::Role::Title:
return QVariant::fromValue(tip["title"]);
case Tips::Role::Description:
return QVariant::fromValue(tip["desc"]);
case Tips::Role::IsTip:
return QVariant::fromValue(tip["isTip"] == "true");
}
return QVariant();
}
QHash<int, QByteArray>
TipsModel::roleNames() const
{
using namespace Tips;
QHash<int, QByteArray> roles;
#define X(role) roles[role] = #role;
TIPS_ROLES
#undef X
return roles;
}
void
TipsModel::remove(QVariant id)
{
auto index = 0;
auto it = tips_.begin();
while (it != tips_.end()) {
if ((*it)["id"] == id.toString()) {
beginRemoveRows(QModelIndex(), index, index);
QStringList hiddenIds = settingsManager_->getValue(Settings::Key::HiddenTips)
.toStringList();
hiddenIds.append(id.toString());
settingsManager_->setValue(Settings::Key::HiddenTips, hiddenIds);
tips_.erase(it);
endRemoveRows();
return;
}
index++;
it++;
}
}

60
src/app/tipsmodel.h Normal file
View file

@ -0,0 +1,60 @@
/*
* Copyright (C) 2022 Savoir-faire Linux Inc.
* Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "lrcinstance.h"
#include "appsettingsmanager.h"
#include "qtutils.h"
#include <QAbstractListModel>
#include <QObject>
#define TIPS_ROLES \
X(TipId) \
X(Title) \
X(Description) \
X(IsTip)
namespace Tips {
Q_NAMESPACE
enum Role {
DummyRole = Qt::UserRole + 1,
#define X(role) role,
TIPS_ROLES
#undef X
};
Q_ENUM_NS(Role)
} // namespace Tips
class TipsModel : public QAbstractListModel
{
Q_OBJECT
public:
TipsModel(AppSettingsManager* sm, QObject* parent = nullptr);
int rowCount(const QModelIndex& parent = QModelIndex()) const override;
QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE void remove(QVariant id);
private:
VectorMapStringString tips_;
AppSettingsManager* settingsManager_;
};

View file

@ -78,7 +78,7 @@ Rectangle {
Layout.margins: 50
text: JamiStrings.advancedAccountSettings
color: JamiTheme.textColor
font.pixelSize: 22
font.pixelSize: JamiTheme.bigFontSize
}
ColumnLayout {
@ -115,18 +115,21 @@ Rectangle {
DropShadow {
z: -1
anchors.fill: parent
visible: openedPassword
width: parent.width
height: parent.height
horizontalOffset: 3.0
verticalOffset: 3.0
radius: 16
source: bg
color: Qt.rgba(0, 0.34,0.6,0.16)
source: bg
transparentBorder: true
}
Rectangle {
id: bg
radius: JamiTheme.formsRadius
border.color: JamiTheme.lightBlue_
border.color: openedPassword? JamiTheme.transparentColor : JamiTheme.lightBlue_
layer.enabled: true
color: JamiTheme.secondaryBackgroundColor
anchors.fill: parent
@ -138,7 +141,7 @@ Rectangle {
width: parent.width /2
anchors.bottom: parent.bottom
anchors.left: parent.left
border.color: JamiTheme.lightBlue_
border.color: openedPassword? JamiTheme.transparentColor : JamiTheme.lightBlue_
color: JamiTheme.secondaryBackgroundColor
Rectangle {
@ -148,7 +151,7 @@ Rectangle {
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.margins: 1
border.color: JamiTheme.secondaryBackgroundColor
border.color: openedPassword? JamiTheme.transparentColor : JamiTheme.secondaryBackgroundColor
color: JamiTheme.secondaryBackgroundColor
}
@ -164,6 +167,7 @@ Rectangle {
text: JamiStrings.encryptAccount
font.pixelSize: JamiTheme.creditsTextSize
font.weight: Font.Medium
Layout.fillWidth: true
Layout.leftMargin: 35
Layout.topMargin: 25
@ -283,7 +287,7 @@ Rectangle {
color: openedPassword ? JamiTheme.lightBlue_ : JamiTheme.transparentColor
Layout.alignment: Qt.AlignBottom | Qt.AlignLeft
Layout.leftMargin: openedPassword ? 2 : openedNickname ? 0 : 20
Layout.bottomMargin: openedPassword ? 1 : 0
Layout.bottomMargin: openedPassword ? 2 : 0
Rectangle {
@ -359,19 +363,22 @@ Rectangle {
DropShadow {
z: -1
anchors.fill: parent
visible: openedNickname
width: parent.width
height: parent.height
horizontalOffset: 3.0
verticalOffset: 3.0
radius: 16
source: bg2
color: Qt.rgba(0, 0.34,0.6,0.16)
source: bg2
transparentBorder: true
}
Rectangle {
id: bg2
radius: JamiTheme.formsRadius
border.color: JamiTheme.lightBlue_
border.color: openedNickname ? JamiTheme.transparentColor : JamiTheme.lightBlue_
layer.enabled: true
color: JamiTheme.secondaryBackgroundColor
anchors.fill: parent
@ -382,7 +389,7 @@ Rectangle {
width: parent.width /2
anchors.bottom: parent.bottom
anchors.right: parent.right
border.color: JamiTheme.lightBlue_
border.color: openedNickname ? JamiTheme.transparentColor : JamiTheme.lightBlue_
color: JamiTheme.secondaryBackgroundColor
layer.enabled: true
@ -394,7 +401,7 @@ Rectangle {
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.margins: 1
border.color: JamiTheme.secondaryBackgroundColor
border.color: openedNickname ? JamiTheme.transparentColor : JamiTheme.secondaryBackgroundColor
color: JamiTheme.secondaryBackgroundColor
}
@ -411,6 +418,7 @@ Rectangle {
visible: openedNickname
text: JamiStrings.customizeProfile
elide: Text.ElideRight
font.weight: Font.Medium
Layout.topMargin: 25
Layout.leftMargin: 35
font.pixelSize: JamiTheme.creditsTextSize

View file

@ -93,6 +93,8 @@ Rectangle {
text: JamiStrings.enterJAMSURL
Layout.alignment: Qt.AlignCenter
Layout.topMargin: 30
font.weight: Font.Medium
Layout.preferredWidth: Math.min(400, root.width - JamiTheme.preferredMarginSize * 2)
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter

View file

@ -381,7 +381,7 @@ Rectangle {
id: title
text: JamiStrings.goodToKnow
color: JamiTheme.textColor
font.weight: Font.Medium
Layout.topMargin: 15
Layout.alignment: Qt.AlignCenter | Qt.AlignTop

View file

@ -100,6 +100,7 @@ Rectangle {
Layout.topMargin: 15
Layout.alignment: Qt.AlignCenter
font.pixelSize: JamiTheme.wizardViewDescriptionFontPixelSize
font.weight: Font.Medium
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter