Show rooms you share with someone
This commit is contained in:
parent
d46a67f64b
commit
aae3300860
8 changed files with 320 additions and 139 deletions
25
resources/qml/components/NhekoTabButton.qml
Normal file
25
resources/qml/components/NhekoTabButton.qml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import im.nheko 1.0
|
||||
|
||||
TabButton {
|
||||
id: control
|
||||
|
||||
contentItem: Text {
|
||||
text: control.text
|
||||
font: control.font
|
||||
opacity: enabled ? 1.0 : 0.3
|
||||
color: control.down ? Nheko.colors.highlightedText : Nheko.colors.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
border.color: control.down ? Nheko.colors.highlight : Nheko.theme.separator
|
||||
color: control.checked ? Nheko.colors.highlight : Nheko.colors.base
|
||||
border.width: 1
|
||||
radius: 2
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -49,30 +49,10 @@ ApplicationWindow {
|
|||
width: parent.width
|
||||
palette: Nheko.colors
|
||||
|
||||
component TabB : TabButton {
|
||||
id: control
|
||||
|
||||
contentItem: Text {
|
||||
text: control.text
|
||||
font: control.font
|
||||
opacity: enabled ? 1.0 : 0.3
|
||||
color: control.down ? Nheko.colors.highlightedText : Nheko.colors.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
}
|
||||
|
||||
background: Rectangle {
|
||||
border.color: control.down ? Nheko.colors.highlight : Nheko.theme.separator
|
||||
color: control.checked ? Nheko.colors.highlight : Nheko.colors.base
|
||||
border.width: 1
|
||||
radius: 2
|
||||
}
|
||||
}
|
||||
TabB {
|
||||
NhekoTabButton {
|
||||
text: qsTr("Roles")
|
||||
}
|
||||
TabB {
|
||||
NhekoTabButton {
|
||||
text: qsTr("Users")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@
|
|||
import ".."
|
||||
import "../device-verification"
|
||||
import "../ui"
|
||||
import "../components"
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.2
|
||||
import QtQuick.Window 2.13
|
||||
import QtQml.Models 2.2
|
||||
import im.nheko 1.0
|
||||
|
||||
ApplicationWindow {
|
||||
|
|
@ -34,12 +36,13 @@ ApplicationWindow {
|
|||
ListView {
|
||||
id: devicelist
|
||||
|
||||
property int selectedTab: 0
|
||||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
clip: true
|
||||
spacing: 8
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
model: profile.deviceList
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
footerPositioning: ListView.OverlayFooter
|
||||
|
|
@ -297,147 +300,214 @@ ApplicationWindow {
|
|||
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: tabbar
|
||||
visible: !profile.isSelf
|
||||
Layout.fillWidth: true
|
||||
|
||||
onCurrentIndexChanged: devicelist.selectedTab = currentIndex
|
||||
|
||||
palette: Nheko.colors
|
||||
|
||||
NhekoTabButton {
|
||||
text: qsTr("Devices")
|
||||
}
|
||||
NhekoTabButton {
|
||||
text: qsTr("Shared Rooms")
|
||||
}
|
||||
|
||||
Layout.bottomMargin: Nheko.paddingMedium
|
||||
}
|
||||
}
|
||||
|
||||
delegate: RowLayout {
|
||||
required property int verificationStatus
|
||||
required property string deviceId
|
||||
required property string deviceName
|
||||
required property string lastIp
|
||||
required property var lastTs
|
||||
model: (selectedTab == 0) ? devicesModel : sharedRoomsModel
|
||||
|
||||
width: devicelist.width
|
||||
spacing: 4
|
||||
DelegateModel {
|
||||
id: devicesModel
|
||||
model: profile.deviceList
|
||||
delegate: RowLayout {
|
||||
required property int verificationStatus
|
||||
required property string deviceId
|
||||
required property string deviceName
|
||||
required property string lastIp
|
||||
required property var lastTs
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
width: devicelist.width
|
||||
spacing: 4
|
||||
|
||||
ColumnLayout {
|
||||
spacing: 0
|
||||
|
||||
Layout.leftMargin: Nheko.paddingMedium
|
||||
Layout.rightMargin: Nheko.paddingMedium
|
||||
RowLayout {
|
||||
Text {
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
elide: Text.ElideRight
|
||||
font.bold: true
|
||||
color: Nheko.colors.text
|
||||
text: deviceId
|
||||
}
|
||||
|
||||
Image {
|
||||
Layout.preferredHeight: 16
|
||||
Layout.preferredWidth: 16
|
||||
visible: profile.isSelf && verificationStatus != VerificationStatus.NOT_APPLICABLE
|
||||
sourceSize.height: 16 * Screen.devicePixelRatio
|
||||
sourceSize.width: 16 * Screen.devicePixelRatio
|
||||
source: {
|
||||
switch (verificationStatus) {
|
||||
case VerificationStatus.VERIFIED:
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-checkmark.svg?" + Nheko.theme.green;
|
||||
case VerificationStatus.UNVERIFIED:
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-exclamation-mark.svg?" + Nheko.theme.orange;
|
||||
case VerificationStatus.SELF:
|
||||
return "image://colorimage/:/icons/icons/ui/checkmark.svg?" + Nheko.theme.green;
|
||||
default:
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-cross.svg?" + Nheko.theme.orange;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImageButton {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
image: ":/icons/icons/ui/power-off.svg"
|
||||
hoverEnabled: true
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("Sign out this device.")
|
||||
onClicked: profile.signOutDevice(deviceId)
|
||||
visible: profile.isSelf
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: deviceNameRow
|
||||
|
||||
property bool isEditingAllowed
|
||||
|
||||
TextInput {
|
||||
id: deviceNameField
|
||||
|
||||
readOnly: !deviceNameRow.isEditingAllowed
|
||||
text: deviceName
|
||||
color: Nheko.colors.text
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
selectByMouse: true
|
||||
onAccepted: {
|
||||
profile.changeDeviceName(deviceId, deviceNameField.text);
|
||||
deviceNameRow.isEditingAllowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImageButton {
|
||||
visible: profile.isSelf
|
||||
hoverEnabled: true
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("Change device name.")
|
||||
image: deviceNameRow.isEditingAllowed ? ":/icons/icons/ui/checkmark.svg" : ":/icons/icons/ui/edit.svg"
|
||||
onClicked: {
|
||||
if (deviceNameRow.isEditingAllowed) {
|
||||
profile.changeDeviceName(deviceId, deviceNameField.text);
|
||||
deviceNameRow.isEditingAllowed = false;
|
||||
} else {
|
||||
deviceNameRow.isEditingAllowed = true;
|
||||
deviceNameField.focus = true;
|
||||
deviceNameField.selectAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Layout.leftMargin: Nheko.paddingMedium
|
||||
Layout.rightMargin: Nheko.paddingMedium
|
||||
RowLayout {
|
||||
Text {
|
||||
visible: profile.isSelf
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
elide: Text.ElideRight
|
||||
font.bold: true
|
||||
color: Nheko.colors.text
|
||||
text: deviceId
|
||||
text: qsTr("Last seen %1 from %2").arg(new Date(lastTs).toLocaleString(Locale.ShortFormat)).arg(lastIp ? lastIp : "???")
|
||||
}
|
||||
|
||||
Image {
|
||||
Layout.preferredHeight: 16
|
||||
Layout.preferredWidth: 16
|
||||
visible: profile.isSelf && verificationStatus != VerificationStatus.NOT_APPLICABLE
|
||||
sourceSize.height: 16 * Screen.devicePixelRatio
|
||||
sourceSize.width: 16 * Screen.devicePixelRatio
|
||||
source: {
|
||||
switch (verificationStatus) {
|
||||
}
|
||||
|
||||
Image {
|
||||
Layout.preferredHeight: 16
|
||||
Layout.preferredWidth: 16
|
||||
visible: !profile.isSelf && verificationStatus != VerificationStatus.NOT_APPLICABLE
|
||||
source: {
|
||||
switch (verificationStatus) {
|
||||
case VerificationStatus.VERIFIED:
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-checkmark.svg?" + Nheko.theme.green;
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-checkmark.svg?" + Nheko.theme.green;
|
||||
case VerificationStatus.UNVERIFIED:
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-exclamation-mark.svg?" + Nheko.theme.orange;
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-exclamation-mark.svg?" + Nheko.theme.orange;
|
||||
case VerificationStatus.SELF:
|
||||
return "image://colorimage/:/icons/icons/ui/checkmark.svg?" + Nheko.theme.green;
|
||||
return "image://colorimage/:/icons/icons/ui/checkmark.svg?" + Nheko.theme.green;
|
||||
default:
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-cross.svg?" + Nheko.theme.orange;
|
||||
}
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled.svg?" + Nheko.theme.red;
|
||||
}
|
||||
}
|
||||
|
||||
ImageButton {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
image: ":/icons/icons/ui/power-off.svg"
|
||||
hoverEnabled: true
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("Sign out this device.")
|
||||
onClicked: profile.signOutDevice(deviceId)
|
||||
visible: profile.isSelf
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: deviceNameRow
|
||||
Button {
|
||||
id: verifyButton
|
||||
|
||||
property bool isEditingAllowed
|
||||
|
||||
TextInput {
|
||||
id: deviceNameField
|
||||
|
||||
readOnly: !deviceNameRow.isEditingAllowed
|
||||
text: deviceName
|
||||
color: Nheko.colors.text
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
selectByMouse: true
|
||||
onAccepted: {
|
||||
profile.changeDeviceName(deviceId, deviceNameField.text);
|
||||
deviceNameRow.isEditingAllowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
ImageButton {
|
||||
visible: profile.isSelf
|
||||
hoverEnabled: true
|
||||
ToolTip.visible: hovered
|
||||
ToolTip.text: qsTr("Change device name.")
|
||||
image: deviceNameRow.isEditingAllowed ? ":/icons/icons/ui/checkmark.svg" : ":/icons/icons/ui/edit.svg"
|
||||
onClicked: {
|
||||
if (deviceNameRow.isEditingAllowed) {
|
||||
profile.changeDeviceName(deviceId, deviceNameField.text);
|
||||
deviceNameRow.isEditingAllowed = false;
|
||||
} else {
|
||||
deviceNameRow.isEditingAllowed = true;
|
||||
deviceNameField.focus = true;
|
||||
deviceNameField.selectAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: profile.isSelf
|
||||
Layout.fillWidth: true
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
elide: Text.ElideRight
|
||||
color: Nheko.colors.text
|
||||
text: qsTr("Last seen %1 from %2").arg(new Date(lastTs).toLocaleString(Locale.ShortFormat)).arg(lastIp ? lastIp : "???")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Image {
|
||||
Layout.preferredHeight: 16
|
||||
Layout.preferredWidth: 16
|
||||
visible: !profile.isSelf && verificationStatus != VerificationStatus.NOT_APPLICABLE
|
||||
source: {
|
||||
switch (verificationStatus) {
|
||||
case VerificationStatus.VERIFIED:
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-checkmark.svg?" + Nheko.theme.green;
|
||||
case VerificationStatus.UNVERIFIED:
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled-exclamation-mark.svg?" + Nheko.theme.orange;
|
||||
case VerificationStatus.SELF:
|
||||
return "image://colorimage/:/icons/icons/ui/checkmark.svg?" + Nheko.theme.green;
|
||||
default:
|
||||
return "image://colorimage/:/icons/icons/ui/shield-filled.svg?" + Nheko.theme.red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Button {
|
||||
id: verifyButton
|
||||
|
||||
visible: verificationStatus == VerificationStatus.UNVERIFIED && (profile.isSelf || !profile.userVerificationEnabled)
|
||||
text: (verificationStatus != VerificationStatus.VERIFIED) ? qsTr("Verify") : qsTr("Unverify")
|
||||
onClicked: {
|
||||
if (verificationStatus == VerificationStatus.VERIFIED)
|
||||
visible: verificationStatus == VerificationStatus.UNVERIFIED && (profile.isSelf || !profile.userVerificationEnabled)
|
||||
text: (verificationStatus != VerificationStatus.VERIFIED) ? qsTr("Verify") : qsTr("Unverify")
|
||||
onClicked: {
|
||||
if (verificationStatus == VerificationStatus.VERIFIED)
|
||||
profile.unverify(deviceId);
|
||||
else
|
||||
else
|
||||
profile.verify(deviceId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DelegateModel {
|
||||
id: sharedRoomsModel
|
||||
model: profile.sharedRooms
|
||||
delegate: RowLayout {
|
||||
required property string roomId
|
||||
required property string roomName
|
||||
required property string avatarUrl
|
||||
|
||||
width: devicelist.width
|
||||
spacing: 4
|
||||
|
||||
|
||||
Avatar {
|
||||
id: avatar
|
||||
|
||||
enabled: false
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.leftMargin: Nheko.paddingMedium
|
||||
|
||||
property int avatarSize: Math.ceil(fontMetrics.lineSpacing * 1.6)
|
||||
height: avatarSize
|
||||
width: avatarSize
|
||||
url: avatarUrl.replace("mxc://", "image://MxcImage/")
|
||||
roomid: roomId
|
||||
displayName: roomName
|
||||
}
|
||||
|
||||
ElidedLabel {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
color: Nheko.colors.text
|
||||
Layout.fillWidth: true
|
||||
elideWidth: width
|
||||
fullText: roomName
|
||||
textFormat: Text.PlainText
|
||||
Layout.rightMargin: Nheko.paddingMedium
|
||||
}
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
footer: DialogButtonBox {
|
||||
|
|
|
|||
|
|
@ -129,6 +129,7 @@
|
|||
<file>qml/components/AvatarListTile.qml</file>
|
||||
<file>qml/components/FlatButton.qml</file>
|
||||
<file>qml/components/MainWindowDialog.qml</file>
|
||||
<file>qml/components/NhekoTabButton.qml</file>
|
||||
<file>qml/components/NotificationBubble.qml</file>
|
||||
<file>qml/components/ReorderableListview.qml</file>
|
||||
<file>qml/components/SpaceMenuLevel.qml</file>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue