diff --git a/FontUtility.swift b/FontUtility.swift new file mode 100644 index 0000000..0477927 --- /dev/null +++ b/FontUtility.swift @@ -0,0 +1,71 @@ +// +// FontUtility.swift +// Kabinett +// +// Created by Song Kim on 10/24/24. +// + +import Foundation +import UIKit +import SwiftUI + +class FontUtility { + static let screenSize = UIScreen.main.bounds.width + + static func selectedUIFont(font: String, size: CGFloat) -> UIFont { + if font == "SFMONO" { + return UIFont.monospacedSystemFont(ofSize: size, weight: .regular) + } else if font == "SFDisplay" { + return UIFont.systemFont(ofSize: size) + } else { + return UIFont(name: font, size: size) ?? UIFont.systemFont(ofSize: size) + } + } + + static func selectedFont(font: String, size: CGFloat) -> Font { + if font == "SFMONO" { + return .system(size: size, design: .monospaced) + } else if font == "SFDisplay" { + return .system(size: size) + } else { + return .custom(font, size: size) + } + } + + static func fontSize(font: String) -> CGFloat { + if font == "SourceHanSerifK-Regular" { + return screenSize * 0.0333 + } else if font == "NanumMyeongjoOTF" { + return screenSize * 0.0392 + } else if font == "Baskervville-Regular" { + return screenSize * 0.0369 + } else if font == "Pecita" { + return screenSize * 0.037 + } + return (screenSize * 0.0382) + } + + static func lineSpacing(font: String) -> CGFloat { + if font == "Pecita" { + return screenSize * 0.0069 + } else if font == "SFDisplay" { + return screenSize * 0.0013 + } else if font == "goormSansOTF4" { + return screenSize * 0.0013 + } else if font == "Baskervville-Regular" { + return screenSize * 0.002 + } + return 0.0 + } + + static func kerning(font: String) -> CGFloat { + if font == "SFMONO" { + return -(screenSize * 0.0025) + } else if font == "SFDisplay" { + return (screenSize * 0.0005) + } else if font == "goormSansOTF4" { + return (screenSize * 0.001) + } + return 0.0 + } +} diff --git a/Kabinett.xcodeproj/project.pbxproj b/Kabinett.xcodeproj/project.pbxproj index 9ad34ac..95bcd99 100644 --- a/Kabinett.xcodeproj/project.pbxproj +++ b/Kabinett.xcodeproj/project.pbxproj @@ -63,6 +63,7 @@ 57966BA42C7FF739008D650B /* PreviewLetterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57966BA32C7FF738008D650B /* PreviewLetterView.swift */; }; 57966BA62C81FD98008D650B /* PreviewLetterViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57966BA52C81FD98008D650B /* PreviewLetterViewModel.swift */; }; 57A014FE2CA57E7100580883 /* NanumMyeongjo.otf in Resources */ = {isa = PBXBuildFile; fileRef = 57A014FD2CA57E7100580883 /* NanumMyeongjo.otf */; }; + 57C35C672CCA02130083A346 /* FontUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57C35C662CCA02130083A346 /* FontUtility.swift */; }; 57EBE5B02C69E5F2003ECD7F /* UserSelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57EBE5AF2C69E5F2003ECD7F /* UserSelectionView.swift */; }; 57EBE5B92C6B399C003ECD7F /* StationerySelectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57EBE5B82C6B399C003ECD7F /* StationerySelectionView.swift */; }; 57ED94FA2C84AFAC00A6F187 /* LetterWriteModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 57ED94F92C84AFAC00A6F187 /* LetterWriteModel.swift */; }; @@ -199,6 +200,7 @@ 57966BA32C7FF738008D650B /* PreviewLetterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewLetterView.swift; sourceTree = ""; }; 57966BA52C81FD98008D650B /* PreviewLetterViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreviewLetterViewModel.swift; sourceTree = ""; }; 57A014FD2CA57E7100580883 /* NanumMyeongjo.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = NanumMyeongjo.otf; sourceTree = ""; }; + 57C35C662CCA02130083A346 /* FontUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = FontUtility.swift; path = ../../../../FontUtility.swift; sourceTree = ""; }; 57EBE5AF2C69E5F2003ECD7F /* UserSelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSelectionView.swift; sourceTree = ""; }; 57EBE5B82C6B399C003ECD7F /* StationerySelectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StationerySelectionView.swift; sourceTree = ""; }; 57ED94F92C84AFAC00A6F187 /* LetterWriteModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = LetterWriteModel.swift; path = Kabinett/Presentation/ViewModel/WriteLetter/LetterWriteModel.swift; sourceTree = SOURCE_ROOT; }; @@ -588,6 +590,7 @@ 8366B6F82C65ED0F0021FAE0 /* WriteLetter */ = { isa = PBXGroup; children = ( + 57C35C662CCA02130083A346 /* FontUtility.swift */, 57ED94F92C84AFAC00A6F187 /* LetterWriteModel.swift */, 57ED9CDD2C73698B00A4312C /* StationerySelectionViewModel.swift */, 57ED9CD62C72C8C900A4312C /* UserSelectionViewModel.swift */, @@ -972,6 +975,7 @@ 53A482D42C6B4E8600F00A9A /* LetterBoxView.swift in Sources */, 530C765A2C7638D9007E09C6 /* LetterBoxViewModel.swift in Sources */, 5359618D2C7488DD0031E181 /* TransparentBlurView.swift in Sources */, + 57C35C672CCA02130083A346 /* FontUtility.swift in Sources */, 538150512C8AD5FB007B1E5A /* LayoutHelper.swift in Sources */, 535961912C74F5870031E181 /* CalendarView.swift in Sources */, 530C765C2C76CEFC007E09C6 /* LetterBoxUseCaseStub.swift in Sources */, diff --git a/Kabinett/Application/KabinettApp.swift b/Kabinett/Application/KabinettApp.swift index 164f11f..147c964 100644 --- a/Kabinett/Application/KabinettApp.swift +++ b/Kabinett/Application/KabinettApp.swift @@ -23,14 +23,6 @@ struct KabinettApp: App { @StateObject private var imagePickerViewModel: ImagePickerViewModel @StateObject private var customTabViewModel: CustomTabViewModel - // MARK: - LetterWrite Flow - @StateObject private var userSelectionViewModel: UserSelectionViewModel - @StateObject private var stationerySelectionViewModel: StationerySelectionViewModel - @StateObject private var fontSelectionViewModel: FontSelectionViewModel - @StateObject private var contentWriteViewModel: ContentWriteViewModel - @StateObject private var envelopStampSelectionViewModel: EnvelopeStampSelectionViewModel - @StateObject private var previewLetterViewModel: PreviewLetterViewModel - init() { // Init Firebase App FirebaseApp.configure() @@ -106,34 +98,6 @@ struct KabinettApp: App { _customTabViewModel = .init( wrappedValue: CustomTabViewModel() ) - - // MARK: - LetterWrite ViewModels - _userSelectionViewModel = .init( - wrappedValue: UserSelectionViewModel( - useCase: normalLetterUseCase - ) - ) - _stationerySelectionViewModel = .init( - wrappedValue: StationerySelectionViewModel( - useCase: normalLetterUseCase - ) - ) - _fontSelectionViewModel = .init( - wrappedValue: FontSelectionViewModel() - ) - _contentWriteViewModel = .init( - wrappedValue: ContentWriteViewModel() - ) - _envelopStampSelectionViewModel = .init( - wrappedValue: EnvelopeStampSelectionViewModel( - useCase: normalLetterUseCase - ) - ) - _previewLetterViewModel = .init( - wrappedValue: PreviewLetterViewModel( - useCase: normalLetterUseCase - ) - ) } var body: some Scene { @@ -143,12 +107,6 @@ struct KabinettApp: App { .environmentObject(signUpViewModel) .environmentObject(imagePickerViewModel) .environmentObject(customTabViewModel) - .environmentObject(userSelectionViewModel) - .environmentObject(stationerySelectionViewModel) - .environmentObject(fontSelectionViewModel) - .environmentObject(contentWriteViewModel) - .environmentObject(envelopStampSelectionViewModel) - .environmentObject(previewLetterViewModel) } } diff --git a/Kabinett/Presentation/View/LetterBox/Cells/LetterEnvelopeCell.swift b/Kabinett/Presentation/View/LetterBox/Cells/LetterEnvelopeCell.swift index 6307cbe..90b526a 100644 --- a/Kabinett/Presentation/View/LetterBox/Cells/LetterEnvelopeCell.swift +++ b/Kabinett/Presentation/View/LetterBox/Cells/LetterEnvelopeCell.swift @@ -20,7 +20,7 @@ struct SmallEnvelopeCell: View { .font(.custom("SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.006, forOthers: 0.006))) .foregroundStyle(.contentPrimary) Text(letter.fromUserName) - .font(fontViewModel.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.0122, forOthers: 0.0122))) + .font(FontUtility.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.0122, forOthers: 0.0122))) .foregroundStyle(.contentPrimary) .frame(maxWidth: LayoutHelper.shared.getWidth(forSE: 0.4, forOthers: 0.443), alignment: .leading) } @@ -46,7 +46,7 @@ struct SmallEnvelopeCell: View { .font(.custom("SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.006, forOthers: 0.006))) .foregroundStyle(.contentPrimary) Text(letter.toUserName) - .font(fontViewModel.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.0122, forOthers: 0.0122))) + .font(FontUtility.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.0122, forOthers: 0.0122))) .foregroundStyle(.contentPrimary) .frame(maxWidth: LayoutHelper.shared.getWidth(forSE: 0.17, forOthers: 0.2), alignment: .leading) .padding(.bottom, LayoutHelper.shared.getSize(forSE: 0.008, forOthers: 0.008)) @@ -77,7 +77,7 @@ struct LargeEnvelopeCell: View { .font(.custom("SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.009, forOthers: 0.008))) .foregroundStyle(.contentPrimary) Text(letter.fromUserName) - .font(fontViewModel.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.018, forOthers: 0.017))) + .font(FontUtility.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.018, forOthers: 0.017))) .foregroundStyle(.contentPrimary) .frame(maxWidth: LayoutHelper.shared.getWidth(forSE: 0.57, forOthers: 0.57), alignment: .leading) } @@ -94,7 +94,7 @@ struct LargeEnvelopeCell: View { HStack(alignment: .top) { Text(letter.postScript ?? "") - .font(fontViewModel.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.012, forOthers: 0.012))) + .font(FontUtility.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.012, forOthers: 0.012))) .foregroundStyle(.contentPrimary) .frame(width: LayoutHelper.shared.getWidth(forSE: 0.4, forOthers: 0.4), alignment: .leading) @@ -103,7 +103,7 @@ struct LargeEnvelopeCell: View { .font(.custom("SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.008, forOthers: 0.008))) .foregroundStyle(.contentPrimary) Text(letter.toUserName) - .font(fontViewModel.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.017, forOthers: 0.017))) + .font(FontUtility.selectedFont(font: letter.fontString ?? "SFDisplay", size: LayoutHelper.shared.getSize(forSE: 0.017, forOthers: 0.017))) .foregroundStyle(.contentPrimary) .frame(maxWidth: LayoutHelper.shared.getWidth(forSE: 0.26, forOthers: 0.26), alignment: .leading) } diff --git a/Kabinett/Presentation/View/LetterBox/Components/ContentRectangleView.swift b/Kabinett/Presentation/View/LetterBox/Components/ContentRectangleView.swift index 4981cb4..d122f01 100644 --- a/Kabinett/Presentation/View/LetterBox/Components/ContentRectangleView.swift +++ b/Kabinett/Presentation/View/LetterBox/Components/ContentRectangleView.swift @@ -38,7 +38,7 @@ struct ContentRectangleView: View { VStack { Text(toUserName) - .font(fontViewModel.selectedFont(font: fontString, size: 14)) + .font(FontUtility.selectedFont(font: fontString, size: 14)) .foregroundStyle(.contentPrimary) .frame(maxWidth: .infinity, alignment: .leading) .padding(.top, geometry.size.height * 0.2) @@ -46,7 +46,7 @@ struct ContentRectangleView: View { .opacity(currentPageIndex == 0 ? 1 : 0) Text(letterContent.forceCharWrapping) - .font(fontViewModel.selectedFont(font: fontString, size: LayoutHelper.shared.getSize(forSE: 0.017, forOthers: 0.015))) + .font(FontUtility.selectedFont(font: fontString, size: LayoutHelper.shared.getSize(forSE: 0.017, forOthers: 0.015))) .foregroundStyle(.contentPrimary) .lineSpacing(8) .frame(maxWidth: .infinity, alignment: .leading) @@ -56,14 +56,14 @@ struct ContentRectangleView: View { Spacer() Text(formattedDate(date: date)) - .font(fontViewModel.selectedFont(font: fontString, size: 14)) + .font(FontUtility.selectedFont(font: fontString, size: 14)) .foregroundStyle(.contentPrimary) .frame(maxWidth: .infinity, alignment: .trailing) .padding(.bottom, 0.1) .opacity(currentPageIndex == max(totalPages - 1, 0) ? 1 : 0) Text(fromUserName) - .font(fontViewModel.selectedFont(font: fontString, size: 14)) + .font(FontUtility.selectedFont(font: fontString, size: 14)) .foregroundStyle(.contentPrimary) .frame(maxWidth: .infinity, alignment: .trailing) .padding(.bottom, geometry.size.height * 0.2) diff --git a/Kabinett/Presentation/View/WriteLetter/ContentWriteView.swift b/Kabinett/Presentation/View/WriteLetter/ContentWriteView.swift index 4baa9eb..0d9dcfb 100644 --- a/Kabinett/Presentation/View/WriteLetter/ContentWriteView.swift +++ b/Kabinett/Presentation/View/WriteLetter/ContentWriteView.swift @@ -12,7 +12,7 @@ import PhotosUI struct ContentWriteView: View { @Binding var letterContent: LetterWriteModel - @EnvironmentObject var viewModel: ContentWriteViewModel + @StateObject var viewModel = ContentWriteViewModel() @EnvironmentObject var imageViewModel: ImagePickerViewModel @EnvironmentObject var customViewModel: CustomTabViewModel @@ -79,7 +79,7 @@ struct ContentWriteView: View { .background(letterContent.photoContents.isEmpty ? Color(.primary300) : Color(.primary900)) .clipShape(Capsule()) - ScrollableLetterView(letterContent: $letterContent, currentIndex: $viewModel.currentIndex) + ScrollableLetterView(letterContent: $letterContent, viewModel: viewModel, currentIndex: $viewModel.currentIndex) Text("\(viewModel.currentIndex+1) / \(viewModel.texts.count)") } @@ -100,8 +100,7 @@ struct ContentWriteView: View { // MARK: - ScrollableLetterView struct ScrollableLetterView: View { @Binding var letterContent: LetterWriteModel - @EnvironmentObject var viewModel: ContentWriteViewModel - @EnvironmentObject var fontViewModel: FontSelectionViewModel + @ObservedObject var viewModel: ContentWriteViewModel @Binding var currentIndex: Int var body: some View { @@ -139,9 +138,9 @@ struct ScrollableLetterView: View { text: $viewModel.texts[i], maxWidth: geo.size.width, maxHeight: geo.size.height, - font: fontViewModel.selectedUIFont(font: letterContent.fontString ?? "", size: fontViewModel.fontSize(font: letterContent.fontString ?? "")), - lineSpacing: fontViewModel.lineSpacing(font: letterContent.fontString ?? ""), - kerning: fontViewModel.kerning(font: letterContent.fontString ?? "") + font: FontUtility.selectedUIFont(font: letterContent.fontString ?? "", size: FontUtility.fontSize(font: letterContent.fontString ?? "")), + lineSpacing: FontUtility.lineSpacing(font: letterContent.fontString ?? ""), + kerning: FontUtility.kerning(font: letterContent.fontString ?? "") ) } .onChange(of: viewModel.texts[i]) { @@ -166,7 +165,7 @@ struct ScrollableLetterView: View { .frame(width: UIScreen.main.bounds.width * 0.88) .id(i) Spacer() - .anchorPreference(key: AnchorsKey.self, value: .trailing, transform: { [i: $0] }) + .anchorPreference(key: AnchorsKey.self, value: .trailing, transform: { [i: $0] }) } } } @@ -175,7 +174,7 @@ struct ScrollableLetterView: View { .scrollTargetLayout() } .scrollTargetBehavior(.viewAligned) - .font(fontViewModel.selectedFont(font: letterContent.fontString ?? "", size: 15)) + .font(FontUtility.selectedFont(font: letterContent.fontString ?? "", size: 15)) .onChange(of: viewModel.texts.count) { withAnimation { scrollViewProxy.scrollTo((currentIndex+1), anchor: .center) diff --git a/Kabinett/Presentation/View/WriteLetter/EnvelopeStampSelectionView.swift b/Kabinett/Presentation/View/WriteLetter/EnvelopeStampSelectionView.swift index e382caf..aa9c5df 100644 --- a/Kabinett/Presentation/View/WriteLetter/EnvelopeStampSelectionView.swift +++ b/Kabinett/Presentation/View/WriteLetter/EnvelopeStampSelectionView.swift @@ -10,9 +10,8 @@ import Kingfisher struct EnvelopeStampSelectionView: View { @Binding var letterContent: LetterWriteModel - @EnvironmentObject var viewModel: EnvelopeStampSelectionViewModel - @EnvironmentObject var imagePickerViewModel: ImagePickerViewModel - @EnvironmentObject var fontViewModel: FontSelectionViewModel + @StateObject var viewModel: EnvelopeStampSelectionViewModel + @StateObject var imageViewModel: ImagePickerViewModel @State private var text: String = "" @State private var envelopeImageUrl: String @State private var stampImageUrl: String @@ -23,6 +22,11 @@ struct EnvelopeStampSelectionView: View { _envelopeImageUrl = State(initialValue: letterContent.wrappedValue.envelopeImageUrlString) _stampImageUrl = State(initialValue: letterContent.wrappedValue.stampImageUrlString) _postScriptText = State(initialValue: letterContent.wrappedValue.postScript ?? "") + + @Injected(WriteLetterUseCaseKey.self) var writeLetterUseCase: WriteLetterUseCase + _viewModel = StateObject(wrappedValue: EnvelopeStampSelectionViewModel(useCase: writeLetterUseCase)) + @Injected(ImportLetterUseCaseKey.self) var importLetterUseCase: ImportLetterUseCase + _imageViewModel = StateObject(wrappedValue: ImagePickerViewModel(componentsUseCase: importLetterUseCase)) } var body: some View { @@ -82,7 +86,7 @@ struct EnvelopeStampSelectionView: View { Text("보내는 사람") .font(.system(size: 7)) Text(letterContent.fromUserName) - .font(fontViewModel.selectedFont(font: letterContent.fontString ?? "", size: 14)) + .font(FontUtility.selectedFont(font: letterContent.fontString ?? "", size: 14)) } Spacer() @@ -109,7 +113,7 @@ struct EnvelopeStampSelectionView: View { HStack(alignment: .top) { VStack { Text(text) - .font(fontViewModel.selectedFont(font: letterContent.fontString ?? "", size: 10)) + .font(FontUtility.selectedFont(font: letterContent.fontString ?? "", size: 10)) .frame(width: geo.size.width * 0.43, alignment: .leading) } @@ -117,7 +121,7 @@ struct EnvelopeStampSelectionView: View { Text("받는 사람") .font(.system(size: 7)) Text(letterContent.toUserName) - .font(fontViewModel.selectedFont(font: letterContent.fontString ?? "", size: 14)) + .font(FontUtility.selectedFont(font: letterContent.fontString ?? "", size: 14)) } .padding(.top, -1) .padding(.leading, geo.size.width * 0.1) @@ -149,29 +153,32 @@ struct EnvelopeStampSelectionView: View { } .padding(.bottom, 30) } - SelectionTabView(letterContent: $letterContent, envelopeImageUrl: $envelopeImageUrl, stampImageUrl: $stampImageUrl) + SelectionTabView(envelopeStampSelectionViewModel: viewModel, letterContent: $letterContent, envelopeImageUrl: $envelopeImageUrl, stampImageUrl: $stampImageUrl) } .padding(.horizontal, UIScreen.main.bounds.width * 0.06) } .slideToDismiss() .task { + await viewModel.loadStamps() + await viewModel.loadEnvelopes() + postScriptText = letterContent.postScript ?? "" if letterContent.dataSource == .fromImagePicker { - await imagePickerViewModel.loadAndUpdateEnvelopeAndStamp() - envelopeImageUrl = imagePickerViewModel.envelopeURL ?? "" - stampImageUrl = imagePickerViewModel.stampURL ?? "" + await imageViewModel.loadAndUpdateEnvelopeAndStamp() + envelopeImageUrl = imageViewModel.envelopeURL ?? "" + stampImageUrl = imageViewModel.stampURL ?? "" } else { - await imagePickerViewModel.loadAndUpdateEnvelopeAndStamp() + await imageViewModel.loadAndUpdateEnvelopeAndStamp() envelopeImageUrl = letterContent.envelopeImageUrlString stampImageUrl = letterContent.stampImageUrlString } } .onChange(of: envelopeImageUrl) { _, newValue in - imagePickerViewModel.updateEnvelopeAndStamp(envelope: newValue, stamp: stampImageUrl) + imageViewModel.updateEnvelopeAndStamp(envelope: newValue, stamp: stampImageUrl) letterContent.envelopeImageUrlString = newValue } .onChange(of: stampImageUrl) { _, newValue in - imagePickerViewModel.updateEnvelopeAndStamp(envelope: envelopeImageUrl, stamp: newValue) + imageViewModel.updateEnvelopeAndStamp(envelope: envelopeImageUrl, stamp: newValue) letterContent.stampImageUrlString = newValue } .navigationBarBackButtonHidden() @@ -184,7 +191,7 @@ struct EnvelopeStampSelectionView: View { struct EnvelopeCell: View { @Binding var letterContent: LetterWriteModel @Binding var envelopeImageUrl: String - @EnvironmentObject var viewModel: EnvelopeStampSelectionViewModel + @ObservedObject var viewModel: EnvelopeStampSelectionViewModel var body: some View { ZStack { @@ -245,7 +252,7 @@ struct EnvelopeCell: View { struct StampCell: View { @Binding var letterContent: LetterWriteModel @Binding var stampImageUrl: String - @EnvironmentObject var viewModel: EnvelopeStampSelectionViewModel + @ObservedObject var viewModel: EnvelopeStampSelectionViewModel var body: some View { ZStack { diff --git a/Kabinett/Presentation/View/WriteLetter/FontSelectionView.swift b/Kabinett/Presentation/View/WriteLetter/FontSelectionView.swift index 24ce38a..bbb8834 100644 --- a/Kabinett/Presentation/View/WriteLetter/FontSelectionView.swift +++ b/Kabinett/Presentation/View/WriteLetter/FontSelectionView.swift @@ -9,7 +9,7 @@ import SwiftUI struct FontSelectionView: View { @Binding var letterContent: LetterWriteModel - @EnvironmentObject var viewModel: FontSelectionViewModel + @StateObject var viewModel = FontSelectionViewModel() var body: some View { ZStack { @@ -36,7 +36,7 @@ struct FontSelectionView: View { VStack { HStack { Text("\(viewModel.dummyFonts[i].fontName)") - .font(viewModel.selectedFont(font: viewModel.dummyFonts[i].font, size: 13)) + .font(FontUtility.selectedFont(font: viewModel.dummyFonts[i].font, size: 13)) Spacer() } .padding(.top, 20) @@ -48,7 +48,7 @@ struct FontSelectionView: View { ) .baselineOffset(viewModel.dummyFonts[i].fontName == "Pecita" ? -1 : 0) .padding(.leading, 6) - .font(viewModel.selectedFont(font: viewModel.dummyFonts[i].font, size: 13)) + .font(FontUtility.selectedFont(font: viewModel.dummyFonts[i].font, size: 13)) .frame(maxWidth: .infinity, minHeight: 35, alignment: .leading) .background(Color.white) .clipShape(RoundedRectangle(cornerRadius: 5)) diff --git a/Kabinett/Presentation/View/WriteLetter/PreviewLetterView.swift b/Kabinett/Presentation/View/WriteLetter/PreviewLetterView.swift index 78c4c1d..fd5ff6b 100644 --- a/Kabinett/Presentation/View/WriteLetter/PreviewLetterView.swift +++ b/Kabinett/Presentation/View/WriteLetter/PreviewLetterView.swift @@ -11,16 +11,16 @@ import UIKit struct PreviewLetterView: View { @Binding var letterContent: LetterWriteModel - @EnvironmentObject var viewModel: PreviewLetterViewModel - - @EnvironmentObject var userSelectionViewModel: UserSelectionViewModel - @EnvironmentObject var stationerySelectionViewModel: StationerySelectionViewModel - @EnvironmentObject var fontSelectionViewModel: FontSelectionViewModel - @EnvironmentObject var contentWriteViewModel: ContentWriteViewModel - @EnvironmentObject var envelopStampSelectionViewModel: EnvelopeStampSelectionViewModel + @StateObject var viewModel: PreviewLetterViewModel @EnvironmentObject var customTabViewModel: CustomTabViewModel @EnvironmentObject var imagePickerViewModel: ImagePickerViewModel + init(letterContent: Binding) { + @Injected(WriteLetterUseCaseKey.self) var writeLetterUseCase: WriteLetterUseCase + _viewModel = StateObject(wrappedValue: PreviewLetterViewModel(useCase: writeLetterUseCase)) + self._letterContent = letterContent + } + var body: some View { ZStack { Color(.background).ignoresSafeArea() @@ -46,7 +46,7 @@ struct PreviewLetterView: View { Text("보내는 사람") .font(.system(size: 7)) Text(letterContent.fromUserName) - .font(fontSelectionViewModel.selectedFont(font: letterContent.fontString ?? "", size: 14)) + .font(FontUtility.selectedFont(font: letterContent.fontString ?? "", size: 14)) } Spacer() @@ -65,7 +65,7 @@ struct PreviewLetterView: View { HStack(alignment: .top) { VStack { Text(letterContent.postScript ?? "") - .font(fontSelectionViewModel.selectedFont(font: letterContent.fontString ?? "", size: 10)) + .font(FontUtility.selectedFont(font: letterContent.fontString ?? "", size: 10)) .frame(width: geo.size.width * 0.43, alignment: .leading) } @@ -73,7 +73,7 @@ struct PreviewLetterView: View { Text("받는 사람") .font(.system(size: 7)) Text(letterContent.toUserName) - .font(fontSelectionViewModel.selectedFont(font: letterContent.fontString ?? "", size: 14)) + .font(FontUtility.selectedFont(font: letterContent.fontString ?? "", size: 14)) } .padding(.top, -1) .padding(.leading, geo.size.width * 0.1) @@ -121,13 +121,8 @@ struct PreviewLetterView: View { isRead: false) letterContent.reset() - userSelectionViewModel.reset() - stationerySelectionViewModel.reset() - fontSelectionViewModel.reset() - contentWriteViewModel.reset() - envelopStampSelectionViewModel.reset() - imagePickerViewModel.resetState() customTabViewModel.hideOptions() + imagePickerViewModel.resetSelections() } label: { Text("편지 보내기") .font(.system(size: 16)) diff --git a/Kabinett/Presentation/View/WriteLetter/SelectionTabView.swift b/Kabinett/Presentation/View/WriteLetter/SelectionTabView.swift index 875cf6e..798ab14 100644 --- a/Kabinett/Presentation/View/WriteLetter/SelectionTabView.swift +++ b/Kabinett/Presentation/View/WriteLetter/SelectionTabView.swift @@ -9,6 +9,7 @@ import SwiftUI struct SelectionTabView: View { @State private var selectedTab: Int = 0 + @ObservedObject var envelopeStampSelectionViewModel: EnvelopeStampSelectionViewModel @Binding var letterContent: LetterWriteModel @Binding var envelopeImageUrl: String @Binding var stampImageUrl: String @@ -26,9 +27,9 @@ struct SelectionTabView: View { .scrollDisabled(true) TabView(selection: $selectedTab) { - EnvelopeCell(letterContent: $letterContent, envelopeImageUrl: $envelopeImageUrl) + EnvelopeCell(letterContent: $letterContent, envelopeImageUrl: $envelopeImageUrl, viewModel: envelopeStampSelectionViewModel) .tag(0) - StampCell(letterContent: $letterContent, stampImageUrl: $stampImageUrl) + StampCell(letterContent: $letterContent, stampImageUrl: $stampImageUrl, viewModel: envelopeStampSelectionViewModel) .tag(1) } .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never)) diff --git a/Kabinett/Presentation/View/WriteLetter/StationerySelectionView.swift b/Kabinett/Presentation/View/WriteLetter/StationerySelectionView.swift index 88cd9cb..ca27910 100644 --- a/Kabinett/Presentation/View/WriteLetter/StationerySelectionView.swift +++ b/Kabinett/Presentation/View/WriteLetter/StationerySelectionView.swift @@ -11,13 +11,13 @@ import Kingfisher struct StationerySelectionView: View { @Environment(\.dismiss) var dismiss @Binding var letterContent: LetterWriteModel - @EnvironmentObject var stationerySelectionViewModel: StationerySelectionViewModel - @EnvironmentObject var envelopeStampSelectionViewModel: EnvelopeStampSelectionViewModel - @EnvironmentObject var userSelectionViewModel: UserSelectionViewModel - @EnvironmentObject var fontSelectionViewModel: FontSelectionViewModel - @EnvironmentObject var contentWriteViewModel: ContentWriteViewModel - @EnvironmentObject var customTabViewModel: CustomTabViewModel - @EnvironmentObject var imagePickerViewModel: ImagePickerViewModel + @StateObject var viewModel : StationerySelectionViewModel + + init(letterContent: Binding) { + @Injected(WriteLetterUseCaseKey.self) var writeLetterUseCase: WriteLetterUseCase + _viewModel = StateObject(wrappedValue: StationerySelectionViewModel(useCase: writeLetterUseCase)) + self._letterContent = letterContent + } var body: some View { NavigationStack { @@ -33,21 +33,20 @@ struct StationerySelectionView: View { .foregroundStyle(.contentPrimary) } } backAction: { - resetViewModels() dismiss() } List { - ForEach(0..) { + @Injected(WriteLetterUseCaseKey.self) var writeLetterUseCase: WriteLetterUseCase + _viewModel = StateObject(wrappedValue: UserSelectionViewModel(useCase: writeLetterUseCase)) + self._letterContent = letterContent + } var body: some View { @@ -33,7 +39,7 @@ struct UserSelectionView: View { .foregroundColor(.contentPrimary) .padding(.bottom, -3) - FormToUser(letterContent: $letterContent) + FormToUser(letterContent: $letterContent, viewModel: viewModel) HStack { if viewModel.checkLogin { @@ -49,10 +55,6 @@ struct UserSelectionView: View { .lineSpacing(3) .foregroundStyle(Color("ContentSecondary")) .bold() - .onAppear { - letterContent.toUserName = "나" - letterContent.fromUserName = "나" - } HStack { Spacer() Button("로그인하기") { @@ -85,11 +87,9 @@ struct UserSelectionView: View { // MARK: - FormToUserView struct FormToUser: View { @Binding var letterContent: LetterWriteModel - @EnvironmentObject var viewModel : UserSelectionViewModel + @ObservedObject var viewModel : UserSelectionViewModel var body: some View { - let fromName = letterContent.fromUserName.isEmpty ? viewModel.fromUser?.name ?? "" : letterContent.fromUserName - HStack { Text("보내는 사람") .foregroundStyle(Color("ContentPrimary")) @@ -105,9 +105,18 @@ struct FormToUser: View { } .padding(.top, 15) .onChange(of: viewModel.fromUser?.kabinettNumber) { - letterContent.toUserId = viewModel.toUser?.id - letterContent.toUserName = viewModel.toUser?.name ?? "" - letterContent.toUserKabinettNumber = viewModel.toUser?.kabinettNumber + if viewModel.checkLogin { + letterContent.fromUserId = viewModel.fromUser?.id + letterContent.fromUserName = viewModel.fromUser?.name ?? "" + letterContent.fromUserKabinettNumber = viewModel.fromUser?.kabinettNumber + letterContent.toUserId = viewModel.toUser?.id + letterContent.toUserName = viewModel.toUser?.name ?? "" + letterContent.toUserKabinettNumber = viewModel.toUser?.kabinettNumber + } else { + letterContent.toUserName = "나" + letterContent.fromUserName = "나" + } + letterContent.date = Date() } HStack { @@ -115,21 +124,8 @@ struct FormToUser: View { .foregroundStyle(Color("ContentPrimary")) .font(.system(size: 16)) .bold() - .onAppear { - letterContent.fromUserId = viewModel.fromUser?.id - letterContent.fromUserName = viewModel.fromUser?.name ?? "" - letterContent.fromUserKabinettNumber = viewModel.fromUser?.kabinettNumber - if letterContent.toUserId == "" { - viewModel.updateToUser(&letterContent, toUserName: letterContent.fromUserName) - } - letterContent.toUserId = viewModel.toUser?.id - letterContent.toUserName = viewModel.toUser?.name ?? "" - letterContent.toUserKabinettNumber = viewModel.toUser?.kabinettNumber - - letterContent.date = Date() - } Spacer(minLength: 37) - let toName = letterContent.toUserName.isEmpty ? fromName : letterContent.toUserName + let toName = letterContent.toUserName.isEmpty ? viewModel.toUser?.name ?? "" : letterContent.toUserName let toKabi = letterContent.toUserName.isEmpty ? viewModel.fromUser?.kabinettNumber ?? 0 : letterContent.toUserKabinettNumber Text(viewModel.checkLogin ? "\(toName) \(viewModel.checkMe(kabiNumber: toKabi ?? 0))" : "나") .foregroundStyle(viewModel.checkLogin ? Color.black : Color("ContentSecondary")) diff --git a/Kabinett/Presentation/ViewModel/WriteLetter/FontSelectionViewModel.swift b/Kabinett/Presentation/ViewModel/WriteLetter/FontSelectionViewModel.swift index 58b0648..2ee5acd 100644 --- a/Kabinett/Presentation/ViewModel/WriteLetter/FontSelectionViewModel.swift +++ b/Kabinett/Presentation/ViewModel/WriteLetter/FontSelectionViewModel.swift @@ -29,8 +29,6 @@ class FontSelectionViewModel: ObservableObject { Fonts(fontName: "Pecita", font: "Pecita"), ] - let screenSize = UIScreen.main.bounds.width - init() { updateText() } @@ -50,61 +48,4 @@ class FontSelectionViewModel: ObservableObject { func isSelected(index: Int) -> Bool { return selectedIndex == index } - - func selectedUIFont(font: String, size: CGFloat) -> UIFont { - if font == "SFMONO" { - return UIFont.monospacedSystemFont(ofSize: size, weight: .regular) - } else if font == "SFDisplay" { - return UIFont.systemFont(ofSize: size) - } else { - return UIFont(name: font, size: size) ?? UIFont.systemFont(ofSize: size) - } - } - - func selectedFont(font: String, size: CGFloat) -> Font { - if font == "SFMONO" { - return .system(size: size, design: .monospaced) - } else if font == "SFDisplay" { - return .system(size: size) - } else { - return .custom(font, size: size) - } - } - - func fontSize(font: String) -> CGFloat { - if font == "SourceHanSerifK-Regular" { - return screenSize * 0.0333 - } else if font == "NanumMyeongjoOTF" { - return screenSize * 0.0392 - } else if font == "Baskervville-Regular" { - return screenSize * 0.0369 - } else if font == "Pecita" { - return screenSize * 0.037 - } - return (screenSize * 0.0382) - } - - func lineSpacing(font: String) -> CGFloat { - if font == "Pecita" { - return screenSize * 0.0069 - } else if font == "SFDisplay" { - return screenSize * 0.0013 - } else if font == "goormSansOTF4" { - return screenSize * 0.0013 - } else if font == "Baskervville-Regular" { - return screenSize * 0.002 - } - return 0.0 - } - - func kerning(font: String) -> CGFloat { - if font == "SFMONO" { - return -(screenSize * 0.0025) - } else if font == "SFDisplay" { - return (screenSize * 0.0005) - } else if font == "goormSansOTF4" { - return (screenSize * 0.001) - } - return 0.0 - } } diff --git a/Kabinett/Presentation/ViewModel/WriteLetter/FontUtility.swift b/Kabinett/Presentation/ViewModel/WriteLetter/FontUtility.swift new file mode 100644 index 0000000..cc40892 --- /dev/null +++ b/Kabinett/Presentation/ViewModel/WriteLetter/FontUtility.swift @@ -0,0 +1,71 @@ +// +// FontUtility.swift +// Kabinett +// +// Created by Song Kim on 10/17/24. +// + +import Foundation +import SwiftUI +import UIKit + +class FontUtility { + static let screenSize = UIScreen.main.bounds.width + + static func selectedUIFont(font: String, size: CGFloat) -> UIFont { + if font == "SFMONO" { + return UIFont.monospacedSystemFont(ofSize: size, weight: .regular) + } else if font == "SFDisplay" { + return UIFont.systemFont(ofSize: size) + } else { + return UIFont(name: font, size: size) ?? UIFont.systemFont(ofSize: size) + } + } + + static func selectedFont(font: String, size: CGFloat) -> Font { + if font == "SFMONO" { + return .system(size: size, design: .monospaced) + } else if font == "SFDisplay" { + return .system(size: size) + } else { + return .custom(font, size: size) + } + } + + static func fontSize(font: String) -> CGFloat { + if font == "SourceHanSerifK-Regular" { + return screenSize * 0.0333 + } else if font == "NanumMyeongjoOTF" { + return screenSize * 0.0392 + } else if font == "Baskervville-Regular" { + return screenSize * 0.0369 + } else if font == "Pecita" { + return screenSize * 0.037 + } + return (screenSize * 0.0382) + } + + static func lineSpacing(font: String) -> CGFloat { + if font == "Pecita" { + return screenSize * 0.0069 + } else if font == "SFDisplay" { + return screenSize * 0.0013 + } else if font == "goormSansOTF4" { + return screenSize * 0.0013 + } else if font == "Baskervville-Regular" { + return screenSize * 0.002 + } + return 0.0 + } + + static func kerning(font: String) -> CGFloat { + if font == "SFMONO" { + return -(screenSize * 0.0025) + } else if font == "SFDisplay" { + return (screenSize * 0.0005) + } else if font == "goormSansOTF4" { + return (screenSize * 0.001) + } + return 0.0 + } +}