d81bf48984
This fixes the weird dialog not getting a press but just closing problem which seems to stem from the horizontal listview getting its current index set. So we just avoid doing that. This fixes the bug in the last release where not having the payments tab visible meant we didn't see the tabbar at all. The logic is now fixed to include the fact that we can have a tokens tab too.
233 lines
7.7 KiB
QML
233 lines
7.7 KiB
QML
/*
|
|
* This file is part of the Flowee project
|
|
* Copyright (C) 2023-2026 Tom Zander <tom@flowee.org>
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
import QtQuick
|
|
import QtQuick.Controls.Basic as QQC2
|
|
import "../Flowee" as Flowee
|
|
import "../Utils.js" as Utils
|
|
import Flowee.org.pay
|
|
|
|
Item {
|
|
property string icon: "qrc:/homeButtonIcon" + (Pay.useDarkSkin ? "-light.svg" : ".svg")
|
|
property string title: qsTr("Home")
|
|
property bool showFilterIcon: tabBar.currentIndex === 0
|
|
property bool showAllWalletsOption: tabBar.currentIndex !== 0
|
|
required property bool allWalletsEntrySelected
|
|
|
|
property bool itIsChristmas: {
|
|
var today = new Date()
|
|
return today.getMonth() == 11 && today.getDate() >= 24 && today.getDate() <= 31
|
|
}
|
|
|
|
Rectangle {
|
|
id: headerBg
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
anchors.top: parent.top
|
|
anchors.bottom: tabBar.bottom
|
|
anchors.bottomMargin: -6
|
|
color: palette.window
|
|
property var headerGradient: Gradient {
|
|
GradientStop { position: 0.93; color: headerBg.color }
|
|
GradientStop { position: 1; color: {
|
|
let c = headerBg.color
|
|
return Qt.rgba(c.r, c.g, c.b, 0)
|
|
}
|
|
}
|
|
}
|
|
gradient: tabBar.visible ? undefined : headerGradient
|
|
}
|
|
|
|
ListView {
|
|
id: tabBar
|
|
orientation: Qt.Horizontal
|
|
width: parent.width
|
|
height: {
|
|
if (!visible || count <= 1 || currentItem === null)
|
|
return 0
|
|
return currentItem.height
|
|
}
|
|
property bool havePlannedTab: Pay.haveRepeatPayments
|
|
property bool haveTokensTab: tokens.showTokenTab !== Wallet.AlwaysOff
|
|
visible: count > 1
|
|
|
|
function selectTab(index) {
|
|
// fast move
|
|
activityTabs.positionViewAtIndex(index, ListView.Beginning)
|
|
// slow scroll
|
|
currentIndex = index
|
|
}
|
|
|
|
clip: true
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
model: ListModel {
|
|
id: tabsModel
|
|
ListElement {
|
|
title: qsTr("Activity")
|
|
qml: "AccountHistory.qml"
|
|
}
|
|
}
|
|
onHavePlannedTabChanged: {
|
|
if (!havePlannedTab)
|
|
return
|
|
tabBar.selectTab(0)
|
|
for (let i = 1; i < tabsModel.count; ++i) {
|
|
let tab = tabsModel.get(i)
|
|
if (tab.qml === "PlannedPayments.qml")
|
|
return
|
|
}
|
|
tabsModel.append({ title: qsTr("Planned"), qml: "PlannedPayments.qml" })
|
|
}
|
|
onHaveTokensTabChanged: {
|
|
tabBar.selectTab(0)
|
|
for (let i = 1; i < tabsModel.count; ++i) {
|
|
let tab = tabsModel.get(i)
|
|
if (tab.qml === "TokensTab.qml") {
|
|
if (!haveTokensTab)
|
|
tabsModel.remove(i)
|
|
return
|
|
}
|
|
}
|
|
if (haveTokensTab)
|
|
tabsModel.insert(1, { title: qsTr("Tokens"), qml: "TokensTab.qml" })
|
|
}
|
|
|
|
delegate: Item {
|
|
width: Math.max(tabName.width, 120)
|
|
height: tabName.height + 20
|
|
|
|
Rectangle {
|
|
x: 5
|
|
height: 4
|
|
width: parent.width - 10
|
|
color: palette.highlight
|
|
visible: index === tabBar.currentIndex
|
|
anchors.bottom: parent.bottom
|
|
}
|
|
Rectangle {
|
|
anchors.fill: parent
|
|
color: palette.highlight
|
|
visible: index === tabBar.currentIndex
|
|
opacity: 0.15
|
|
}
|
|
|
|
Text {
|
|
id: tabName
|
|
color: palette.windowText
|
|
text: model.title
|
|
anchors.centerIn: parent
|
|
}
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: tabBar.selectTab(index)
|
|
}
|
|
}
|
|
}
|
|
Rectangle {
|
|
color: palette.base // background is dark.
|
|
anchors.fill: activityTabs
|
|
}
|
|
ListView {
|
|
id: activityTabs
|
|
anchors.top: tabBar.bottom
|
|
anchors.topMargin: tabBar.visible ? 0 : 6
|
|
anchors.bottom: parent.bottom
|
|
width: parent.width
|
|
model: tabBar.model
|
|
|
|
orientation: ListView.Horizontal
|
|
snapMode: ListView.SnapOneItem
|
|
onContentXChanged: tabBar.currentIndex = Math.round(contentX / width)
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
onCurrentItemChanged: currentItem.makeActive()
|
|
delegate: Loader {
|
|
id: delegateRoot
|
|
width: activityTabs.width
|
|
height: activityTabs.height
|
|
clip: true
|
|
source: model.qml
|
|
function makeActive() {
|
|
if (item != null) {
|
|
if (typeof(item.active) != "undefined")
|
|
item.active = true
|
|
item.forceActiveFocus()
|
|
}
|
|
}
|
|
Connections {
|
|
target: tabBar
|
|
function onCurrentIndexChanged() {
|
|
// let a tab know if it is currently active.
|
|
// as the user can slide between them, we can't use visible and tabs have
|
|
// a right to know if they are actually visible.
|
|
if (item != null && typeof(item.active) != "undefined")
|
|
item.active = index == tabBar.currentIndex
|
|
}
|
|
}
|
|
}
|
|
}
|
|
Rectangle {
|
|
id: startQRButton
|
|
width: height
|
|
height: {
|
|
let i = activityTabs.itemAtIndex(tabBar.currentIndex)
|
|
if (i != null && i.item !== null) { // at creation this is the case.
|
|
let hide = i.item.hideQRScanButton
|
|
if (typeof(hide) === "boolean" && hide)
|
|
return 0
|
|
}
|
|
return 70
|
|
}
|
|
radius: 35
|
|
clip: true
|
|
x: parent.width - width - 30 - (70 / 2 - width / 2) // almost right, but keep this centered around the max width
|
|
y: parent.height - height - 15 - (70 / 2 - height / 2)
|
|
color: mainWindow.floweeBlue
|
|
|
|
Image {
|
|
source: "qrc:/qr-code-scan-light.svg"
|
|
anchors.centerIn: parent
|
|
width: 40
|
|
height: 40
|
|
}
|
|
MouseArea {
|
|
anchors.fill: parent
|
|
onClicked: thePile.push("ScanQRPage.qml")
|
|
}
|
|
Behavior on height { NumberAnimation { } }
|
|
}
|
|
|
|
Keys.onPressed: (event)=> {
|
|
if (event.key === Qt.Key_Escape || event.key === Qt.Key_Back) {
|
|
// when we are on another tab, we can go to 'main' on back.
|
|
if (tabBar.currentIndex !== 0) {
|
|
event.accepted = true
|
|
tabBar.selectTab(0)
|
|
}
|
|
}
|
|
}
|
|
|
|
// should the app be started with the intent to open the "Planned Payment" screen,
|
|
// we handle that here.
|
|
Connections {
|
|
target: intent
|
|
function onGenericIntentChanged() { // it only ever changes at most once
|
|
if (intent.genericIntent === Intent.OpenPlannedPaymentScreen)
|
|
tabBar.selectTab(1)
|
|
}
|
|
}
|
|
}
|