This commit is contained in:
Artem Kokos
2026-04-14 00:02:02 +07:00
parent 1d31767ee0
commit 8198ea09ae
9 changed files with 403 additions and 4 deletions

View File

@@ -19,10 +19,15 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
final _keyCtrl = TextEditingController();
final _latCtrl = TextEditingController();
final _lonCtrl = TextEditingController();
bool _geofenceEnabled = false;
bool _saving = false;
bool get _isEdit => widget.home != null;
/// Координаты заполнены (оба поля непустые)
bool get _hasCoordinates =>
_latCtrl.text.trim().isNotEmpty && _lonCtrl.text.trim().isNotEmpty;
@override
void initState() {
super.initState();
@@ -36,11 +41,27 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
if (widget.home!.longitude != null) {
_lonCtrl.text = widget.home!.longitude.toString();
}
_geofenceEnabled = widget.home!.geofenceEnabled;
}
// Следим за полями координат чтобы обновлять доступность Switch
_latCtrl.addListener(_onCoordsChanged);
_lonCtrl.addListener(_onCoordsChanged);
}
void _onCoordsChanged() {
// Если координаты очистили -- выключаем геофенс
if (!_hasCoordinates && _geofenceEnabled) {
setState(() => _geofenceEnabled = false);
} else {
setState(() {}); // перерисовать Switch enabled/disabled
}
}
@override
void dispose() {
_latCtrl.removeListener(_onCoordsChanged);
_lonCtrl.removeListener(_onCoordsChanged);
_nameCtrl.dispose();
_urlCtrl.dispose();
_keyCtrl.dispose();
@@ -134,6 +155,43 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
],
),
const SizedBox(height: 16),
// ─── Геофенс ───
SwitchListTile(
title: const Text('Выключать свет при уходе'),
subtitle: Text(
_hasCoordinates
? 'Автовыключение при удалении на 500 м'
: 'Задайте координаты для активации',
style: TextStyle(
fontSize: 12,
color: _hasCoordinates ? Colors.white38 : Colors.white24,
),
),
value: _geofenceEnabled,
activeColor: Colors.deepOrange,
onChanged: _hasCoordinates
? (v) => setState(() => _geofenceEnabled = v)
: null,
contentPadding: EdgeInsets.zero,
secondary: Icon(
Icons.directions_walk,
color: _geofenceEnabled && _hasCoordinates
? Colors.deepOrange
: Colors.white24,
),
),
if (_geofenceEnabled && _hasCoordinates)
const Padding(
padding: EdgeInsets.only(left: 40, bottom: 4),
child: Text(
'Проверка раз в ~15 мин (ограничение Android).\n'
'Работает в фоне, без постоянной нотификации.',
style: TextStyle(fontSize: 11, color: Colors.white24),
),
),
const SizedBox(height: 24),
SizedBox(
width: double.infinity,
@@ -193,6 +251,8 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
setState(() => _saving = true);
final clearCoords = latText.isEmpty && lonText.isEmpty;
final home = _isEdit
? widget.home!.copyWith(
name: name,
@@ -200,7 +260,8 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
apiKey: key,
latitude: lat,
longitude: lon,
clearCoordinates: latText.isEmpty && lonText.isEmpty,
geofenceEnabled: clearCoords ? false : _geofenceEnabled,
clearCoordinates: clearCoords,
)
: HomeConfig(
id: DateTime.now().millisecondsSinceEpoch.toString(),
@@ -209,6 +270,7 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
apiKey: key,
latitude: lat,
longitude: lon,
geofenceEnabled: _geofenceEnabled,
);
if (_isEdit) {
@@ -217,6 +279,10 @@ class _HomeEditScreenState extends ConsumerState<HomeEditScreen> {
await ref.read(homesProvider.notifier).add(home);
}
// Синхронизировать фоновый таск с новыми настройками
final allHomes = ref.read(homesProvider);
await syncGeofenceTask(allHomes);
if (mounted) Navigator.of(context).pop();
}
}
}

View File

@@ -191,6 +191,8 @@ class _HomesScreenState extends ConsumerState<HomesScreen> {
onPressed: () async {
Navigator.of(ctx).pop();
await ref.read(homesProvider.notifier).remove(home.id);
// Синхронизировать фоновый таск (мог быть удалён дом с геофенсом)
await syncGeofenceTask(ref.read(homesProvider));
},
child: const Text('Удалить', style: TextStyle(color: Colors.redAccent)),
),