feat: merge health feature and add measure command
- Add REQUEST_HEART_RATE command with measure button in health screen - Add ref.mounted checks and fix early return in measure() - Remove unused SET_LANGUAGE from DeviceCommand enum
This commit is contained in:
@@ -56,14 +56,14 @@ class _HealthScreenState extends ConsumerState<HealthScreen>
|
|||||||
final state = ref.watch(healthViewModelProvider);
|
final state = ref.watch(healthViewModelProvider);
|
||||||
final vm = ref.read(healthViewModelProvider.notifier);
|
final vm = ref.read(healthViewModelProvider.notifier);
|
||||||
|
|
||||||
ref.listen(
|
ref.listen(healthViewModelProvider.select((s) => s.errorMessage), (
|
||||||
healthViewModelProvider.select((s) => s.errorMessage),
|
previous,
|
||||||
(previous, next) {
|
next,
|
||||||
if (next.isNotEmpty) {
|
) {
|
||||||
showTopSnackbar(context, message: next, type: MessageType.error);
|
if (next.isNotEmpty) {
|
||||||
}
|
showTopSnackbar(context, message: next, type: MessageType.error);
|
||||||
},
|
}
|
||||||
);
|
});
|
||||||
|
|
||||||
return LegacyPageLayout(
|
return LegacyPageLayout(
|
||||||
theme: theme,
|
theme: theme,
|
||||||
@@ -130,6 +130,29 @@ class _HealthScreenState extends ConsumerState<HealthScreen>
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
footer: _SaveSection(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _SaveSection extends ConsumerWidget {
|
||||||
|
const _SaveSection();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final theme = ref.read(themePortProvider);
|
||||||
|
|
||||||
|
final vm = ref.read(healthViewModelProvider.notifier);
|
||||||
|
|
||||||
|
return Padding(
|
||||||
|
padding: EdgeInsets.symmetric(horizontal: 24, vertical: 10),
|
||||||
|
child: PrimaryButton(
|
||||||
|
onPressed: () async {
|
||||||
|
await vm.measure();
|
||||||
|
},
|
||||||
|
text: context.translate(I18n.measure),
|
||||||
|
color: theme.getColorFor(ThemeCode.legacyPrimary),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,14 @@ final healthViewModelProvider =
|
|||||||
|
|
||||||
class HealthViewModel extends Notifier<HealthViewState> {
|
class HealthViewModel extends Notifier<HealthViewState> {
|
||||||
late final HealthRepository _repository;
|
late final HealthRepository _repository;
|
||||||
|
late final CommandsRepository _commandsRepository;
|
||||||
|
|
||||||
static const int _historyPageSize = 20;
|
static const int _historyPageSize = 20;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
HealthViewState build() {
|
HealthViewState build() {
|
||||||
_repository = ref.read(healthRepositoryProvider);
|
_repository = ref.read(healthRepositoryProvider);
|
||||||
|
_commandsRepository = ref.read(commandsRepositoryProvider);
|
||||||
_init();
|
_init();
|
||||||
return const HealthViewState();
|
return const HealthViewState();
|
||||||
}
|
}
|
||||||
@@ -247,4 +249,29 @@ class HealthViewModel extends Notifier<HealthViewState> {
|
|||||||
final msg = e.toString();
|
final msg = e.toString();
|
||||||
return msg.startsWith('Exception: ') ? msg.substring(11) : msg;
|
return msg.startsWith('Exception: ') ? msg.substring(11) : msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> measure() async {
|
||||||
|
final device = ref.read(selectedDeviceProvider);
|
||||||
|
if (device == null) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
state = state.copyWith(isLoading: true);
|
||||||
|
|
||||||
|
final request = SendCommandRequestModel(
|
||||||
|
device: device.identificator,
|
||||||
|
command: DeviceCommand.requestHeartRate,
|
||||||
|
);
|
||||||
|
|
||||||
|
await _commandsRepository.send(request: request);
|
||||||
|
if (!ref.mounted) return;
|
||||||
|
|
||||||
|
state = state.copyWith(isLoading: false);
|
||||||
|
} catch (e) {
|
||||||
|
if (!ref.mounted) return;
|
||||||
|
state = state.copyWith(
|
||||||
|
isLoading: false,
|
||||||
|
errorMessage: _formatError(e),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,12 +12,12 @@ enum DeviceCommand {
|
|||||||
findDevice,
|
findDevice,
|
||||||
@JsonValue('REQUEST_PHOTO')
|
@JsonValue('REQUEST_PHOTO')
|
||||||
requestPhoto,
|
requestPhoto,
|
||||||
|
@JsonValue('REQUEST_HEART_RATE')
|
||||||
|
requestHeartRate,
|
||||||
@JsonValue('RESTART')
|
@JsonValue('RESTART')
|
||||||
restart,
|
restart,
|
||||||
@JsonValue('REWARDS')
|
@JsonValue('REWARDS')
|
||||||
rewards,
|
rewards,
|
||||||
@JsonValue('SET_LANGUAGE')
|
|
||||||
setLanguage,
|
|
||||||
@JsonValue('SHUTDOWN')
|
@JsonValue('SHUTDOWN')
|
||||||
shutdown,
|
shutdown,
|
||||||
@JsonValue('SET_SOUND_MODE')
|
@JsonValue('SET_SOUND_MODE')
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ const _$DeviceCommandEnumMap = {
|
|||||||
DeviceCommand.factory: 'FACTORY',
|
DeviceCommand.factory: 'FACTORY',
|
||||||
DeviceCommand.findDevice: 'FIND_DEVICE',
|
DeviceCommand.findDevice: 'FIND_DEVICE',
|
||||||
DeviceCommand.requestPhoto: 'REQUEST_PHOTO',
|
DeviceCommand.requestPhoto: 'REQUEST_PHOTO',
|
||||||
|
DeviceCommand.requestHeartRate: 'REQUEST_HEART_RATE',
|
||||||
DeviceCommand.restart: 'RESTART',
|
DeviceCommand.restart: 'RESTART',
|
||||||
DeviceCommand.rewards: 'REWARDS',
|
DeviceCommand.rewards: 'REWARDS',
|
||||||
DeviceCommand.setLanguage: 'SET_LANGUAGE',
|
|
||||||
DeviceCommand.shutdown: 'SHUTDOWN',
|
DeviceCommand.shutdown: 'SHUTDOWN',
|
||||||
DeviceCommand.setSoundMode: 'SET_SOUND_MODE',
|
DeviceCommand.setSoundMode: 'SET_SOUND_MODE',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -625,5 +625,6 @@
|
|||||||
"volumeHint": "Sie können den Schieberegler ziehen, um die Gerätelautstärke anzupassen. Die App speichert nur die zuletzt erfolgreich eingestellte Lautstärke. Die tatsächliche Lautstärke hängt vom Gerät ab.",
|
"volumeHint": "Sie können den Schieberegler ziehen, um die Gerätelautstärke anzupassen. Die App speichert nur die zuletzt erfolgreich eingestellte Lautstärke. Die tatsächliche Lautstärke hängt vom Gerät ab.",
|
||||||
"volumeSend": "Senden",
|
"volumeSend": "Senden",
|
||||||
"photoTaken": "Foto erfolgreich aufgenommen",
|
"photoTaken": "Foto erfolgreich aufgenommen",
|
||||||
"noPhotosAvailable": "Keine Fotos verfügbar"
|
"noPhotosAvailable": "Keine Fotos verfügbar",
|
||||||
|
"measure": "Messen"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -757,5 +757,6 @@
|
|||||||
"syncClockMessage": "Synchronize the device clock with the current time",
|
"syncClockMessage": "Synchronize the device clock with the current time",
|
||||||
"locationWifiNetworksOptional": "WiFi networks (optional)",
|
"locationWifiNetworksOptional": "WiFi networks (optional)",
|
||||||
"photoTaken": "Photo taken successfully",
|
"photoTaken": "Photo taken successfully",
|
||||||
"noPhotosAvailable": "No photos available"
|
"noPhotosAvailable": "No photos available",
|
||||||
|
"measure": "Measure"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -755,5 +755,6 @@
|
|||||||
"syncClockMessage": "Sincroniza el reloj del dispositivo con la hora actual",
|
"syncClockMessage": "Sincroniza el reloj del dispositivo con la hora actual",
|
||||||
"locationWifiNetworksOptional": "Redes WiFi (opcional)",
|
"locationWifiNetworksOptional": "Redes WiFi (opcional)",
|
||||||
"photoTaken": "Foto tomada exitosamente",
|
"photoTaken": "Foto tomada exitosamente",
|
||||||
"noPhotosAvailable": "No hay fotos disponibles"
|
"noPhotosAvailable": "No hay fotos disponibles",
|
||||||
|
"measure": "Medir"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -625,5 +625,6 @@
|
|||||||
"volumeHint": "Vous pouvez faire glisser le curseur pour régler le volume de l'appareil. L'application ne sauvegarde que le dernier niveau de volume ajusté avec succès. Le volume réel dépendra de l'appareil.",
|
"volumeHint": "Vous pouvez faire glisser le curseur pour régler le volume de l'appareil. L'application ne sauvegarde que le dernier niveau de volume ajusté avec succès. Le volume réel dépendra de l'appareil.",
|
||||||
"volumeSend": "Envoyer",
|
"volumeSend": "Envoyer",
|
||||||
"photoTaken": "Photo prise avec succès",
|
"photoTaken": "Photo prise avec succès",
|
||||||
"noPhotosAvailable": "Aucune photo disponible"
|
"noPhotosAvailable": "Aucune photo disponible",
|
||||||
|
"measure": "Mesurer"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -625,5 +625,6 @@
|
|||||||
"volumeHint": "Puoi trascinare il cursore per regolare il volume del dispositivo. L'app salva solo l'ultimo livello di volume regolato con successo. Il volume effettivo dipenderà dal dispositivo.",
|
"volumeHint": "Puoi trascinare il cursore per regolare il volume del dispositivo. L'app salva solo l'ultimo livello di volume regolato con successo. Il volume effettivo dipenderà dal dispositivo.",
|
||||||
"volumeSend": "Invia",
|
"volumeSend": "Invia",
|
||||||
"photoTaken": "Foto scattata con successo",
|
"photoTaken": "Foto scattata con successo",
|
||||||
"noPhotosAvailable": "Nessuna foto disponibile"
|
"noPhotosAvailable": "Nessuna foto disponibile",
|
||||||
|
"measure": "Misurare"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -625,5 +625,6 @@
|
|||||||
"volumeHint": "Você pode arrastar o controle deslizante para ajustar o volume do dispositivo. O aplicativo salva apenas o nível de volume ajustado com sucesso mais recentemente. O volume real dependerá do dispositivo.",
|
"volumeHint": "Você pode arrastar o controle deslizante para ajustar o volume do dispositivo. O aplicativo salva apenas o nível de volume ajustado com sucesso mais recentemente. O volume real dependerá do dispositivo.",
|
||||||
"volumeSend": "Enviar",
|
"volumeSend": "Enviar",
|
||||||
"photoTaken": "Foto tirada com sucesso",
|
"photoTaken": "Foto tirada com sucesso",
|
||||||
"noPhotosAvailable": "Nenhuma foto disponível"
|
"noPhotosAvailable": "Nenhuma foto disponível",
|
||||||
|
"measure": "Medir"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -762,4 +762,5 @@ class I18n {
|
|||||||
static const String photoTaken = 'photoTaken';
|
static const String photoTaken = 'photoTaken';
|
||||||
static const String noPhotosAvailable = 'noPhotosAvailable';
|
static const String noPhotosAvailable = 'noPhotosAvailable';
|
||||||
static const String yesterday = 'yesterday';
|
static const String yesterday = 'yesterday';
|
||||||
|
static const String measure = 'measure';
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user