diff --git a/HomeAssistant.xcodeproj/project.pbxproj b/HomeAssistant.xcodeproj/project.pbxproj index a4745356e..b671e9b74 100644 --- a/HomeAssistant.xcodeproj/project.pbxproj +++ b/HomeAssistant.xcodeproj/project.pbxproj @@ -605,6 +605,9 @@ 4251AAC02C6CE376004CCC9D /* MagicItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 42D5ACCF2C639AB700D9C4E2 /* MagicItem.swift */; }; 4251AAC12C6CE9C4004CCC9D /* WatchConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4251AAB82C6CE1B4004CCC9D /* WatchConfig.swift */; }; 4251AAC22C6CE9CB004CCC9D /* WatchConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4251AAB82C6CE1B4004CCC9D /* WatchConfig.swift */; }; + 4254C4CA2D103ABB00245021 /* ExternalLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4254C4C92D103ABB00245021 /* ExternalLink.swift */; }; + 4254C4CB2D103ABB00245021 /* ExternalLink.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4254C4C92D103ABB00245021 /* ExternalLink.swift */; }; + 4254C4CD2D103F7B00245021 /* ExternalLinkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4254C4CC2D103F7B00245021 /* ExternalLinkButton.swift */; }; 425573C72B5572AD00145217 /* CarPlayServerListTemplate+Build.swift in Sources */ = {isa = PBXBuildFile; fileRef = 425573C62B5572AD00145217 /* CarPlayServerListTemplate+Build.swift */; }; 425573C92B5572DB00145217 /* CarPlayServerListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 425573C82B5572DB00145217 /* CarPlayServerListViewModel.swift */; }; 425573CC2B5574AD00145217 /* CarPlayAreasZonesTemplate+Build.swift in Sources */ = {isa = PBXBuildFile; fileRef = 425573CB2B5574AD00145217 /* CarPlayAreasZonesTemplate+Build.swift */; }; @@ -703,6 +706,8 @@ 429821172CD0DDCD005ECD39 /* HAButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 429821162CD0DDCD005ECD39 /* HAButtonStyles.swift */; }; 429821192CD0DEE2005ECD39 /* HAButtonStyles.swift in Sources */ = {isa = PBXBuildFile; fileRef = 429821162CD0DDCD005ECD39 /* HAButtonStyles.swift */; }; 429BA2AF2C800CAB00A50996 /* SFSymbolEntity.swift in Sources */ = {isa = PBXBuildFile; fileRef = 429BA2AE2C800CAB00A50996 /* SFSymbolEntity.swift */; }; + 429BEA1A2D102F3A00F070F9 /* ConnectionErrorDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 429BEA192D102F3A00F070F9 /* ConnectionErrorDetailsView.swift */; }; + 429BEA1D2D10315F00F070F9 /* SheetCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 429BEA1B2D1030EA00F070F9 /* SheetCloseButton.swift */; }; 429C72202B28D0EC00BCD558 /* Haptics.swift in Sources */ = {isa = PBXBuildFile; fileRef = 429C721F2B28D0EC00BCD558 /* Haptics.swift */; }; 42A2AB7C2C806D5D00C5608D /* SharedPush in Resources */ = {isa = PBXBuildFile; fileRef = 42A2AB7B2C806D5D00C5608D /* SharedPush */; }; 42A2AB7D2C806D5D00C5608D /* SharedPush in Resources */ = {isa = PBXBuildFile; fileRef = 42A2AB7B2C806D5D00C5608D /* SharedPush */; }; @@ -1912,6 +1917,8 @@ 4251AA9A2C6B9DBE004CCC9D /* MagicItemEditViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MagicItemEditViewModel.swift; sourceTree = ""; }; 4251AAB82C6CE1B4004CCC9D /* WatchConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WatchConfig.swift; sourceTree = ""; }; 4251AABA2C6CE1D0004CCC9D /* MagicItemProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MagicItemProvider.swift; sourceTree = ""; }; + 4254C4C92D103ABB00245021 /* ExternalLink.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLink.swift; sourceTree = ""; }; + 4254C4CC2D103F7B00245021 /* ExternalLinkButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalLinkButton.swift; sourceTree = ""; }; 425573C62B5572AD00145217 /* CarPlayServerListTemplate+Build.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarPlayServerListTemplate+Build.swift"; sourceTree = ""; }; 425573C82B5572DB00145217 /* CarPlayServerListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarPlayServerListViewModel.swift; sourceTree = ""; }; 425573CB2B5574AD00145217 /* CarPlayAreasZonesTemplate+Build.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "CarPlayAreasZonesTemplate+Build.swift"; sourceTree = ""; }; @@ -2011,6 +2018,8 @@ 429821132CD0DD85005ECD39 /* BluetoothPermissionViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BluetoothPermissionViewModel.swift; sourceTree = ""; }; 429821162CD0DDCD005ECD39 /* HAButtonStyles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HAButtonStyles.swift; sourceTree = ""; }; 429BA2AE2C800CAB00A50996 /* SFSymbolEntity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SFSymbolEntity.swift; sourceTree = ""; }; + 429BEA192D102F3A00F070F9 /* ConnectionErrorDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectionErrorDetailsView.swift; sourceTree = ""; }; + 429BEA1B2D1030EA00F070F9 /* SheetCloseButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SheetCloseButton.swift; sourceTree = ""; }; 429C721F2B28D0EC00BCD558 /* Haptics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Haptics.swift; sourceTree = ""; }; 42A2AB7B2C806D5D00C5608D /* SharedPush */ = {isa = PBXFileReference; lastKnownFileType = wrapper; path = SharedPush; sourceTree = ""; }; 42A2AB7F2C80751E00C5608D /* ControlAssist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ControlAssist.swift; sourceTree = ""; }; @@ -3114,6 +3123,7 @@ 113FB1122515A065000AC680 /* ScaleFactorMutator.swift */, 11DE822D24FAC51000E636B8 /* IncomingURLHandler.swift */, B64BB3A71E9C6551001E8B46 /* WebViewController.swift */, + 429BEA192D102F3A00F070F9 /* ConnectionErrorDetailsView.swift */, 420C57C62D0A6DE700D2D9AC /* NoActiveURLView.swift */, 42A47A842C45218D00C9B43D /* WebViewExternalMessageHandler.swift */, 42A47A8B2C4547B800C9B43D /* WebViewExternalMessageHandler+Build.swift */, @@ -4124,10 +4134,12 @@ 42CA28B12B101D9C0093B31A /* Components */ = { isa = PBXGroup; children = ( + 429BEA1B2D1030EA00F070F9 /* SheetCloseButton.swift */, 42FCD0052B9B1D9E0057783F /* CollapsibleView.swift */, 42CA28AF2B101D6B0093B31A /* CardView.swift */, 42CA28B52B1022680093B31A /* HAButton.swift */, 42790C452C4808FA00E31B38 /* AppleLikeBottomSheet.swift */, + 4254C4CC2D103F7B00245021 /* ExternalLinkButton.swift */, ); path = Components; sourceTree = ""; @@ -4966,6 +4978,7 @@ 420F53E92C4E9D43003C8415 /* Widget */, D03D891920E0A85300D4F28D /* Shared.h */, 4235075C2CDB756800A19902 /* HAServices.swift */, + 4254C4C92D103ABB00245021 /* ExternalLink.swift */, ); path = Shared; sourceTree = ""; @@ -6908,6 +6921,7 @@ 4296C36D2B90DB640051B63C /* IntentActionAppEntity.swift in Sources */, 42F1DA5B2B4BF7DF002729BC /* WindowSizeObserver.swift in Sources */, 429106892BA9D5F700D452F9 /* AssistView+Build.swift in Sources */, + 429BEA1A2D102F3A00F070F9 /* ConnectionErrorDetailsView.swift in Sources */, 11EFCDD624F5FA8D00314D85 /* WebViewSceneDelegate.swift in Sources */, 42B94BDF2B9606CD00DEE060 /* AssistView.swift in Sources */, 1185DF94271FBA6100ED7D9A /* OnboardingAuthDetails.swift in Sources */, @@ -7265,6 +7279,7 @@ 491E990025D543560077BBE3 /* LogbookEntry.swift in Sources */, 11B38EF2275C54A300205C7B /* CallServiceIntentHandler.swift in Sources */, 42D3E4C02C5D321C00444BE6 /* NotificationIdentifier.swift in Sources */, + 4254C4CB2D103ABB00245021 /* ExternalLink.swift in Sources */, 42CE8FB12B46C3DA00C707F9 /* CoreStrings+Values.swift in Sources */, 4239D1832C4FFCCE003497FC /* WatchUserDefaults.swift in Sources */, B67CE8A722200F220034C1D0 /* HAAPI+RequestHelpers.swift in Sources */, @@ -7344,6 +7359,7 @@ files = ( 118F046924CB895A00CBBD5C /* UIColor+CSS3+Hex.swift in Sources */, 1109F81F24A1C011002590F2 /* SensorProvider.swift in Sources */, + 4254C4CA2D103ABB00245021 /* ExternalLink.swift in Sources */, 4297ADA82C89C74A00790812 /* GRDB+Initialization.swift in Sources */, 1141182A24AFA10900E6525C /* WebhookResponseHandler.swift in Sources */, 118BDA8825A6DBBA00731016 /* FrontmostAppSensor.swift in Sources */, @@ -7460,6 +7476,7 @@ 4214388C2CF5F1D700E2D44D /* ServerFixture.swift in Sources */, 11B38EE3275C54A200205C7B /* OpenPageIntentHandler.swift in Sources */, 113D29DE24946EDA0014067C /* CLLocationManager+OneShotLocation.swift in Sources */, + 429BEA1D2D10315F00F070F9 /* SheetCloseButton.swift in Sources */, 11ADF940267D34B10040A7E3 /* NotificationsCommandManager.swift in Sources */, 11C4627F24B04CB800031902 /* Promise+RetryNetworking.swift in Sources */, D03D893920E0AF8E00D4F28D /* ClientEvent.swift in Sources */, @@ -7527,6 +7544,7 @@ 4251AABC2C6CE224004CCC9D /* MagicItemProvider.swift in Sources */, D0EEF303214D8F0300D1D360 /* String+HA.swift in Sources */, 11B38EE6275C54A200205C7B /* CallServiceIntentHandler.swift in Sources */, + 4254C4CD2D103F7B00245021 /* ExternalLinkButton.swift in Sources */, 491E98FF25D543560077BBE3 /* LogbookEntry.swift in Sources */, 3997926A2B7F904A00231B54 /* MobileAppConfigPushCategory.swift in Sources */, 42CE8FA72B45D1E900C707F9 /* CoreStrings.swift in Sources */, diff --git a/Sources/App/Resources/Assets.xcassets/CustomSymbols/discord.fill.symbolset/Contents.json b/Sources/App/Resources/Assets.xcassets/CustomSymbols/discord.fill.symbolset/Contents.json new file mode 100644 index 000000000..3e3395226 --- /dev/null +++ b/Sources/App/Resources/Assets.xcassets/CustomSymbols/discord.fill.symbolset/Contents.json @@ -0,0 +1,12 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "filename" : "discord.fill.svg", + "idiom" : "universal" + } + ] +} diff --git a/Sources/App/Resources/Assets.xcassets/CustomSymbols/discord.fill.symbolset/discord.fill.svg b/Sources/App/Resources/Assets.xcassets/CustomSymbols/discord.fill.symbolset/discord.fill.svg new file mode 100644 index 000000000..4819b0373 --- /dev/null +++ b/Sources/App/Resources/Assets.xcassets/CustomSymbols/discord.fill.symbolset/discord.fill.svg @@ -0,0 +1,200 @@ + + + + + + + + + + Weight/Scale Variations + Ultralight + Thin + Light + Regular + Medium + Semibold + Bold + Heavy + Black + + + + + + + + + + + Design Variations + Symbols are supported in up to nine weights and three scales. + For optimal layout with text and other symbols, vertically align + symbols with the adjacent text. + + + + + + Margins + Leading and trailing margins on the left and right side of each symbol + can be adjusted by modifying the x-location of the margin guidelines. + Modifications are automatically applied proportionally to all + scales and weights. + + + + Exporting + Symbols should be outlined when exporting to ensure the + design is preserved when submitting to Xcode. + Template v.4.0 + Requires Xcode 14 or greater + Generated from discord.fill + Typeset at 100 points + Small + Medium + Large + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sources/App/Resources/Assets.xcassets/CustomSymbols/github.fill.symbolset/Contents.json b/Sources/App/Resources/Assets.xcassets/CustomSymbols/github.fill.symbolset/Contents.json new file mode 100644 index 000000000..092d1f2a1 --- /dev/null +++ b/Sources/App/Resources/Assets.xcassets/CustomSymbols/github.fill.symbolset/Contents.json @@ -0,0 +1,12 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "symbols" : [ + { + "filename" : "github.fill.svg", + "idiom" : "universal" + } + ] +} diff --git a/Sources/App/Resources/Assets.xcassets/CustomSymbols/github.fill.symbolset/github.fill.svg b/Sources/App/Resources/Assets.xcassets/CustomSymbols/github.fill.symbolset/github.fill.svg new file mode 100644 index 000000000..9964bc129 --- /dev/null +++ b/Sources/App/Resources/Assets.xcassets/CustomSymbols/github.fill.symbolset/github.fill.svg @@ -0,0 +1,167 @@ + + + + + + + + + + Weight/Scale Variations + Ultralight + Thin + Light + Regular + Medium + Semibold + Bold + Heavy + Black + + + + + + + + + + + Design Variations + Symbols are supported in up to nine weights and three scales. + For optimal layout with text and other symbols, vertically align + symbols with the adjacent text. + + + + + + Margins + Leading and trailing margins on the left and right side of each symbol + can be adjusted by modifying the x-location of the margin guidelines. + Modifications are automatically applied proportionally to all + scales and weights. + + + + Exporting + Symbols should be outlined when exporting to ensure the + design is preserved when submitting to Xcode. + Template v.4.0 + Requires Xcode 14 or greater + Generated from github.fill + Typeset at 100 points + Small + Medium + Large + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Sources/App/Resources/en.lproj/Localizable.strings b/Sources/App/Resources/en.lproj/Localizable.strings index 611cb4e12..9da8f05f8 100644 --- a/Sources/App/Resources/en.lproj/Localizable.strings +++ b/Sources/App/Resources/en.lproj/Localizable.strings @@ -1094,4 +1094,12 @@ Home Assistant is free and open source home automation software with a focus on "widgets.sensors.description" = "Display state of sensors"; "widgets.sensors.not_configured" = "No Sensors Configured"; "widgets.sensors.title" = "Sensors"; -"yes_label" = "Yes"; \ No newline at end of file +"connection.error.generic_title" = "Uh oh! Looks like we are unable to establish a connection."; +"connection.error.details.title" = "Connection error"; +"connection.error.details.label.description" = "Description"; +"connection.error.details.label.domain" = "Domain"; +"connection.error.details.label.code" = "Code"; +"connection.error.details.button.doc" = "Read documentation"; +"connection.error.details.button.discord" = "Ask in Discord"; +"connection.error.details.button.github" = "Report issue in Github"; +"yes_label" = "Yes"; diff --git a/Sources/App/WebView/ConnectionErrorDetailsView.swift b/Sources/App/WebView/ConnectionErrorDetailsView.swift new file mode 100644 index 000000000..51c6e8392 --- /dev/null +++ b/Sources/App/WebView/ConnectionErrorDetailsView.swift @@ -0,0 +1,76 @@ +import SFSafeSymbols +import Shared +import SwiftUI + +struct ConnectionErrorDetailsView: View { + @Environment(\.dismiss) private var dismiss + let error: Error + var body: some View { + ScrollView { + VStack(alignment: .leading) { + HStack { + SheetCloseButton { + dismiss() + } + .frame(maxWidth: .infinity, alignment: .trailing) + } + Text(L10n.Connection.Error.Details.title) + .font(.title.bold()) + VStack(alignment: .leading, spacing: Spaces.two) { + makeRow(title: L10n.Connection.Error.Details.Label.description, body: error.localizedDescription) + makeRow(title: L10n.Connection.Error.Details.Label.domain, body: (error as NSError).domain) + makeRow(title: L10n.Connection.Error.Details.Label.code, body: "\((error as NSError).code)") + } + .padding(.vertical) + documentationLink + discordLink + githubLink + } + .padding() + } + } + + private func makeRow(title: String, body: String) -> some View { + VStack(alignment: .leading) { + Text(title) + .font(.headline.bold()) + Text(body) + .textSelection(.enabled) + } + } + + private var documentationLink: some View { + ExternalLinkButton( + icon: Image(systemSymbol: .docTextFill), + title: L10n.Connection.Error.Details.Button.doc, + url: ExternalLink.companionAppDocs, + tint: .init(uiColor: Asset.Colors.haPrimary.color) + ) + } + + private var discordLink: some View { + ExternalLinkButton( + icon: Image("discord.fill"), + title: L10n.Connection.Error.Details.Button.discord, + url: ExternalLink.discord, + tint: .purple + ) + } + + private var githubLink: some View { + ExternalLinkButton( + icon: Image("github.fill"), + title: L10n.Connection.Error.Details.Button.github, + url: ExternalLink.githubReportIssue, + tint: .black + ) + } +} + +#Preview { + ConnectionErrorDetailsView(error: SomeError.some) +} + +enum SomeError: Error { + case some +} diff --git a/Sources/App/WebView/NoActiveURLView.swift b/Sources/App/WebView/NoActiveURLView.swift index babbdcf10..5d25c2463 100644 --- a/Sources/App/WebView/NoActiveURLView.swift +++ b/Sources/App/WebView/NoActiveURLView.swift @@ -81,23 +81,21 @@ struct NoActiveURLView: View { private var header: some View { HStack { - Group { - Button { - Current.Log.info("Tapped settings button in NoActiveURLView") - showSettings() - } label: { - Image(systemSymbol: .gear) - } - Spacer() - Button { - Current.Log.info("Dismissed NoActiveURLView") - dismiss() - } label: { - Image(systemSymbol: .xmark) - } + Button { + Current.Log.info("Tapped settings button in NoActiveURLView") + showSettings() + } label: { + Image(systemSymbol: .gear) } .font(.title2) .foregroundStyle(Color(uiColor: .secondaryLabel)) + Spacer() + Button { + Current.Log.info("Dismissed NoActiveURLView") + dismiss() + } label: { + Image(systemSymbol: .xmark) + } } } diff --git a/Sources/App/WebView/WebViewController.swift b/Sources/App/WebView/WebViewController.swift index 4d5823347..663a1d079 100644 --- a/Sources/App/WebView/WebViewController.swift +++ b/Sources/App/WebView/WebViewController.swift @@ -734,23 +734,26 @@ final class WebViewController: UIViewController, WKNavigationDelegate, WKUIDeleg func showSwiftMessage(error: Error, duration: SwiftMessages.Duration = .seconds(seconds: 15)) { Current.Log.error(error) - - let nsError = error as NSError - var config = swiftMessagesConfig() config.duration = duration let view = MessageView.viewFromNib(layout: .messageView) - view.configureTheme(.error) view.configureContent( - title: error.localizedDescription, - body: "\(nsError.domain) \(nsError.code)", + title: L10n.Connection.Error.genericTitle, + body: error.localizedDescription, iconImage: nil, iconText: nil, - buttonImage: nil, - buttonTitle: L10n.okLabel, - buttonTapHandler: { _ in + buttonImage: MaterialDesignIcons.helpCircleIcon.image( + ofSize: .init(width: 35, height: 35), + color: Asset.Colors.haPrimary.color + ), + buttonTitle: nil, + buttonTapHandler: { [weak self] _ in SwiftMessages.hide() + self?.presentOverlayController( + controller: UIHostingController(rootView: ConnectionErrorDetailsView(error: error)), + animated: true + ) } ) view.titleLabel?.numberOfLines = 0 diff --git a/Sources/Shared/DesignSystem/Components/ExternalLinkButton.swift b/Sources/Shared/DesignSystem/Components/ExternalLinkButton.swift new file mode 100644 index 000000000..3aecfd12e --- /dev/null +++ b/Sources/Shared/DesignSystem/Components/ExternalLinkButton.swift @@ -0,0 +1,43 @@ +import SwiftUI + +public struct ExternalLinkButton: View { + let icon: Image + let title: String + let url: URL + let tint: Color + + public init(icon: Image, title: String, url: URL, tint: Color) { + self.icon = icon + self.title = title + self.url = url + self.tint = tint + } + + public var body: some View { + Link(destination: url) { + HStack(spacing: Spaces.two) { + icon + .frame(width: 30, height: 30) + .font(.title2) + .tint(tint) + Text(title) + .frame(maxWidth: .infinity, alignment: .leading) + .tint(Color(uiColor: .label)) + .font(.body.bold()) + } + } + .frame(maxWidth: 600) + .padding() + .background(Color(.systemGray6)) + .clipShape(RoundedRectangle(cornerRadius: 12)) + } +} + +#Preview { + ExternalLinkButton( + icon: Image(systemName: "xmark"), + title: "Go there", + url: URL(string: "https://google.com")!, + tint: .blue + ) +} diff --git a/Sources/Shared/DesignSystem/Components/SheetCloseButton.swift b/Sources/Shared/DesignSystem/Components/SheetCloseButton.swift new file mode 100644 index 000000000..ce273b184 --- /dev/null +++ b/Sources/Shared/DesignSystem/Components/SheetCloseButton.swift @@ -0,0 +1,24 @@ +import SFSafeSymbols +import SwiftUI + +public struct SheetCloseButton: View { + let action: () -> Void + + public init(action: @escaping () -> Void) { + self.action = action + } + + public var body: some View { + Button { + action() + } label: { + Image(systemSymbol: .xmark) + } + .font(.title2) + .foregroundStyle(Color(uiColor: .secondaryLabel)) + } +} + +#Preview { + SheetCloseButton(action: {}) +} diff --git a/Sources/Shared/ExternalLink.swift b/Sources/Shared/ExternalLink.swift new file mode 100644 index 000000000..7ac0ff1f0 --- /dev/null +++ b/Sources/Shared/ExternalLink.swift @@ -0,0 +1,7 @@ +import Foundation + +public enum ExternalLink { + public static var companionAppDocs = URL(string: "https://companion.home-assistant.io")! + public static var discord = URL(string: "https://discord.com/channels/330944238910963714/1284965926336335993")! + public static var githubReportIssue = URL(string: "https://github.com/home-assistant/iOS/issues/new/choose")! +} diff --git a/Sources/Shared/Resources/Swiftgen/Strings.swift b/Sources/Shared/Resources/Swiftgen/Strings.swift index dac564f8b..81e008cea 100644 --- a/Sources/Shared/Resources/Swiftgen/Strings.swift +++ b/Sources/Shared/Resources/Swiftgen/Strings.swift @@ -755,6 +755,30 @@ public enum L10n { } public enum Connection { + public enum Error { + /// Uh oh! Looks like we are unable to establish a connection. + public static var genericTitle: String { return L10n.tr("Localizable", "connection.error.generic_title") } + public enum Details { + /// Connection error + public static var title: String { return L10n.tr("Localizable", "connection.error.details.title") } + public enum Button { + /// Ask in Discord + public static var discord: String { return L10n.tr("Localizable", "connection.error.details.button.discord") } + /// Read documentation + public static var doc: String { return L10n.tr("Localizable", "connection.error.details.button.doc") } + /// Report issue in Github + public static var github: String { return L10n.tr("Localizable", "connection.error.details.button.github") } + } + public enum Label { + /// Code + public static var code: String { return L10n.tr("Localizable", "connection.error.details.label.code") } + /// Description + public static var description: String { return L10n.tr("Localizable", "connection.error.details.label.description") } + /// Domain + public static var domain: String { return L10n.tr("Localizable", "connection.error.details.label.domain") } + } + } + } public enum Permission { public enum InternalUrl { /// To access Home Assistant locally in a secure way, you need to grant the location permission ('Always').