Skip to content

Commit

Permalink
Merge pull request #8 from styrix560/1-add-merging-of-bookings
Browse files Browse the repository at this point in the history
1 add merging of bookings
  • Loading branch information
styrix560 authored Jun 1, 2024
2 parents ed7dbda + 2bfae27 commit efd22ee
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 53 deletions.
11 changes: 7 additions & 4 deletions integration_test/app_test.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import "package:bbs4/api/mock_api.dart";
import "package:bbs4/main.dart";
import "package:bbs4/types/booking.dart";
import "package:bbs4/types/booking_time.dart";
import "package:bbs4/types/global_data.dart";
import "package:bbs4/types/price_type.dart";
import "package:bbs4/types/seat.dart";
Expand Down Expand Up @@ -49,7 +50,7 @@ Future<void> main() async {
home: const MainApp(),
));

final globalData = GlobalData();
final globalData = GlobalData(BookingTime.afternoon);

await clickSeat(tester, "R1 P1");

Expand Down Expand Up @@ -88,8 +89,10 @@ Future<void> main() async {
));

final globalData = GlobalData();
globalData.loadBookings();
await wait(1); // let bookings finish
// delete bookings to avoid merging
globalData.bookings.value = [];
await globalData.loadBookings();
await Future.delayed(const Duration(seconds: 1), () {});
await tester.pumpAndSettle();

expect(globalData.activeBooking.value, null);
Expand Down Expand Up @@ -158,7 +161,7 @@ Future<void> main() async {
}

Future<void> wait([int seconds = 5]) async {
await Future.delayed(Duration(seconds: seconds));
await Future.delayed(Duration(seconds: seconds), () {});
}

Future<void> clickSeat(WidgetTester tester, String seatText) async {
Expand Down
69 changes: 39 additions & 30 deletions lib/types/global_data.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,40 +34,33 @@ class GlobalData {
static final Map<BookingTime, GlobalData> globalDataInstances = {};
static late final Api api;

void pushBookings() {
Future<void> pushBookings() async {
isTransactionInProgress.value = true;
// ignore: prefer-async-await
api
.writeBookings(bookingTime.germanName, bookings.value)
.then((_) => snackbar("Buchungen erfolgreich geschrieben"))
.onError(
(error, stackTrace) {
logger.error("error pushing changes to db", error, stackTrace);
snackbar("Fehler beim Schreiben der Buchungen");
},
).then((_) {
isTransactionInProgress.value = false;
});
try {
await api.writeBookings(bookingTime.germanName, bookings.value);
} on Exception catch (error, stacktrace) {
logger.error("error pushing changes to db", error, stacktrace);
snackbar("Fehler beim Schreiben der Buchungen");
}
snackbar("Buchungen erfolgreich geschrieben");
isTransactionInProgress.value = false;
}

void loadBookings() {
Future<void> loadBookings() async {
isTransactionInProgress.value = true;
api
.getBookings(bookingTime.germanName)
.then((value) {
bookings.value = value;
})
.then((_) => snackbar("Buchungen erfolreich geladen"))
.onError((error, stackTrace) {
logger.error("error loading bookings", error, stackTrace);
snackbar(
"Fehler beim Laden der Buchungen. Ist Internet aktiviert und "
"geht die Uhr richtig?",
);
})
.then((value) {
isTransactionInProgress.value = false;
});
late final List<Booking> newBookings;
try {
newBookings = await api.getBookings(bookingTime.germanName);
} on Exception catch (error, stacktrace) {
logger.error("error loading bookings", error, stacktrace);
snackbar(
"Fehler beim Laden der Buchungen. Ist Internet aktiviert und "
"geht die Uhr richtig?",
);
}
bookings.value = mergeBookings(bookings.value, newBookings);
snackbar("Buchungen erfolgreich geladen");
isTransactionInProgress.value = false;
}

static final ValueNotifier<BookingTime> currentBookingTime =
Expand Down Expand Up @@ -147,4 +140,20 @@ class GlobalData {
_activeBooking.value =
Booking(uuid.v4(), "", "", "", {firstSeat}, 0, PriceType.normal, "");
}

// Local changes take absolute precedence. Only if the external bookings
// contain a booking, that we do not know at all, we add it to the list
static List<Booking> mergeBookings(
List<Booking> internal,
List<Booking> external,
) {
final keysToBookings = <String, Booking>{
for (final booking in internal) booking.id: booking,
};
keysToBookings.addAll({
for (final booking in external)
if (!keysToBookings.containsKey(booking.id)) booking.id: booking,
});
return keysToBookings.values.toList();
}
}
38 changes: 19 additions & 19 deletions lib/widgets/seat_cell.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import "../types/booking_time.dart";
import "../types/global_data.dart";
import "../types/price_type.dart";
import "../types/seat.dart";
import "../utils.dart";

class SeatCellWidget extends HookWidget {
const SeatCellWidget(
Expand All @@ -25,26 +24,26 @@ class SeatCellWidget extends HookWidget {
final seat = Seat(y, x);
final globalData = GlobalData.fromTime(bookingTime);
final activeBooking = globalData.activeBooking.value;
final rebuild = useRebuild();
final previousBooking = useRef<Booking?>(null);
// final rebuild = useRebuild();
// final previousBooking = useRef<Booking?>(null);
useListenable(globalData.activeBooking);
useListenable(globalData.bookings);

bool shouldRebuild() {
final prevBooking = previousBooking.value?.copy();
previousBooking.value = activeBooking?.copy();

bool isActive(Booking? booking) => booking?.seats.contains(seat) ?? false;
final isActiveNow = isActive(activeBooking);
final wasActiveBefore = isActive(prevBooking);
if (isActiveNow != wasActiveBefore) return true;
if (!isActiveNow) return false;

return activeBooking!.seats.length != prevBooking!.seats.length ||
activeBooking.lastName != prevBooking.lastName ||
activeBooking.pricePaid != prevBooking.pricePaid ||
activeBooking.priceType != prevBooking.priceType;
}
// bool shouldRebuild() {
// final prevBooking = previousBooking.value?.copy();
// previousBooking.value = activeBooking?.copy();
//
// bool isActive(Booking? booking) => booking?.seats.contains(seat) ?? false;
// final isActiveNow = isActive(activeBooking);
// final wasActiveBefore = isActive(prevBooking);
// if (isActiveNow != wasActiveBefore) return true;
// if (!isActiveNow) return false;
//
// return activeBooking!.seats.length != prevBooking!.seats.length ||
// activeBooking.lastName != prevBooking.lastName ||
// activeBooking.pricePaid != prevBooking.pricePaid ||
// activeBooking.priceType != prevBooking.priceType;
// }

Color getColor() {
Color getColorForBooking(
Expand Down Expand Up @@ -126,7 +125,8 @@ class SeatCellWidget extends HookWidget {
return;
}

final newSeats = activeBooking!.seats;
// make a copy to avoid changing the reference in activeBooking
final newSeats = Set.of(activeBooking!.seats);
if (newSeats.contains(seat)) {
newSeats.remove(seat);
} else {
Expand Down

0 comments on commit efd22ee

Please sign in to comment.