Changes
7 changed files (+280/-74)
-
-
@@ -343,7 +343,7 @@ "localizations" : {"en" : { "stringUnit" : { "state" : "translated", "value" : "Connecting to Roon Server.\nMake sure you granted access at Settings > Extension page in official Roon client." "value" : "Connecting to Roon Server. Make sure you granted access at Settings > Extension page in official Roon client." } }, "ja" : {
-
@@ -354,12 +354,12 @@ }} } }, "ConnectionScreen.NotFound.Description(id=%@)" : { "ConnectionScreen.NotFound.Description" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "Server (ID: %@) does not found on network." "value" : "Server %@ does not found on network." } }, "ja" : {
-
@@ -441,7 +441,7 @@ "extractionState" : "extracted_with_value","localizations" : { "en" : { "stringUnit" : { "state" : "new", "state" : "translated", "value" : "Close" } },
-
@@ -454,11 +454,10 @@ }} }, "PlaybackBar.OutputPanel.Label" : { "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", "state" : "translated", "value" : "Sound Outputs" } },
-
@@ -471,11 +470,10 @@ }} }, "PlaybackBar.OutputPanel.NoVolumeControl" : { "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", "state" : "translated", "value" : "This output does not support volume control." } },
-
@@ -488,11 +486,10 @@ }} }, "PlaybackBar.OutputPanel.StepVolumeLabel" : { "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", "state" : "translated", "value" : "Volume Control" } },
-
@@ -506,11 +503,10 @@ }}, "PlaybackBar.OutputPanel.VolumeSlider" : { "comment" : "A label for volume slider.", "extractionState" : "extracted_with_value", "localizations" : { "en" : { "stringUnit" : { "state" : "new", "state" : "translated", "value" : "Volume slider" } },
-
-
-
@@ -41,7 +41,7 @@ Button {model?.model = nil } label: { Label { Text("Menu.Disconnect") Text(String(localized: "Menu.Disconnect", defaultValue: "Disconnect")) } icon: { Image(systemName: "powercode") }
-
@@ -114,7 +114,10 @@ UserDefaults.standard.set(token, forKey: StorageKeys.extensionToken)} var body: some Scene { WindowGroup(Text("AppTitle"), id: "main-window") { WindowGroup( Text(String(localized: "AppTitle", defaultValue: "Plac")), id: "main-window" ) { if let model = model.model { ConnectionScreen( model: model,
-
-
-
@@ -42,17 +42,29 @@ .background(.background)case .some(.failed(_)): ContentUnavailableView { Label { Text("Browser.Error.Heading") Text( String( localized: "Browser.Error.Heading", defaultValue: "Failed to load" ) ) } icon: { Image(systemName: "exclamationmark.triangle") } } description: { Text("Browser.Error.Description") Text( String( localized: "Browser.Error.Description", defaultValue: "An error occurred when loading the page." ) ) } actions: { Button { model.reload() } label: { Text("Browser.Error.Retry") Text( String(localized: "Browser.Error.Retry", defaultValue: "Retry") ) } } case .some(.loaded(let list, let groups)):
-
-
-
@@ -59,23 +59,68 @@ List(hierarchies, id: \.self, selection: $browsing.hierarchy) {hierarchy in switch hierarchy { case .browse: Text("ConnectedScene.Category.Explore") Text( String( localized: "ConnectedScene.Category.Explore", defaultValue: "Explore" ) ) case .playlists: Text("ConnectedScene.Category.Playlists") Text( String( localized: "ConnectedScene.Category.Playlists", defaultValue: "Playlists" ) ) case .settings: Text("ConnectedScene.Category.Settings") Text( String( localized: "ConnectedScene.Category.Settings", defaultValue: "Settings" ) ) case .albums: Text("ConnectedScene.Category.Albums") Text( String( localized: "ConnectedScene.Category.Albums", defaultValue: "Albums" ) ) case .artists: Text("ConnectedScene.Category.Artists") Text( String( localized: "ConnectedScene.Category.Artists", defaultValue: "Artists" ) ) case .genres: Text("ConnectedScene.Category.Genres") Text( String( localized: "ConnectedScene.Category.Genres", defaultValue: "Genres" ) ) case .composers: Text("ConnectedScene.Category.Composers") Text( String( localized: "ConnectedScene.Category.Composers", defaultValue: "Composers" ) ) case .search: Text("ConnectedScene.Category.Search") Text( String( localized: "ConnectedScene.Category.Search", defaultValue: "Search" ) ) case .internetRadio: Text("ConnectedScene.Category.InternetRadio") Text( String( localized: "ConnectedScene.Category.InternetRadio", defaultValue: "Internet Radios" ) ) } } } detail: {
-
@@ -89,11 +134,21 @@ }} } .alert( Text("ConnectedScene.ServerMessage.Title"), Text( String( localized: "ConnectedScene.ServerMessage.Title", defaultValue: "Message from Roon server" ) ), isPresented: shouldDisplayMessage, presenting: browsing.message ) { _ in Button("ConnectedScene.ServerMessage.Dismiss") { Button( String( localized: "ConnectedScene.ServerMessage.Dismiss", defaultValue: "Dismiss" ) ) { browsing.message = nil } } message: { message in
-
-
-
@@ -50,21 +50,33 @@ )case .failed(RoonKit.ServerLookupError.notFound): ContentUnavailableView { Label { Text("ConnectionScreen.NotFound.Heading") Text( String( localized: "ConnectionScreen.NotFound.Heading", defaultValue: "Server not found" ) ) } icon: { Image(systemName: "exclamationmark.magnifyingglass") } } description: { Text( "ConnectionScreen.NotFound.Description(id=\(self.conn.serverID))" String( localized: "ConnectionScreen.NotFound.Description", defaultValue: "Server \(self.conn.serverID) does not found on network." ) ) } actions: { Button(role: .cancel) { onDisconnect() } label: { Text( "ConnectionScreen.Disconnect", comment: "Button label for aborting connection process." String( localized: "ConnectionScreen.Disconnect", defaultValue: "Close", comment: "Button label for aborting connection process." ) ) }
-
@@ -72,21 +84,34 @@ Button {onReconnect() } label: { Text( "ConnectionScreen.Reconnect", comment: "Button label for connecting to Roon server from non-connected state." String( localized: "ConnectionScreen.Reconnect", defaultValue: "Reconnect", comment: "Button label for connecting to Roon server from non-connected state." ) ) } } case .failed(CancelError.cancelled): ContentUnavailableView { Label { Text("ConnectionScreen.Cancelled.Heading") Text( String( localized: "ConnectionScreen.Cancelled.Heading", defaultValue: "Connection cancelled" ) ) } icon: { Image(systemName: "exclamationmark.magnifyingglass") } } description: { Text("ConnectionScreen.Cancelled.Description") Text( String( localized: "ConnectionScreen.Cancelled.Description", defaultValue: "Cancelled connecting to Roon server." ) ) } actions: { Button(role: .cancel) { onDisconnect()
-
@@ -103,12 +128,22 @@ }case .failed(_): ContentUnavailableView { Label { Text("ConnectionScreen.Error.Heading") Text( String( localized: "ConnectionScreen.Error.Heading", defaultValue: "Failed to connect" ) ) } icon: { Image(systemName: "exclamationmark.magnifyingglass") } } description: { Text("ConnectionScreen.Error.Description") Text( String( localized: "ConnectionScreen.Error.Description", defaultValue: "Failed to connect due to an error." ) ) } actions: { Button(role: .cancel) { onDisconnect()
-
@@ -137,14 +172,25 @@var body: some View { VStack(spacing: 8) { ProgressView { Text("ConnectionScreen.Loading.Label") .multilineTextAlignment(.center) Text( String( localized: "ConnectionScreen.Loading.Label", defaultValue: "Connecting to Roon Server. Make sure you granted access at Settings > Extension page in official Roon client." ) ) .multilineTextAlignment(.center) } Button(role: .cancel) { onCancel?() } label: { Text("ConnectionScreen.Loading.Cancel") Text( String( localized: "ConnectionScreen.Loading.Cancel", defaultValue: "Cancel" ) ) } } }
-
-
-
@@ -63,8 +63,11 @@ }} label: { Label { Text( "PlaybackBar.Previous", comment: "A label for a previous button." String( localized: "PlaybackBar.Previous", defaultValue: "Previous", comment: "A label for a previous button." ) ) } icon: { Image(systemName: "backward.end.fill")
-
@@ -82,8 +85,11 @@ }} label: { Label { Text( "PlaybackBar.Pause", comment: "A label for a pause button." String( localized: "PlaybackBar.Pause", defaultValue: "Pause", comment: "A label for a pause button." ) ) } icon: { Image(systemName: "pause.fill")
-
@@ -100,7 +106,13 @@ await performAction(.play)} } label: { Label { Text("PlaybackBar.Play", comment: "A label for a play button.") Text( String( localized: "PlaybackBar.Play", defaultValue: "Play", comment: "A label for a play button." ) ) } icon: { Image(systemName: "play.fill") }
-
@@ -117,7 +129,13 @@ await performAction(.next)} } label: { Label { Text("PlaybackBar.Next", comment: "A label for a next button.") Text( String( localized: "PlaybackBar.Next", defaultValue: "Next", comment: "A label for a next button." ) ) } icon: { Image(systemName: "forward.end.fill") }
-
@@ -172,7 +190,13 @@ }} } ) { Text("PlaybackBar.Seekbar", comment: "A label for seekbar.") Text( String( localized: "PlaybackBar.Seekbar", defaultValue: "Playback seekbar", comment: "A label for seekbar." ) ) } .labelsHidden() .disabled(!(zone.isSeekAllowed ?? false))
-
@@ -188,8 +212,11 @@ isZonePickerVisible = true} label: { Label { Text( "PlaybackBar.ZonePicker.Label", comment: "A label for zone picker." String( localized: "PlaybackBar.ZonePicker.Label", defaultValue: "Zone", comment: "A label for zone picker." ) ) } icon: { Image(systemName: "square.2.layers.3d.top.filled")
-
@@ -204,7 +231,12 @@ ForEach(model.zones) { (zone: TransportService.Zone) inText(zone.displayName).tag(zone) } } header: { Text("PlaybackBar.ZonePicker.Title") Text( String( localized: "PlaybackBar.ZonePicker.Title", defaultValue: "Zones" ) ) } } }
-
-
-
@@ -105,8 +105,11 @@ Button {onConnectAction?(server) } label: { Text( "ServerDiscovery.Open", comment: "Label for a button that starts a connection." String( localized: "ServerDiscovery.Open", defaultValue: "Open", comment: "Label for a button that starts a connection." ) ) } .buttonStyle(.borderedProminent)
-
@@ -114,8 +117,11 @@ }VStack(alignment: .leading) { Text( "ServerDiscovery.Version", comment: "A label for server version field." String( localized: "ServerDiscovery.Version", defaultValue: "Version", comment: "A label for server version field." ) ) .font(.headline)
-
@@ -125,8 +131,11 @@ }VStack(alignment: .leading) { Text( "ServerDiscovery.Host", comment: "A label for server host field." String( localized: "ServerDiscovery.Host", defaultValue: "IP Address", comment: "A label for server host field." ) ) .font(.headline)
-
@@ -143,8 +152,11 @@ }} .navigationTitle( Text( "ServerDiscovery.Title", comment: "Title of server discovery scene. Not visible on macOS." String( localized: "ServerDiscovery.Title", defaultValue: "Servers", comment: "Title of server discovery scene. Not visible on macOS." ) ) ) .toolbar {
-
@@ -156,8 +168,11 @@ }} label: { Label { Text( "ServerDiscovery.Refresh", comment: "Icon label for refresh button." String( localized: "ServerDiscovery.Refresh", defaultValue: "Refresh", comment: "Icon label for refresh button." ) ) } icon: { Image(systemName: "arrow.trianglehead.clockwise")
-
@@ -165,8 +180,11 @@ }} .help( Text( "ServerDiscovery.RefreshHelp", comment: "Help tooltip text for refresh button." String( localized: "ServerDiscovery.RefreshHelp", defaultValue: "Refresh server list", comment: "Help tooltip text for refresh button." ) ) ) .disabled(busy)
-
@@ -177,29 +195,52 @@ switch status {case .loading: ContentUnavailableView { Label { Text("ServerDiscovery.Loading.Heading") Text( String( localized: "ServerDiscovery.Loading.Heading", defaultValue: "Scanning" ) ) } icon: { Image(systemName: "waveform.badge.magnifyingglass") } .symbolEffect(.variableColor) } description: { Text("ServerDiscovery.Loading.Description") Text( String( localized: "ServerDiscovery.Loading.Description", defaultValue: "Scanning Roon servers on local network." ) ) } case .loaded: if servers.isEmpty { ContentUnavailableView { Label { Text("ServerDiscovery.Empty.Heading") Text( String( localized: "ServerDiscovery.Empty.Heading", defaultValue: "No server found" ) ) } icon: { Image(systemName: "square.dashed") } } description: { Text("ServerDiscovery.Empty.Description") Text( String( localized: "ServerDiscovery.Empty.Description", defaultValue: "No Roon server found on local network." ) ) } } else { Text( "ServerDiscovery.Placeholder", comment: "Placeholder text for server details view." String( localized: "ServerDiscovery.Placeholder", defaultValue: "Select server from list", comment: "Placeholder text for server details view." ) ) } case .failed(let error):
-
@@ -208,22 +249,43 @@ case RoonKit.ServerLookupError.socketError(_),RoonKit.ServerLookupError.connectionClosed: ContentUnavailableView { Label { Text("ServerDiscovery.NetworkError.Heading") Text( String( localized: "ServerDiscovery.NetworkError.Heading", defaultValue: "Scan failed" ) ) } icon: { Image(systemName: "wifi.exclamationmark") } } description: { Text("ServerDiscovery.NetworkError.Description") Text( String( localized: "ServerDiscovery.NetworkError.Description", defaultValue: "Failed to scan Roon servers due to network error." ) ) } default: ContentUnavailableView { Label { Text("ServerDiscovery.Error.Heading") Text( String( localized: "ServerDiscovery.Error.Heading", defaultValue: "Scan failed" ) ) } icon: { Image(systemName: "exclamationmark.magnifyingglass") } } description: { Text("ServerDiscovery.Error.Description") Text( String( localized: "ServerDiscovery.Error.Description", defaultValue: "An error occurred during a scan." ) ) } } }
-