diff --git a/.gitignore b/.gitignore index 13d57e65..51ba722b 100644 --- a/.gitignore +++ b/.gitignore @@ -118,4 +118,6 @@ xcuserdata **/xcshareddata/WorkspaceSettings.xcsettings # End of https://www.toptal.com/developers/gitignore/api/swift,swiftpm,xcode,cocoapods -n \ No newline at end of file + +Mastodon/Localization/StringsConvertor/input +Mastodon/Localization/StringsConvertor/output \ No newline at end of file diff --git a/Localization/StringsConvertor/input/en_US/app.json b/Localization/StringsConvertor/input/en_US/app.json deleted file mode 100644 index 8fa05456..00000000 --- a/Localization/StringsConvertor/input/en_US/app.json +++ /dev/null @@ -1,83 +0,0 @@ -{ - "common": { - "alerts": {}, - "controls": { - "actions": { - "add": "Add", - "remove": "Remove", - "edit": "Edit", - "save": "Save", - "ok": "OK", - "confirm": "Confirm", - "continue": "Continue", - "cancel": "Cancel", - "take_photo": "Take photo", - "save_photo": "Save photo", - "sign_in": "Sign in", - "sign_up": "Sign up", - "see_more": "See More", - "preview": "Preview", - "open_in_safari": "Open in Safari" - }, - "status": { - "user_boosted": "%s boosted", - "content_warning": "content warning", - "show_post": "Show Post" - }, - "timeline": { - "load_more": "Load More" - } - }, - "countable": { - "photo": { - "single": "photo", - "multiple": "photos" - } - } - }, - "scene": { - "welcome": { - "slogan": "Social networking\nback in your hands." - }, - "server_picker": { - "title": "Pick a Server,\nany server.", - "input": { - "placeholder": "Find a server or join your own..." - } - }, - "register": { - "title": "Tell us about you.", - "input": { - "username": { - "placeholder": "username", - "duplicate_prompt": "This username is taken." - }, - "display_name": { - "placeholder": "display name" - }, - "email": { - "placeholder": "email" - }, - "password": { - "placeholder": "password", - "prompt": "Your password needs at least:", - "prompt_eight_characters": "Eight characters" - } - } - }, - "server_rules": { - "title": "Some ground rules.", - "subtitle": "These rules are set by the admins of %s.", - "prompt": "By continuing, you're subject to the terms of service and privacy policy for %s.", - "button": { - "confirm": "I Agree" - } - }, - "home_timeline": { - "title": "Home" - }, - "public_timeline": { - "title": "Public" - } - } -} diff --git a/Localization/StringsConvertor/input/en_US/ios-infoPlist.json b/Localization/StringsConvertor/input/en_US/ios-infoPlist.json deleted file mode 100644 index 0a260c27..00000000 --- a/Localization/StringsConvertor/input/en_US/ios-infoPlist.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "NSCameraUsageDescription": "Used to take photo for toot", - "NSPhotoLibraryAddUsageDescription": "Used to save photo into the Photo Library" -} diff --git a/Localization/StringsConvertor/output/en.lproj/Localizable.strings b/Localization/StringsConvertor/output/en.lproj/Localizable.strings deleted file mode 100644 index 75dc3999..00000000 --- a/Localization/StringsConvertor/output/en.lproj/Localizable.strings +++ /dev/null @@ -1,40 +0,0 @@ -"Common.Controls.Actions.Add" = "Add"; -"Common.Controls.Actions.Cancel" = "Cancel"; -"Common.Controls.Actions.Confirm" = "Confirm"; -"Common.Controls.Actions.Continue" = "Continue"; -"Common.Controls.Actions.Edit" = "Edit"; -"Common.Controls.Actions.Ok" = "OK"; -"Common.Controls.Actions.OpenInSafari" = "Open in Safari"; -"Common.Controls.Actions.Preview" = "Preview"; -"Common.Controls.Actions.Remove" = "Remove"; -"Common.Controls.Actions.Save" = "Save"; -"Common.Controls.Actions.SavePhoto" = "Save photo"; -"Common.Controls.Actions.SeeMore" = "See More"; -"Common.Controls.Actions.SignIn" = "Sign in"; -"Common.Controls.Actions.SignUp" = "Sign up"; -"Common.Controls.Actions.TakePhoto" = "Take photo"; -"Common.Controls.Status.ContentWarning" = "content warning"; -"Common.Controls.Status.ShowPost" = "Show Post"; -"Common.Controls.Status.UserBoosted" = "%@ boosted"; -"Common.Controls.Timeline.LoadMore" = "Load More"; -"Common.Countable.Photo.Multiple" = "photos"; -"Common.Countable.Photo.Single" = "photo"; -"Scene.HomeTimeline.Title" = "Home"; -"Scene.PublicTimeline.Title" = "Public"; -"Scene.Register.Input.DisplayName.Placeholder" = "display name"; -"Scene.Register.Input.Email.Placeholder" = "email"; -"Scene.Register.Input.Password.Placeholder" = "password"; -"Scene.Register.Input.Password.Prompt" = "Your password needs at least:"; -"Scene.Register.Input.Password.PromptEightCharacters" = "Eight characters"; -"Scene.Register.Input.Username.DuplicatePrompt" = "This username is taken."; -"Scene.Register.Input.Username.Placeholder" = "username"; -"Scene.Register.Title" = "Tell us about you."; -"Scene.ServerPicker.Input.Placeholder" = "Find a server or join your own..."; -"Scene.ServerPicker.Title" = "Pick a Server, -any server."; -"Scene.ServerRules.Button.Confirm" = "I Agree"; -"Scene.ServerRules.Prompt" = "By continuing, you're subject to the terms of service and privacy policy for %@."; -"Scene.ServerRules.Subtitle" = "These rules are set by the admins of %@."; -"Scene.ServerRules.Title" = "Some ground rules."; -"Scene.Welcome.Slogan" = "Social networking -back in your hands."; \ No newline at end of file diff --git a/Localization/StringsConvertor/output/en.lproj/infoPlist.strings b/Localization/StringsConvertor/output/en.lproj/infoPlist.strings deleted file mode 100644 index 972e1a7a..00000000 --- a/Localization/StringsConvertor/output/en.lproj/infoPlist.strings +++ /dev/null @@ -1,2 +0,0 @@ -"NSCameraUsageDescription" = "Used to take photo for toot"; -"NSPhotoLibraryAddUsageDescription" = "Used to save photo into the Photo Library"; \ No newline at end of file diff --git a/Localization/app.json b/Localization/app.json index 8fa05456..56a54a7f 100644 --- a/Localization/app.json +++ b/Localization/app.json @@ -1,6 +1,14 @@ { "common": { - "alerts": {}, + "alerts": { + "sign_up_failure": { + "title": "Sign Up Failure" + }, + "server_error": { + "title": "Server Error" + } + + }, "controls": { "actions": { "add": "Add", diff --git a/Mastodon/Extension/UIAlertController.swift b/Mastodon/Extension/UIAlertController.swift index 7abe20cb..83c0ff55 100644 --- a/Mastodon/Extension/UIAlertController.swift +++ b/Mastodon/Extension/UIAlertController.swift @@ -9,26 +9,34 @@ import UIKit // https://nshipster.com/swift-foundation-error-protocols/ extension UIAlertController { convenience init( - _ error: Error, + for error: Error, + title: String?, preferredStyle: UIAlertController.Style ) { - let title: String + let _title: String let message: String? if let error = error as? LocalizedError { - title = error.errorDescription ?? "Unknown Error" - message = [ + var messages: [String?] = [] + if let title = title { + _title = title + messages.append(error.errorDescription) + } else { + _title = error.errorDescription ?? "Error" + } + messages.append(contentsOf: [ error.failureReason, error.recoverySuggestion - ] - .compactMap { $0 } - .joined(separator: " ") + ]) + message = messages + .compactMap { $0 } + .joined(separator: " ") } else { - title = "Internal Error" + _title = "Internal Error" message = error.localizedDescription } self.init( - title: title, + title: _title, message: message, preferredStyle: preferredStyle ) diff --git a/Mastodon/Generated/Strings.swift b/Mastodon/Generated/Strings.swift index 7b9d9eca..fa641fbb 100644 --- a/Mastodon/Generated/Strings.swift +++ b/Mastodon/Generated/Strings.swift @@ -12,6 +12,16 @@ import Foundation internal enum L10n { internal enum Common { + internal enum Alerts { + internal enum ServerError { + /// Server Error + internal static let title = L10n.tr("Localizable", "Common.Alerts.ServerError.Title") + } + internal enum SignUpFailure { + /// Sign Up Failure + internal static let title = L10n.tr("Localizable", "Common.Alerts.SignUpFailure.Title") + } + } internal enum Controls { internal enum Actions { /// Add diff --git a/Mastodon/Resources/en.lproj/Localizable.strings b/Mastodon/Resources/en.lproj/Localizable.strings index 75dc3999..efb3fed7 100644 --- a/Mastodon/Resources/en.lproj/Localizable.strings +++ b/Mastodon/Resources/en.lproj/Localizable.strings @@ -1,3 +1,5 @@ +"Common.Alerts.ServerError.Title" = "Server Error"; +"Common.Alerts.SignUpFailure.Title" = "Sign Up Failure"; "Common.Controls.Actions.Add" = "Add"; "Common.Controls.Actions.Cancel" = "Cancel"; "Common.Controls.Actions.Confirm" = "Confirm"; diff --git a/Mastodon/Scene/Authentication/AuthenticationViewController.swift b/Mastodon/Scene/Authentication/AuthenticationViewController.swift index 5ab500bc..a4a96dd5 100644 --- a/Mastodon/Scene/Authentication/AuthenticationViewController.swift +++ b/Mastodon/Scene/Authentication/AuthenticationViewController.swift @@ -195,7 +195,7 @@ extension AuthenticationViewController { .receive(on: DispatchQueue.main) .sink { [weak self] error in guard let self = self else { return } - let alertController = UIAlertController(error, preferredStyle: .alert) + let alertController = UIAlertController(for: error, title: nil, preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) alertController.addAction(okAction) self.coordinator.present( diff --git a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift index 1ebb17bd..1ff30bf6 100644 --- a/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift +++ b/Mastodon/Scene/Authentication/Register/MastodonRegisterViewController.swift @@ -398,7 +398,7 @@ extension MastodonRegisterViewController { .receive(on: DispatchQueue.main) .sink { [weak self] error in guard let self = self else { return } - let alertController = UIAlertController(error, preferredStyle: .alert) + let alertController = UIAlertController(for: error, title: "Sign Up Failure", preferredStyle: .alert) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) alertController.addAction(okAction) self.coordinator.present( diff --git a/Mastodon/Scene/MainTab/MainTabBarController.swift b/Mastodon/Scene/MainTab/MainTabBarController.swift index c946ffef..a556854e 100644 --- a/Mastodon/Scene/MainTab/MainTabBarController.swift +++ b/Mastodon/Scene/MainTab/MainTabBarController.swift @@ -112,7 +112,7 @@ extension MainTabBarController { case .implicit: break case .explicit: - let alertController = UIAlertController(error, preferredStyle: .alert) + let alertController = UIAlertController(for: error, title: nil, preferredStyle: .alert) let okAction = UIAlertAction(title: "OK", style: .default, handler: nil) alertController.addAction(okAction) coordinator.present( diff --git a/Mastodon/Scene/Share/View/TableviewCell/TimelineBottomLoaderTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/TimelineBottomLoaderTableViewCell.swift index 2dfbd625..7fe4c0a7 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/TimelineBottomLoaderTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/TimelineBottomLoaderTableViewCell.swift @@ -17,3 +17,20 @@ final class TimelineBottomLoaderTableViewCell: TimelineLoaderTableViewCell { activityIndicatorView.startAnimating() } } + +#if canImport(SwiftUI) && DEBUG +import SwiftUI + +struct TimelineBottomLoaderTableViewCell_Previews: PreviewProvider { + + static var previews: some View { + UIViewPreview(width: 375) { + TimelineBottomLoaderTableViewCell() + } + .previewLayout(.fixed(width: 375, height: 100)) + } + +} + +#endif + diff --git a/Mastodon/Scene/Share/View/TableviewCell/TimelineMiddleLoaderTableViewCell.swift b/Mastodon/Scene/Share/View/TableviewCell/TimelineMiddleLoaderTableViewCell.swift index 6c692b64..16ab241f 100644 --- a/Mastodon/Scene/Share/View/TableviewCell/TimelineMiddleLoaderTableViewCell.swift +++ b/Mastodon/Scene/Share/View/TableviewCell/TimelineMiddleLoaderTableViewCell.swift @@ -36,3 +36,20 @@ extension TimelineMiddleLoaderTableViewCell { delegate?.timelineMiddleLoaderTableViewCell(self, loadMoreButtonDidPressed: sender) } } + +#if canImport(SwiftUI) && DEBUG +import SwiftUI + +struct TimelineMiddleLoaderTableViewCell_Previews: PreviewProvider { + + static var previews: some View { + UIViewPreview(width: 375) { + TimelineMiddleLoaderTableViewCell() + } + .previewLayout(.fixed(width: 375, height: 100)) + } + +} + +#endif +