Reorder QML files to follow coding conventions

https://doc.qt.io/qt-5/qml-codingconventions.html#qml-object-declarations
This commit is contained in:
miruka 2020-07-12 00:25:57 -04:00
parent 229fbee298
commit 3c7b78d4ca
131 changed files with 1022 additions and 1122 deletions

View File

@ -15,6 +15,7 @@ HGridLayout {
return sum return sum
} }
flow: flow:
width >= summedImplicitWidth ? width >= summedImplicitWidth ?
HGridLayout.LeftToRight : HGridLayout.LeftToRight :

View File

@ -5,21 +5,6 @@ import QtQuick.Controls 2.12
Rectangle { Rectangle {
id: avatar id: avatar
implicitWidth: implicitHeight
implicitHeight:
compact ?
theme.controls.avatar.compactSize :
theme.controls.avatar.size
radius: theme.controls.avatar.radius
color: avatarImage.visible ? "transparent" : utils.hsluv(
name ? utils.hueFrom(name) : 0,
name ? theme.controls.avatar.background.saturation : 0,
theme.controls.avatar.background.lightness,
theme.controls.avatar.background.opacity
)
property bool compact: false property bool compact: false
@ -37,6 +22,21 @@ Rectangle {
readonly property alias circleRadius: avatarImage.circleRadius readonly property alias circleRadius: avatarImage.circleRadius
implicitWidth: implicitHeight
implicitHeight:
compact ?
theme.controls.avatar.compactSize :
theme.controls.avatar.size
radius: theme.controls.avatar.radius
color: avatarImage.visible ? "transparent" : utils.hsluv(
name ? utils.hueFrom(name) : 0,
name ? theme.controls.avatar.background.saturation : 0,
theme.controls.avatar.background.lightness,
theme.controls.avatar.background.opacity
)
Behavior on color { HColorAnimation {} } Behavior on color { HColorAnimation {} }
HLabel { HLabel {
@ -73,13 +73,6 @@ Rectangle {
HToolTip { HToolTip {
id: avatarToolTip id: avatarToolTip
visible: ! avatarImage.broken &&
avatarImage.status !== Image.Error &&
avatarImage.width < dimension * 0.75 &&
(toolTipSourceOverride || toolTipMxc) &&
hoverHandler.hovered
delay: 1000
backgroundColor: theme.controls.avatar.hoveredImage.background
readonly property int dimension: Math.min( readonly property int dimension: Math.min(
mainUI.width / 1.25, mainUI.width / 1.25,
@ -88,6 +81,14 @@ Rectangle {
background.border.width * 2, background.border.width * 2,
) )
visible: ! avatarImage.broken &&
avatarImage.status !== Image.Error &&
avatarImage.width < dimension * 0.75 &&
(toolTipSourceOverride || toolTipMxc) &&
hoverHandler.hovered
delay: 1000
backgroundColor: theme.controls.avatar.hoveredImage.background
contentItem: HMxcImage { contentItem: HMxcImage {
id: avatarToolTipImage id: avatarToolTipImage
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop

View File

@ -6,7 +6,6 @@ import QtQuick 2.12
HRectangleBottomBorder { HRectangleBottomBorder {
id: line id: line
property bool show: false property bool show: false

View File

@ -12,7 +12,6 @@ HFlickableColumnPage {
radius: theme.controls.box.radius radius: theme.controls.box.radius
} }
HNumberAnimation on scale { HNumberAnimation on scale {
running: true running: true
from: 0 from: 0

View File

@ -9,7 +9,6 @@ HCircleProgressBar {
baseCircle.strokeWidth: 2 baseCircle.strokeWidth: 2
progressCircle.strokeWidth: 2 progressCircle.strokeWidth: 2
HNumberAnimation on rotation { HNumberAnimation on rotation {
from: 0 from: 0
to: 360 to: 360

View File

@ -6,6 +6,28 @@ import QtQuick.Layouts 1.12
Button { Button {
id: button id: button
readonly property alias iconItem: contentItem.icon
readonly property alias label: contentItem.label
property color backgroundColor: theme.controls.button.background
property color focusLineColor:
Qt.colorEqual(icon.color, theme.icons.colorize) ?
theme.controls.button.focusedBorder :
icon.color
property bool disableWhileLoading: true
property bool loading: false
property bool circle: false
property bool padded: true
property bool enableRadius: false
property HToolTip toolTip: HToolTip {
id: toolTip
visible: text && hovered
}
enabled: ! button.loading enabled: ! button.loading
spacing: theme.spacing spacing: theme.spacing
topPadding: padded ? spacing * (circle ? 1 : 0.5) : 0 topPadding: padded ? spacing * (circle ? 1 : 0.5) : 0
@ -45,28 +67,6 @@ Button {
Keys.onEnterPressed: Keys.onReturnPressed(event) Keys.onEnterPressed: Keys.onReturnPressed(event)
activeFocusOnTab: true activeFocusOnTab: true
readonly property alias iconItem: contentItem.icon
readonly property alias label: contentItem.label
property color backgroundColor: theme.controls.button.background
property color focusLineColor:
Qt.colorEqual(icon.color, theme.icons.colorize) ?
theme.controls.button.focusedBorder :
icon.color
property bool disableWhileLoading: true
property bool loading: false
property bool circle: false
property bool padded: true
property bool enableRadius: false
property HToolTip toolTip: HToolTip {
id: toolTip
visible: text && hovered
}
Binding on enabled { Binding on enabled {
when: disableWhileLoading && button.loading when: disableWhileLoading && button.loading
value: false value: false

View File

@ -15,7 +15,6 @@ Rectangle {
enabled ? 1 : enabled ? 1 :
theme.disabledElementsOpacity theme.disabledElementsOpacity
Behavior on opacity { HNumberAnimation {} } Behavior on opacity { HNumberAnimation {} }
Rectangle { Rectangle {

View File

@ -6,10 +6,6 @@ import QtQuick.Layouts 1.12
HRowLayout { HRowLayout {
id: buttonContent id: buttonContent
spacing: button.spacing
opacity: button.loading ? theme.loadingElementsOpacity :
enabled ? 1 : theme.disabledElementsOpacity
property var button property var button
property QtObject buttonTheme property QtObject buttonTheme
@ -18,8 +14,11 @@ HRowLayout {
readonly property alias label: label readonly property alias label: label
Behavior on opacity { HNumberAnimation {} } spacing: button.spacing
opacity: button.loading ? theme.loadingElementsOpacity :
enabled ? 1 : theme.disabledElementsOpacity
Behavior on opacity { HNumberAnimation {} }
Item { Item {
visible: button.icon.name || button.loading visible: button.icon.name || button.loading

View File

@ -6,6 +6,15 @@ import QtQuick.Layouts 1.12
CheckBox { CheckBox {
id: box id: box
property alias mainText: mainText
property alias subtitle: subtitleText
property bool defaultChecked: false
readonly property bool changed: checked !== defaultChecked
function reset() { checked = defaultChecked }
checked: defaultChecked checked: defaultChecked
spacing: contentItem.visible ? theme.spacing : 0 spacing: contentItem.visible ? theme.spacing : 0
padding: 0 padding: 0
@ -83,15 +92,5 @@ CheckBox {
} }
} }
property alias mainText: mainText
property alias subtitle: subtitleText
property bool defaultChecked: false
readonly property bool changed: checked !== defaultChecked
function reset() { checked = defaultChecked }
Behavior on opacity { HNumberAnimation { factor: 2 } } Behavior on opacity { HNumberAnimation { factor: 2 } }
} }

View File

@ -5,14 +5,6 @@ import QtQuick.Shapes 1.12
Item { Item {
implicitWidth: 96 * (theme ? theme.uiScale : 1)
implicitHeight: implicitWidth
layer.enabled: true
layer.samples: 4
layer.smooth: true
property real progress: 0 // 0-1 property real progress: 0 // 0-1
readonly property alias baseCircle: baseCircle readonly property alias baseCircle: baseCircle
@ -20,14 +12,22 @@ Item {
readonly property alias label: label readonly property alias label: label
implicitWidth: 96 * (theme ? theme.uiScale : 1)
implicitHeight: implicitWidth
layer.enabled: true
layer.samples: 4
layer.smooth: true
HLabel { HLabel {
id: label id: label
property int progressNumber: Math.floor(progress * 100)
anchors.centerIn: parent anchors.centerIn: parent
text: progressNumber + "%" text: progressNumber + "%"
font.pixelSize: theme ? theme.fontSize.big : 22 font.pixelSize: theme ? theme.fontSize.big : 22
property int progressNumber: Math.floor(progress * 100)
Behavior on progressNumber { HNumberAnimation { factor: 2 } } Behavior on progressNumber { HNumberAnimation { factor: 2 } }
} }

View File

@ -4,5 +4,7 @@ import QtQuick 2.12
ColorAnimation { ColorAnimation {
property real factor: 1.0 property real factor: 1.0
duration: theme.animationDuration * factor duration: theme.animationDuration * factor
} }

View File

@ -5,15 +5,14 @@ import QtQuick 2.12
HPage { HPage {
id: page id: page
default property alias columnData: column.data default property alias columnData: column.data
property alias column: column property alias column: column
implicitWidth: theme.controls.box.defaultWidth implicitWidth: theme.controls.box.defaultWidth
contentHeight: column.childrenRect.height contentHeight: column.childrenRect.height
HColumnLayout { HColumnLayout {
id: column id: column
anchors.fill: parent anchors.fill: parent

View File

@ -5,29 +5,6 @@ import QtQuick.Controls 2.12
Drawer { Drawer {
id: drawer id: drawer
implicitWidth: horizontal ? calculatedSize : parent.width
implicitHeight: vertical ? calculatedSize : parent.height
// Prevents this: open a popup, make the window small enough for the
// drawer to collapse, then make it big again popup is now behind drawer
z: -1
topPadding: 0
bottomPadding: 0
leftPadding: 0
rightPadding: 0
// FIXME: https://bugreports.qt.io/browse/QTBUG-59141
// dragMargin: parent.width / 2
interactive: collapse
position: 1
visible: ! collapse
modal: false
closePolicy: Popup.NoAutoClose
background: Rectangle { id: bg; color: theme.colors.strongBackground }
property string saveName: "" property string saveName: ""
property var saveId: "ALL" property var saveId: "ALL"
@ -77,6 +54,29 @@ Drawer {
readonly property bool vertical: ! horizontal readonly property bool vertical: ! horizontal
implicitWidth: horizontal ? calculatedSize : parent.width
implicitHeight: vertical ? calculatedSize : parent.height
// Prevents this: open a popup, make the window small enough for the
// drawer to collapse, then make it big again popup is now behind drawer
z: -1
topPadding: 0
bottomPadding: 0
leftPadding: 0
rightPadding: 0
// FIXME: https://bugreports.qt.io/browse/QTBUG-59141
// dragMargin: parent.width / 2
interactive: collapse
position: 1
visible: ! collapse
modal: false
closePolicy: Popup.NoAutoClose
background: Rectangle { id: bg; color: theme.colors.strongBackground }
Behavior on width { Behavior on width {
enabled: horizontal && ! resizeMouseHandler.drag.active enabled: horizontal && ! resizeMouseHandler.drag.active
NumberAnimation { duration: 100 } NumberAnimation { duration: 100 }
@ -97,6 +97,12 @@ Drawer {
MouseArea { MouseArea {
id: resizeMouseHandler id: resizeMouseHandler
function snapSize(num) {
return num < snapAt + snapZone && num > snapAt - snapZone ?
snapAt : num
}
anchors.fill: parent anchors.fill: parent
enabled: ! drawer.collapse enabled: ! drawer.collapse
acceptedButtons: Qt.LeftButton acceptedButtons: Qt.LeftButton
@ -124,11 +130,6 @@ Drawer {
} }
onReleased: window.saveState(drawer) onReleased: window.saveState(drawer)
function snapSize(num) {
return num < snapAt + snapZone && num > snapAt - snapZone ?
snapAt : num
}
} }
} }
} }

View File

@ -6,12 +6,9 @@ import "../ShortcutBundles"
HPage { HPage {
id: page id: page
implicitWidth: theme.controls.box.defaultWidth
contentHeight:
flickable.contentHeight + flickable.topMargin + flickable.bottomMargin
default property alias columnData: column.data default property alias columnData: column.data
property alias column: column property alias column: column
property alias flickable: flickable property alias flickable: flickable
property alias flickShortcuts: flickShortcuts property alias flickShortcuts: flickShortcuts
@ -20,8 +17,11 @@ HPage {
SwipeView ? SwipeView.isCurrentItem : true SwipeView ? SwipeView.isCurrentItem : true
padding: 0 implicitWidth: theme.controls.box.defaultWidth
contentHeight:
flickable.contentHeight + flickable.topMargin + flickable.bottomMargin
padding: 0
HFlickable { HFlickable {
id: flickable id: flickable

View File

@ -5,58 +5,6 @@ import QtQuick.Controls 2.12
GridView { GridView {
id: gridView id: gridView
currentIndex: -1
keyNavigationWraps: true
highlightMoveDuration: theme.animationDuration
// Keep highlighted delegate at the center
highlightRangeMode: GridView.ApplyRange
preferredHighlightBegin: height / 2 - currentItemHeight / 2
preferredHighlightEnd: height / 2 + currentItemHeight / 2
maximumFlickVelocity: window.settings.kineticScrollingMaxSpeed
highlight: Rectangle {
color: theme.controls.gridView.highlight
}
ScrollBar.vertical: HScrollBar {
visible: gridView.interactive
}
// property bool debug: false
// https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
// #handling-interrupted-animations
add: Transition {
// ScriptAction { script: if (gridView.debug) print("add") }
HNumberAnimation { property: "opacity"; from: 0; to: 1 }
HNumberAnimation { property: "scale"; from: 0; to: 1 }
}
move: Transition {
// ScriptAction { script: if (gridView.debug) print("move") }
HNumberAnimation { property: "opacity"; to: 1 }
HNumberAnimation { property: "scale"; to: 1 }
HNumberAnimation { properties: "x,y" }
}
remove: Transition {
// ScriptAction { script: if (gridView.debug) print("remove") }
HNumberAnimation { property: "opacity"; to: 0 }
HNumberAnimation { property: "scale"; to: 0 }
}
displaced: Transition {
// ScriptAction { script: if (gridView.debug) print("displaced") }
HNumberAnimation { property: "opacity"; to: 1 }
HNumberAnimation { property: "scale"; to: 1 }
HNumberAnimation { properties: "x,y" }
}
onSelectedCountChanged: if (! selectedCount) lastCheckedDelegateIndex = 0
property alias cursorShape: mouseArea.cursorShape property alias cursorShape: mouseArea.cursorShape
property int currentItemHeight: currentItem ? currentItem.height : 0 property int currentItemHeight: currentItem ? currentItem.height : 0
@ -117,6 +65,58 @@ GridView {
} }
currentIndex: -1
keyNavigationWraps: true
highlightMoveDuration: theme.animationDuration
// Keep highlighted delegate at the center
highlightRangeMode: GridView.ApplyRange
preferredHighlightBegin: height / 2 - currentItemHeight / 2
preferredHighlightEnd: height / 2 + currentItemHeight / 2
maximumFlickVelocity: window.settings.kineticScrollingMaxSpeed
highlight: Rectangle {
color: theme.controls.gridView.highlight
}
ScrollBar.vertical: HScrollBar {
visible: gridView.interactive
}
// property bool debug: false
// https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
// #handling-interrupted-animations
add: Transition {
// ScriptAction { script: if (gridView.debug) print("add") }
HNumberAnimation { property: "opacity"; from: 0; to: 1 }
HNumberAnimation { property: "scale"; from: 0; to: 1 }
}
move: Transition {
// ScriptAction { script: if (gridView.debug) print("move") }
HNumberAnimation { property: "opacity"; to: 1 }
HNumberAnimation { property: "scale"; to: 1 }
HNumberAnimation { properties: "x,y" }
}
remove: Transition {
// ScriptAction { script: if (gridView.debug) print("remove") }
HNumberAnimation { property: "opacity"; to: 0 }
HNumberAnimation { property: "scale"; to: 0 }
}
displaced: Transition {
// ScriptAction { script: if (gridView.debug) print("displaced") }
HNumberAnimation { property: "opacity"; to: 1 }
HNumberAnimation { property: "scale"; to: 1 }
HNumberAnimation { properties: "x,y" }
}
onSelectedCountChanged: if (! selectedCount) lastCheckedDelegateIndex = 0
HKineticScrollingDisabler { HKineticScrollingDisabler {
id: mouseArea id: mouseArea
width: enabled ? parent.width : 0 width: enabled ? parent.width : 0

View File

@ -5,15 +5,6 @@ import QtGraphicalEffects 1.12
Image { Image {
id: icon id: icon
cache: true
asynchronous: true
fillMode: Image.PreserveAspectFit
visible: Boolean(svgName)
source: svgName ? `../../icons/${iconPack}/${svgName}.svg` : ""
sourceSize.width: svgName ? dimension : 0
sourceSize.height: svgName ? dimension : 0
property string svgName: "" property string svgName: ""
@ -27,6 +18,15 @@ Image {
property string iconPack: theme ? theme.icons.preferredPack : "thin" property string iconPack: theme ? theme.icons.preferredPack : "thin"
cache: true
asynchronous: true
fillMode: Image.PreserveAspectFit
visible: Boolean(svgName)
source: svgName ? `../../icons/${iconPack}/${svgName}.svg` : ""
sourceSize.width: svgName ? dimension : 0
sourceSize.height: svgName ? dimension : 0
layer.enabled: ! Qt.colorEqual(colorize, "transparent") layer.enabled: ! Qt.colorEqual(colorize, "transparent")
layer.effect: ColorOverlay { layer.effect: ColorOverlay {
color: icon.colorize color: icon.colorize

View File

@ -5,16 +5,6 @@ import QtGraphicalEffects 1.12
Image { Image {
id: image id: image
autoTransform: true
asynchronous: true
fillMode: Image.PreserveAspectFit
cache: ! (animate && animated) &&
(sourceSize.width + sourceSize.height) <= 512
layer.enabled: radius !== 0
layer.effect: OpacityMask { maskSource: roundMask }
property bool circle: radius === circleRadius property bool circle: radius === circleRadius
property bool broken: false property bool broken: false
@ -31,11 +21,24 @@ Image {
Math.ceil(Math.max(image.width, image.height)) Math.ceil(Math.max(image.width, image.height))
autoTransform: true
asynchronous: true
fillMode: Image.PreserveAspectFit
cache: ! (animate && animated) &&
(sourceSize.width + sourceSize.height) <= 512
layer.enabled: radius !== 0
layer.effect: OpacityMask { maskSource: roundMask }
Component { Component {
id: animatedImageComponent id: animatedImageComponent
AnimatedImage { AnimatedImage {
id: animatedImage id: animatedImage
property bool userPaused: ! window.settings.media.autoPlayGIF
source: image.source source: image.source
autoTransform: image.autoTransform autoTransform: image.autoTransform
asynchronous: image.asynchronous asynchronous: image.asynchronous
@ -46,6 +49,14 @@ Image {
horizontalAlignment: image.horizontalAlignment horizontalAlignment: image.horizontalAlignment
verticalAlignment: image.verticalAlignment verticalAlignment: image.verticalAlignment
// Online GIFs won't be able to loop if cache is set to false,
// but caching GIFs is expansive.
cache: ! Qt.resolvedUrl(source).startsWith("file://")
paused: ! visible || window.hidden || userPaused
layer.enabled: image.radius !== 0
layer.effect: OpacityMask { maskSource: roundMask }
// Hack to make the non-animated image behind this one // Hack to make the non-animated image behind this one
// basically invisible // basically invisible
Binding { Binding {
@ -64,16 +75,6 @@ Image {
value: 1 value: 1
} }
// Online GIFs won't be able to loop if cache is set to false,
// but caching GIFs is expansive.
cache: ! Qt.resolvedUrl(source).startsWith("file://")
paused: ! visible || window.hidden || userPaused
layer.enabled: image.radius !== 0
layer.effect: OpacityMask { maskSource: roundMask }
property bool userPaused: ! window.settings.media.autoPlayGIF
TapHandler { TapHandler {
enabled: image.enabledAnimatedPausing enabled: image.enabledAnimatedPausing
onTapped: parent.userPaused = ! parent.userPaused onTapped: parent.userPaused = ! parent.userPaused

View File

@ -4,27 +4,12 @@ import QtQuick 2.12
MouseArea { MouseArea {
id: mouseArea id: mouseArea
enabled: ! window.settings.enableKineticScrolling
propagateComposedEvents: true
acceptedButtons: Qt.NoButton
onWheel: {
// Make components below the stack notice the wheel event
wheel.accepted = false
const pos = getNewPosition(flickable, wheel)
flickable.flick(0, 0)
flickable.contentY = pos
}
property Flickable flickable: parent property Flickable flickable: parent
// Used to get default flickDeceleration value // Used to get default flickDeceleration value
readonly property Flickable dummy: Flickable {} readonly property Flickable dummy: Flickable {}
function getNewPosition(flickable, wheel) { function getNewPosition(flickable, wheel) {
// wheel.pixelDelta will be available on high resolution trackpads. // wheel.pixelDelta will be available on high resolution trackpads.
// Otherwise use wheel.angleDelta, which is available from mouses and // Otherwise use wheel.angleDelta, which is available from mouses and
@ -53,6 +38,19 @@ MouseArea {
} }
enabled: ! window.settings.enableKineticScrolling
propagateComposedEvents: true
acceptedButtons: Qt.NoButton
onWheel: {
// Make components below the stack notice the wheel event
wheel.accepted = false
const pos = getNewPosition(flickable, wheel)
flickable.flick(0, 0)
flickable.contentY = pos
}
Binding { Binding {
target: flickable target: flickable
property: "maximumFlickVelocity" property: "maximumFlickVelocity"

View File

@ -4,9 +4,6 @@ import QtQuick 2.12
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
HColumnLayout { HColumnLayout {
spacing: theme.spacing / 2
default property alias insideData: itemHolder.data default property alias insideData: itemHolder.data
property bool loading: false property bool loading: false
@ -17,6 +14,8 @@ HColumnLayout {
readonly property alias toolTip: toolTip readonly property alias toolTip: toolTip
spacing: theme.spacing / 2
HRowLayout { HRowLayout {
spacing: theme.spacing spacing: theme.spacing

View File

@ -5,59 +5,6 @@ import QtQuick.Controls 2.12
ListView { ListView {
id: listView id: listView
currentIndex: -1
keyNavigationWraps: true
highlightMoveDuration: theme.animationDuration
highlightResizeDuration: theme.animationDuration
// Keep highlighted delegate at the center
highlightRangeMode: ListView.ApplyRange
preferredHighlightBegin: height / 2 - currentItemHeight / 2
preferredHighlightEnd: height / 2 + currentItemHeight / 2
maximumFlickVelocity: window.settings.kineticScrollingMaxSpeed
highlight: Rectangle {
color: theme.controls.listView.highlight
}
ScrollBar.vertical: HScrollBar {
visible: listView.interactive
}
// property bool debug: false
// https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
// #handling-interrupted-animations
add: Transition {
// ScriptAction { script: if (listView.debug) print("add") }
HNumberAnimation { property: "opacity"; from: 0; to: 1 }
HNumberAnimation { property: "scale"; from: 0; to: 1 }
}
move: Transition {
// ScriptAction { script: if (listView.debug) print("move") }
HNumberAnimation { property: "opacity"; to: 1 }
HNumberAnimation { property: "scale"; to: 1 }
HNumberAnimation { properties: "x,y" }
}
remove: Transition {
// ScriptAction { script: if (listView.debug) print("remove") }
HNumberAnimation { property: "opacity"; to: 0 }
HNumberAnimation { property: "scale"; to: 0 }
}
displaced: Transition {
// ScriptAction { script: if (listView.debug) print("displaced") }
HNumberAnimation { property: "opacity"; to: 1 }
HNumberAnimation { property: "scale"; to: 1 }
HNumberAnimation { properties: "x,y" }
}
onSelectedCountChanged: if (! selectedCount) lastCheckedDelegateIndex = 0
property alias cursorShape: cursorShapeArea.cursorShape property alias cursorShape: cursorShapeArea.cursorShape
property int currentItemHeight: currentItem ? currentItem.height : 0 property int currentItemHeight: currentItem ? currentItem.height : 0
@ -67,7 +14,6 @@ ListView {
property int lastCheckedDelegateIndex: 0 property int lastCheckedDelegateIndex: 0
property int selectedCount: Object.keys(checked).length property int selectedCount: Object.keys(checked).length
function check(...indices) { function check(...indices) {
for (const i of indices) { for (const i of indices) {
const model = listView.model.get(i) const model = listView.model.get(i)
@ -131,6 +77,59 @@ ListView {
} }
currentIndex: -1
keyNavigationWraps: true
highlightMoveDuration: theme.animationDuration
highlightResizeDuration: theme.animationDuration
// Keep highlighted delegate at the center
highlightRangeMode: ListView.ApplyRange
preferredHighlightBegin: height / 2 - currentItemHeight / 2
preferredHighlightEnd: height / 2 + currentItemHeight / 2
maximumFlickVelocity: window.settings.kineticScrollingMaxSpeed
highlight: Rectangle {
color: theme.controls.listView.highlight
}
ScrollBar.vertical: HScrollBar {
visible: listView.interactive
}
// property bool debug: false
// https://doc.qt.io/qt-5/qml-qtquick-viewtransition.html
// #handling-interrupted-animations
add: Transition {
// ScriptAction { script: if (listView.debug) print("add") }
HNumberAnimation { property: "opacity"; from: 0; to: 1 }
HNumberAnimation { property: "scale"; from: 0; to: 1 }
}
move: Transition {
// ScriptAction { script: if (listView.debug) print("move") }
HNumberAnimation { property: "opacity"; to: 1 }
HNumberAnimation { property: "scale"; to: 1 }
HNumberAnimation { properties: "x,y" }
}
remove: Transition {
// ScriptAction { script: if (listView.debug) print("remove") }
HNumberAnimation { property: "opacity"; to: 0 }
HNumberAnimation { property: "scale"; to: 0 }
}
displaced: Transition {
// ScriptAction { script: if (listView.debug) print("displaced") }
HNumberAnimation { property: "opacity"; to: 1 }
HNumberAnimation { property: "scale"; to: 1 }
HNumberAnimation { properties: "x,y" }
}
onSelectedCountChanged: if (! selectedCount) lastCheckedDelegateIndex = 0
MouseArea { MouseArea {
id: cursorShapeArea id: cursorShapeArea
anchors.fill: parent anchors.fill: parent

View File

@ -6,6 +6,17 @@ import CppUtils 0.1
Menu { Menu {
id: menu id: menu
property var previouslyFocused: null
// MenuItems that open popups (or other elements taking focus when opened)
// should set this to null. It will be reset to previouslyFocus when
// the Menu is closed and opened again.
property Item focusOnClosed: previouslyFocused
readonly property string uuid: CppUtils.uuid()
modal: true modal: true
dim: false dim: false
padding: theme.controls.menu.borderWidth padding: theme.controls.menu.borderWidth
@ -48,24 +59,17 @@ Menu {
previouslyFocused = window.activeFocusItem previouslyFocused = window.activeFocusItem
focusOnClosed = Qt.binding(() => previouslyFocused) focusOnClosed = Qt.binding(() => previouslyFocused)
} }
onOpened: { onOpened: {
window.visibleMenus[uuid] = this window.visibleMenus[uuid] = this
window.visibleMenusChanged() window.visibleMenusChanged()
} }
onClosed: { onClosed: {
if (focusOnClosed) focusOnClosed.forceActiveFocus() if (focusOnClosed) focusOnClosed.forceActiveFocus()
delete window.visibleMenus[uuid] delete window.visibleMenus[uuid]
window.visibleMenusChanged() window.visibleMenusChanged()
} }
Component.onDestruction: closed() Component.onDestruction: closed()
property var previouslyFocused: null
// MenuItems that open popups (or other elements taking focus when opened)
// should set this to null. It will be reset to previouslyFocus when
// the Menu is closed and opened again.
property Item focusOnClosed: previouslyFocused
readonly property string uuid: CppUtils.uuid()
} }

View File

@ -5,6 +5,11 @@ import QtQuick.Controls 2.12
MenuItem { MenuItem {
id: menuItem id: menuItem
readonly property alias iconItem: contentItem.icon
readonly property alias label: contentItem.label
spacing: theme.spacing spacing: theme.spacing
leftPadding: spacing leftPadding: spacing
rightPadding: leftPadding rightPadding: leftPadding
@ -27,8 +32,4 @@ MenuItem {
buttonTheme: theme.controls.menuItem buttonTheme: theme.controls.menuItem
label.horizontalAlignment: Label.AlignLeft label.horizontalAlignment: Label.AlignLeft
} }
readonly property alias iconItem: contentItem.icon
readonly property alias label: contentItem.label
} }

View File

@ -4,6 +4,11 @@ import QtQuick 2.12
import QtQuick.Controls 2.12 import QtQuick.Controls 2.12
HMenuItem { HMenuItem {
property var popup // url or HPopup Component
property bool autoDestruct: true
property var properties: ({})
onTriggered: { onTriggered: {
menu.focusOnClosed = null menu.focusOnClosed = null
@ -16,9 +21,4 @@ HMenuItem {
autoDestruct, autoDestruct,
) )
} }
property var popup // url or HPopup Component
property bool autoDestruct: true
property var properties: ({})
} }

View File

@ -5,15 +5,6 @@ import "../PythonBridge"
HImage { HImage {
id: image id: image
inderterminateProgressBar: isMxc
source: sourceOverride || (show ? cachedPath : "")
onWidthChanged: Qt.callLater(update)
onHeightChanged: Qt.callLater(update)
onVisibleChanged: Qt.callLater(update)
onMxcChanged: Qt.callLater(update)
Component.onDestruction: if (getFuture) getFuture.cancel()
property string mxc property string mxc
property string title property string title
@ -28,7 +19,6 @@ HImage {
readonly property bool isMxc: mxc.startsWith("mxc://") readonly property bool isMxc: mxc.startsWith("mxc://")
function update() { function update() {
if (! py) return // component was destroyed if (! py) return // component was destroyed
@ -64,4 +54,14 @@ HImage {
}, },
) )
} }
inderterminateProgressBar: isMxc
source: sourceOverride || (show ? cachedPath : "")
onWidthChanged: Qt.callLater(update)
onHeightChanged: Qt.callLater(update)
onVisibleChanged: Qt.callLater(update)
onMxcChanged: Qt.callLater(update)
Component.onDestruction: if (getFuture) getFuture.cancel()
} }

View File

@ -11,6 +11,7 @@ HRowLayout {
property alias backgroundColor: noticeLabelBackground.color property alias backgroundColor: noticeLabelBackground.color
property alias radius: noticeLabelBackground.radius property alias radius: noticeLabelBackground.radius
HLabel { HLabel {
id: noticeLabel id: noticeLabel
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter

View File

@ -6,6 +6,7 @@ NumberAnimation {
property real factor: 1.0 property real factor: 1.0
property real overshoot: 1.0 property real overshoot: 1.0
duration: theme.animationDuration * Math.max(overshoot / 1.7, 1.0) * factor duration: theme.animationDuration * Math.max(overshoot / 1.7, 1.0) * factor
easing.type: overshoot > 1 ? Easing.OutBack : Easing.Linear easing.type: overshoot > 1 ? Easing.OutBack : Easing.Linear
easing.overshoot: overshoot easing.overshoot: overshoot

View File

@ -4,14 +4,6 @@ import QtQuick 2.12
import QtQuick.Controls 2.12 import QtQuick.Controls 2.12
Page { Page {
padding: currentSpacing < theme.spacing ? 0 : currentSpacing
background: null
Keys.onReturnPressed: keyboardAccept()
Keys.onEnterPressed: keyboardAccept()
Keys.onEscapePressed: keyboardCancel()
property bool useVariableSpacing: true property bool useVariableSpacing: true
property int currentSpacing: property int currentSpacing:
@ -27,5 +19,12 @@ Page {
signal keyboardCancel() signal keyboardCancel()
padding: currentSpacing < theme.spacing ? 0 : currentSpacing
background: null
Keys.onReturnPressed: keyboardAccept()
Keys.onEnterPressed: keyboardAccept()
Keys.onEscapePressed: keyboardCancel()
Behavior on padding { HNumberAnimation {} } Behavior on padding { HNumberAnimation {} }
} }

View File

@ -6,6 +6,19 @@ import CppUtils 0.1
Popup { Popup {
id: popup id: popup
property var previouslyFocused: null
property Item focusOnClosed: previouslyFocused
readonly property int maximumPreferredWidth:
window.width - leftMargin - rightMargin - leftInset - rightInset
readonly property int maximumPreferredHeight:
window.height - topMargin - bottomMargin - topInset - bottomInset
readonly property string uuid: CppUtils.uuid()
modal: true modal: true
focus: true focus: true
padding: 0 padding: 0
@ -43,17 +56,6 @@ Popup {
delete window.visiblePopups[uuid] delete window.visiblePopups[uuid]
window.visibleMenusChanged() window.visibleMenusChanged()
} }
Component.onDestruction: closed() Component.onDestruction: closed()
property var previouslyFocused: null
property Item focusOnClosed: previouslyFocused
readonly property int maximumPreferredWidth:
window.width - leftMargin - rightMargin - leftInset - rightInset
readonly property int maximumPreferredHeight:
window.height - topMargin - bottomMargin - topInset - bottomInset
readonly property string uuid: CppUtils.uuid()
} }

View File

@ -9,6 +9,7 @@ ProgressBar {
property color backgroundColor: theme.controls.progressBar.background property color backgroundColor: theme.controls.progressBar.background
property color foregroundColor: theme.controls.progressBar.foreground property color foregroundColor: theme.controls.progressBar.foreground
background: Rectangle { background: Rectangle {
implicitWidth: 200 implicitWidth: 200
implicitHeight: theme.controls.progressBar.height implicitHeight: theme.controls.progressBar.height

View File

@ -7,6 +7,7 @@ Item {
property alias borderHeight: clipArea.height property alias borderHeight: clipArea.height
property alias color: borderRectangle.color property alias color: borderRectangle.color
implicitWidth: rectangle.width implicitWidth: rectangle.width
implicitHeight: rectangle.height implicitHeight: rectangle.height

View File

@ -7,7 +7,6 @@ import QtQuick 2.12
Repeater { Repeater {
id: repeater id: repeater
readonly property var childrenImplicitWidth: { readonly property var childrenImplicitWidth: {
const widths = [] const widths = []

View File

@ -3,13 +3,13 @@
import QtQuick 2.12 import QtQuick 2.12
HAvatar { HAvatar {
property string roomId
property string displayName
name: displayName[0] === "#" && displayName.length > 1 ? name: displayName[0] === "#" && displayName.length > 1 ?
displayName.substring(1) : displayName.substring(1) :
displayName displayName
title: "room_" + roomId + ".avatar" title: "room_" + roomId + ".avatar"
property string roomId
property string displayName
} }

View File

@ -5,6 +5,7 @@ import QtQuick.Controls 2.12
ScrollBar { ScrollBar {
id: scrollBar id: scrollBar
minimumSize: (Math.min(height / 1.5, 48) * theme.uiScale) / height minimumSize: (Math.min(height / 1.5, 48) * theme.uiScale) / height
opacity: size < 1 && (active || hovered) ? 1 : 0 opacity: size < 1 && (active || hovered) ? 1 : 0
padding: 0 padding: 0

View File

@ -5,6 +5,19 @@ import QtQuick.Controls 2.12
TextEdit { TextEdit {
id: label id: label
property bool enableLinkActivation: true
function selectWordAt(position) {
label.cursorPosition = positionAt(position.x, position.y)
label.selectWord()
}
function selectAllText() {
label.selectAll()
}
font.family: theme.fontFamily.sans font.family: theme.fontFamily.sans
font.pixelSize: theme.fontSize.normal font.pixelSize: theme.fontSize.normal
color: theme.colors.text color: theme.colors.text
@ -18,20 +31,6 @@ TextEdit {
selectByMouse: true selectByMouse: true
onLinkActivated: if (enableLinkActivation) Qt.openUrlExternally(link) onLinkActivated: if (enableLinkActivation) Qt.openUrlExternally(link)
property bool enableLinkActivation: true
function selectWordAt(position) {
label.cursorPosition = positionAt(position.x, position.y)
label.selectWord()
}
function selectAllText() {
label.selectAll()
}
MouseArea { MouseArea {
anchors.fill: label anchors.fill: label
acceptedButtons: Qt.NoButton acceptedButtons: Qt.NoButton

View File

@ -3,10 +3,10 @@
import QtQuick 2.12 import QtQuick 2.12
Shortcut { Shortcut {
enabled: ! window.anyPopupOrMenu && active
context: Qt.ApplicationShortcut
// TODO: use enabled + a Binding with restoreValue when switch to Qt 5.15 // TODO: use enabled + a Binding with restoreValue when switch to Qt 5.15
property bool active: true property bool active: true
enabled: ! window.anyPopupOrMenu && active
context: Qt.ApplicationShortcut
} }

View File

@ -5,10 +5,6 @@ import QtQuick.Controls 2.12
Slider { Slider {
id: slider id: slider
leftPadding: 0
rightPadding: leftPadding
topPadding: 0
bottomPadding: topPadding
property bool enableRadius: true property bool enableRadius: true
property bool fullHeight: false property bool fullHeight: false
@ -18,6 +14,12 @@ Slider {
property alias toolTip: toolTip property alias toolTip: toolTip
property alias mouseArea: mouseArea property alias mouseArea: mouseArea
leftPadding: 0
rightPadding: leftPadding
topPadding: 0
bottomPadding: topPadding
background: Rectangle { background: Rectangle {
color: backgroundColor color: backgroundColor
x: slider.leftPadding x: slider.leftPadding

View File

@ -7,21 +7,6 @@ import "../ShortcutBundles"
SwipeView { SwipeView {
id: swipeView id: swipeView
Component.onCompleted: if (! changed) {
setCurrentIndex(window.getState(this, "currentIndex", defaultIndex))
saveEnabled = true
}
onCurrentIndexChanged: {
if (saveEnabled) window.saveState(this)
if (currentIndex < previousIndex) lastMove = HSwipeView.Move.ToPrevious
if (currentIndex > previousIndex) lastMove = HSwipeView.Move.ToNext
previousIndex = currentIndex
}
enum Move { ToPrevious, ToNext } enum Move { ToPrevious, ToNext }
property string saveName: "" property string saveName: ""
@ -52,6 +37,20 @@ SwipeView {
} }
Component.onCompleted: if (! changed) {
setCurrentIndex(window.getState(this, "currentIndex", defaultIndex))
saveEnabled = true
}
onCurrentIndexChanged: {
if (saveEnabled) window.saveState(this)
if (currentIndex < previousIndex) lastMove = HSwipeView.Move.ToPrevious
if (currentIndex > previousIndex) lastMove = HSwipeView.Move.ToNext
previousIndex = currentIndex
}
TabShortcuts { TabShortcuts {
container: swipeView container: swipeView
} }

View File

@ -6,6 +6,7 @@ import "../ShortcutBundles"
TabBar { TabBar {
id: tabBar id: tabBar
spacing: 0 spacing: 0
position: TabBar.Header position: TabBar.Header
@ -18,7 +19,6 @@ TabBar {
} }
} }
TabShortcuts { TabShortcuts {
container: tabBar container: tabBar
} }

View File

@ -6,27 +6,6 @@ import QtQuick.Layouts 1.12
TabButton { TabButton {
id: button id: button
spacing: theme.spacing
topPadding: spacing / 1.5
bottomPadding: topPadding
leftPadding: spacing
rightPadding: leftPadding
icon.color: theme.icons.colorize
implicitWidth: Math.max(
implicitBackgroundWidth + leftInset + rightInset,
// FIXME: why is *2 needed to not get ellided text in AddAccount page?
implicitContentWidth + leftPadding * 2 + rightPadding * 2,
)
implicitHeight: Math.max(
implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding,
)
// Prevent button from gaining focus and being highlighted on click
focusPolicy: Qt.TabFocus
readonly property alias iconItem: contentItem.icon readonly property alias iconItem: contentItem.icon
readonly property alias label: contentItem.label readonly property alias label: contentItem.label
@ -48,6 +27,27 @@ TabButton {
} }
spacing: theme.spacing
topPadding: spacing / 1.5
bottomPadding: topPadding
leftPadding: spacing
rightPadding: leftPadding
icon.color: theme.icons.colorize
implicitWidth: Math.max(
implicitBackgroundWidth + leftInset + rightInset,
// FIXME: why is *2 needed to not get ellided text in AddAccount page?
implicitContentWidth + leftPadding * 2 + rightPadding * 2,
)
implicitHeight: Math.max(
implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding,
)
// Prevent button from gaining focus and being highlighted on click
focusPolicy: Qt.TabFocus
background: HButtonBackground { background: HButtonBackground {
button: button button: button
buttonTheme: theme.controls.tab buttonTheme: theme.controls.tab

View File

@ -6,7 +6,6 @@ import QtQuick.Controls 2.12
TextArea { TextArea {
id: textArea id: textArea
property string saveName: "" property string saveName: ""
property var saveId: "ALL" property var saveId: "ALL"
property var saveProperties: ["text"] property var saveProperties: ["text"]
@ -27,7 +26,6 @@ TextArea {
property string previousDefaultText: "" // private property string previousDefaultText: "" // private
function reset() { clear(); text = Qt.binding(() => defaultText || "") } function reset() { clear(); text = Qt.binding(() => defaultText || "") }
function insertAtCursor(text) { insert(cursorPosition, text) } function insertAtCursor(text) { insert(cursorPosition, text) }

View File

@ -7,7 +7,6 @@ HMenu {
property bool hadPersistentSelection: false // TODO: use a Qt 5.15 Binding property bool hadPersistentSelection: false // TODO: use a Qt 5.15 Binding
function spawn(atMousePosition=true) { function spawn(atMousePosition=true) {
hadPersistentSelection = control.persistentSelection hadPersistentSelection = control.persistentSelection
control.persistentSelection = true control.persistentSelection = true
@ -25,7 +24,6 @@ HMenu {
Component.onDestruction: Component.onDestruction:
control.persistentSelection = hadPersistentSelection control.persistentSelection = hadPersistentSelection
HMenuItem { HMenuItem {
icon.name: "undo" icon.name: "undo"
text: qsTr("Undo") text: qsTr("Undo")

View File

@ -5,6 +5,33 @@ import QtQuick.Controls 2.12
TextField { TextField {
id: field id: field
property string saveName: ""
property var saveId: "ALL"
property var saveProperties: ["text"]
property bool error: false
property alias radius: textFieldBackground.radius
property bool bordered: true
property color backgroundColor: theme.controls.textField.background
property color borderColor: theme.controls.textField.border
property color errorBorder: theme.controls.textField.errorBorder
property color focusedBackgroundColor:
theme.controls.textField.focusedBackground
property color focusedBorderColor: theme.controls.textField.focusedBorder
property var disabledText: null
property var defaultText: null
readonly property bool changed: text !== (defaultText || "")
property string previousDefaultText: "" // private
function reset() { clear(); text = Qt.binding(() => defaultText || "")}
text: defaultText || "" text: defaultText || ""
opacity: enabled ? 1 : theme.disabledElementsOpacity opacity: enabled ? 1 : theme.disabledElementsOpacity
selectByMouse: true selectByMouse: true
@ -75,33 +102,6 @@ TextField {
event.accepted = cursorPosition === length && ! selectedText event.accepted = cursorPosition === length && ! selectedText
property string saveName: ""
property var saveId: "ALL"
property var saveProperties: ["text"]
property bool error: false
property alias radius: textFieldBackground.radius
property bool bordered: true
property color backgroundColor: theme.controls.textField.background
property color borderColor: theme.controls.textField.border
property color errorBorder: theme.controls.textField.errorBorder
property color focusedBackgroundColor:
theme.controls.textField.focusedBackground
property color focusedBorderColor: theme.controls.textField.focusedBorder
property var disabledText: null
property var defaultText: null
readonly property bool changed: text !== (defaultText || "")
property string previousDefaultText: "" // private
function reset() { clear(); text = Qt.binding(() => defaultText || "")}
Binding on color { Binding on color {
value: "transparent" value: "transparent"
when: disabledText !== null && ! field.enabled when: disabledText !== null && ! field.enabled

View File

@ -4,9 +4,9 @@ import QtQuick 2.12
import ".." import ".."
HRowLayout { HRowLayout {
property HTile tile
spacing: tile.spacing spacing: tile.spacing
opacity: tile.contentOpacity opacity: tile.contentOpacity
property HTile tile
} }

View File

@ -5,26 +5,15 @@ import ".."
HButton { HButton {
id: tile id: tile
topPadding: padded ? spacing / (compact ? 4 : 2) : 0
bottomPadding: topPadding
Keys.onEnterPressed: leftClicked()
Keys.onReturnPressed: leftClicked()
Keys.onSpacePressed: leftClicked()
Keys.onMenuPressed: doRightClick(false)
property bool compact: window.settings.compactMode
property real contentOpacity: 1
property Component contextMenu: null
signal leftClicked() signal leftClicked()
signal rightClicked() signal rightClicked()
signal longPressed() signal longPressed()
property bool compact: window.settings.compactMode
property real contentOpacity: 1
property Component contextMenu: null
function openMenu(atCursor=true) { function openMenu(atCursor=true) {
if (! contextMenu) return if (! contextMenu) return
const menu = contextMenu.createObject(tile) const menu = contextMenu.createObject(tile)
@ -38,6 +27,15 @@ HButton {
} }
topPadding: padded ? spacing / (compact ? 4 : 2) : 0
bottomPadding: topPadding
Keys.onEnterPressed: leftClicked()
Keys.onReturnPressed: leftClicked()
Keys.onSpacePressed: leftClicked()
Keys.onMenuPressed: doRightClick(false)
Behavior on topPadding { HNumberAnimation {} } Behavior on topPadding { HNumberAnimation {} }
Behavior on bottomPadding { HNumberAnimation {} } Behavior on bottomPadding { HNumberAnimation {} }

View File

@ -7,6 +7,7 @@ import ".."
HLabel { HLabel {
property HTile tile property HTile tile
textFormat: Text.StyledText textFormat: Text.StyledText
font.pixelSize: theme.fontSize.small font.pixelSize: theme.fontSize.small
verticalAlignment: Qt.AlignVCenter verticalAlignment: Qt.AlignVCenter

View File

@ -5,6 +5,9 @@ import QtQuick.Layouts 1.12
import ".." import ".."
HLabel { HLabel {
property HTile tile
font.pixelSize: theme.fontSize.small font.pixelSize: theme.fontSize.small
verticalAlignment: Qt.AlignVCenter verticalAlignment: Qt.AlignVCenter
color: theme.colors.halfDimText color: theme.colors.halfDimText
@ -15,9 +18,5 @@ HLabel {
text && tile.width >= 200 * theme.uiScale ? text && tile.width >= 200 * theme.uiScale ?
implicitWidth : 0 implicitWidth : 0
property HTile tile
Behavior on Layout.maximumWidth { HNumberAnimation {} } Behavior on Layout.maximumWidth { HNumberAnimation {} }
} }

View File

@ -6,6 +6,23 @@ import QtQuick.Layouts 1.12
ToolTip { ToolTip {
id: toolTip id: toolTip
property bool instant: false
property alias label: label
property alias backgroundColor: background.color
readonly property bool hideNow: ! window.hovered
function instantShow() {
if (visible) return
instant = true
open()
instant = false
}
delay: instant ? 0 : theme.controls.toolTip.delay delay: instant ? 0 : theme.controls.toolTip.delay
padding: background.border.width padding: background.border.width
@ -43,23 +60,6 @@ ToolTip {
onHideNowChanged: if (visible && hideNow) toolTip.hide() onHideNowChanged: if (visible && hideNow) toolTip.hide()
property bool instant: false
property alias label: label
property alias backgroundColor: background.color
readonly property bool hideNow: ! window.hovered
function instantShow() {
if (visible) return
instant = true
open()
instant = false
}
TapHandler { TapHandler {
onTapped: toolTip.hide() onTapped: toolTip.hide()
} }

View File

@ -3,10 +3,6 @@
import QtQuick 2.12 import QtQuick 2.12
HAvatar { HAvatar {
name: displayName || userId.substring(1) // no leading @
title: "user_" + userId + ".avatar"
property string userId property string userId
property string displayName property string displayName
property string presence: "" property string presence: ""
@ -18,6 +14,9 @@ HAvatar {
readonly property bool moderator: powerLevel >= 50 && ! admin readonly property bool moderator: powerLevel >= 50 && ! admin
name: displayName || userId.substring(1) // no leading @
title: "user_" + userId + ".avatar"
HLoader { HLoader {
active: admin || moderator || invited active: admin || moderator || invited
anchors.top: parent.top anchors.top: parent.top
@ -53,6 +52,11 @@ HAvatar {
} }
HLoader { HLoader {
property int diameter:
window.settings.compactMode ?
theme.controls.presence.radius * 2 :
theme.controls.presence.radius * 2.5
active: presence && presence !== "offline" active: presence && presence !== "offline"
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
@ -61,11 +65,6 @@ HAvatar {
opacity: theme.controls.presence.opacity opacity: theme.controls.presence.opacity
z: 300 z: 300
property int diameter:
window.settings.compactMode ?
theme.controls.presence.radius * 2 :
theme.controls.presence.radius * 2.5
sourceComponent: Rectangle { sourceComponent: Rectangle {
width: diameter width: diameter
height: diameter height: diameter

View File

@ -5,16 +5,16 @@ import QtAV 1.7
OSD { OSD {
id: osd id: osd
property alias source: audioPlayer.source
audioOnly: true audioOnly: true
media: audioPlayer media: audioPlayer
implicitWidth: osd.width implicitWidth: osd.width
implicitHeight: osd.height implicitHeight: osd.height
property alias source: audioPlayer.source
MediaPlayer { MediaPlayer {
id: audioPlayer id: audioPlayer
autoLoad: window.settings.media.autoLoad autoLoad: window.settings.media.autoLoad

View File

@ -7,20 +7,6 @@ import "../../Base"
HColumnLayout { HColumnLayout {
id: osd id: osd
visible: osdScaleTransform.yScale > 0
transform: Scale {
id: osdScaleTransform
yScale: audioOnly ||
osdHover.hovered ||
media.playbackState !== MediaPlayer.PlayingState ||
osd.showup ?
1 : 0
origin.y: osd.height
Behavior on yScale { HNumberAnimation {} }
}
property QtObject media: parent // QtAV.Video or QtAV.MediaPlayer property QtObject media: parent // QtAV.Video or QtAV.MediaPlayer
property bool audioOnly: false property bool audioOnly: false
@ -35,12 +21,6 @@ HColumnLayout {
savedDuration ? savedDuration ?
Math.min(media.position, savedDuration) : media.position Math.min(media.position, savedDuration) : media.position
onShowupChanged: if (showup) osdHideTimer.restart()
onDurationChanged: if (duration) savedDuration = duration
onAspectRatioChanged: if (aspectRatio) savedAspectRatio = aspectRatio
function togglePlay() { function togglePlay() {
media.playbackState === MediaPlayer.PlayingState ? media.playbackState === MediaPlayer.PlayingState ?
media.pause() : media.play() media.pause() : media.play()
@ -52,6 +32,24 @@ HColumnLayout {
} }
visible: osdScaleTransform.yScale > 0
transform: Scale {
id: osdScaleTransform
yScale: audioOnly ||
osdHover.hovered ||
media.playbackState !== MediaPlayer.PlayingState ||
osd.showup ?
1 : 0
origin.y: osd.height
Behavior on yScale { HNumberAnimation {} }
}
onShowupChanged: if (showup) osdHideTimer.restart()
onDurationChanged: if (duration) savedDuration = duration
onAspectRatioChanged: if (aspectRatio) savedAspectRatio = aspectRatio
HoverHandler { id: osdHover } HoverHandler { id: osdHover }
Timer { Timer {
@ -77,6 +75,13 @@ HColumnLayout {
HToolTip { HToolTip {
id: previewToolTip id: previewToolTip
readonly property int wantTimestamp:
visible ?
savedDuration *
(timeSlider.mouseArea.mouseX / timeSlider.mouseArea.width) :
-1
x: timeSlider.mouseArea.mouseX - width / 2 x: timeSlider.mouseArea.mouseX - width / 2
visible: ! audioOnly && visible: ! audioOnly &&
@ -88,20 +93,6 @@ HColumnLayout {
! timeSlider.pressed && timeSlider.mouseArea.containsMouse ! timeSlider.pressed && timeSlider.mouseArea.containsMouse
readonly property int wantTimestamp:
visible ?
savedDuration *
(timeSlider.mouseArea.mouseX / timeSlider.mouseArea.width) :
-1
Timer {
interval: 300
running: previewToolTip.visible
repeat: true
triggeredOnStart: true
onTriggered: preview.timestamp = previewToolTip.wantTimestamp
}
contentItem: VideoPreview { contentItem: VideoPreview {
id: preview id: preview
implicitHeight: Math.min( implicitHeight: Math.min(
@ -129,11 +120,19 @@ HColumnLayout {
} }
} }
} }
}
Binding on value { Binding on value {
value: boundPosition value: boundPosition
when: ! timeSlider.pressed when: ! timeSlider.pressed
}
Timer {
interval: 300
running: previewToolTip.visible
repeat: true
triggeredOnStart: true
onTriggered: preview.timestamp = previewToolTip.wantTimestamp
}
} }
} }

View File

@ -3,7 +3,6 @@
import QtQuick 2.12 import QtQuick 2.12
import "../../Base" import "../../Base"
HButton { HButton {
backgroundColor: "transparent" backgroundColor: "transparent"
iconItem.dimension: theme.mediaPlayer.controls.iconSize iconItem.dimension: theme.mediaPlayer.controls.iconSize

View File

@ -4,7 +4,6 @@ import QtQuick 2.12
import QtQuick.Layouts 1.12 import QtQuick.Layouts 1.12
import "../../Base" import "../../Base"
HLabel { HLabel {
Layout.leftMargin: theme.spacing / 2 Layout.leftMargin: theme.spacing / 2
Layout.rightMargin: Layout.leftMargin Layout.rightMargin: Layout.leftMargin

View File

@ -6,9 +6,8 @@ import QtQuick.Layouts 1.12
HDrawer { HDrawer {
id: pane id: pane
defaultSize: buttonRepeater.count * buttonWidth
minimumSize: buttonWidth
default property alias swipeViewData: swipeView.contentData
property color buttonsBackgroundColor property color buttonsBackgroundColor
@ -18,8 +17,9 @@ HDrawer {
readonly property alias buttonRepeater: buttonRepeater readonly property alias buttonRepeater: buttonRepeater
readonly property alias swipeView: swipeView readonly property alias swipeView: swipeView
default property alias swipeViewData: swipeView.contentData
defaultSize: buttonRepeater.count * buttonWidth
minimumSize: buttonWidth
HColumnLayout { HColumnLayout {
anchors.fill: parent anchors.fill: parent

View File

@ -8,37 +8,6 @@ import "ShortcutBundles"
HDrawer { HDrawer {
id: debugConsole id: debugConsole
objectName: "debugConsole"
edge: Qt.TopEdge
x: horizontal ? 0 : referenceSizeParent.width / 2 - width / 2
y: vertical ? 0 : referenceSizeParent.height / 2 - height / 2
width: horizontal ? calculatedSize : Math.min(window.width, 720)
height: vertical ? calculatedSize : Math.min(window.height, 720)
defaultSize: 400
z: 9999
position: 0
onTargetChanged: {
commandsView.model.insert(0, {
input: "t = " + String(target),
output: "",
error: false,
})
}
onVisibleChanged: {
if (visible) {
previouslyFocused = window.activeFocusItem
forceActiveFocus()
} else if (previouslyFocused) {
previouslyFocused.forceActiveFocus()
}
}
onHistoryEntryChanged:
inputField.text =
historyEntry === -1 ? "" : history.slice(-historyEntry - 1)[0]
property Item previouslyFocused: null property Item previouslyFocused: null
@ -74,7 +43,6 @@ HDrawer {
readonly property alias commandsView: commandsView readonly property alias commandsView: commandsView
function toggle(targetItem=null, js="", addToHistory=false) { function toggle(targetItem=null, js="", addToHistory=false) {
if (debugConsole.visible) { if (debugConsole.visible) {
debugConsole.visible = false debugConsole.visible = false
@ -90,7 +58,6 @@ HDrawer {
if (js) debugConsole.runJS(js, addToHistory) if (js) debugConsole.runJS(js, addToHistory)
} }
function runJS(input, addToHistory=true) { function runJS(input, addToHistory=true) {
if (addToHistory && history.slice(-1)[0] !== input) { if (addToHistory && history.slice(-1)[0] !== input) {
history.push(input) history.push(input)
@ -135,6 +102,37 @@ HDrawer {
} }
objectName: "debugConsole"
edge: Qt.TopEdge
x: horizontal ? 0 : referenceSizeParent.width / 2 - width / 2
y: vertical ? 0 : referenceSizeParent.height / 2 - height / 2
width: horizontal ? calculatedSize : Math.min(window.width, 720)
height: vertical ? calculatedSize : Math.min(window.height, 720)
defaultSize: 400
z: 9999
position: 0
onTargetChanged: {
commandsView.model.insert(0, {
input: "t = " + String(target),
output: "",
error: false,
})
}
onVisibleChanged: {
if (visible) {
previouslyFocused = window.activeFocusItem
forceActiveFocus()
} else if (previouslyFocused) {
previouslyFocused.forceActiveFocus()
}
}
onHistoryEntryChanged:
inputField.text =
historyEntry === -1 ? "" : history.slice(-historyEntry - 1)[0]
HShortcut { HShortcut {
sequences: settings.keys.toggleDebugConsole sequences: settings.keys.toggleDebugConsole
onActivated: debugConsole.toggle() onActivated: debugConsole.toggle()

View File

@ -5,24 +5,13 @@ import Qt.labs.platform 1.1
import "../Popups" import "../Popups"
HFileDialogOpener { HFileDialogOpener {
fill: false
dialog.title: qsTr("Save decryption keys file as...")
dialog.fileMode: FileDialog.SaveFile
onFilePicked: {
exportPasswordPopup.file = file
exportPasswordPopup.open()
}
// This is used for the SignOutPopup to know when the export is done // This is used for the SignOutPopup to know when the export is done
// so it can close // so it can close
signal done() signal done()
property string userId: "" property string userId: ""
property bool exporting: false property bool exporting: false
function exportKeys(file, passphrase) { function exportKeys(file, passphrase) {
exporting = true exporting = true
@ -35,14 +24,23 @@ HFileDialogOpener {
} }
fill: false
dialog.title: qsTr("Save decryption keys file as...")
dialog.fileMode: FileDialog.SaveFile
onFilePicked: {
exportPasswordPopup.file = file
exportPasswordPopup.open()
}
PasswordPopup { PasswordPopup {
id: exportPasswordPopup id: exportPasswordPopup
property url file: ""
summary.text: qsTr("Passphrase to protect this file:") summary.text: qsTr("Passphrase to protect this file:")
validateButton.text: qsTr("Export") validateButton.text: qsTr("Export")
validateButton.icon.name: "export-keys" validateButton.icon.name: "export-keys"
onAcceptedPasswordChanged: exportKeys(file, acceptedPassword) onAcceptedPasswordChanged: exportKeys(file, acceptedPassword)
property url file: ""
} }
} }

View File

@ -5,13 +5,8 @@ import Qt.labs.platform 1.1
Item { Item {
id: opener id: opener
anchors.fill: fill ? parent : undefined
signal filePicked(string file)
signal filesPicked(var files)
signal cancelled()
enum FileType { All, Images }
property bool fill: true property bool fill: true
@ -24,9 +19,14 @@ Item {
property string selectSubject: property string selectSubject:
dialog.fileMode === FileDialog.SaveFile ? qsTr("file") : qsTr("open") dialog.fileMode === FileDialog.SaveFile ? qsTr("file") : qsTr("open")
enum FileType { All, Images }
property int fileType: HFileDialogOpener.FileType.All property int fileType: HFileDialogOpener.FileType.All
signal filePicked(string file)
signal filesPicked(var files)
signal cancelled()
anchors.fill: fill ? parent : undefined
TapHandler { enabled: opener.enabled && fill; onTapped: fileDialog.open() } TapHandler { enabled: opener.enabled && fill; onTapped: fileDialog.open() }

View File

@ -7,6 +7,10 @@ import "../Popups"
import "../PythonBridge" import "../PythonBridge"
HFileDialogOpener { HFileDialogOpener {
property string userId: ""
property Future importFuture: null
fill: false fill: false
dialog.title: qsTr("Select a decryption keys file to import") dialog.title: qsTr("Select a decryption keys file to import")
onFilePicked: { onFilePicked: {
@ -14,26 +18,11 @@ HFileDialogOpener {
importPasswordPopup.open() importPasswordPopup.open()
} }
property string userId: ""
property Future importFuture: null
PasswordPopup { PasswordPopup {
id: importPasswordPopup id: importPasswordPopup
summary.text:
importFuture ?
qsTr("This might take a while...") :
qsTr("Passphrase used to protect this file:")
validateButton.text: qsTr("Import")
validateButton.icon.name: "import-keys"
onClosed: if (importFuture) importFuture.cancel()
property url file: "" property url file: ""
function verifyPassword(pass, callback) { function verifyPassword(pass, callback) {
const call = py.callClientCoro const call = py.callClientCoro
const path = file.toString().replace(/^file:\/\//, "") const path = file.toString().replace(/^file:\/\//, "")
@ -72,6 +61,14 @@ HFileDialogOpener {
}) })
} }
summary.text:
importFuture ?
qsTr("This might take a while...") :
qsTr("Passphrase used to protect this file:")
validateButton.text: qsTr("Import")
validateButton.icon.name: "import-keys"
onClosed: if (importFuture) importFuture.cancel()
Binding on closePolicy { Binding on closePolicy {
value: Popup.CloseOnEscape value: Popup.CloseOnEscape

View File

@ -4,6 +4,11 @@ import QtQuick 2.12
import Qt.labs.platform 1.1 import Qt.labs.platform 1.1
HFileDialogOpener { HFileDialogOpener {
property string userId
property string roomId
property bool destroyWhenDone: false
fill: false fill: false
dialog.title: qsTr("Select a file to send") dialog.title: qsTr("Select a file to send")
dialog.fileMode: FileDialog.OpenFiles dialog.fileMode: FileDialog.OpenFiles
@ -23,9 +28,4 @@ HFileDialogOpener {
} }
onCancelled: if (destroyWhenDone) destroy() onCancelled: if (destroyWhenDone) destroy()
property string userId
property string roomId
property bool destroyWhenDone: false
} }

View File

@ -8,7 +8,6 @@ Timer {
readonly property ListModel accounts: ModelStore.get("accounts") readonly property ListModel accounts: ModelStore.get("accounts")
readonly property var accountsSet: new Set() readonly property var accountsSet: new Set()
function setPresence(userId, presence) { function setPresence(userId, presence) {
py.callClientCoro(userId, "set_presence", [presence, undefined, false]) py.callClientCoro(userId, "set_presence", [presence, undefined, false])
} }

View File

@ -7,14 +7,13 @@ import "../Base"
import "../Base/HTile" import "../Base/HTile"
Rectangle { Rectangle {
implicitHeight: accountList.count >= 2 ? accountList.contentHeight : 0
color: theme.mainPane.accountBar.background
property RoomList roomList property RoomList roomList
readonly property alias accountList: accountList readonly property alias accountList: accountList
implicitHeight: accountList.count >= 2 ? accountList.contentHeight : 0
color: theme.mainPane.accountBar.background
Behavior on implicitHeight { HNumberAnimation {} } Behavior on implicitHeight { HNumberAnimation {} }
HGridView { HGridView {

View File

@ -13,10 +13,8 @@ HMenu {
property string presence property string presence
property string statusMsg property string statusMsg
signal wentToAccountPage() signal wentToAccountPage()
function setPresence(presence, statusMsg=undefined) { function setPresence(presence, statusMsg=undefined) {
py.callClientCoro(userId, "set_presence", [presence, statusMsg]) py.callClientCoro(userId, "set_presence", [presence, statusMsg])
} }
@ -24,7 +22,6 @@ HMenu {
onOpened: statusText.forceActiveFocus() onOpened: statusText.forceActiveFocus()
HLabeledItem { HLabeledItem {
id: statusMsgLabel id: statusMsgLabel
enabled: presence && presence !== "offline" enabled: presence && presence !== "offline"

View File

@ -7,6 +7,39 @@ import "../Base/HTile"
HTile { HTile {
id: account id: account
property bool enableKeybinds: false
property bool filterActive: false
readonly property bool collapsed:
(window.uiState.collapseAccounts[model.id] || false) &&
! filterActive
readonly property alias avatar: title
readonly property alias totalMessageIndicator: totalMessageIndicator
readonly property alias title: title
readonly property alias addChat: addChat
readonly property alias expand: expand
signal wentToAccountPage()
function setCollapse(collapse) {
window.uiState.collapseAccounts[model.id] = collapse
window.uiStateChanged()
py.callCoro("set_account_collapse", [model.id, collapse])
}
function toggleCollapse() {
setCollapse(! collapsed)
}
function togglePresence(presence) {
if (model.presence === presence) presence = "online"
py.callClientCoro(model.id, "set_presence", [presence])
}
backgroundColor: theme.mainPane.listView.account.background backgroundColor: theme.mainPane.listView.account.background
contentItem: ContentRow { contentItem: ContentRow {
@ -171,40 +204,6 @@ HTile {
onWentToAccountPage: account.wentToAccountPage() onWentToAccountPage: account.wentToAccountPage()
} }
property bool enableKeybinds: false
property bool filterActive: false
readonly property bool collapsed:
(window.uiState.collapseAccounts[model.id] || false) &&
! filterActive
readonly property alias avatar: title
readonly property alias totalMessageIndicator: totalMessageIndicator
readonly property alias title: title
readonly property alias addChat: addChat
readonly property alias expand: expand
signal wentToAccountPage()
function setCollapse(collapse) {
window.uiState.collapseAccounts[model.id] = collapse
window.uiStateChanged()
py.callCoro("set_account_collapse", [model.id, collapse])
}
function toggleCollapse() {
setCollapse(! collapsed)
}
function togglePresence(presence) {
if (model.presence === presence) presence = "online"
py.callClientCoro(model.id, "set_presence", [presence])
}
HShortcut { HShortcut {
enabled: enableKeybinds enabled: enableKeybinds
sequences: window.settings.keys.accountSettings sequences: window.settings.keys.accountSettings

View File

@ -5,17 +5,16 @@ import QtQuick.Layouts 1.12
import "../Base" import "../Base"
Rectangle { Rectangle {
// Hide filter field overflowing for a sec on size changes
clip: true
implicitHeight: theme.baseElementsHeight
color: theme.mainPane.bottomBar.background
property RoomList roomList property RoomList roomList
readonly property alias addAccountButton: addAccountButton readonly property alias addAccountButton: addAccountButton
readonly property alias filterField: filterField readonly property alias filterField: filterField
// Hide filter field overflowing for a sec on size changes
clip: true
implicitHeight: theme.baseElementsHeight
color: theme.mainPane.bottomBar.background
HRowLayout { HRowLayout {
anchors.fill: parent anchors.fill: parent

View File

@ -6,15 +6,11 @@ import "../Base"
HDrawer { HDrawer {
id: mainPane id: mainPane
saveName: "mainPane"
background: Rectangle { color: theme.mainPane.background }
minimumSize: theme.mainPane.minimumSize
readonly property alias accountBar: accountBar readonly property alias accountBar: accountBar
readonly property alias roomList: roomList readonly property alias roomList: roomList
readonly property alias bottomBar: bottomBar readonly property alias bottomBar: bottomBar
function toggleFocus() { function toggleFocus() {
if (bottomBar.filterField.activeFocus) { if (bottomBar.filterField.activeFocus) {
pageLoader.takeFocus() pageLoader.takeFocus()
@ -26,6 +22,10 @@ HDrawer {
} }
saveName: "mainPane"
background: Rectangle { color: theme.mainPane.background }
minimumSize: theme.mainPane.minimumSize
Behavior on opacity { HNumberAnimation {} } Behavior on opacity { HNumberAnimation {} }
Binding on visible { Binding on visible {

View File

@ -4,6 +4,13 @@ import QtQuick 2.12
import "../Base" import "../Base"
HLabel { HLabel {
property QtObject indicatorTheme
property int unreads: 0
property int highlights: 0
property bool localUnreads: false
property bool localHighlights: false
text: text:
unreads >= 1000000 ? Math.floor(unreads / 1000000) + "M" : unreads >= 1000000 ? Math.floor(unreads / 1000000) + "M" :
unreads >= 1000 ? Math.floor(unreads / 1000) + "K" : unreads >= 1000 ? Math.floor(unreads / 1000) + "K" :
@ -31,13 +38,5 @@ HLabel {
Behavior on color { HColorAnimation {} } Behavior on color { HColorAnimation {} }
} }
property QtObject indicatorTheme
property int unreads: 0
property int highlights: 0
property bool localUnreads: false
property bool localHighlights: false
Behavior on scale { HNumberAnimation {} } Behavior on scale { HNumberAnimation {} }
} }

View File

@ -9,6 +9,22 @@ import "../Base/HTile"
HTile { HTile {
id: room id: room
readonly property bool joined: ! invited && ! parted
readonly property bool invited: model.inviter_id && ! parted
readonly property bool parted: model.left
readonly property ListModel eventModel:
ModelStore.get(model.for_account, model.id, "events")
// FIXME: binding loop
readonly property QtObject accountModel:
ModelStore.get("accounts").find(model.for_account)
readonly property QtObject lastEvent:
eventModel.count > 0 ? eventModel.get(0) : null
backgroundColor: theme.mainPane.listView.room.background backgroundColor: theme.mainPane.listView.room.background
leftPadding: theme.spacing * 2 leftPadding: theme.spacing * 2
rightPadding: theme.spacing rightPadding: theme.spacing
@ -179,19 +195,4 @@ HTile {
}) })
} }
} }
readonly property bool joined: ! invited && ! parted
readonly property bool invited: model.inviter_id && ! parted
readonly property bool parted: model.left
readonly property ListModel eventModel:
ModelStore.get(model.for_account, model.id, "events")
// FIXME: binding loop
readonly property QtObject accountModel:
ModelStore.get("accounts").find(model.for_account)
readonly property QtObject lastEvent:
eventModel.count > 0 ? eventModel.get(0) : null
} }

View File

@ -8,83 +8,19 @@ import "../Base"
HListView { HListView {
id: roomList id: roomList
model: ModelStore.get("all_rooms")
delegate: DelegateChooser {
role: "type"
DelegateChoice {
roleValue: "Account"
AccountDelegate {
width: roomList.width
leftPadding: theme.spacing
rightPadding: 0 // the right buttons have padding
filterActive: Boolean(filter)
enableKeybinds: Boolean(
roomList.model.get(currentIndex) && (
roomList.model.get(currentIndex).for_account ||
roomList.model.get(currentIndex).id
) === model.id
)
totalMessageIndicator.visible: false
onLeftClicked: showItemAtIndex(model.index)
onCollapsedChanged:
if (wantedUserId === model.id) startCorrectItemSearch()
onWentToAccountPage: roomList.currentIndex = model.index
}
}
DelegateChoice {
roleValue: "Room"
RoomDelegate {
width: roomList.width
onLeftClicked: showItemAtIndex(model.index)
}
}
}
onFilterChanged: {
py.callCoro("set_substring_filter", ["all_rooms", filter], () => {
if (filter) {
currentIndex = 1 // highlight the first matching room
return
}
const item = model.get(currentIndex)
if (
! filter &&
item && (
currentIndex === 1 || // required, related to the if above
(
currentShouldBeAccount &&
wantedUserId !== item.id
) || (
currentShouldBeRoom && (
wantedUserId !== item.for_account ||
wantedRoomId !== item.id
)
)
)
)
startCorrectItemSearch()
})
}
property string filter: "" property string filter: ""
readonly property bool currentShouldBeAccount: readonly property bool currentShouldBeAccount:
window.uiState.page === "Pages/AccountSettings/AccountSettings.qml" || window.uiState.page === "Pages/AccountSettings/AccountSettings.qml" ||
window.uiState.page === "Pages/AddChat/AddChat.qml" window.uiState.page === "Pages/AddChat/AddChat.qml"
readonly property bool currentShouldBeRoom: readonly property bool currentShouldBeRoom:
window.uiState.page === "Pages/Chat/Chat.qml" window.uiState.page === "Pages/Chat/Chat.qml"
readonly property string wantedUserId: readonly property string wantedUserId:
window.uiState.pageProperties.userId || "" window.uiState.pageProperties.userId || ""
readonly property string wantedRoomId: readonly property string wantedRoomId:
window.uiState.pageProperties.roomId || "" window.uiState.pageProperties.roomId || ""
@ -99,7 +35,6 @@ HListView {
return accounts return accounts
} }
function goToAccount(userId) { function goToAccount(userId) {
accountIndice[userId] + 1 <= model.count -1 && accountIndice[userId] + 1 <= model.count -1 &&
model.get(accountIndice[userId] + 1).type === "Room" ? model.get(accountIndice[userId] + 1).type === "Room" ?
@ -200,6 +135,73 @@ HListView {
} }
model: ModelStore.get("all_rooms")
delegate: DelegateChooser {
role: "type"
DelegateChoice {
roleValue: "Account"
AccountDelegate {
width: roomList.width
leftPadding: theme.spacing
rightPadding: 0 // the right buttons have padding
filterActive: Boolean(filter)
enableKeybinds: Boolean(
roomList.model.get(currentIndex) && (
roomList.model.get(currentIndex).for_account ||
roomList.model.get(currentIndex).id
) === model.id
)
totalMessageIndicator.visible: false
onLeftClicked: showItemAtIndex(model.index)
onCollapsedChanged:
if (wantedUserId === model.id) startCorrectItemSearch()
onWentToAccountPage: roomList.currentIndex = model.index
}
}
DelegateChoice {
roleValue: "Room"
RoomDelegate {
width: roomList.width
onLeftClicked: showItemAtIndex(model.index)
}
}
}
onFilterChanged: {
py.callCoro("set_substring_filter", ["all_rooms", filter], () => {
if (filter) {
currentIndex = 1 // highlight the first matching room
return
}
const item = model.get(currentIndex)
if (
! filter &&
item && (
currentIndex === 1 || // required, related to the if above
(
currentShouldBeAccount &&
wantedUserId !== item.id
) || (
currentShouldBeRoom && (
wantedUserId !== item.for_account ||
wantedRoomId !== item.id
)
)
)
)
startCorrectItemSearch()
})
}
Connections { Connections {
target: pageLoader target: pageLoader

View File

@ -6,22 +6,17 @@ import "PythonBridge"
QtObject { QtObject {
property QtObject privates: QtObject { property QtObject privates: QtObject {
onEnsureModelExists:
py.callCoro("models.ensure_exists_from_qml", [modelId])
signal ensureModelExists(var modelId)
readonly property var store: ({}) readonly property var store: ({})
readonly property PythonBridge py: PythonBridge {} readonly property PythonBridge py: PythonBridge {}
readonly property Component model: Component { readonly property Component model: Component {
ListModel { ListModel {
property var modelId
// Used by HFilterModel // Used by HFilterModel
signal fieldsChanged(int index, var changes) signal fieldsChanged(int index, var changes)
property var modelId
function findIndex(id, default_=null) { function findIndex(id, default_=null) {
for (let i = 0; i < count; i++) for (let i = 0; i < count; i++)
if (get(i).id === id) return i if (get(i).id === id) return i
@ -37,6 +32,11 @@ QtObject {
} }
} }
} }
signal ensureModelExists(var modelId)
onEnsureModelExists:
py.callCoro("models.ensure_exists_from_qml", [modelId])
} }

View File

@ -10,31 +10,6 @@ import "MainPane"
HLoader { HLoader {
id: pageLoader id: pageLoader
clip: appearAnimation.running
onLoaded: { takeFocus(); appearAnimation.start() }
Component.onCompleted: {
if (! py.startupAnyAccountsSaved) {
pageLoader.showPage(
"AddAccount/AddAccount", {"header.show": false},
)
return
}
const page = window.uiState.page
const props = window.uiState.pageProperties
if (page === "Pages/Chat/Chat.qml") {
pageLoader.showRoom(props.userId, props.roomId)
} else {
pageLoader._show(page, props)
}
}
signal previousShown(string componentUrl, var properties)
property bool isWide: width > theme.contentIsWideAbove property bool isWide: width > theme.contentIsWideAbove
@ -44,6 +19,7 @@ HLoader {
readonly property alias appearAnimation: appearAnimation readonly property alias appearAnimation: appearAnimation
signal previousShown(string componentUrl, var properties)
function _show(componentUrl, properties={}) { function _show(componentUrl, properties={}) {
history.unshift([componentUrl, properties]) history.unshift([componentUrl, properties])
@ -90,6 +66,28 @@ HLoader {
} }
clip: appearAnimation.running
onLoaded: { takeFocus(); appearAnimation.start() }
Component.onCompleted: {
if (! py.startupAnyAccountsSaved) {
pageLoader.showPage(
"AddAccount/AddAccount", {"header.show": false},
)
return
}
const page = window.uiState.page
const props = window.uiState.pageProperties
if (page === "Pages/Chat/Chat.qml") {
pageLoader.showRoom(props.userId, props.roomId)
} else {
pageLoader._show(page, props)
}
}
HNumberAnimation { HNumberAnimation {
id: appearAnimation id: appearAnimation
target: pageLoader.item target: pageLoader.item

View File

@ -11,12 +11,10 @@ import "../../Dialogs"
HFlickableColumnPage { HFlickableColumnPage {
id: page id: page
property string userId property string userId
readonly property QtObject account: ModelStore.get("accounts").find(userId) readonly property QtObject account: ModelStore.get("accounts").find(userId)
readonly property bool ready: account && account.profile_updated >= new Date(1) readonly property bool ready: account && account.profile_updated >= new Date(1)
function takeFocus() { function takeFocus() {
nameField.item.forceActiveFocus() nameField.item.forceActiveFocus()
} }
@ -90,11 +88,11 @@ HFlickableColumnPage {
onKeyboardCancel: cancel() onKeyboardCancel: cancel()
onKeyboardAccept: applyChanges() onKeyboardAccept: applyChanges()
HUserAvatar { HUserAvatar {
id: avatar
property bool changed: Boolean(sourceOverride) property bool changed: Boolean(sourceOverride)
id: avatar
userId: page.userId userId: page.userId
displayName: nameField.item.text displayName: nameField.item.text
mxc: account ? account.avatar_url : "" mxc: account ? account.avatar_url : ""
@ -231,6 +229,8 @@ HFlickableColumnPage {
} }
HLabeledItem { HLabeledItem {
id: aliasField
readonly property var aliases: window.settings.writeAliases readonly property var aliases: window.settings.writeAliases
readonly property string currentAlias: aliases[userId] || "" readonly property string currentAlias: aliases[userId] || ""
@ -243,9 +243,6 @@ HFlickableColumnPage {
return "" return ""
} }
id: aliasField
label.text: qsTr("Composer alias:") label.text: qsTr("Composer alias:")
errorLabel.text: errorLabel.text:

View File

@ -9,7 +9,6 @@ import "../../Base"
HPage { HPage {
id: page id: page
property string userId property string userId

View File

@ -9,7 +9,6 @@ import "../../Base/HTile"
HTile { HTile {
id: deviceTile id: deviceTile
property HListView view property HListView view
property string userId property string userId

View File

@ -15,6 +15,7 @@ HRowLayout {
readonly property int sectionTotalCount: readonly property int sectionTotalCount:
deviceList.sectionItemCounts[section] || 0 deviceList.sectionItemCounts[section] || 0
HCheckBox { HCheckBox {
id: checkBox id: checkBox
padding: theme.spacing padding: theme.spacing

View File

@ -8,10 +8,8 @@ import "../../Base/Buttons"
HFlickableColumnPage { HFlickableColumnPage {
id: page id: page
property string userId property string userId
function takeFocus() { exportButton.forceActiveFocus() } function takeFocus() { exportButton.forceActiveFocus() }

View File

@ -11,15 +11,6 @@ import "../../ShortcutBundles"
HColumnPage { HColumnPage {
id: page id: page
enabled: ModelStore.get("accounts").find(userId).presence !== "offline"
contentHeight: Math.min(
window.height,
Math.max(
deviceList.contentHeight + deviceList.bottomMargin,
busyIndicatorLoader.height + theme.spacing * 2,
)
)
property string userId property string userId
@ -28,7 +19,6 @@ HColumnPage {
property Future loadFuture: null property Future loadFuture: null
function takeFocus() {} // TODO function takeFocus() {} // TODO
function loadDevices() { function loadDevices() {
@ -100,6 +90,15 @@ HColumnPage {
} }
enabled: ModelStore.get("accounts").find(userId).presence !== "offline"
contentHeight: Math.min(
window.height,
Math.max(
deviceList.contentHeight + deviceList.bottomMargin,
busyIndicatorLoader.height + theme.spacing * 2,
)
)
footer: AutoDirectionLayout { footer: AutoDirectionLayout {
GroupButton { GroupButton {
id: refreshButton id: refreshButton
@ -126,7 +125,6 @@ HColumnPage {
Keys.forwardTo: [deviceList] Keys.forwardTo: [deviceList]
HListView { HListView {
id: deviceList id: deviceList

View File

@ -20,7 +20,6 @@ HFlickableColumnPage {
} }
} }
HLabel { HLabel {
wrapMode: Text.Wrap wrapMode: Text.Wrap
horizontalAlignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter

View File

@ -21,7 +21,6 @@ HFlickableColumnPage {
} }
} }
HLabel { HLabel {
wrapMode: Text.Wrap wrapMode: Text.Wrap
horizontalAlignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter

View File

@ -8,7 +8,6 @@ import "../../Base/Buttons"
HFlickableColumnPage { HFlickableColumnPage {
id: page id: page
property var loginFuture: null property var loginFuture: null
property string signInWith: "username" property string signInWith: "username"
@ -17,7 +16,6 @@ HFlickableColumnPage {
serverField.item.text.trim() && idField.item.text.trim() && serverField.item.text.trim() && idField.item.text.trim() &&
passwordField.item.text && ! serverField.item.error passwordField.item.text && ! serverField.item.error
function takeFocus() { idField.item.forceActiveFocus() } function takeFocus() { idField.item.forceActiveFocus() }
function signIn() { function signIn() {
@ -95,7 +93,6 @@ HFlickableColumnPage {
onKeyboardAccept: page.signIn() onKeyboardAccept: page.signIn()
onKeyboardCancel: page.cancel() onKeyboardCancel: page.cancel()
Timer { Timer {
id: signInTimeout id: signInTimeout
interval: 30 * 1000 interval: 30 * 1000
@ -190,11 +187,11 @@ HFlickableColumnPage {
Layout.fillWidth: true Layout.fillWidth: true
HTextField { HTextField {
readonly property string cleanText: text.toLowerCase().trim()
width: parent.width width: parent.width
text: "https://matrix.org" text: "https://matrix.org"
error: ! /.+:\/\/.+/.test(cleanText) error: ! /.+:\/\/.+/.test(cleanText)
readonly property string cleanText: text.toLowerCase().trim()
} }
} }

View File

@ -7,7 +7,6 @@ import "../../Base"
HPage { HPage {
id: page id: page
property string userId property string userId

View File

@ -8,13 +8,10 @@ import "../../Base/Buttons"
HFlickableColumnPage { HFlickableColumnPage {
id: page id: page
enabled: account && account.presence !== "offline"
property string userId property string userId
readonly property QtObject account: ModelStore.get("accounts").find(userId) readonly property QtObject account: ModelStore.get("accounts").find(userId)
function takeFocus() { nameField.item.forceActiveFocus() } function takeFocus() { nameField.item.forceActiveFocus() }
function create() { function create() {
@ -52,6 +49,8 @@ HFlickableColumnPage {
} }
enabled: account && account.presence !== "offline"
footer: AutoDirectionLayout { footer: AutoDirectionLayout {
ApplyButton { ApplyButton {
id: applyButton id: applyButton
@ -68,7 +67,6 @@ HFlickableColumnPage {
onKeyboardAccept: create() onKeyboardAccept: create()
onKeyboardCancel: cancel() onKeyboardCancel: cancel()
HRoomAvatar { HRoomAvatar {
id: avatar id: avatar
roomId: "" roomId: ""

View File

@ -7,6 +7,7 @@ import "../../Base"
HUserAvatar { HUserAvatar {
property QtObject account property QtObject account
// userId: (set me) // userId: (set me)
displayName: account ? account.display_name : "" displayName: account ? account.display_name : ""
mxc: account ? account.avatar_url : "" mxc: account ? account.avatar_url : ""

View File

@ -8,13 +8,10 @@ import "../../Base/Buttons"
HFlickableColumnPage { HFlickableColumnPage {
id: page id: page
enabled: account && account.presence !== "offline"
property string userId property string userId
readonly property QtObject account: ModelStore.get("accounts").find(userId) readonly property QtObject account: ModelStore.get("accounts").find(userId)
function takeFocus() { function takeFocus() {
userField.item.forceActiveFocus() userField.item.forceActiveFocus()
} }
@ -64,6 +61,8 @@ HFlickableColumnPage {
} }
enabled: account && account.presence !== "offline"
footer: AutoDirectionLayout { footer: AutoDirectionLayout {
ApplyButton { ApplyButton {
id: applyButton id: applyButton
@ -85,7 +84,6 @@ HFlickableColumnPage {
onKeyboardAccept: startChat() onKeyboardAccept: startChat()
onKeyboardCancel: cancel() onKeyboardCancel: cancel()
CurrentUserAvatar { CurrentUserAvatar {
userId: page.userId userId: page.userId
account: page.account account: page.account

View File

@ -5,11 +5,11 @@ import "../../Base"
HCheckBox { HCheckBox {
text: qsTr("Encrypt messages") text: qsTr("Encrypt messages")
subtitle.textFormat: Text.StyledText
subtitle.text: subtitle.text:
qsTr("Only you and those you trust will be able to read the " + qsTr("Only you and those you trust will be able to read the " +
"conversation") + "conversation") +
`<br><font color="${theme.colors.warningText}">` + `<br><font color="${theme.colors.warningText}">` +
qsTr("Cannot be disabled later!") + qsTr("Cannot be disabled later!") +
"</font>" "</font>"
subtitle.textFormat: Text.StyledText
} }

View File

@ -8,13 +8,10 @@ import "../../Base/Buttons"
HFlickableColumnPage { HFlickableColumnPage {
id: page id: page
enabled: account && account.presence !== "offline"
property string userId property string userId
readonly property QtObject account: ModelStore.get("accounts").find(userId) readonly property QtObject account: ModelStore.get("accounts").find(userId)
function takeFocus() { function takeFocus() {
roomField.item.forceActiveFocus() roomField.item.forceActiveFocus()
} }
@ -57,6 +54,8 @@ HFlickableColumnPage {
} }
enabled: account && account.presence !== "offline"
footer: AutoDirectionLayout { footer: AutoDirectionLayout {
ApplyButton { ApplyButton {
id: joinButton id: joinButton
@ -74,7 +73,6 @@ HFlickableColumnPage {
onKeyboardAccept: join() onKeyboardAccept: join()
onKeyboardCancel: cancel() onKeyboardCancel: cancel()
CurrentUserAvatar { CurrentUserAvatar {
userId: page.userId userId: page.userId
account: page.account account: page.account

View File

@ -6,8 +6,6 @@ import "../../../Base"
Rectangle { Rectangle {
id: banner id: banner
implicitHeight: childrenRect.height
color: theme.controls.box.background
property alias avatar: bannerAvatar property alias avatar: bannerAvatar
property alias icon: bannerIcon property alias icon: bannerIcon
@ -15,6 +13,10 @@ Rectangle {
property alias buttonModel: bannerRepeater.model property alias buttonModel: bannerRepeater.model
property var buttonCallbacks: [] property var buttonCallbacks: []
implicitHeight: childrenRect.height
color: theme.controls.box.background
HGridLayout { HGridLayout {
id: bannerGrid id: bannerGrid
width: parent.width width: parent.width

View File

@ -8,6 +8,7 @@ Banner {
property string inviterName: chat.roomInfo.inviter_name property string inviterName: chat.roomInfo.inviter_name
property string inviterAvatar: chat.roomInfo.inviter_avatar property string inviterAvatar: chat.roomInfo.inviter_avatar
color: theme.chat.inviteBanner.background color: theme.chat.inviteBanner.background
avatar.userId: inviterId avatar.userId: inviterId

View File

@ -9,10 +9,6 @@ import "RoomPane"
Item { Item {
id: chat id: chat
onFocusChanged: if (focus && loader.item) loader.item.composer.takeFocus()
onReadyChanged: longLoading = false
property string userId property string userId
property string roomId property string roomId
@ -33,6 +29,9 @@ Item {
Boolean(loader.item && loader.item.composer.hasFocus) Boolean(loader.item && loader.item.composer.hasFocus)
onFocusChanged: if (focus && loader.item) loader.item.composer.takeFocus()
onReadyChanged: longLoading = false
HShortcut { HShortcut {
sequences: window.settings.keys.leaveRoom sequences: window.settings.keys.leaveRoom
active: userInfo && userInfo.presence !== "offline" active: userInfo && userInfo.presence !== "offline"

View File

@ -10,12 +10,6 @@ import "Timeline"
HColumnPage { HColumnPage {
id: chatPage id: chatPage
padding: 0
column.spacing: 0
onLoadEventListChanged: if (loadEventList) loadedOnce = true
Component.onDestruction: if (loadMembersFuture) loadMembersFuture.cancel()
property bool loadedOnce: false property bool loadedOnce: false
property var loadMembersFuture: null property var loadMembersFuture: null
@ -26,6 +20,12 @@ HColumnPage {
! mainUI.mainPane.visible : ! pageLoader.appearAnimation.running ! mainUI.mainPane.visible : ! pageLoader.appearAnimation.running
padding: 0
column.spacing: 0
onLoadEventListChanged: if (loadEventList) loadedOnce = true
Component.onDestruction: if (loadMembersFuture) loadMembersFuture.cancel()
Timer { Timer {
interval: 200 interval: 200
running: true running: true

View File

@ -8,7 +8,6 @@ Rectangle {
property alias eventList: messageArea.eventList property alias eventList: messageArea.eventList
readonly property bool hasFocus: messageArea.activeFocus readonly property bool hasFocus: messageArea.activeFocus
function takeFocus() { messageArea.forceActiveFocus() } function takeFocus() { messageArea.forceActiveFocus() }
@ -17,7 +16,6 @@ Rectangle {
color: theme.chat.composer.background color: theme.chat.composer.background
HRowLayout { HRowLayout {
anchors.fill: parent anchors.fill: parent

View File

@ -7,7 +7,6 @@ import "../../../Base"
HTextArea { HTextArea {
id: textArea id: textArea
property HListView eventList property HListView eventList
property string indent: " " property string indent: " "
@ -50,7 +49,6 @@ HTextArea {
return obj return obj
} }
function setTyping(typing) { function setTyping(typing) {
py.callClientCoro( py.callClientCoro(
writingUserId, "room_typing", [chat.roomId, typing, 5000], writingUserId, "room_typing", [chat.roomId, typing, 5000],

View File

@ -19,7 +19,6 @@ HButton {
onClicked: sendFilePicker.dialog.open() onClicked: sendFilePicker.dialog.open()
HShortcut { HShortcut {
sequences: window.settings.keys.sendFileFromPathInClipboard sequences: window.settings.keys.sendFileFromPathInClipboard
onActivated: utils.sendFile( onActivated: utils.sendFile(

View File

@ -8,7 +8,6 @@ import "../../../Base"
HColumnLayout { HColumnLayout {
id: transfer id: transfer
property bool cancelPending: false property bool cancelPending: false
property int msLeft: model.time_left property int msLeft: model.time_left
@ -18,7 +17,6 @@ HColumnLayout {
readonly property string status: model.status readonly property string status: model.status
readonly property bool paused: model.paused readonly property bool paused: model.paused
function cancel() { function cancel() {
cancelPending = true cancelPending = true
// Python will delete this model item on cancel // Python will delete this model item on cancel
@ -51,6 +49,15 @@ HColumnLayout {
HLabel { HLabel {
id: statusLabel id: statusLabel
property bool expand: status === "Error"
readonly property string fileName:
model.filepath.split("/").slice(-1)[0]
readonly property string filePath:
model.filepath.replace(/^file:\/\//, "")
elide: expand ? Text.ElideNone : Text.ElideRight elide: expand ? Text.ElideNone : Text.ElideRight
wrapMode: expand ? Text.Wrap : Text.NoWrap wrapMode: expand ? Text.Wrap : Text.NoWrap
@ -92,16 +99,6 @@ HColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
property bool expand: status === "Error"
readonly property string fileName:
model.filepath.split("/").slice(-1)[0]
readonly property string filePath:
model.filepath.replace(/^file:\/\//, "")
HoverHandler { id: statusLabelHover } HoverHandler { id: statusLabelHover }
HToolTip { HToolTip {

View File

@ -5,13 +5,6 @@ import "../../.."
import "../../../Base" import "../../../Base"
Rectangle { Rectangle {
implicitWidth: 800
implicitHeight: firstDelegate ? firstDelegate.height : 0
color: theme.chat.fileTransfer.background
opacity: implicitHeight ? 1 : 0
clip: true
property int delegateHeight: 0 property int delegateHeight: 0
readonly property var firstDelegate: readonly property var firstDelegate:
@ -20,6 +13,12 @@ Rectangle {
readonly property alias transferCount: transferList.count readonly property alias transferCount: transferList.count
implicitWidth: 800
implicitHeight: firstDelegate ? firstDelegate.height : 0
color: theme.chat.fileTransfer.background
opacity: implicitHeight ? 1 : 0
clip: true
Behavior on implicitHeight { HNumberAnimation {} } Behavior on implicitHeight { HNumberAnimation {} }
HListView { HListView {

View File

@ -5,15 +5,15 @@ import QtQuick.Layouts 1.12
import "../../Base" import "../../Base"
Rectangle { Rectangle {
implicitHeight: label.text ? rowLayout.height : 0 default property alias rowLayoutData: rowLayout.data
opacity: implicitHeight ? 1 : 0
readonly property alias icon: icon readonly property alias icon: icon
readonly property alias label: label readonly property alias label: label
default property alias rowLayoutData: rowLayout.data
implicitHeight: label.text ? rowLayout.height : 0
opacity: implicitHeight ? 1 : 0
Behavior on implicitHeight { HNumberAnimation {} } Behavior on implicitHeight { HNumberAnimation {} }
HRowLayout { HRowLayout {

View File

@ -5,6 +5,13 @@ import QtQuick.Layouts 1.12
import "../../Base" import "../../Base"
InfoBar { InfoBar {
property string replyToEventId: ""
property string replyToUserId: ""
property string replyToDisplayName: ""
signal cancel()
color: theme.chat.replyBar.background color: theme.chat.replyBar.background
icon.svgName: "reply-to" icon.svgName: "reply-to"
label.textFormat: Text.StyledText label.textFormat: Text.StyledText
@ -13,15 +20,6 @@ InfoBar {
utils.coloredNameHtml(replyToDisplayName, replyToUserId) : utils.coloredNameHtml(replyToDisplayName, replyToUserId) :
"" ""
signal cancel()
property string replyToEventId: ""
property string replyToUserId: ""
property string replyToDisplayName: ""
HButton { HButton {
backgroundColor: "transparent" backgroundColor: "transparent"
icon.name: "reply-cancel" icon.name: "reply-cancel"

View File

@ -5,16 +5,15 @@ import QtQuick.Layouts 1.12
import "../../Base" import "../../Base"
Rectangle { Rectangle {
implicitHeight: theme.baseElementsHeight
color: theme.chat.roomHeader.background
readonly property bool showPaneButtons: mainUI.mainPane.collapse readonly property bool showPaneButtons: mainUI.mainPane.collapse
readonly property bool center: readonly property bool center:
showPaneButtons || window.settings.alwaysCenterRoomHeader showPaneButtons || window.settings.alwaysCenterRoomHeader
implicitHeight: theme.baseElementsHeight
color: theme.chat.roomHeader.background
HRowLayout { HRowLayout {
id: row id: row
anchors.fill: parent anchors.fill: parent
@ -113,16 +112,16 @@ Rectangle {
} }
HToolTip { HToolTip {
visible: text && (nameHover.hovered || topicHover.hovered)
label.textFormat: Text.StyledText
text: name && topic ? (`${name}<br>${topic}`) : (name || topic)
readonly property string name: readonly property string name:
nameLabel.truncated ? nameLabel.truncated ?
(`<b>${chat.roomInfo.display_name}</b>`) : "" (`<b>${chat.roomInfo.display_name}</b>`) : ""
readonly property string topic: readonly property string topic:
topicLabel.truncated ? chat.roomInfo.topic : "" topicLabel.truncated ? chat.roomInfo.topic : ""
visible: text && (nameHover.hovered || topicHover.hovered)
label.textFormat: Text.StyledText
text: name && topic ? (`${name}<br>${topic}`) : (name || topic)
} }
HSpacer { HSpacer {

View File

@ -8,7 +8,6 @@ import "../../../../Base/Buttons"
HFlickableColumnPage { HFlickableColumnPage {
id: page id: page
property string deviceOwner property string deviceOwner
property string deviceOwnerDisplayName property string deviceOwnerDisplayName
property string deviceId property string deviceId
@ -20,7 +19,6 @@ HFlickableColumnPage {
signal trustSet(bool trust) signal trustSet(bool trust)
function close() { function close() {
if (previouslyFocused) previouslyFocused.forceActiveFocus() if (previouslyFocused) previouslyFocused.forceActiveFocus()
stackView.pop() stackView.pop()
@ -72,7 +70,6 @@ HFlickableColumnPage {
onKeyboardCancel: page.close() onKeyboardCancel: page.close()
HRowLayout { HRowLayout {
HButton { HButton {
id: closeButton id: closeButton

View File

@ -9,6 +9,7 @@ import "../../../../Popups"
HTile { HTile {
id: member id: member
backgroundColor: theme.chat.roomPane.listView.member.background backgroundColor: theme.chat.roomPane.listView.member.background
contentOpacity: contentOpacity:
model.invited ? theme.chat.roomPane.listView.member.invitedOpacity : 1 model.invited ? theme.chat.roomPane.listView.member.invitedOpacity : 1
@ -142,7 +143,6 @@ HTile {
} }
} }
Behavior on contentOpacity { HNumberAnimation {} } Behavior on contentOpacity { HNumberAnimation {} }
Behavior on spacing { HNumberAnimation {} } Behavior on spacing { HNumberAnimation {} }

View File

@ -8,13 +8,11 @@ import "../../../../Base"
HListView { HListView {
id: profile id: profile
property string userId property string userId
property string roomId property string roomId
property QtObject member // RoomMember model item property QtObject member // RoomMember model item
property HStackView stackView property HStackView stackView
function loadDevices() { function loadDevices() {
py.callClientCoro(userId, "member_devices", [member.id], devices => { py.callClientCoro(userId, "member_devices", [member.id], devices => {
profile.model.clear() profile.model.clear()
@ -211,7 +209,6 @@ HListView {
} }
Keys.onEscapePressed: stackView.pop() Keys.onEscapePressed: stackView.pop()
Connections { Connections {
target: py.eventHandlers target: py.eventHandlers

View File

@ -10,6 +10,7 @@ HColumnLayout {
readonly property var modelSyncId: readonly property var modelSyncId:
[chat.userId, chat.roomId, "filtered_members"] [chat.userId, chat.roomId, "filtered_members"]
HStackView { HStackView {
id: stackView id: stackView

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