Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions EATSSU/App/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@
"home.dodamEtc" = "Asian food, pork cutlet, salad, gukbap, etc.\nCafe";
/// RestaurantMenuGroupCell - "영업 시간이 아니에요."
"home.notBusinessHour" = "Closed now";
/// RestaurantMenuGroupCell - "메뉴를 불러오지 못했어요."
"home.menuLoadFailed" = "Couldn't load the menu";
/// RestaurantTableViewHeader - "기숙사 식당"
"home.dormitoryRestaurant" = "Dormitory Restaurant";

Expand Down
2 changes: 2 additions & 0 deletions EATSSU/App/Resources/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@
"home.dodamEtc" = "アジアンフード、トンカツ、サラダ、クッパなど\nカフェ";
/// RestaurantMenuGroupCell - "영업 시간이 아니에요."
"home.notBusinessHour" = "営業時間外です。";
/// RestaurantMenuGroupCell - "메뉴를 불러오지 못했어요."
"home.menuLoadFailed" = "メニューを読み込めませんでした。";
/// RestaurantTableViewHeader - "기숙사 식당"
"home.dormitoryRestaurant" = "寮食堂";

Expand Down
2 changes: 2 additions & 0 deletions EATSSU/App/Resources/ko.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@
"home.dodamEtc" = "아시안푸드, 돈까스, 샐러드, 국밥 등\n카페";
/// RestaurantMenuGroupCell - "영업 시간이 아니에요."
"home.notBusinessHour" = "영업 시간이 아니에요.";
/// RestaurantMenuGroupCell - "메뉴를 불러오지 못했어요."
"home.menuLoadFailed" = "메뉴를 불러오지 못했어요.";
/// RestaurantTableViewHeader - "기숙사 식당"
"home.dormitoryRestaurant" = "기숙사 식당";

Expand Down
2 changes: 2 additions & 0 deletions EATSSU/App/Resources/vi.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,8 @@
"home.dodamEtc" = "Món Á, tonkatsu, salad, gukbap, v.v.\nQuán cà phê";
/// RestaurantMenuGroupCell - "영업 시간이 아니에요."
"home.notBusinessHour" = "Hiện không trong giờ hoạt động.";
/// RestaurantMenuGroupCell - "메뉴를 불러오지 못했어요."
"home.menuLoadFailed" = "Không thể tải thực đơn.";
/// RestaurantTableViewHeader - "기숙사 식당"
"home.dormitoryRestaurant" = "Nhà ăn ký túc xá";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,11 @@ final class SetNickNameViewController: BaseViewController {
myPageVC.showToast(message: TextLiteral.Auth.updateSuccess, type: .success)
}
} else {
let homeVC = HomeViewController()
// 로그인 완료와 같은 탭바 화면으로 이동 (홈만 올리면 지도·찜·마이 탭이 없다)
let customTabVC = CustomTabBarContainerController()
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let keyWindow = windowScene.windows.first(where: { $0.isKeyWindow }) {
keyWindow.replaceRootViewController(
UINavigationController(rootViewController: homeVC)
)
keyWindow.replaceRootViewController(customTabVC)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,21 @@ final class RestaurantMenuGroupCell: BaseTableViewCell {

/// 메뉴 데이터를 이용해 스택뷰를 구성
/// - Parameter menus: 메뉴 리스트 (MenuTypeInfo 배열)
/// - Parameter emptyMessage: 메뉴가 없을 때 보여줄 문구 (영업 시간 아님 / 조회 실패)
/// - Parameter indexPath: 현재 테이블뷰 indexPath (섹션, row)
/// - Parameter onMenuTap: 터치 시 실행할 클로저 (section, index 전달)
func configure(with menus: [MenuTypeInfo], at indexPath: IndexPath, onMenuTap: @escaping (IndexPath, Int) -> Void) {
func configure(
with menus: [MenuTypeInfo],
emptyMessage: String = TextLiteral.Home.notBusinessHour,
at indexPath: IndexPath,
onMenuTap: @escaping (IndexPath, Int) -> Void
) {
// 이전 뷰들 제거 (주의: prepareForReuse와 중복 제거됨 → 안정성 보장용)
menuStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }

// 메뉴가 없을 경우 → 안내 텍스트 표시
if menus.isEmpty {
emptyLabel.text = emptyMessage
emptyLabel.isHidden = false
menuStackView.isHidden = true
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ final class CustomTimeTabController: BaseViewController {
dateSubject.send(date)
}

/// 같은 날짜라도 다시 조회한다 (리뷰 작성 후 평점 갱신 등)
/// 날짜 파이프라인은 같은 날짜를 거르므로 거치지 않고 바로 요청한다
func reloadData(for date: Date) {
performDateUpdate(date)
}

private func setupPageViewController() {
addChild(pageViewController)
view.addSubview(pageViewController.view)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ final class HomeRestaurantViewController: BaseViewController {

// 고정 메뉴 데이터 (간식코너)
var fixMenuTableViewData: [String: [Menus]] = [:]

// 메뉴 조회에 실패한 식당. 빈 목록을 "영업 시간 아님"과 구분해 안내한다
private var failedRestaurants: Set<String> = []

// MARK: - UI Components

Expand Down Expand Up @@ -189,6 +192,8 @@ final class HomeRestaurantViewController: BaseViewController {
guard let self else { return }

let isHoliday = await self.isHoliday(date: date)
// 공휴일을 조회하는 사이 다른 날짜로 바뀌었다면 반영하지 않는다
guard !_Concurrency.Task.isCancelled else { return }

if !FirebaseRemoteConfig.shared.isVacationPeriod,
!weekday.isWeekend,
Expand Down Expand Up @@ -227,6 +232,7 @@ final class HomeRestaurantViewController: BaseViewController {
private func hideSnackCorner() {
isSelectable = false
fixMenuTableViewData[RestaurantIdentifier.snackCorner.rawValue] = []
setLoadFailed(false, for: RestaurantIdentifier.snackCorner.rawValue)

if let sectionIndex = getSectionIndex(for: RestaurantIdentifier.snackCorner.rawValue) {
restaurantView.restaurantTableView.reloadSections(
Expand Down Expand Up @@ -264,7 +270,11 @@ extension HomeRestaurantViewController: UITableViewDataSource {
? (fixMenuTableViewData[sectionKey]?.map { .fix($0) } ?? [])
: (changeMenuTableViewData[sectionKey]?.map { .change($0) } ?? [])

cell.configure(with: menuList, at: indexPath) { [weak self] indexPath, menuIndex in
let emptyMessage = failedRestaurants.contains(sectionKey)
? TextLiteral.Home.menuLoadFailed
: TextLiteral.Home.notBusinessHour

cell.configure(with: menuList, emptyMessage: emptyMessage, at: indexPath) { [weak self] indexPath, menuIndex in
self?.handleMenuTap(section: indexPath.section, menuIndex: menuIndex)
}
return cell
Expand Down Expand Up @@ -347,7 +357,8 @@ extension HomeRestaurantViewController: UITableViewDataSource {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let sceneDelegate = windowScene.delegate as? SceneDelegate,
let window = sceneDelegate.window {
window.replaceRootViewController(loginVC)
// 신규 가입자는 로그인 화면에서 닉네임 설정으로 push되므로 네비게이션으로 감싼다
window.replaceRootViewController(UINavigationController(rootViewController: loginVC))
}
}
alert.addAction(confirm)
Expand Down Expand Up @@ -428,13 +439,22 @@ extension HomeRestaurantViewController: UITableViewDelegate {
// MARK: - Network

extension HomeRestaurantViewController {
private func setLoadFailed(_ didFail: Bool, for restaurant: String) {
if didFail {
failedRestaurants.insert(restaurant)
} else {
failedRestaurants.remove(restaurant)
}
}
Comment thread
Hrepay marked this conversation as resolved.

// 변경 메뉴 요청 API 호출
func fetchChangeMenuData(date: String, restaurant: String, time: String) async {

// UI 업데이트에 사용할 메뉴 목록과 애니메이션 타입을 저장할 변수
let menusToUpdate: [ChangeMenuTableResponse]
let animation: UITableView.RowAnimation

var didFail = false

do {
// 비동기 네트워크 요청을 통해 메뉴 데이터 가져오기
let menus: [ChangeMenuTableResponse] = try await withCheckedThrowingContinuation { continuation in
Expand All @@ -458,11 +478,15 @@ extension HomeRestaurantViewController {
print("\(restaurant) 변경 메뉴 조회 실패: \(error.localizedDescription)")
menusToUpdate = []
animation = .none
didFail = true
}

// 메인 스레드에서 UI 업데이트
await MainActor.run {
// 네트워크 요청은 취소되지 않으므로, 다른 날짜로 바뀐 뒤 도착한 응답은 버린다
guard !_Concurrency.Task.isCancelled else { return }
self.changeMenuTableViewData[restaurant] = menusToUpdate
self.setLoadFailed(didFail, for: restaurant)

if let sectionIndex = self.getSectionIndex(for: restaurant) {
self.restaurantView.restaurantTableView.reloadSections(IndexSet(integer: sectionIndex), with: animation)
Expand All @@ -474,6 +498,7 @@ extension HomeRestaurantViewController {
func fetchFixedMenuData(restaurant: String) async {
var menuData: [Menus] = []
var animation: UITableView.RowAnimation = .none
var didFail = false

do {
let response: FixedMenuTableResponse = try await withCheckedThrowingContinuation { continuation in
Expand All @@ -492,11 +517,15 @@ extension HomeRestaurantViewController {
animation = .fade
} catch {
print("\(restaurant) 고정 메뉴 조회 실패: \(error.localizedDescription)")
didFail = true
}

// 메인 스레드에서 UI 업데이트
await MainActor.run {
// 네트워크 요청은 취소되지 않으므로, 다른 날짜로 바뀐 뒤 도착한 응답은 버린다
guard !_Concurrency.Task.isCancelled else { return }
self.fixMenuTableViewData[restaurant] = menuData
self.setLoadFailed(didFail, for: restaurant)
if let sectionIndex = self.getSectionIndex(for: restaurant) {
self.restaurantView.restaurantTableView.reloadSections(IndexSet(integer: sectionIndex), with: animation)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ final class HomeViewController: BaseViewController {

/// 리뷰 작성 후 데이터 새로고침
func refreshAfterReview() {
tabmanController.dateFetchData(for: currentDate)
tabmanController.reloadData(for: currentDate)
}

/// 하단 탭바에서 학식 탭 클릭 시 오늘 날짜로 초기화
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@ final class CustomTabBarContainerController: UITabBarController {
if let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
let sceneDelegate = windowScene.delegate as? SceneDelegate,
let window = sceneDelegate.window {
window.replaceRootViewController(loginVC)
// 신규 가입자는 로그인 화면에서 닉네임 설정으로 push되므로 네비게이션으로 감싼다
window.replaceRootViewController(UINavigationController(rootViewController: loginVC))
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions EATSSU/App/Sources/Utility/Literal/TextLiteral.swift
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,11 @@ enum TextLiteral {
Localization.localized("home.notBusinessHour", fallback: "영업 시간이 아니에요.")
}

/// RestaurantMenuGroupCell - "메뉴를 불러오지 못했어요."
static var menuLoadFailed: String {
Localization.localized("home.menuLoadFailed", fallback: "메뉴를 불러오지 못했어요.")
}

/// RestaurantTableViewHeader - "기숙사 식당"
static var dormitoryRestaurant: String {
Localization.localized("home.dormitoryRestaurant", fallback: "기숙사 식당")
Expand Down
Loading