diff --git a/qml/pages/MainPage.qml b/qml/pages/MainPage.qml
index 60ed817..4f89bb0 100644
--- a/qml/pages/MainPage.qml
+++ b/qml/pages/MainPage.qml
@@ -60,6 +60,22 @@ Page {
header: SectionHeader { text: qsTr("Ports") }
+ footer: Item {
+ width: parent.width
+ height: portModel.count === 0 ? Theme.itemSizeMedium : 0
+ Label {
+ visible: portModel.count === 0
+ anchors.fill: parent
+ anchors.margins: Theme.horizontalPageMargin
+ text: qsTr("No ports match the filter. Try the free city search above.")
+ color: Theme.secondaryColor
+ font.pixelSize: Theme.fontSizeSmall
+ wrapMode: Text.Wrap
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+
delegate: ListItem {
contentHeight: Theme.itemSizeMedium
highlighted: model.isPreferred
@@ -92,6 +108,7 @@ Page {
anchors.verticalCenter: parent.verticalCenter
}
onClicked: {
+ console.log("[tide] open port:", model.name, "custom:", model.custom)
page.pageStack.push(Qt.resolvedUrl("DetailPage.qml"),
{ port: model.port, portIndex: model.realIndex, custom: model.custom })
}
@@ -130,13 +147,14 @@ Page {
}
// --- Ricerca libera (geocoding) ---
- function geoFail() {
- geoMsg.text = qsTr("City not found (offline and not in local dataset).")
+ function geoFail(msg) {
+ geoMsg.text = msg || qsTr("City not found (offline and not in local dataset).")
geoMsg.visible = true
geoMsg.color = Theme.errorColor
}
function geoFound(name, lat, lon, src) {
+ console.log("[tide] geoFound:", name, lat, lon, src)
if (!name) { geoFail(); return }
var np = Tides.nearestPort(lat, lon)
var cost, flag
@@ -153,19 +171,37 @@ Page {
geoMsg.text = qsTr("Found %1 (via %2)").arg(name).arg(src)
geoMsg.visible = true
geoMsg.color = Theme.highlightColor
- page.pageStack.push(Qt.resolvedUrl("DetailPage.qml"),
- { port: port, portIndex: -1, custom: true })
+ try {
+ page.pageStack.push(Qt.resolvedUrl("DetailPage.qml"),
+ { port: port, portIndex: -1, custom: true })
+ } catch (e) {
+ console.log("[tide] push DetailPage failed:", e)
+ geoFail(qsTr("Could not open the detail page: %1").arg(e))
+ }
}
function geoXhr(query, cb) {
// Photon (komoot) invece di Nominatim: accetta qualsiasi User-Agent
// (Nominatim risponde 403 all'UA generico inviato dalle XHR QML di Qt)
// e supporta il filtro osm_tag=place:city per le città vere.
+ console.log("[tide] geoXhr:", query)
var xhr = new XMLHttpRequest()
+ var done = false
+ var to = setTimeout(function() {
+ if (!done) {
+ done = true
+ console.log("[tide] geoXhr timeout")
+ cb(null, true)
+ }
+ }, 12000)
xhr.open("GET", "https://photon.komoot.io/api/?limit=1&osm_tag=place:city&q="
+ encodeURIComponent(query), true)
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
+ if (done) return
+ done = true
+ clearTimeout(to)
+ console.log("[tide] geoXhr status:", xhr.status)
if (xhr.status === 200) {
try {
var j = JSON.parse(xhr.responseText)
@@ -190,6 +226,7 @@ Page {
function findCity() {
var q = geoField.text.trim()
+ console.log("[tide] findCity:", q)
if (q === "") return
geoMsg.text = qsTr("Searching…")
geoMsg.visible = true
@@ -198,7 +235,13 @@ Page {
if (loc) {
geoFound(loc[0], loc[2], loc[3], qsTr("local dataset"))
} else {
- geoXhr(q, geoFound)
+ geoXhr(q, function(name, lat, lon, src, timeout) {
+ if (timeout) {
+ geoFail(qsTr("Geocoding service not reachable (timeout). Check the network."))
+ return
+ }
+ geoFound(name, lat, lon, src)
+ })
}
}
diff --git a/translations/harbour-tide.ts b/translations/harbour-tide.ts
index 90bb8fd..d1a9026 100644
--- a/translations/harbour-tide.ts
+++ b/translations/harbour-tide.ts
@@ -12,6 +12,9 @@
local dataset
searched city
Ports
+ No ports match the filter. Try the free city search above.
+ Geocoding service not reachable (timeout). Check the network.
+ Could not open the detail page: %1
DetailPage
diff --git a/translations/harbour-tide_it.ts b/translations/harbour-tide_it.ts
index 58f5392..5bc1b8b 100644
--- a/translations/harbour-tide_it.ts
+++ b/translations/harbour-tide_it.ts
@@ -12,6 +12,9 @@
local datasetdataset locale
searched citycittà cercata
PortsPorti
+ No ports match the filter. Try the free city search above.Nessun porto corrisponde al filtro. Prova la ricerca libera qui sopra.
+ Geocoding service not reachable (timeout). Check the network.Servizio di geocoding non raggiungibile (timeout). Controlla la rete.
+ Could not open the detail page: %1Impossibile aprire la pagina di dettaglio: %1
DetailPage