calendario 30 giorni: pagina con alte/basse per ogni giorno, dal menu del dettaglio (EN/IT)

This commit is contained in:
2026-09-02 12:47:46 +02:00
parent a246c8db12
commit e9154f6eef
4 changed files with 117 additions and 0 deletions
+96
View File
@@ -0,0 +1,96 @@
import QtQuick 2.0
import Sailfish.Silica 1.0
import "../js/tides.js" as Tides
// Calendario maree: i prossimi 30 giorni con le ore di alta e bassa marea.
Page {
id: page
property var port
SilicaListView {
id: list
anchors.fill: parent
model: ListModel { id: dayModel }
header: PageHeader {
title: page.port ? page.port[0] : ""
description: qsTr("Next 30 days — high and low tides")
}
delegate: Item {
width: parent.width
height: model.isDay ? Theme.itemSizeSmall : Theme.itemSizeSmall * 0.8
// riga del giorno
Rectangle {
visible: model.isDay
anchors.fill: parent
color: Theme.rgba(Theme.highlightBackgroundColor, 0.2)
Label {
text: model.day
anchors.left: parent.left
anchors.leftMargin: Theme.horizontalPageMargin
anchors.verticalCenter: parent.verticalCenter
color: Theme.highlightColor
font.pixelSize: Theme.fontSizeSmall
}
}
// riga evento (alta/bassa)
Label {
visible: !model.isDay
text: model.kind === "high" ? "▲" : "▼"
color: model.kind === "high" ? Theme.highlightColor : Theme.errorColor
font.pixelSize: Theme.fontSizeSmall
anchors.left: parent.left
anchors.leftMargin: Theme.horizontalPageMargin
anchors.verticalCenter: parent.verticalCenter
}
Label {
visible: !model.isDay
text: model.time
color: Theme.primaryColor
anchors.left: parent.left
anchors.leftMargin: Theme.horizontalPageMargin + 36
anchors.verticalCenter: parent.verticalCenter
}
Label {
visible: !model.isDay
text: model.height
color: Theme.secondaryColor
font.pixelSize: Theme.fontSizeSmall
anchors.right: parent.right
anchors.rightMargin: Theme.horizontalPageMargin
anchors.verticalCenter: parent.verticalCenter
}
}
VerticalScrollDecorator {}
}
Component.onCompleted: build()
function build() {
dayModel.clear()
if (!port) {
console.log("[tide] calendar: port undefined")
return
}
console.log("[tide] calendar build:", port[0])
var now = new Date()
for (var g = 0; g < 30; g++) {
var d = new Date(now.getFullYear(), now.getMonth(), now.getDate() + g)
var ex = Tides.extrema(port, d, 1)
dayModel.append({ isDay: true, day: Tides.fmtDate(d.getTime()),
time: "", kind: "", height: "" })
for (var i = 0; i < ex.length; i++) {
dayModel.append({ isDay: false, day: "",
time: Tides.fmtHM(ex[i].t),
kind: ex[i].kind,
height: Tides.fmtH(ex[i].h, appSettings.unit) })
}
}
console.log("[tide] calendar giorni:", 30, "righe:", dayModel.count)
}
}
+11
View File
@@ -49,6 +49,12 @@ Page {
{ port: port, portIndex: Tides.PORTS.indexOf(port), custom: false }) { port: port, portIndex: Tides.PORTS.indexOf(port), custom: false })
} }
function openCalendar() {
console.log("[tide] openCalendar:", page.port ? page.port[0] : "undefined")
pageStack.push(Qt.resolvedUrl("CalendarPage.qml"),
{ port: page.port })
}
function refresh() { function refresh() {
if (!port) { if (!port) {
console.log("[tide] refresh: port UNDEFINED") console.log("[tide] refresh: port UNDEFINED")
@@ -378,6 +384,11 @@ Page {
pageStack.replace(Qt.resolvedUrl("MainPage.qml")) pageStack.replace(Qt.resolvedUrl("MainPage.qml"))
} }
} }
MenuItem {
text: qsTr("30-day calendar")
visible: page.port !== undefined
onClicked: page.openCalendar()
}
MenuItem { MenuItem {
text: qsTr("Settings") text: qsTr("Settings")
onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml")) onClicked: pageStack.push(Qt.resolvedUrl("SettingsPage.qml"))
+5
View File
@@ -22,6 +22,7 @@
</context> </context>
<context> <context>
<name>DetailPage</name> <name>DetailPage</name>
<message><source>30-day calendar</source><translation type="unfinished"></translation></message>
<message><source>lat %1°</source><translation type="unfinished"></translation></message> <message><source>lat %1°</source><translation type="unfinished"></translation></message>
<message><source>📍 Nearest port: %1 — %2 · ±%3 m</source><translation type="unfinished"></translation></message> <message><source>📍 Nearest port: %1 — %2 · ±%3 m</source><translation type="unfinished"></translation></message>
<message><source>24 h</source><translation type="unfinished"></translation></message> <message><source>24 h</source><translation type="unfinished"></translation></message>
@@ -69,4 +70,8 @@
<name>CoverPage</name> <name>CoverPage</name>
<message><source>No port selected</source><translation type="unfinished"></translation></message> <message><source>No port selected</source><translation type="unfinished"></translation></message>
</context> </context>
<context>
<name>CalendarPage</name>
<message><source>Next 30 days — high and low tides</source><translation type="unfinished"></translation></message>
</context>
</TS> </TS>
+5
View File
@@ -22,6 +22,7 @@
</context> </context>
<context> <context>
<name>DetailPage</name> <name>DetailPage</name>
<message><source>30-day calendar</source><translation>Calendario 30 giorni</translation></message>
<message><source>lat %1°</source><translation>lat %1°</translation></message> <message><source>lat %1°</source><translation>lat %1°</translation></message>
<message><source>📍 Nearest port: %1 — %2 · ±%3 m</source><translation>📍 Porto più vicino: %1 — %2 · ±%3 m</translation></message> <message><source>📍 Nearest port: %1 — %2 · ±%3 m</source><translation>📍 Porto più vicino: %1 — %2 · ±%3 m</translation></message>
<message><source>24 h</source><translation>24 h</translation></message> <message><source>24 h</source><translation>24 h</translation></message>
@@ -69,4 +70,8 @@
<name>CoverPage</name> <name>CoverPage</name>
<message><source>No port selected</source><translation>Nessun porto selezionato</translation></message> <message><source>No port selected</source><translation>Nessun porto selezionato</translation></message>
</context> </context>
<context>
<name>CalendarPage</name>
<message><source>Next 30 days — high and low tides</source><translation>Prossimi 30 giorni — alte e basse maree</translation></message>
</context>
</TS> </TS>