From b76d824de31cb2c1f0540ddf25fc448dcb7e7c9e Mon Sep 17 00:00:00 2001 From: IvanStepanok <128456094+IvanStepanok@users.noreply.github.com> Date: Wed, 4 Oct 2023 18:24:57 +0300 Subject: [PATCH] october bugfixes (#100) * october bugfixes Change some icons to help adjust color themes (DeleteAccountView, Send button on the keyboard, etc.) Fix CSSInjector style by adding 100% width. Need for normal work at Handouts view. Add new logic for icons viewing in CourseVerticalView. Fix a bug where the discussion page does not appear in case there is only one on the page. Fix a bug with text trimming on ParentCommentView. Change button design on PostsView by Design code. Fix the issue with the English localization on DeleteAccountView. Fix error handling at DeleteAccountViewModel. * update xcode version for unit tests * Downgrade xcode version for unit tests * Update unit_tests.yml * Update Fastfile * Update unit_tests.yml * code style improvements --- .github/workflows/unit_tests.yml | 3 -- .../Discussions/send.imageset/Contents.json | 4 +- .../Discussions/send.imageset/Group 62-2.svg | 12 ------ .../Discussions/send.imageset/Group 62.svg | 12 ------ .../Discussions/send.imageset/send 1.svg | 11 +++++ .../Discussions/send.imageset/send.svg | 11 +++++ .../Contents.json | 4 +- .../bg_delete.imageset/bg_delete 1.svg | 7 ++++ .../bg_delete.imageset/delete_bg_light.svg | 7 ++++ .../deleteAccount.imageset/Group-2.svg | 13 ------ .../Profile/deleteAccount.imageset/Group.svg | 13 ------ .../delete_char.imageset/Contents.json | 15 +++++++ .../delete_char.imageset/delete_char.svg | 8 ++++ .../delete_eyes.imageset/Contents.json | 12 ++++++ .../delete_eyes.imageset/delete_eyes.svg | 7 ++++ Core/Core/Configuration/CSSInjector.swift | 6 ++- Core/Core/SwiftGen/Assets.swift | 4 +- .../View/Base/FlexibleKeyboardInputView.swift | 14 +++++-- .../Handouts/HandoutsUpdatesDetailView.swift | 11 ++++- .../Outline/CourseVerticalView.swift | 16 +++++++- .../Presentation/Unit/CourseUnitView.swift | 5 +++ .../Comments/Base/ParentCommentView.swift | 1 + .../Presentation/Posts/PostsView.swift | 40 +++++++++++++------ .../DeleteAccount/DeleteAccountView.swift | 10 ++++- .../DeleteAccountViewModel.swift | 2 +- Profile/Profile/SwiftGen/Strings.swift | 4 +- Profile/Profile/en.lproj/Localizable.strings | 2 +- fastlane/Fastfile | 2 +- 28 files changed, 172 insertions(+), 84 deletions(-) delete mode 100644 Core/Core/Assets.xcassets/Discussions/send.imageset/Group 62-2.svg delete mode 100644 Core/Core/Assets.xcassets/Discussions/send.imageset/Group 62.svg create mode 100644 Core/Core/Assets.xcassets/Discussions/send.imageset/send 1.svg create mode 100644 Core/Core/Assets.xcassets/Discussions/send.imageset/send.svg rename Core/Core/Assets.xcassets/Profile/{deleteAccount.imageset => bg_delete.imageset}/Contents.json (77%) create mode 100644 Core/Core/Assets.xcassets/Profile/bg_delete.imageset/bg_delete 1.svg create mode 100644 Core/Core/Assets.xcassets/Profile/bg_delete.imageset/delete_bg_light.svg delete mode 100644 Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Group-2.svg delete mode 100644 Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Group.svg create mode 100644 Core/Core/Assets.xcassets/Profile/delete_char.imageset/Contents.json create mode 100644 Core/Core/Assets.xcassets/Profile/delete_char.imageset/delete_char.svg create mode 100644 Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/Contents.json create mode 100644 Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/delete_eyes.svg diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index e9d655c49..16dee327e 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -35,9 +35,6 @@ jobs: run: source ci_scripts/ci_prepare_env.sh && setup_github_actions_environment - - run: | - xcversion installed - - name: SwiftLint run: bundle exec fastlane linting diff --git a/Core/Core/Assets.xcassets/Discussions/send.imageset/Contents.json b/Core/Core/Assets.xcassets/Discussions/send.imageset/Contents.json index 66cc886a8..501261e9c 100644 --- a/Core/Core/Assets.xcassets/Discussions/send.imageset/Contents.json +++ b/Core/Core/Assets.xcassets/Discussions/send.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Group 62.svg", + "filename" : "send.svg", "idiom" : "universal" }, { @@ -11,7 +11,7 @@ "value" : "dark" } ], - "filename" : "Group 62-2.svg", + "filename" : "send 1.svg", "idiom" : "universal" } ], diff --git a/Core/Core/Assets.xcassets/Discussions/send.imageset/Group 62-2.svg b/Core/Core/Assets.xcassets/Discussions/send.imageset/Group 62-2.svg deleted file mode 100644 index bafc12f2e..000000000 --- a/Core/Core/Assets.xcassets/Discussions/send.imageset/Group 62-2.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/Core/Core/Assets.xcassets/Discussions/send.imageset/Group 62.svg b/Core/Core/Assets.xcassets/Discussions/send.imageset/Group 62.svg deleted file mode 100644 index 312dc8d1a..000000000 --- a/Core/Core/Assets.xcassets/Discussions/send.imageset/Group 62.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/Core/Core/Assets.xcassets/Discussions/send.imageset/send 1.svg b/Core/Core/Assets.xcassets/Discussions/send.imageset/send 1.svg new file mode 100644 index 000000000..db8ab01ea --- /dev/null +++ b/Core/Core/Assets.xcassets/Discussions/send.imageset/send 1.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Core/Core/Assets.xcassets/Discussions/send.imageset/send.svg b/Core/Core/Assets.xcassets/Discussions/send.imageset/send.svg new file mode 100644 index 000000000..db8ab01ea --- /dev/null +++ b/Core/Core/Assets.xcassets/Discussions/send.imageset/send.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Contents.json b/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/Contents.json similarity index 77% rename from Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Contents.json rename to Core/Core/Assets.xcassets/Profile/bg_delete.imageset/Contents.json index 2a3f6edf2..118426dbb 100644 --- a/Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Contents.json +++ b/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "Group-2.svg", + "filename" : "delete_bg_light.svg", "idiom" : "universal" }, { @@ -11,7 +11,7 @@ "value" : "dark" } ], - "filename" : "Group.svg", + "filename" : "bg_delete 1.svg", "idiom" : "universal" } ], diff --git a/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/bg_delete 1.svg b/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/bg_delete 1.svg new file mode 100644 index 000000000..92b146822 --- /dev/null +++ b/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/bg_delete 1.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/delete_bg_light.svg b/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/delete_bg_light.svg new file mode 100644 index 000000000..96007a9b5 --- /dev/null +++ b/Core/Core/Assets.xcassets/Profile/bg_delete.imageset/delete_bg_light.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Group-2.svg b/Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Group-2.svg deleted file mode 100644 index 60f0fafb9..000000000 --- a/Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Group-2.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Group.svg b/Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Group.svg deleted file mode 100644 index 09d83d54a..000000000 --- a/Core/Core/Assets.xcassets/Profile/deleteAccount.imageset/Group.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/Core/Core/Assets.xcassets/Profile/delete_char.imageset/Contents.json b/Core/Core/Assets.xcassets/Profile/delete_char.imageset/Contents.json new file mode 100644 index 000000000..44ef99c1d --- /dev/null +++ b/Core/Core/Assets.xcassets/Profile/delete_char.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "delete_char.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/Core/Core/Assets.xcassets/Profile/delete_char.imageset/delete_char.svg b/Core/Core/Assets.xcassets/Profile/delete_char.imageset/delete_char.svg new file mode 100644 index 000000000..d1422ad6a --- /dev/null +++ b/Core/Core/Assets.xcassets/Profile/delete_char.imageset/delete_char.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/Contents.json b/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/Contents.json new file mode 100644 index 000000000..19c371f58 --- /dev/null +++ b/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "delete_eyes.svg", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/delete_eyes.svg b/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/delete_eyes.svg new file mode 100644 index 000000000..af854563b --- /dev/null +++ b/Core/Core/Assets.xcassets/Profile/delete_eyes.imageset/delete_eyes.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Core/Core/Configuration/CSSInjector.swift b/Core/Core/Configuration/CSSInjector.swift index 9e7faf0ec..b90afc26f 100644 --- a/Core/Core/Configuration/CSSInjector.swift +++ b/Core/Core/Configuration/CSSInjector.swift @@ -115,6 +115,10 @@ public class CSSInjector { let style = """ - +
""" diff --git a/Core/Core/SwiftGen/Assets.swift b/Core/Core/SwiftGen/Assets.swift index 887501306..ee82da098 100644 --- a/Core/Core/SwiftGen/Assets.swift +++ b/Core/Core/SwiftGen/Assets.swift @@ -84,8 +84,10 @@ public enum CoreAssets { public static let profile = ImageAsset(name: "profile") public static let programs = ImageAsset(name: "programs") public static let addPhoto = ImageAsset(name: "addPhoto") + public static let bgDelete = ImageAsset(name: "bg_delete") public static let checkmark = ImageAsset(name: "checkmark") - public static let deleteAccount = ImageAsset(name: "deleteAccount") + public static let deleteChar = ImageAsset(name: "delete_char") + public static let deleteEyes = ImageAsset(name: "delete_eyes") public static let done = ImageAsset(name: "done") public static let gallery = ImageAsset(name: "gallery") public static let leaveProfile = ImageAsset(name: "leaveProfile") diff --git a/Core/Core/View/Base/FlexibleKeyboardInputView.swift b/Core/Core/View/Base/FlexibleKeyboardInputView.swift index 97bc11401..e8d6d0d8a 100644 --- a/Core/Core/View/Base/FlexibleKeyboardInputView.swift +++ b/Core/Core/View/Base/FlexibleKeyboardInputView.swift @@ -74,9 +74,17 @@ public struct FlexibleKeyboardInputView: View { } }, label: { VStack { - commentText.trimmingCharacters(in: .whitespacesAndNewlines).count > 0 - ? CoreAssets.send.swiftUIImage - : CoreAssets.sendDisabled.swiftUIImage + if commentText.trimmingCharacters(in: .whitespacesAndNewlines).count > 0 { + ZStack { + Circle() + .frame(width: 36, height: 36) + .foregroundColor(.accentColor) + CoreAssets.send.swiftUIImage + .offset(y: 1) + } + } else { + CoreAssets.sendDisabled.swiftUIImage + } } .frame(width: 36, height: 36) .foregroundColor(.white) diff --git a/Course/Course/Presentation/Handouts/HandoutsUpdatesDetailView.swift b/Course/Course/Presentation/Handouts/HandoutsUpdatesDetailView.swift index 57b12b542..46d79825d 100644 --- a/Course/Course/Presentation/Handouts/HandoutsUpdatesDetailView.swift +++ b/Course/Course/Presentation/Handouts/HandoutsUpdatesDetailView.swift @@ -10,8 +10,9 @@ import Core public struct HandoutsUpdatesDetailView: View { - @Environment(\.colorScheme) var colorScheme + @Environment(\.colorScheme) var colorSchemeNative private var idiom: UIUserInterfaceIdiom { UIDevice.current.userInterfaceIdiom } + @State var colorScheme: ColorScheme = UITraitCollection.current.userInterfaceStyle == .light ? .light : .dark private var router: CourseRouter private let cssInjector: CSSInjector @@ -36,6 +37,10 @@ public struct HandoutsUpdatesDetailView: View { self.cssInjector = cssInjector } + private func updateColorScheme() { + colorScheme = UITraitCollection.current.userInterfaceStyle == .light ? .light : .dark + } + private func fixBrokenLinks(in htmlString: String) -> String { do { let regex = try NSRegularExpression( @@ -126,6 +131,10 @@ public struct HandoutsUpdatesDetailView: View { .navigationBarHidden(false) .navigationBarBackButtonHidden(false) .navigationTitle(title) + .onChange(of: colorSchemeNative) { newValue in + guard UIApplication.shared.applicationState == .active else { return } + updateColorScheme() + } } } diff --git a/Course/Course/Presentation/Outline/CourseVerticalView.swift b/Course/Course/Presentation/Outline/CourseVerticalView.swift index c5cb290af..20b1bc56f 100644 --- a/Course/Course/Presentation/Outline/CourseVerticalView.swift +++ b/Course/Course/Presentation/Outline/CourseVerticalView.swift @@ -31,6 +31,20 @@ public struct CourseVerticalView: View { self.viewModel = viewModel } + private func verticalImage(childs: [CourseBlock]) -> Image { + if childs.contains(where: { $0.type == .problem }) { + return CoreAssets.pen.swiftUIImage.renderingMode(.template) + } else if childs.contains(where: { $0.type == .video }) { + return CoreAssets.video.swiftUIImage.renderingMode(.template) + } else if childs.contains(where: { $0.type == .discussion }) { + return CoreAssets.discussion.swiftUIImage.renderingMode(.template) + } else if childs.contains(where: { $0.type == .html }) { + return CoreAssets.extra.swiftUIImage.renderingMode(.template) + } else { + return CoreAssets.extra.swiftUIImage.renderingMode(.template) + } + } + public var body: some View { ZStack(alignment: .top) { // MARK: - Page Body @@ -67,7 +81,7 @@ public struct CourseVerticalView: View { .renderingMode(.template) .foregroundColor(.accentColor) } else { - vertical.type.image + verticalImage(childs: vertical.childs) } Text(vertical.displayName) .font(Theme.Fonts.titleMedium) diff --git a/Course/Course/Presentation/Unit/CourseUnitView.swift b/Course/Course/Presentation/Unit/CourseUnitView.swift index e9afacbc1..411d8ac15 100644 --- a/Course/Course/Presentation/Unit/CourseUnitView.swift +++ b/Course/Course/Presentation/Unit/CourseUnitView.swift @@ -197,6 +197,11 @@ public struct CourseUnitView: View { } } } + .onAppear { + DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) { + showDiscussion = viewModel.selectedLesson().type == .discussion + } + } .navigationBarHidden(false) .navigationBarBackButtonHidden(false) .navigationTitle("") diff --git a/Discussion/Discussion/Presentation/Comments/Base/ParentCommentView.swift b/Discussion/Discussion/Presentation/Comments/Base/ParentCommentView.swift index ab6aa3455..0e8a35828 100644 --- a/Discussion/Discussion/Presentation/Comments/Base/ParentCommentView.swift +++ b/Discussion/Discussion/Presentation/Comments/Base/ParentCommentView.swift @@ -68,6 +68,7 @@ public struct ParentCommentView: View { .font(Theme.Fonts.titleLarge) Text(comments.postBodyHtml.hideHtmlTagsAndUrls()) .font(Theme.Fonts.bodyMedium) + .fixedSize(horizontal: false, vertical: true) .padding(.bottom, 8) ForEach(Array(comments.postBody.extractURLs().enumerated()), id: \.offset) { _, url in if url.isImage() { diff --git a/Discussion/Discussion/Presentation/Posts/PostsView.swift b/Discussion/Discussion/Presentation/Posts/PostsView.swift index dc7145a3a..906a47ce2 100644 --- a/Discussion/Discussion/Presentation/Posts/PostsView.swift +++ b/Discussion/Discussion/Presentation/Posts/PostsView.swift @@ -20,8 +20,16 @@ public struct PostsView: View { private let courseID: String private var showTopMenu: Bool - public init(courseID: String, currentBlockID: String, topics: Topics, title: String, type: ThreadType, - viewModel: PostsViewModel, router: DiscussionRouter, showTopMenu: Bool = true) { + public init( + courseID: String, + currentBlockID: String, + topics: Topics, + title: String, + type: ThreadType, + viewModel: PostsViewModel, + router: DiscussionRouter, + showTopMenu: Bool = true + ) { self.courseID = courseID self.title = title self.currentBlockID = currentBlockID @@ -155,18 +163,24 @@ public struct PostsView: View { .multilineTextAlignment(.center) .frame(maxWidth: .infinity) .padding(.top, 12) - StyledButton(DiscussionLocalization.Posts.NoDiscussion.createbutton, - action: { - router.createNewThread(courseID: courseID, - selectedTopic: currentBlockID, - onPostCreated: { - reloadPage(onSuccess: { - withAnimation { - scroll.scrollTo(1) - } + StyledButton( + DiscussionLocalization.Posts.NoDiscussion.createbutton, + action: { + router.createNewThread(courseID: courseID, + selectedTopic: currentBlockID, + onPostCreated: { + reloadPage(onSuccess: { + withAnimation { + scroll.scrollTo(1) + } + }) }) - }) - }).frame(width: 215).padding(.top, 40) + }, + isTransparent: true) + .frame(width: 215) + .padding(.top, 40) + .colorMultiply(.accentColor) + }.padding(24) .padding(.top, 100) } diff --git a/Profile/Profile/Presentation/DeleteAccount/DeleteAccountView.swift b/Profile/Profile/Presentation/DeleteAccount/DeleteAccountView.swift index 88c5546a2..7f8afff4c 100644 --- a/Profile/Profile/Presentation/DeleteAccount/DeleteAccountView.swift +++ b/Profile/Profile/Presentation/DeleteAccount/DeleteAccountView.swift @@ -23,8 +23,14 @@ public struct DeleteAccountView: View { ScrollView { VStack { Group { - CoreAssets.deleteAccount.swiftUIImage - .padding(.top, 50) + ZStack { + CoreAssets.bgDelete.swiftUIImage + CoreAssets.deleteChar.swiftUIImage + .foregroundColor(.accentColor) + .offset(y: -31) + CoreAssets.deleteEyes.swiftUIImage + .offset(x: -7, y: -27) + }.padding(.top, 50) Text(ProfileLocalization.DeleteAccount.areYouSure) .foregroundColor(Theme.Colors.textPrimary) + Text(ProfileLocalization.DeleteAccount.wantToDelete) diff --git a/Profile/Profile/Presentation/DeleteAccount/DeleteAccountViewModel.swift b/Profile/Profile/Presentation/DeleteAccount/DeleteAccountViewModel.swift index 58dbe5c52..c5f464d6d 100644 --- a/Profile/Profile/Presentation/DeleteAccount/DeleteAccountViewModel.swift +++ b/Profile/Profile/Presentation/DeleteAccount/DeleteAccountViewModel.swift @@ -47,7 +47,7 @@ public class DeleteAccountViewModel: ObservableObject { } } catch { isShowProgress = false - if error.asAFError?.responseCode == 403 { + if error.validationError?.statusCode == 403 { incorrectPassword = true } else if let validationError = error.validationError, let value = validationError.data?["error_code"] as? String, diff --git a/Profile/Profile/SwiftGen/Strings.swift b/Profile/Profile/SwiftGen/Strings.swift index f31fe2bf0..7f57c3ee7 100644 --- a/Profile/Profile/SwiftGen/Strings.swift +++ b/Profile/Profile/SwiftGen/Strings.swift @@ -50,8 +50,8 @@ public enum ProfileLocalization { public static let backToProfile = ProfileLocalization.tr("Localizable", "DELETE_ACCOUNT.BACK_TO_PROFILE", fallback: "Back to profile") /// Yes, delete account public static let comfirm = ProfileLocalization.tr("Localizable", "DELETE_ACCOUNT.COMFIRM", fallback: "Yes, delete account") - /// To confirm this action you need to enter you account password. - public static let description = ProfileLocalization.tr("Localizable", "DELETE_ACCOUNT.DESCRIPTION", fallback: "To confirm this action you need to enter you account password.") + /// To confirm this action you need to enter your account password. + public static let description = ProfileLocalization.tr("Localizable", "DELETE_ACCOUNT.DESCRIPTION", fallback: "To confirm this action you need to enter your account password.") /// The password is incorrect. Please try again. public static let incorrectPassword = ProfileLocalization.tr("Localizable", "DELETE_ACCOUNT.INCORRECT_PASSWORD", fallback: "The password is incorrect. Please try again.") /// Password diff --git a/Profile/Profile/en.lproj/Localizable.strings b/Profile/Profile/en.lproj/Localizable.strings index 5c0cd4270..9eef8b47f 100644 --- a/Profile/Profile/en.lproj/Localizable.strings +++ b/Profile/Profile/en.lproj/Localizable.strings @@ -48,7 +48,7 @@ "DELETE_ACCOUNT.TITLE" = "Delete account"; "DELETE_ACCOUNT.ARE_YOU_SURE" = "Are you sure you want to "; "DELETE_ACCOUNT.WANT_TO_DELETE" = "delete your account?"; -"DELETE_ACCOUNT.DESCRIPTION" = "To confirm this action you need to enter you account password."; +"DELETE_ACCOUNT.DESCRIPTION" = "To confirm this action you need to enter your account password."; "DELETE_ACCOUNT.PASSWORD" = "Password"; "DELETE_ACCOUNT.PASSWORD_DESCRIPTION" = "Enter password"; "DELETE_ACCOUNT.COMFIRM" = "Yes, delete account"; diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 0f4ba890a..35445da9e 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -14,7 +14,7 @@ # update_fastlane before_all do - xcversion(version: "~> 14.3") + xcversion(version: "~> 15.0.0") ENV["FASTLANE_XCODEBUILD_SETTINGS_TIMEOUT"] = "180" ENV["FASTLANE_XCODE_LIST_TIMEOUT"] = "180"