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
44 changes: 40 additions & 4 deletions Keychy/Keychy.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,6 @@
AA2146B12F15D43C0048D40E /* BundleEditView+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2146B02F15D43C0048D40E /* BundleEditView+Alert.swift */; };
AA2146B52F15D8490048D40E /* KeyringCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2146B42F15D8490048D40E /* KeyringCell.swift */; };
AA2146B72F15E5B60048D40E /* BundleEditView+SelectSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2146B62F15E5B60048D40E /* BundleEditView+SelectSheet.swift */; };
AA2146B92F160E2B0048D40E /* BundleEditView+RestoreSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2146B82F160E2B0048D40E /* BundleEditView+RestoreSelection.swift */; };
AA2146BB2F161D0C0048D40E /* BundleEditView+Initialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA2146BA2F161D0C0048D40E /* BundleEditView+Initialization.swift */; };
AA3908F82EC8BF0400D87EEC /* BundleDetailView+SaveImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3908F72EC8BF0400D87EEC /* BundleDetailView+SaveImage.swift */; };
AA3909462EC9F29500D87EEC /* UIApplication+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA3909452EC9F29500D87EEC /* UIApplication+Extension.swift */; };
Expand All @@ -384,6 +383,16 @@
AABA4DBD2ED2D6CA00A7D062 /* festivalCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = AABA4DBC2ED2D6CA00A7D062 /* festivalCard.swift */; };
AAEB46AD2EC1C893002B13E5 /* BundleMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAEB46AC2EC1C893002B13E5 /* BundleMenu.swift */; };
AAEB46AF2EC1D648002B13E5 /* BundleNameEditView.swift in Sources */ = {isa = PBXBuildFile; fileRef = AAEB46AE2EC1D648002B13E5 /* BundleNameEditView.swift */; };
BC0001072F35F00100000007 /* BundleCreateView+SelectSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC0001012F35F00100000001 /* BundleCreateView+SelectSheet.swift */; };
BC0001082F35F00100000008 /* BundleCreateView+Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC0001022F35F00100000002 /* BundleCreateView+Alert.swift */; };
BC0001092F35F00100000009 /* BundleCreateView+Purchase.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC0001032F35F00100000003 /* BundleCreateView+Purchase.swift */; };
BC00010A2F35F0010000000A /* BundleCreateView+Initialization.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC0001042F35F00100000004 /* BundleCreateView+Initialization.swift */; };
BC00010B2F35F0010000000B /* BundleCreateView+Capture.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC0001052F35F00100000005 /* BundleCreateView+Capture.swift */; };
BC00010C2F35F0010000000C /* BundleEditView+Capture.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC0001062F35F00100000006 /* BundleEditView+Capture.swift */; };
BC00020F2F35F00200000003 /* BundleSearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC00020D2F35F00200000001 /* BundleSearchBar.swift */; };
BC0002102F35F00200000004 /* KeyringEmptyStateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC00020E2F35F00200000002 /* KeyringEmptyStateView.swift */; };
BC0002132F35F00200000006 /* KeyringSelectionContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC0002112F35F00200000005 /* KeyringSelectionContent.swift */; };
BC0002152F35F00200000008 /* BundleKeyringCellView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BC0002142F35F00200000007 /* BundleKeyringCellView.swift */; };
C645AE9F2EB1055C004BFE69 /* CategoryTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = C645AE9E2EB1055C004BFE69 /* CategoryTabBar.swift */; };
C645AEA32EB1B8FC004BFE69 /* DataInitializer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C645AEA22EB1B8FC004BFE69 /* DataInitializer.swift */; };
C665DDE82EAEFA8700CE4495 /* CoinChargeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C665DDE72EAEFA8700CE4495 /* CoinChargeView.swift */; };
Expand Down Expand Up @@ -808,7 +817,6 @@
AA2146B02F15D43C0048D40E /* BundleEditView+Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleEditView+Alert.swift"; sourceTree = "<group>"; };
AA2146B42F15D8490048D40E /* KeyringCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyringCell.swift; sourceTree = "<group>"; };
AA2146B62F15E5B60048D40E /* BundleEditView+SelectSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleEditView+SelectSheet.swift"; sourceTree = "<group>"; };
AA2146B82F160E2B0048D40E /* BundleEditView+RestoreSelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleEditView+RestoreSelection.swift"; sourceTree = "<group>"; };
AA2146BA2F161D0C0048D40E /* BundleEditView+Initialization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleEditView+Initialization.swift"; sourceTree = "<group>"; };
AA3908F72EC8BF0400D87EEC /* BundleDetailView+SaveImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleDetailView+SaveImage.swift"; sourceTree = "<group>"; };
AA3909452EC9F29500D87EEC /* UIApplication+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIApplication+Extension.swift"; sourceTree = "<group>"; };
Expand All @@ -835,6 +843,16 @@
AABA4DBC2ED2D6CA00A7D062 /* festivalCard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = festivalCard.swift; sourceTree = "<group>"; };
AAEB46AC2EC1C893002B13E5 /* BundleMenu.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleMenu.swift; sourceTree = "<group>"; };
AAEB46AE2EC1D648002B13E5 /* BundleNameEditView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleNameEditView.swift; sourceTree = "<group>"; };
BC0001012F35F00100000001 /* BundleCreateView+SelectSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleCreateView+SelectSheet.swift"; sourceTree = "<group>"; };
BC0001022F35F00100000002 /* BundleCreateView+Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleCreateView+Alert.swift"; sourceTree = "<group>"; };
BC0001032F35F00100000003 /* BundleCreateView+Purchase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleCreateView+Purchase.swift"; sourceTree = "<group>"; };
BC0001042F35F00100000004 /* BundleCreateView+Initialization.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleCreateView+Initialization.swift"; sourceTree = "<group>"; };
BC0001052F35F00100000005 /* BundleCreateView+Capture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleCreateView+Capture.swift"; sourceTree = "<group>"; };
BC0001062F35F00100000006 /* BundleEditView+Capture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "BundleEditView+Capture.swift"; sourceTree = "<group>"; };
BC00020D2F35F00200000001 /* BundleSearchBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleSearchBar.swift; sourceTree = "<group>"; };
BC00020E2F35F00200000002 /* KeyringEmptyStateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyringEmptyStateView.swift; sourceTree = "<group>"; };
BC0002112F35F00200000005 /* KeyringSelectionContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = KeyringSelectionContent.swift; sourceTree = "<group>"; };
BC0002142F35F00200000007 /* BundleKeyringCellView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BundleKeyringCellView.swift; sourceTree = "<group>"; };
C645AE9E2EB1055C004BFE69 /* CategoryTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoryTabBar.swift; sourceTree = "<group>"; };
C645AEA22EB1B8FC004BFE69 /* DataInitializer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataInitializer.swift; sourceTree = "<group>"; };
C665DDE72EAEFA8700CE4495 /* CoinChargeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoinChargeView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1792,6 +1810,7 @@
4CEC61F62EAE08DA0099ECEE /* BackgroundCell.swift */,
AA9115072EB126A60026E9BC /* CarabinerCell.swift */,
AA2146B42F15D8490048D40E /* KeyringCell.swift */,
BC0002142F35F00200000007 /* BundleKeyringCellView.swift */,
AAA4467B2EC64C9900080AB1 /* SelectBackgroundSheet.swift */,
AAA446812EC6519700080AB1 /* SelectCarabinerSheet.swift */,
4C2525D92F35B2A7003CC5AD /* BundleSheetFilterBar.swift */,
Expand All @@ -1800,6 +1819,9 @@
F82FD6112F9442AAAD58DB97 /* BundleSheetToggleButtons.swift */,
5E036016318043AC801A19DA /* BundlePurchaseCartItem.swift */,
AA6298552EC3AD16001576C0 /* DraggableSheet.swift */,
BC00020D2F35F00200000001 /* BundleSearchBar.swift */,
BC00020E2F35F00200000002 /* KeyringEmptyStateView.swift */,
BC0002112F35F00200000005 /* KeyringSelectionContent.swift */,
);
path = Shared;
sourceTree = "<group>";
Expand Down Expand Up @@ -2117,6 +2139,11 @@
isa = PBXGroup;
children = (
AA6298532EC39065001576C0 /* BundleCreateView.swift */,
BC0001042F35F00100000004 /* BundleCreateView+Initialization.swift */,
BC0001052F35F00100000005 /* BundleCreateView+Capture.swift */,
BC0001022F35F00100000002 /* BundleCreateView+Alert.swift */,
BC0001012F35F00100000001 /* BundleCreateView+SelectSheet.swift */,
BC0001032F35F00100000003 /* BundleCreateView+Purchase.swift */,
AA0219DD2EB1C041006EF269 /* BundleNameInputView.swift */,
);
path = Create;
Expand Down Expand Up @@ -2184,7 +2211,7 @@
children = (
AA6298512EC233D2001576C0 /* BundleEditView.swift */,
AA2146BA2F161D0C0048D40E /* BundleEditView+Initialization.swift */,
AA2146B82F160E2B0048D40E /* BundleEditView+RestoreSelection.swift */,
BC0001062F35F00100000006 /* BundleEditView+Capture.swift */,
AA2146B02F15D43C0048D40E /* BundleEditView+Alert.swift */,
AA2146B62F15E5B60048D40E /* BundleEditView+SelectSheet.swift */,
AA2146AE2F15D0160048D40E /* BundleEditView+Purchase.swift */,
Expand Down Expand Up @@ -2740,6 +2767,10 @@
AA0A54B92EC05C41007B5413 /* BundleRingComponent.swift in Sources */,
C6C361422ED44EE4009642F4 /* Showcase25BoardView+Sheet.swift in Sources */,
4C2525DA2F35B2A7003CC5AD /* BundleSheetFilterBar.swift in Sources */,
BC00020F2F35F00200000003 /* BundleSearchBar.swift in Sources */,
BC0002102F35F00200000004 /* KeyringEmptyStateView.swift in Sources */,
BC0002132F35F00200000006 /* KeyringSelectionContent.swift in Sources */,
BC0002152F35F00200000008 /* BundleKeyringCellView.swift in Sources */,
3828F5452EC4CC0A00F1B040 /* CollectionViewModel+Filter.swift in Sources */,
38C3C28A2EC1D879003C5DE1 /* UnpackPopup.swift in Sources */,
C6C361E42ED4AF48009642F4 /* Showcase25BoardView+Grid.swift in Sources */,
Expand Down Expand Up @@ -2799,7 +2830,12 @@
4CEC61EC2EAE08C00099ECEE /* BodyType.swift in Sources */,
C6C361E22ED4AC49009642F4 /* SubmitCompleteAlert.swift in Sources */,
C6C361442ED44EF1009642F4 /* Showcase25BoardView+Detail.swift in Sources */,
AA2146B92F160E2B0048D40E /* BundleEditView+RestoreSelection.swift in Sources */,
BC0001072F35F00100000007 /* BundleCreateView+SelectSheet.swift in Sources */,
BC0001082F35F00100000008 /* BundleCreateView+Alert.swift in Sources */,
BC0001092F35F00100000009 /* BundleCreateView+Purchase.swift in Sources */,
BC00010A2F35F0010000000A /* BundleCreateView+Initialization.swift in Sources */,
BC00010B2F35F0010000000B /* BundleCreateView+Capture.swift in Sources */,
BC00010C2F35F0010000000C /* BundleEditView+Capture.swift in Sources */,
38C3C2922EC1F787003C5DE1 /* CollectionKeyringDetailView+Lifecycle.swift in Sources */,
4C8426642ED375840050B6FE /* ColorPalette.swift in Sources */,
C6C402A32EB40ACA006B58DF /* AlarmView.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,16 +136,18 @@ struct PurchaseToolbarButton: View {
// MARK: - Custom Text Toolbar Button
struct TextToolbarButton: View {
let title: String
var isDisabled: Bool = false
let action: () -> Void

var body: some View {
Button(action: action) {
Text(title)
.typography(.suit17B)
.padding(4)
.foregroundStyle(.black100)
.foregroundStyle(isDisabled ? .gray300 : .main500)
}
.frame(width: 62, height: 44)
.glassEffect(.regular.interactive(), in: .capsule)
.disabled(isDisabled)
}
}
7 changes: 7 additions & 0 deletions Keychy/Keychy/Core/DesignSystem/Colors/Gradient+Keychy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import SwiftUI

enum GradientStyle {
case primary
case festivalPublished
}

extension GradientStyle {
Expand All @@ -24,6 +25,12 @@ extension GradientStyle {
startPoint: .topLeading,
endPoint: .bottomTrailing
)
case .festivalPublished:
return LinearGradient(
colors: [.gradient3, .gradient4],
startPoint: .topLeading,
endPoint: .bottomTrailing
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ struct Typography {
static let notosans12R = Typography(font: .custom(.notoSansRegular, size: 12), lineSpacing: 0)

static let notosans13M = Typography(font: .custom(.notoSansMedium, size: 13), lineSpacing: 0)
static let notosans13SB = Typography(font: .custom(.notoSansSemiBold, size: 13), lineSpacing: 0)

static let notosans14SB = Typography(font: .custom(.notoSansSemiBold, size: 14), lineSpacing: 0)
static let notosans14M = Typography(font: .custom(.notoSansMedium, size: 14), lineSpacing: 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,41 +192,39 @@ extension BundleViewModel {

/// 키링 선택 시트용 정렬된 키링 리스트
/// - 1순위: 현재 위치에 선택된 키링
/// - 2순위: 일반 키링들 (선택되지 않고, published/packaged 아님)
/// - 3순위: 다른 위치에 장착된 키링들
/// - 1순위: 현재 위치에 장착된 키링
/// - 2순위: 다른 위치에 장착된 키링들
/// - 3순위: 일반 키링들 (선택되지 않고, published/packaged 아님)
/// - 4순위: published 또는 packaged 상태의 키링들 (맨 뒤)
func sortedKeyringsForSelection(selectedKeyrings: [Int: Keyring], selectedPosition: Int) -> [Keyring] {
let selectedKeyring = selectedKeyrings[selectedPosition]
let currentKeyring = selectedKeyrings[selectedPosition]

return keyring.sorted { keyring1, keyring2 in
let isKeyring1SelectedHere = keyring1.id == selectedKeyring?.id
let isKeyring2SelectedHere = keyring2.id == selectedKeyring?.id
let isKeyring1Current = keyring1.id == currentKeyring?.id
let isKeyring2Current = keyring2.id == currentKeyring?.id

let isKeyring1SelectedElsewhere = selectedKeyrings.values.contains { $0.id == keyring1.id } && !isKeyring1SelectedHere
let isKeyring2SelectedElsewhere = selectedKeyrings.values.contains { $0.id == keyring2.id } && !isKeyring2SelectedHere
let isKeyring1Elsewhere = selectedKeyrings.values.contains { $0.id == keyring1.id } && !isKeyring1Current
let isKeyring2Elsewhere = selectedKeyrings.values.contains { $0.id == keyring2.id } && !isKeyring2Current

let isKeyring1Unavailable = keyring1.status == .published || keyring1.status == .packaged
let isKeyring2Unavailable = keyring2.status == .published || keyring2.status == .packaged

if isKeyring1SelectedHere != isKeyring2SelectedHere {
return isKeyring1SelectedHere
// 1순위: 현재 위치 키링
if isKeyring1Current != isKeyring2Current {
return isKeyring1Current
}

let isKeyring1Normal = !isKeyring1SelectedElsewhere && !isKeyring1Unavailable
let isKeyring2Normal = !isKeyring2SelectedElsewhere && !isKeyring2Unavailable

if isKeyring1Normal != isKeyring2Normal {
return isKeyring1Normal
}

if isKeyring1SelectedElsewhere != isKeyring2SelectedElsewhere {
return isKeyring1SelectedElsewhere
// 2순위: 다른 위치 장착 키링
if isKeyring1Elsewhere != isKeyring2Elsewhere {
return isKeyring1Elsewhere
}

// 3순위: 일반 키링 (사용 불가 아닌 것)
if isKeyring1Unavailable != isKeyring2Unavailable {
return isKeyring2Unavailable
}

// 동일 순위면 원래 순서 유지
guard let index1 = keyring.firstIndex(of: keyring1),
let index2 = keyring.firstIndex(of: keyring2) else {
return false
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// BundleCreateView+Alert.swift
// Keychy
//
// Created by 김서현 on 11/12/25.
//

import SwiftUI

// MARK: - Alert 컨텐츠
extension BundleCreateView {
var alertContent: some View {
ZStack {
// 구매 성공 Alert
if showPurchaseSuccessAlert {
Color.black20
.ignoresSafeArea()
.onTapGesture {
showPurchaseSuccessAlert = false
purchasesSuccessScale = 0.3
}

KeychyAlert(type: .checkmark, message: "구매가 완료되었어요!", isPresented: $showPurchaseSuccessAlert)
.zIndex(101)
}

// 구매 실패 Alert
if showPurchaseFailAlert {
ZStack {
Color.black20
.ignoresSafeArea()
.onTapGesture {
showPurchaseFailAlert = false
purchaseFailScale = 0.3
}

PurchaseFailAlert(
checkmarkScale: purchaseFailScale,
onCancel: {
showPurchaseFailAlert = false
purchaseFailScale = 0.3
},
onCharge: {
showPurchaseFailAlert = false
purchaseFailScale = 0.3
bundleVM.saveCurrentSelection()
router.push(.coinCharge)
}
)
.padding(.horizontal, 51)
}
}
}
}
}
Loading