Add login page and forget room system
This commit is contained in:
@@ -9,7 +9,8 @@ ApplicationWindow {
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
source: "UI.qml"
|
||||
source: Backend.clientManager.clientCount < 1 ?
|
||||
"pages/LoginPage.qml" : "pages/MainUI.qml"
|
||||
objectName: "UILoader"
|
||||
}
|
||||
}
|
||||
|
@@ -3,9 +3,73 @@ import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.4
|
||||
|
||||
Button {
|
||||
property alias fontSize: buttonLabel.font.pixelSize
|
||||
property color backgroundColor: "lightgray"
|
||||
property alias overlayOpacity: buttonBackgroundOverlay.opacity
|
||||
property string iconName: ""
|
||||
property bool circle: false
|
||||
|
||||
id: button
|
||||
display: Button.TextBesideIcon
|
||||
icon.source: "../../icons/" + iconName + ".svg"
|
||||
|
||||
background: Rectangle {
|
||||
id: buttonBackground
|
||||
color: Qt.lighter(backgroundColor, checked ? 1.3 : 1.0)
|
||||
radius: circle ? height : 0
|
||||
|
||||
Rectangle {
|
||||
id: buttonBackgroundOverlay
|
||||
anchors.fill: parent
|
||||
radius: parent.radius
|
||||
color: "black"
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
|
||||
contentItem: HRowLayout {
|
||||
spacing: button.text && iconName ? 5 : 0
|
||||
|
||||
Component {
|
||||
id: buttonIcon
|
||||
Image {
|
||||
cache: true
|
||||
mipmap: true
|
||||
source: "../../icons/" + iconName + ".svg"
|
||||
fillMode: Image.PreserveAspectFit
|
||||
width: button.text ? 20 : 24
|
||||
height: width
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
sourceComponent: iconName ? buttonIcon : undefined
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
HLabel {
|
||||
id: buttonLabel
|
||||
|
||||
text: button.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
Layout.maximumWidth: button.width - buttonIcon.width
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
propagateComposedEvents: true
|
||||
|
||||
onEntered: overlayOpacity = checked ? 0 : 0.3
|
||||
onExited: overlayOpacity = 0
|
||||
onPressed: overlayOpacity += 0.3
|
||||
onReleased: {
|
||||
if (checkable) { checked = ! checked }
|
||||
overlayOpacity = checked ? 0 : 0.3
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,12 +1,9 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.0
|
||||
import "."
|
||||
|
||||
Label {
|
||||
property int bigSize: 24
|
||||
property int normalSize: 16
|
||||
property int smallSize: 12
|
||||
|
||||
font.family: "Roboto"
|
||||
font.pixelSize: normalSize
|
||||
font.family: HStyle.fontFamily.sans
|
||||
font.pixelSize: HStyle.fontSize.normal
|
||||
textFormat: Text.PlainText
|
||||
}
|
||||
|
22
harmonyqml/components/base/HStyle.qml
Normal file
22
harmonyqml/components/base/HStyle.qml
Normal file
@@ -0,0 +1,22 @@
|
||||
pragma Singleton
|
||||
import QtQuick 2.7
|
||||
|
||||
QtObject {
|
||||
readonly property int foo: 3
|
||||
|
||||
readonly property QtObject fontSize: QtObject {
|
||||
readonly property int smallest: 6
|
||||
readonly property int smaller: 8
|
||||
readonly property int small: 12
|
||||
readonly property int normal: 16
|
||||
readonly property int big: 24
|
||||
readonly property int bigger: 32
|
||||
readonly property int biggest: 48
|
||||
}
|
||||
|
||||
readonly property QtObject fontFamily: QtObject {
|
||||
readonly property string sans: "Roboto"
|
||||
readonly property string serif: "Roboto Slab"
|
||||
readonly property string mono: "Hack"
|
||||
}
|
||||
}
|
9
harmonyqml/components/base/HTextField.qml
Normal file
9
harmonyqml/components/base/HTextField.qml
Normal file
@@ -0,0 +1,9 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.0
|
||||
|
||||
TextField {
|
||||
font.family: HStyle.fontFamily.sans
|
||||
font.pixelSize: HStyle.fontSize.normal
|
||||
|
||||
selectByMouse: true
|
||||
}
|
1
harmonyqml/components/base/qmldir
Normal file
1
harmonyqml/components/base/qmldir
Normal file
@@ -0,0 +1 @@
|
||||
singleton HStyle 1.0 HStyle.qml
|
@@ -9,6 +9,8 @@ Rectangle {
|
||||
Layout.preferredHeight: 32
|
||||
color: "#BBB"
|
||||
|
||||
signal buttonClicked(string signalId)
|
||||
|
||||
property alias avatarName: bannerAvatar.name
|
||||
property alias avatarSource: bannerAvatar.imageSource
|
||||
property alias labelText: bannerLabel.text
|
||||
@@ -77,8 +79,6 @@ Rectangle {
|
||||
|
||||
text: modelData.text
|
||||
iconName: modelData.iconName
|
||||
icon.color: modelData.iconColor
|
||||
icon.width: 32
|
||||
display: bannerButtons.displayMode
|
||||
|
||||
onClicked: {
|
||||
@@ -87,14 +87,20 @@ Rectangle {
|
||||
iconName = "hourglass"
|
||||
alreadyClicked = true
|
||||
|
||||
// modelData might become undefined after Backend call
|
||||
var signalId = modelData.signalId
|
||||
var iconName_ = modelData.iconName
|
||||
|
||||
var future =
|
||||
Backend.clientManager.clients[chatPage.userId].
|
||||
call(modelData.clientFunction,
|
||||
modelData.clientArgs)
|
||||
|
||||
future.onGotResult.connect(
|
||||
function() { iconName = modelData.iconName }
|
||||
)
|
||||
future.onGotResult.connect(function() {
|
||||
iconName = iconName_
|
||||
})
|
||||
|
||||
if (signalId) { buttonClicked(signalId) }
|
||||
}
|
||||
|
||||
Layout.maximumWidth: bannerButtons.compact ? height : -1
|
||||
|
@@ -16,6 +16,6 @@ Base.HLabel {
|
||||
|
||||
text: dateTime.toLocaleDateString() + (isToday ? qsTr(" (Today)") : "")
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
font.pixelSize: normalSize * 1.1
|
||||
font.pixelSize: Base.HStyle.fontSize.big
|
||||
color: "darkolivegreen"
|
||||
}
|
||||
|
@@ -27,7 +27,8 @@ RowLayout {
|
||||
(displayName.value || dict.sender) +
|
||||
(contentText.startsWith("'s ") ? "" : " ") +
|
||||
contentText +
|
||||
" <font size=" + smallSize + "px color='gray'>" +
|
||||
" <font size=" + Base.HStyle.fontSize.small +
|
||||
"px color='gray'>" +
|
||||
Qt.formatDateTime(dateTime, "hh:mm:ss") +
|
||||
"</font></font>"
|
||||
textFormat: Text.RichText
|
||||
|
@@ -17,15 +17,15 @@ Banner {
|
||||
buttonModel: [
|
||||
{
|
||||
text: "Accept",
|
||||
iconName: "accept",
|
||||
iconColor: Qt.hsla(0.45, 0.9, 0.3, 1),
|
||||
iconName: "invite_accept",
|
||||
//iconColor: Qt.hsla(0.45, 0.9, 0.3, 1),
|
||||
clientFunction: "joinRoom",
|
||||
clientArgs: [chatPage.roomId],
|
||||
},
|
||||
{
|
||||
text: "Decline",
|
||||
iconName: "decline",
|
||||
iconColor: Qt.hsla(0.95, 0.9, 0.35, 1),
|
||||
iconName: "invite_decline",
|
||||
//iconColor: Qt.hsla(0.95, 0.9, 0.35, 1),
|
||||
clientFunction: "leaveRoom",
|
||||
clientArgs: [chatPage.roomId],
|
||||
}
|
||||
|
@@ -7,14 +7,20 @@ import "utils.js" as ChatJS
|
||||
Banner {
|
||||
property var leftEvent: null
|
||||
|
||||
onButtonClicked: if (signalId === "forget") {
|
||||
chatPage.canLoadPastEvents = false
|
||||
pageStack.clear()
|
||||
}
|
||||
|
||||
avatarName: ChatJS.getLeftBannerAvatarName(leftEvent, chatPage.userId)
|
||||
labelText: ChatJS.getLeftBannerText(leftEvent)
|
||||
|
||||
buttonModel: [
|
||||
{
|
||||
signalId: "forget",
|
||||
text: "Forget",
|
||||
iconName: "trash_can",
|
||||
iconColor: Qt.hsla(0.95, 0.9, 0.35, 1),
|
||||
iconName: "forget_room",
|
||||
//iconColor: Qt.hsla(0.95, 0.9, 0.35, 1),
|
||||
clientFunction: "forgetRoom",
|
||||
clientArgs: [chatPage.roomId],
|
||||
}
|
||||
|
@@ -35,11 +35,13 @@ Row {
|
||||
text: (dict.formatted_body ?
|
||||
Backend.htmlFilter.filter(dict.formatted_body) :
|
||||
dict.body) +
|
||||
" <font size=" + smallSize + "px color=gray>" +
|
||||
" <font size=" + Base.HStyle.fontSize.small +
|
||||
"px color=gray>" +
|
||||
Qt.formatDateTime(dateTime, "hh:mm:ss") +
|
||||
"</font>" +
|
||||
(isLocalEcho ?
|
||||
" <font size=" + smallSize + "px>⏳</font>" : "")
|
||||
" <font size=" + Base.HStyle.fontSize.small +
|
||||
"px>⏳</font>" : "")
|
||||
textFormat: Text.RichText
|
||||
background: Rectangle {color: "#DDD"}
|
||||
wrapMode: Text.Wrap
|
||||
|
@@ -4,6 +4,7 @@ import QtQuick.Layouts 1.4
|
||||
import "../base" as Base
|
||||
|
||||
Rectangle {
|
||||
property bool canLoadPastEvents: true
|
||||
property int space: 8
|
||||
|
||||
Layout.fillWidth: true
|
||||
@@ -30,7 +31,7 @@ Rectangle {
|
||||
property real yPos: visibleArea.yPosition
|
||||
|
||||
onYPosChanged: {
|
||||
if (yPos <= 0.1) {
|
||||
if (chatPage.canLoadPastEvents && yPos <= 0.1) {
|
||||
Backend.loadPastEvents(chatPage.roomId)
|
||||
}
|
||||
}
|
||||
|
@@ -28,7 +28,7 @@ Rectangle {
|
||||
Base.HLabel {
|
||||
id: roomName
|
||||
text: displayName
|
||||
font.pixelSize: bigSize
|
||||
font.pixelSize: Base.HStyle.fontSize.big
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
Layout.maximumWidth:
|
||||
@@ -39,7 +39,7 @@ Rectangle {
|
||||
Base.HLabel {
|
||||
id: roomTopic
|
||||
text: topic
|
||||
font.pixelSize: smallSize
|
||||
font.pixelSize: Base.HStyle.fontSize.small
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
Layout.maximumWidth:
|
||||
|
@@ -9,6 +9,8 @@ ColumnLayout {
|
||||
readonly property var roomInfo:
|
||||
Backend.models.rooms.get(userId).getWhere("roomId", roomId)
|
||||
|
||||
property bool canLoadPastEvents: true
|
||||
|
||||
Component.onCompleted: console.log("replaced")
|
||||
|
||||
|
||||
|
@@ -1,9 +0,0 @@
|
||||
import QtQuick 2.7
|
||||
import "../base" as Base
|
||||
|
||||
Rectangle {
|
||||
Base.HLabel {
|
||||
anchors.centerIn: parent
|
||||
text: "Add account page"
|
||||
}
|
||||
}
|
@@ -1,9 +0,0 @@
|
||||
import QtQuick 2.7
|
||||
import "../base" as Base
|
||||
|
||||
Rectangle {
|
||||
Base.HLabel {
|
||||
anchors.centerIn: parent
|
||||
text: "Add room page"
|
||||
}
|
||||
}
|
122
harmonyqml/components/pages/LoginPage.qml
Normal file
122
harmonyqml/components/pages/LoginPage.qml
Normal file
@@ -0,0 +1,122 @@
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.4
|
||||
import "../base" as Base
|
||||
|
||||
Image {
|
||||
id: loginBackground
|
||||
asynchronous: true
|
||||
fillMode: Image.PreserveAspectCrop
|
||||
cache: false
|
||||
source: "../../images/login_background.jpg"
|
||||
|
||||
Rectangle {
|
||||
color: Qt.hsla(1, 1, 1, 0.3)
|
||||
|
||||
id: loginBox
|
||||
|
||||
property real widthForHeight: 0.75
|
||||
property int baseHeight: 300
|
||||
property int baseWidth: baseHeight * widthForHeight
|
||||
property int startScalingUpAboveHeight: 1080
|
||||
|
||||
anchors.centerIn: parent
|
||||
height: Math.min(parent.height, baseHeight)
|
||||
width: Math.min(parent.width, baseWidth)
|
||||
scale: Math.max(1, parent.height / startScalingUpAboveHeight)
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
id: mainColumn
|
||||
|
||||
property int hMargin: loginBox.baseWidth * 0.05
|
||||
property int vMargin: hMargin * loginBox.widthForHeight
|
||||
|
||||
Base.HRowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.margins: mainColumn.hMargin
|
||||
Layout.topMargin: mainColumn.vMargin
|
||||
Layout.bottomMargin: mainColumn.vMargin
|
||||
|
||||
Base.HLabel {
|
||||
text: "Sign in"
|
||||
font.pixelSize: Base.HStyle.fontSize.big
|
||||
}
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true }
|
||||
|
||||
Base.HRowLayout {
|
||||
Layout.margins: mainColumn.hMargin
|
||||
Layout.topMargin: mainColumn.vMargin
|
||||
Layout.bottomMargin: mainColumn.vMargin
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: mainColumn.hMargin * 1.25
|
||||
|
||||
Base.HButton {
|
||||
id: loginWithUsernameButton
|
||||
iconName: "username"
|
||||
circle: true
|
||||
checked: true
|
||||
checkable: true
|
||||
autoExclusive: true
|
||||
}
|
||||
Base.HButton {
|
||||
id: loginWithEmailButton
|
||||
iconName: "email"
|
||||
circle: true
|
||||
checkable: true
|
||||
autoExclusive: true
|
||||
}
|
||||
Base.HButton {
|
||||
id: loginWithPhoneButton
|
||||
iconName: "phone"
|
||||
circle: true
|
||||
checkable: true
|
||||
autoExclusive: true
|
||||
}
|
||||
}
|
||||
|
||||
Base.HTextField {
|
||||
placeholderText: qsTr(
|
||||
loginWithEmailButton.checked ? "Email" :
|
||||
loginWithPhoneButton.checked ? "Phone" :
|
||||
"Username"
|
||||
)
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: mainColumn.hMargin
|
||||
Layout.topMargin: mainColumn.vMargin
|
||||
Layout.bottomMargin: mainColumn.vMargin
|
||||
}
|
||||
|
||||
Base.HTextField {
|
||||
placeholderText: qsTr("Password")
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.margins: mainColumn.hMargin
|
||||
Layout.topMargin: mainColumn.vMargin
|
||||
Layout.bottomMargin: mainColumn.vMargin
|
||||
}
|
||||
|
||||
Item { Layout.fillHeight: true }
|
||||
|
||||
Base.HRowLayout {
|
||||
Base.HButton {
|
||||
text: qsTr("Register")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Base.HButton {
|
||||
text: qsTr("Login")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Base.HButton {
|
||||
text: qsTr("Forgot?")
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -2,8 +2,8 @@ import QtQuick 2.7
|
||||
import QtQuick.Controls 1.4 as Controls1
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Layouts 1.4
|
||||
import "sidePane" as SidePane
|
||||
import "chat" as Chat
|
||||
import "../sidePane" as SidePane
|
||||
import "../chat" as Chat
|
||||
|
||||
//https://doc.qt.io/qt-5/qml-qtquick-controls-splitview.html
|
||||
Controls1.SplitView {
|
||||
@@ -17,13 +17,15 @@ Controls1.SplitView {
|
||||
StackView {
|
||||
function showRoom(userId, roomId) {
|
||||
pageStack.replace(
|
||||
"chat/Root.qml", { userId: userId, roomId: roomId }
|
||||
"../chat/Root.qml", { userId: userId, roomId: roomId }
|
||||
)
|
||||
}
|
||||
|
||||
id: pageStack
|
||||
|
||||
onCurrentItemChanged: currentItem.forceActiveFocus()
|
||||
onCurrentItemChanged: if (currentItem) {
|
||||
currentItem.forceActiveFocus()
|
||||
}
|
||||
|
||||
initialItem: Item { // TODO: (test, remove)
|
||||
Keys.onEnterPressed: pageStack.showRoom(
|
@@ -1,9 +0,0 @@
|
||||
import QtQuick 2.7
|
||||
import "../base" as Base
|
||||
|
||||
Rectangle {
|
||||
Base.HLabel {
|
||||
anchors.centerIn: parent
|
||||
text: "Settings page"
|
||||
}
|
||||
}
|
@@ -52,7 +52,7 @@ MouseArea {
|
||||
text: getText()
|
||||
textFormat: Text.StyledText
|
||||
|
||||
font.pixelSize: smallSize
|
||||
font.pixelSize: Base.HStyle.fontSize.small
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 1
|
||||
Layout.maximumWidth: roomLabel.Layout.maximumWidth
|
||||
|
Reference in New Issue
Block a user