163 lines
5.9 KiB
Dart
163 lines
5.9 KiB
Dart
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,
|
||
|
|
),
|
||
|
|
),
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|