Skip to content

Commit

Permalink
feat: 예약을 듣는 유스케이스 등록
Browse files Browse the repository at this point in the history
  • Loading branch information
potados99 committed Feb 17, 2022
1 parent c3d0c45 commit 5b45070
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 6 deletions.
39 changes: 33 additions & 6 deletions src/data/repositories/BookingRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,37 +17,64 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import Config from '../../common/Config';
import axios from 'axios';
import {plainToClass} from 'class-transformer';
import BookingOption from '../../domain/entities/BookingOption';
import Config from '../../common/Config';
import Booking from '../../domain/entities/Booking';
import EventSource from 'react-native-event-source';
import BookingOption from '../../domain/entities/BookingOption';
import {plainToClass} from 'class-transformer';

export default class BookingRepository {
static instance = new BookingRepository();

private url = {
options: (cafeteriaId: number) => `${Config.baseUrl}/booking/options?cafeteriaId=${cafeteriaId}`,
bookings: `${Config.baseUrl}/booking/bookings`,
bookings: (sse: boolean = false) => `${Config.baseUrl}/booking/bookings?sse=${sse}`,
bookingsWithId: (bookingId: number) => `${Config.baseUrl}/booking/bookings/${bookingId}`,
};

private previousEventSource?: EventSource = undefined;

async getBookingOptions(cafeteriaId: number) {
return plainToClass(BookingOption, (await axios.get(this.url.options(cafeteriaId))).data as any[], {
excludeExtraneousValues: true,
});
}

async makeBooking(params: Record<string, any>) {
await axios.post(this.url.bookings, params);
await axios.post(this.url.bookings(), params);
}

async getMyBookings() {
return plainToClass(Booking, (await axios.get(this.url.bookings)).data as any[], {
return plainToClass(Booking, (await axios.get(this.url.bookings())).data as any[], {
excludeExtraneousValues: true,
});
}

listenForMyBookings(onBookings: (bookings: Booking[]) => void) {
this.previousEventSource?.close();

const eventSource = new EventSource(this.url.bookings(true), {withCredentials: true});

eventSource.addEventListener('bookings', event => {
const payload = event['data'] as string;

const bookings = plainToClass(Booking, JSON.parse(payload) as any[], {
excludeExtraneousValues: true,
});

onBookings(bookings);
});

this.previousEventSource = eventSource;
}

stopListeningForMyBookings() {
this.previousEventSource?.removeAllListeners();
this.previousEventSource?.close();
this.previousEventSource = undefined;
}

async cancelBooking(bookingId: number) {
await axios.delete(this.url.bookingsWithId(bookingId));
}
Expand Down
3 changes: 3 additions & 0 deletions src/domain/usecases/GetMyBookings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import UseCase from './UseCase';
import Booking from '../entities/Booking';
import BookingRepository from '../../data/repositories/BookingRepository';

/**
* REST 요청으로 예약 내역을 즉시 가져옵니다.
*/
class GetMyBookings extends UseCase<void, Booking[]> {
constructor(private readonly bookingRepository: BookingRepository) {
super();
Expand Down
46 changes: 46 additions & 0 deletions src/domain/usecases/ListenForMyBookings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/**
* This file is part of INU Cafeteria.
*
* Copyright 2021 INU Global App Center <potados99@gmail.com>
*
* INU Cafeteria is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* INU Cafeteria is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

import UseCase from './UseCase';
import Booking from '../entities/Booking';
import BookingRepository from '../../data/repositories/BookingRepository';

type Params = {
onBookings?: (bookings: Booking[]) => void;
};

/**
* SSE로 예약 내역을 구독합니다.
* 인자로 undefined를 넘기면 구독 중단입니다.
*/
class ListenForMyBookings extends UseCase<Params, void> {
constructor(private readonly bookingRepository: BookingRepository) {
super();
}

async onExecute({onBookings}: Params): Promise<void> {
if (onBookings == null) {
this.bookingRepository.stopListeningForMyBookings();
} else {
this.bookingRepository.listenForMyBookings(onBookings);
}
}
}

export default new ListenForMyBookings(BookingRepository.instance);

0 comments on commit 5b45070

Please sign in to comment.