Fix: Resolve critical linting issues and bugs (concurrency, syntax, dead code)
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:krow_core/core.dart';
|
||||
import 'package:krow_domain/krow_domain.dart';
|
||||
import '../../domain/usecases/get_todays_shift_usecase.dart';
|
||||
import '../../domain/usecases/get_attendance_status_usecase.dart';
|
||||
@@ -10,8 +11,8 @@ import '../../domain/arguments/clock_out_arguments.dart';
|
||||
import 'clock_in_event.dart';
|
||||
import 'clock_in_state.dart';
|
||||
|
||||
class ClockInBloc extends Bloc<ClockInEvent, ClockInState> {
|
||||
|
||||
class ClockInBloc extends Bloc<ClockInEvent, ClockInState>
|
||||
with BlocErrorHandler<ClockInState> {
|
||||
ClockInBloc({
|
||||
required GetTodaysShiftUseCase getTodaysShift,
|
||||
required GetAttendanceStatusUseCase getAttendanceStatus,
|
||||
@@ -47,92 +48,105 @@ class ClockInBloc extends Bloc<ClockInEvent, ClockInState> {
|
||||
Emitter<ClockInState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(status: ClockInStatus.loading));
|
||||
try {
|
||||
final List<Shift> shifts = await _getTodaysShift();
|
||||
final AttendanceStatus status = await _getAttendanceStatus();
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final List<Shift> shifts = await _getTodaysShift();
|
||||
final AttendanceStatus status = await _getAttendanceStatus();
|
||||
|
||||
// Check permissions silently on load? Maybe better to wait for user interaction or specific event
|
||||
// However, if shift exists, we might want to check permission state
|
||||
Shift? selectedShift;
|
||||
if (shifts.isNotEmpty) {
|
||||
if (status.activeShiftId != null) {
|
||||
try {
|
||||
selectedShift =
|
||||
shifts.firstWhere((Shift s) => s.id == status.activeShiftId);
|
||||
} catch (_) {}
|
||||
Shift? selectedShift;
|
||||
if (shifts.isNotEmpty) {
|
||||
if (status.activeShiftId != null) {
|
||||
try {
|
||||
selectedShift =
|
||||
shifts.firstWhere((Shift s) => s.id == status.activeShiftId);
|
||||
} catch (_) {}
|
||||
}
|
||||
selectedShift ??= shifts.last;
|
||||
}
|
||||
selectedShift ??= shifts.last;
|
||||
}
|
||||
|
||||
emit(state.copyWith(
|
||||
status: ClockInStatus.success,
|
||||
todayShifts: shifts,
|
||||
selectedShift: selectedShift,
|
||||
attendance: status,
|
||||
));
|
||||
emit(state.copyWith(
|
||||
status: ClockInStatus.success,
|
||||
todayShifts: shifts,
|
||||
selectedShift: selectedShift,
|
||||
attendance: status,
|
||||
));
|
||||
|
||||
if (selectedShift != null && !status.isCheckedIn) {
|
||||
add(RequestLocationPermission());
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
if (selectedShift != null && !status.isCheckedIn) {
|
||||
add(RequestLocationPermission());
|
||||
}
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
status: ClockInStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onRequestLocationPermission(
|
||||
RequestLocationPermission event,
|
||||
Emitter<ClockInState> emit,
|
||||
) async {
|
||||
try {
|
||||
LocationPermission permission = await Geolocator.checkPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
permission = await Geolocator.requestPermission();
|
||||
}
|
||||
|
||||
final bool hasConsent = permission == LocationPermission.always || permission == LocationPermission.whileInUse;
|
||||
|
||||
emit(state.copyWith(hasLocationConsent: hasConsent));
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
LocationPermission permission = await Geolocator.checkPermission();
|
||||
if (permission == LocationPermission.denied) {
|
||||
permission = await Geolocator.requestPermission();
|
||||
}
|
||||
|
||||
if (hasConsent) {
|
||||
_startLocationUpdates();
|
||||
}
|
||||
} catch (e) {
|
||||
emit(state.copyWith(errorMessage: "Location error: $e"));
|
||||
}
|
||||
final bool hasConsent =
|
||||
permission == LocationPermission.always ||
|
||||
permission == LocationPermission.whileInUse;
|
||||
|
||||
emit(state.copyWith(hasLocationConsent: hasConsent));
|
||||
|
||||
if (hasConsent) {
|
||||
await _startLocationUpdates();
|
||||
}
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _startLocationUpdates() async {
|
||||
// Note: handleErrorWithResult could be used here too if we want centralized logging/conversion
|
||||
try {
|
||||
final Position position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
|
||||
|
||||
final Position position = await Geolocator.getCurrentPosition(
|
||||
desiredAccuracy: LocationAccuracy.high,
|
||||
);
|
||||
|
||||
double distance = 0;
|
||||
bool isVerified = false; // Require location match by default if shift has location
|
||||
bool isVerified =
|
||||
false; // Require location match by default if shift has location
|
||||
|
||||
if (state.selectedShift != null &&
|
||||
state.selectedShift!.latitude != null &&
|
||||
state.selectedShift!.longitude != null) {
|
||||
distance = Geolocator.distanceBetween(
|
||||
position.latitude,
|
||||
position.longitude,
|
||||
state.selectedShift!.latitude!,
|
||||
state.selectedShift!.longitude!,
|
||||
);
|
||||
isVerified = distance <= allowedRadiusMeters;
|
||||
distance = Geolocator.distanceBetween(
|
||||
position.latitude,
|
||||
position.longitude,
|
||||
state.selectedShift!.latitude!,
|
||||
state.selectedShift!.longitude!,
|
||||
);
|
||||
isVerified = distance <= allowedRadiusMeters;
|
||||
} else {
|
||||
// If no shift location, assume verified or don't restrict?
|
||||
// For strict clock-in, maybe false? but let's default to verified to avoid blocking if data missing
|
||||
isVerified = true;
|
||||
isVerified = true;
|
||||
}
|
||||
|
||||
|
||||
if (!isClosed) {
|
||||
add(LocationUpdated(position: position, distance: distance, isVerified: isVerified));
|
||||
add(
|
||||
LocationUpdated(
|
||||
position: position,
|
||||
distance: distance,
|
||||
isVerified: isVerified,
|
||||
),
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
// Handle error silently or via state
|
||||
} catch (_) {
|
||||
// Geolocator errors usually handled via onRequestLocationPermission
|
||||
}
|
||||
}
|
||||
|
||||
@@ -144,7 +158,8 @@ class ClockInBloc extends Bloc<ClockInEvent, ClockInState> {
|
||||
currentLocation: event.position,
|
||||
distanceFromVenue: event.distance,
|
||||
isLocationVerified: event.isVerified,
|
||||
etaMinutes: (event.distance / 80).round(), // Rough estimate: 80m/min walking speed
|
||||
etaMinutes:
|
||||
(event.distance / 80).round(), // Rough estimate: 80m/min walking speed
|
||||
));
|
||||
}
|
||||
|
||||
@@ -152,10 +167,10 @@ class ClockInBloc extends Bloc<ClockInEvent, ClockInState> {
|
||||
CommuteModeToggled event,
|
||||
Emitter<ClockInState> emit,
|
||||
) {
|
||||
emit(state.copyWith(isCommuteModeOn: event.isEnabled));
|
||||
if (event.isEnabled) {
|
||||
add(RequestLocationPermission());
|
||||
}
|
||||
emit(state.copyWith(isCommuteModeOn: event.isEnabled));
|
||||
if (event.isEnabled) {
|
||||
add(RequestLocationPermission());
|
||||
}
|
||||
}
|
||||
|
||||
void _onShiftSelected(
|
||||
@@ -186,28 +201,23 @@ class ClockInBloc extends Bloc<ClockInEvent, ClockInState> {
|
||||
CheckInRequested event,
|
||||
Emitter<ClockInState> emit,
|
||||
) async {
|
||||
// Only verify location if not using NFC (or depending on requirements) - enforcing for swipe
|
||||
if (state.checkInMode == 'swipe' && !state.isLocationVerified) {
|
||||
// Allow for now since coordinates are hardcoded and might not match user location
|
||||
// emit(state.copyWith(errorMessage: "You must be at the location to clock in."));
|
||||
// return;
|
||||
}
|
||||
|
||||
emit(state.copyWith(status: ClockInStatus.actionInProgress));
|
||||
try {
|
||||
final AttendanceStatus newStatus = await _clockIn(
|
||||
ClockInArguments(shiftId: event.shiftId, notes: event.notes),
|
||||
);
|
||||
emit(state.copyWith(
|
||||
status: ClockInStatus.success,
|
||||
attendance: newStatus,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final AttendanceStatus newStatus = await _clockIn(
|
||||
ClockInArguments(shiftId: event.shiftId, notes: event.notes),
|
||||
);
|
||||
emit(state.copyWith(
|
||||
status: ClockInStatus.success,
|
||||
attendance: newStatus,
|
||||
));
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
status: ClockInStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _onCheckOut(
|
||||
@@ -215,23 +225,25 @@ class ClockInBloc extends Bloc<ClockInEvent, ClockInState> {
|
||||
Emitter<ClockInState> emit,
|
||||
) async {
|
||||
emit(state.copyWith(status: ClockInStatus.actionInProgress));
|
||||
try {
|
||||
final AttendanceStatus newStatus = await _clockOut(
|
||||
ClockOutArguments(
|
||||
notes: event.notes,
|
||||
breakTimeMinutes: 0, // Should be passed from event if supported
|
||||
applicationId: state.attendance.activeApplicationId,
|
||||
),
|
||||
);
|
||||
emit(state.copyWith(
|
||||
status: ClockInStatus.success,
|
||||
attendance: newStatus,
|
||||
));
|
||||
} catch (e) {
|
||||
emit(state.copyWith(
|
||||
await handleError(
|
||||
emit: emit,
|
||||
action: () async {
|
||||
final AttendanceStatus newStatus = await _clockOut(
|
||||
ClockOutArguments(
|
||||
notes: event.notes,
|
||||
breakTimeMinutes: 0,
|
||||
applicationId: state.attendance.activeApplicationId,
|
||||
),
|
||||
);
|
||||
emit(state.copyWith(
|
||||
status: ClockInStatus.success,
|
||||
attendance: newStatus,
|
||||
));
|
||||
},
|
||||
onError: (String errorKey) => state.copyWith(
|
||||
status: ClockInStatus.failure,
|
||||
errorMessage: e.toString(),
|
||||
));
|
||||
}
|
||||
errorMessage: errorKey,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ class ClockInCubit extends Cubit<ClockInState> { // 500m radius
|
||||
return;
|
||||
}
|
||||
|
||||
_getCurrentLocation();
|
||||
await _getCurrentLocation();
|
||||
} catch (e) {
|
||||
emit(state.copyWith(isLoading: false, error: e.toString()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user