2024-03-12 20:41:04 +00:00
|
|
|
import 'dart:async';
|
|
|
|
import 'dart:convert';
|
|
|
|
|
|
|
|
import 'package:fast_immutable_collections/fast_immutable_collections.dart';
|
|
|
|
import 'package:flutter/foundation.dart';
|
2024-03-14 19:50:30 +00:00
|
|
|
import 'package:get_it/get_it.dart';
|
|
|
|
import 'package:ot_viewer_app/global_location_store.dart';
|
2024-03-12 20:41:04 +00:00
|
|
|
import 'package:rust_core/option.dart';
|
|
|
|
import 'package:anyhow/anyhow.dart';
|
|
|
|
import 'package:bloc/bloc.dart';
|
|
|
|
import 'package:meta/meta.dart';
|
|
|
|
import 'package:ot_viewer_app/owntracks_api.dart';
|
|
|
|
import 'package:ot_viewer_app/settings_page.dart';
|
|
|
|
import 'package:ws/ws.dart';
|
|
|
|
|
|
|
|
part 'user_path_event.dart';
|
|
|
|
|
|
|
|
part 'user_path_state.dart';
|
|
|
|
|
|
|
|
class UserPathBloc extends Bloc<UserPathEvent, UserPathState> {
|
|
|
|
final (String, String) deviceId;
|
|
|
|
SettingsState settingsState;
|
|
|
|
Option<WebSocketClient> _ws = None;
|
|
|
|
|
2024-03-17 20:17:09 +00:00
|
|
|
OwntracksApi get _api =>
|
|
|
|
OwntracksApi(baseUrl: settingsState.url, username: settingsState.username, pass: settingsState.password);
|
2024-03-12 20:41:04 +00:00
|
|
|
|
|
|
|
UserPathBloc(this.deviceId, this.settingsState)
|
|
|
|
: super(MainUserPathState(
|
|
|
|
initialPoints: const IListConst([]),
|
|
|
|
livePoints: const IListConst([]),
|
2024-03-17 20:17:09 +00:00
|
|
|
from: DateTime.now().subtract(settingsState.historyTime),
|
|
|
|
to: DateTime.now())) /*.add(const Duration(days: 365 * 100)))) */ {
|
2024-03-12 20:41:04 +00:00
|
|
|
on<UserPathLoginDataChanged>((event, emit) {
|
2024-03-17 20:17:09 +00:00
|
|
|
if (event.newSettings == settingsState) {
|
|
|
|
print('settings states the same, returning. states:\nold: $settingsState\nnew: ${event.newSettings}');
|
|
|
|
return;
|
|
|
|
}
|
2024-03-12 20:41:04 +00:00
|
|
|
settingsState = event.newSettings;
|
2024-03-17 20:17:09 +00:00
|
|
|
|
|
|
|
emit(MainUserPathState.copy(
|
|
|
|
state as MainUserPathState,
|
|
|
|
from: DateTime.now().subtract(settingsState.historyTime),
|
|
|
|
));
|
|
|
|
|
|
|
|
print('settings states differ, doing full update');
|
|
|
|
|
|
|
|
add(UserPathFullUpdate());
|
2024-03-12 20:41:04 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
on<UserPathLiveSubscriptionUpdate>((event, emit) {
|
|
|
|
print("DEBUG: adding point ${event.point} to bloc $deviceId");
|
|
|
|
emit(MainUserPathState.copy(
|
|
|
|
state as MainUserPathState,
|
|
|
|
// FIXME: inefficient as heck. Maybe use fast_immutable_collections package?
|
|
|
|
livePoints: (state as MainUserPathState).livePoints.add(event.point),
|
|
|
|
));
|
|
|
|
});
|
|
|
|
|
|
|
|
on<UserPathFullUpdate>((event, emit) async {
|
|
|
|
print("fpu");
|
|
|
|
if (state is MainUserPathState) {
|
|
|
|
final istate = state as MainUserPathState;
|
2024-03-17 20:17:09 +00:00
|
|
|
var history = await _api.fetchPointsForDevice(
|
2024-03-12 20:41:04 +00:00
|
|
|
user: deviceId.$1,
|
|
|
|
device: deviceId.$2,
|
|
|
|
from: istate.from,
|
|
|
|
to: istate.to,
|
|
|
|
);
|
|
|
|
|
2024-03-17 20:17:09 +00:00
|
|
|
history = await history.toFutureResult().map((h) async {
|
|
|
|
if (h.isEmpty) {
|
|
|
|
final last = await _api.fetchLastPoint(user: deviceId.$1, device: deviceId.$2);
|
|
|
|
if (last.isOk()) {
|
|
|
|
return [last.unwrap()];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return h;
|
|
|
|
});
|
|
|
|
|
|
|
|
final Result<List<Point>> livePoints = history.map((ok) => ok.isNotEmpty ? [ok.last] : []);
|
2024-03-12 20:41:04 +00:00
|
|
|
|
|
|
|
emit(MainUserPathState(
|
2024-03-17 20:17:09 +00:00
|
|
|
initialPoints: history.expect("Couldn't retrieve path history for $deviceId").lock,
|
|
|
|
livePoints: livePoints.expect("Couldn\'t retrieve last (current) point").lock,
|
2024-03-12 20:41:04 +00:00
|
|
|
from: istate.from,
|
|
|
|
to: istate.to));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
@override
|
|
|
|
void onTransition(Transition<UserPathEvent, UserPathState> transition) {
|
2024-03-14 19:50:30 +00:00
|
|
|
super.onTransition(transition);
|
|
|
|
|
|
|
|
if (transition.nextState is MainUserPathState) {
|
|
|
|
// add current location to global location thingy
|
|
|
|
final pt = (transition.nextState as MainUserPathState).livePoints.lastOrNull;
|
|
|
|
if (pt != null) {
|
|
|
|
GetIt.I.get<GlobalLocationStoreCubit>().updatePoint(deviceId.$1, deviceId.$2, pt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-12 20:41:04 +00:00
|
|
|
print("upb $deviceId: $transition");
|
|
|
|
}
|
|
|
|
}
|