diff --git a/ReadLog/ReadLog.xcodeproj/project.pbxproj b/ReadLog/ReadLog.xcodeproj/project.pbxproj index 2a19a1a..d40a553 100644 --- a/ReadLog/ReadLog.xcodeproj/project.pbxproj +++ b/ReadLog/ReadLog.xcodeproj/project.pbxproj @@ -27,6 +27,8 @@ E622526B2AFB7AE600D33EC3 /* omyu pretty.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E622526A2AFB7AE600D33EC3 /* omyu pretty.ttf */; }; E622526E2AFB7CB300D33EC3 /* Color+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E622526D2AFB7CB300D33EC3 /* Color+Extension.swift */; }; E62252702AFB7E7000D33EC3 /* TextStyle+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E622526F2AFB7E7000D33EC3 /* TextStyle+Extension.swift */; }; + E6B184D12B142C6600776177 /* BookShelfView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6B184D02B142C6600776177 /* BookShelfView.swift */; }; + E6B184D32B142FD400776177 /* BookShelfCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6B184D22B142FD400776177 /* BookShelfCell.swift */; }; E6C73D5B2B02F82E00A3C9C9 /* UINavigationController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6C73D5A2B02F82E00A3C9C9 /* UINavigationController+Extension.swift */; }; E6E4BF532B01B70300FEEE10 /* AddNoteView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6E4BF522B01B70300FEEE10 /* AddNoteView.swift */; }; E6E4BF562B01BF4000FEEE10 /* Header.swift in Sources */ = {isa = PBXBuildFile; fileRef = E6E4BF552B01BF4000FEEE10 /* Header.swift */; }; @@ -64,6 +66,8 @@ E622526C2AFB7B0400D33EC3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = ""; }; E622526D2AFB7CB300D33EC3 /* Color+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Color+Extension.swift"; sourceTree = ""; }; E622526F2AFB7E7000D33EC3 /* TextStyle+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TextStyle+Extension.swift"; sourceTree = ""; }; + E6B184D02B142C6600776177 /* BookShelfView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookShelfView.swift; sourceTree = ""; }; + E6B184D22B142FD400776177 /* BookShelfCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BookShelfCell.swift; sourceTree = ""; }; E6C73D5A2B02F82E00A3C9C9 /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Extension.swift"; sourceTree = ""; }; E6E4BF522B01B70300FEEE10 /* AddNoteView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddNoteView.swift; sourceTree = ""; }; E6E4BF552B01BF4000FEEE10 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = ""; }; @@ -147,6 +151,15 @@ path = Fonts; sourceTree = ""; }; + E6B184CF2B142C5C00776177 /* BookShelf */ = { + isa = PBXGroup; + children = ( + E6B184D02B142C6600776177 /* BookShelfView.swift */, + E6B184D22B142FD400776177 /* BookShelfCell.swift */, + ); + path = BookShelf; + sourceTree = ""; + }; E6E4BF542B01BD9B00FEEE10 /* AddNote */ = { isa = PBXGroup; children = ( @@ -209,8 +222,8 @@ E6E68EE82AF1DDF400172557 /* Presenter */ = { isa = PBXGroup; children = ( + E6B184CF2B142C5C00776177 /* BookShelf */, E6F5AD282B134BEC00A605D4 /* URLImage */, - E6035B882B0CF07F00C34007 /* BookShelf */, E6035B852B0CEF4200C34007 /* ReadingBook */, 9DC96E9D2B0C57B500034878 /* BookDetail */, E618517D2B0B9CFC0067811C /* BookInfo */, @@ -386,6 +399,7 @@ E60DDA9F2B0AF95500F25BB2 /* BookProfileContainer.swift in Sources */, E6F5AD1E2B0FCAFC00A605D4 /* ISBNScannerView.swift in Sources */, E60DDA992B0A8D1400F25BB2 /* BookSearchView.swift in Sources */, + E6B184D12B142C6600776177 /* BookShelfView.swift in Sources */, E60DDA9B2B0A8F2400F25BB2 /* SearchBar.swift in Sources */, E6E4BF5B2B01CE1100FEEE10 /* NoteLabel.swift in Sources */, E6E4BF592B01C88500FEEE10 /* Note.swift in Sources */, @@ -396,6 +410,7 @@ 9DA3579C2B009AD1004EC3C1 /* viewBookMemo.swift in Sources */, DB633C1B2B02FC8F004CEC27 /* Model.xcdatamodeld in Sources */, DB18172D2B062ED600A55F80 /* Persistence.swift in Sources */, + E6B184D32B142FD400776177 /* BookShelfCell.swift in Sources */, E6F5AD2A2B134C0200A605D4 /* URLImage.swift in Sources */, E6F5AD252B112AEE00A605D4 /* BookInfoData_Temporal.swift in Sources */, E61851832B0B9EA80067811C /* APIKEY.swift in Sources */, @@ -548,11 +563,13 @@ ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = ReadLog/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "책의 내용을 스캔하기 위해서 카메라 사용 허용이 필요합니다."; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UIUserInterfaceStyle = Light; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -584,11 +601,13 @@ ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; INFOPLIST_FILE = ReadLog/Info.plist; + INFOPLIST_KEY_NSCameraUsageDescription = "책의 내용을 스캔하기 위해서 카메라 사용 허용이 필요합니다."; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + INFOPLIST_KEY_UIUserInterfaceStyle = Light; IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/ReadLog/ReadLog/Assets.xcassets/usualWords.imageset/Contents.json b/ReadLog/ReadLog/Assets.xcassets/bookExample.imageset/Contents.json similarity index 100% rename from ReadLog/ReadLog/Assets.xcassets/usualWords.imageset/Contents.json rename to ReadLog/ReadLog/Assets.xcassets/bookExample.imageset/Contents.json diff --git a/ReadLog/ReadLog/Assets.xcassets/usualWords.imageset/usualWords.jpeg b/ReadLog/ReadLog/Assets.xcassets/bookExample.imageset/usualWords.jpeg similarity index 100% rename from ReadLog/ReadLog/Assets.xcassets/usualWords.imageset/usualWords.jpeg rename to ReadLog/ReadLog/Assets.xcassets/bookExample.imageset/usualWords.jpeg diff --git a/ReadLog/ReadLog/Presenter/AddNote/AddNoteView.swift b/ReadLog/ReadLog/Presenter/AddNote/AddNoteView.swift index 0722520..e2cad62 100644 --- a/ReadLog/ReadLog/Presenter/AddNote/AddNoteView.swift +++ b/ReadLog/ReadLog/Presenter/AddNote/AddNoteView.swift @@ -28,6 +28,7 @@ struct AddNoteView: View { } .padding(.horizontal, 32) } + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) .toolbar(.hidden) .fullScreenCover(isPresented: $showScannerSheet, content: { scannerView diff --git a/ReadLog/ReadLog/Presenter/BookShelf/BookShelfCell.swift b/ReadLog/ReadLog/Presenter/BookShelf/BookShelfCell.swift new file mode 100644 index 0000000..e1d69bb --- /dev/null +++ b/ReadLog/ReadLog/Presenter/BookShelf/BookShelfCell.swift @@ -0,0 +1,81 @@ +// +// BookShelfCell.swift +// ReadLog +// +// Created by sanghyo on 11/27/23. +// + +import SwiftUI + +struct BookShelfCell: View { + var renderedBook: [BookExample?] + + var body: some View { + VStack(spacing: 5) { + bookRow(renderedBook).padding(.horizontal, 20) + horizontalLine + } + .listRowSeparator(.hidden) + .listRowBackground(Color.backgroundColor) + .frame(maxWidth: .infinity, maxHeight: .infinity) + .padding(.bottom, 5) + } +} + +private extension BookShelfCell { + @ViewBuilder + func bookRow(_ bookList: [BookExample?]) -> some View { + HStack(alignment: .center) { + bookCell(bookList[0]) + Spacer() + bookCell(bookList[1]) + Spacer() + bookCell(bookList[2]) + } + } + + @ViewBuilder + func bookCell(_ book: BookExample?) -> some View { + if let book = book { + Image(book.imageName) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 80) + .shadow(radius: 4, y: 4) + .onTapGesture { + // move to detail page + } + } else { + Spacer() + .frame(width: 80) + } + } + + var horizontalLine: some View { + Rectangle() + .foregroundStyle(Color.white) + .frame(height: 6) + .shadow(radius: 4, y: 4) + } + +} + +struct BookExample: Identifiable { + let id: Int + let imageName: String + + static var mock: [BookExample?] { + return [ + BookExample(id: 0, imageName: "bookExample"), + BookExample(id: 1, imageName: "bookExample"), + BookExample(id: 3, imageName: "bookExample"), + BookExample(id: 4, imageName: "bookExample"), + nil, + + ] + } +} + +#Preview { + BookShelfCell(renderedBook: BookExample.mock) +} diff --git a/ReadLog/ReadLog/Presenter/BookShelf/BookShelfView.swift b/ReadLog/ReadLog/Presenter/BookShelf/BookShelfView.swift index 6ce09ba..c87a5d5 100644 --- a/ReadLog/ReadLog/Presenter/BookShelf/BookShelfView.swift +++ b/ReadLog/ReadLog/Presenter/BookShelf/BookShelfView.swift @@ -2,14 +2,63 @@ // BookShelfView.swift // ReadLog // -// Created by sanghyo on 11/21/23. +// Created by sanghyo on 11/27/23. // import SwiftUI struct BookShelfView: View { + private var bookList: [BookExample] = BookExample.mock.compactMap { $0 } + private let bookCountInRow: Int = 3 + private var interpolatedBookList: [BookExample?] { + get { + interpolateBookList(bookList) + } + } + var body: some View { - Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + NavigationStack { + ZStack { + Color.backgroundColor + .ignoresSafeArea() + VStack(spacing: 40) { + header + List { + ForEach(0.. [BookExample?] { + let bookCount = bookList.count + let addBookCount = (bookCountInRow - bookCount % bookCountInRow) % bookCountInRow + let nilArray: [BookExample?] = Array(repeating: nil, count: addBookCount) + return bookList + nilArray + } + + func dataForRow(idx: Int) -> [BookExample?] { + Array(interpolatedBookList[idx*bookCountInRow..