Ntrip szervíz refraktorálás, beállítások, jelszó secure store-ba

This commit is contained in:
2026-07-05 03:43:07 +02:00
parent 80f7c8d571
commit fa25a320eb
8 changed files with 501 additions and 126 deletions
@@ -0,0 +1,162 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:terepi_seged/pages/ntrip_settings/presentation/views/ntrip_settings_sheet.dart';
import 'package:terepi_seged/services/gnss/gnss_connection.dart';
import 'package:terepi_seged/services/gnss/gnss_device_service.dart';
import 'package:terepi_seged/services/gnss/gnss_service.dart';
import 'package:terepi_seged/services/ntrip_service.dart';
import 'package:terepi_seged/widgets/gnss_device_picker_dialog.dart';
/// Központi beállítások oldal.
///
/// Material 3 konvenciók:
/// - egyetlen görgethető lista, szekciókra bontva
/// - az aktuális érték a subtitle-ben látszik
/// - kapcsolók azonnal érvényesülnek (nincs "Mentés" gomb ezen a szinten)
/// - űrlap-jellegű beállítás (NTRIP) al-sheetre megy, explicit mentéssel
///
/// Bővítés: új ListTile / SwitchListTile a megfelelő szekcióba,
/// vagy új _SettingsSection, ha új témakör jön.
class SettingsView extends StatelessWidget {
const SettingsView({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Beállítások'),
),
body: ListView(
children: [
// ── Kapcsolat ─────────────────────────────────────────────
const _SettingsSection('Kapcsolat'),
// NTRIP — subtitle mutatja az aktuális konfigurációt,
// a trailing pötty a kapcsolat állapotát.
Obx(() {
final ntrip = NtripService.to;
final configured = ntrip.hasCompleteSettings;
final subtitle = configured
? '${ntrip.host.value} · ${ntrip.mountpoint.value}'
: 'Nincs beállítva';
return ListTile(
leading: const Icon(Icons.cell_tower),
title: const Text('NTRIP korrekció'),
subtitle: Text(subtitle, style: const TextStyle(fontSize: 12)),
trailing: Icon(
Icons.circle,
size: 12,
color: ntrip.isConnected.value
? Colors.green
: (configured ? Colors.grey : Colors.orange),
),
onTap: NtripSettingsSheet.show,
);
}),
// GNSS eszköz — ugyanaz a választó, mint a drawer-ben.
Obx(() {
final device = GnssDeviceService.to.selectedDevice.value;
final connected = GnssService.to.connectionState.value ==
GnssConnectionState.connected;
return ListTile(
leading: Icon(
device?.type == GnssConnectionType.ble
? Icons.bluetooth_searching
: device?.type == GnssConnectionType.phoneGps
? Icons.phone_android
: Icons.bluetooth,
),
title: const Text('GNSS eszköz'),
subtitle: Text(
device?.name ?? 'Nincs kiválasztva',
style: const TextStyle(fontSize: 12),
),
trailing: Icon(
Icons.circle,
size: 12,
color: connected ? Colors.green : Colors.grey,
),
onTap: GnssDevicePickerDialog.show,
);
}),
const Divider(height: 24),
// ── Térkép ────────────────────────────────────────────────
const _SettingsSection('Térkép'),
// Helykitöltők — a onTap kitöltésével élesíthetők,
// az enabled: false vizuálisan is jelzi, hogy még nem aktívak.
const ListTile(
leading: Icon(Icons.map_outlined),
title: Text('Alaptérkép'),
subtitle: Text('OpenStreetMap', style: TextStyle(fontSize: 12)),
enabled: false,
),
const ListTile(
leading: Icon(Icons.straighten),
title: Text('Koordináta-megjelenítés'),
subtitle: Text('EOV', style: TextStyle(fontSize: 12)),
enabled: false,
),
const Divider(height: 24),
// ── Névjegy ───────────────────────────────────────────────
const _SettingsSection('Névjegy'),
FutureBuilder<PackageInfo>(
future: PackageInfo.fromPlatform(),
builder: (_, snap) => ListTile(
leading: const Icon(Icons.info_outline),
title: const Text('Verzió'),
subtitle: Text(
snap.hasData
? '${snap.data!.version} (build ${snap.data!.buildNumber})'
: '',
style: const TextStyle(fontSize: 12),
),
),
),
ListTile(
leading: const Icon(Icons.description_outlined),
title: const Text('Nyílt forráskódú licencek'),
onTap: () => showLicensePage(
context: context,
applicationName: 'Terepi Segéd',
),
),
const SizedBox(height: 24),
],
),
);
}
}
// ── Szekció felirat — ugyanaz a stílus, mint a drawer-ben ───────────
class _SettingsSection extends StatelessWidget {
final String text;
const _SettingsSection(this.text);
@override
Widget build(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(16, 8, 16, 4),
child: Text(
text.toUpperCase(),
style: TextStyle(
fontSize: 10,
fontWeight: FontWeight.w600,
color: Colors.grey.shade500,
letterSpacing: 0.8,
),
),
);
}
}