diff --git a/Persephone.xcodeproj/project.pbxproj b/Persephone.xcodeproj/project.pbxproj index 59a2b00..499e7ca 100644 --- a/Persephone.xcodeproj/project.pbxproj +++ b/Persephone.xcodeproj/project.pbxproj @@ -55,6 +55,9 @@ E450AD7E222620A10091BED3 /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = E450AD7D222620A10091BED3 /* Album.swift */; }; E451E36B22BD214D008BE9B2 /* DraggedSongType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */; }; E451E36E22BD2501008BE9B2 /* DraggedSong.swift in Sources */ = {isa = PBXBuildFile; fileRef = E451E36C22BD23DB008BE9B2 /* DraggedSong.swift */; }; + E453825223FA0186007F6BFC /* VolumeControlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E453825023FA0186007F6BFC /* VolumeControlView.swift */; }; + E453825323FA0186007F6BFC /* VolumeControlView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E453825123FA0186007F6BFC /* VolumeControlView.xib */; }; + E453825523FA347C007F6BFC /* MPDClient+Mixer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E453825423FA347C007F6BFC /* MPDClient+Mixer.swift */; }; E45878382296173C00586A1C /* AlbumDetailSongRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */; }; E45962C62241A78500FC1A1E /* MPDCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = E45962C52241A78500FC1A1E /* MPDCommand.swift */; }; E45E4FDA22515D87004B537F /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FD722515D87004B537F /* CHANGELOG.md */; }; @@ -259,6 +262,9 @@ E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PersephoneBridgingHeader.h; sourceTree = ""; }; E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedSongType.swift; sourceTree = ""; }; E451E36C22BD23DB008BE9B2 /* DraggedSong.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedSong.swift; sourceTree = ""; }; + E453825023FA0186007F6BFC /* VolumeControlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VolumeControlView.swift; sourceTree = ""; }; + E453825123FA0186007F6BFC /* VolumeControlView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VolumeControlView.xib; sourceTree = ""; }; + E453825423FA347C007F6BFC /* MPDClient+Mixer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MPDClient+Mixer.swift"; sourceTree = ""; }; E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailSongRowView.swift; sourceTree = ""; }; E45962C52241A78500FC1A1E /* MPDCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDCommand.swift; sourceTree = ""; }; E45E4FD722515D87004B537F /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = SOURCE_ROOT; }; @@ -446,14 +452,15 @@ E42410B52241B956005ED6DF /* MPDClient+Database.swift */, E41E5304223BFB0700173814 /* MPDClient+Error.swift */, E41E5302223BF9C300173814 /* MPDClient+Idle.swift */, + E453825423FA347C007F6BFC /* MPDClient+Mixer.swift */, E41E5300223BF99300173814 /* MPDClient+Queue.swift */, E42A4D5022E2167E001C6CAD /* MPDClient+Songs.swift */, - E408D3BD220E03EE0006D9BE /* RawRepresentable.swift */, E41E5306223C019100173814 /* MPDClient+Status.swift */, E41E52FE223BF95E00173814 /* MPDClient+Transport.swift */, - E4DCCFAC23E4DB5D009A8113 /* MPDClientWrapper.h */, E4DCCFAD23E4DB5D009A8113 /* MPDClientWrapper.c */, + E4DCCFAC23E4DB5D009A8113 /* MPDClientWrapper.h */, E4DCCFAB23E4DB5D009A8113 /* Persephone-Bridging-Header.h */, + E408D3BD220E03EE0006D9BE /* RawRepresentable.swift */, ); path = Extensions; sourceTree = ""; @@ -520,6 +527,7 @@ E442CCC42347D5B900004E0C /* Components */ = { isa = PBXGroup; children = ( + E453824D23F9F700007F6BFC /* VolumeControl */, E442CCCB2347D77A00004E0C /* Browser */, E4A83BEC2221F5DD0098FED6 /* Preferences */, E442CCC62347D5E700004E0C /* Queue */, @@ -603,6 +611,15 @@ path = Browser; sourceTree = ""; }; + E453824D23F9F700007F6BFC /* VolumeControl */ = { + isa = PBXGroup; + children = ( + E453825023FA0186007F6BFC /* VolumeControlView.swift */, + E453825123FA0186007F6BFC /* VolumeControlView.xib */, + ); + path = VolumeControl; + sourceTree = ""; + }; E4A642DB220912FA00067D21 /* MPDClient */ = { isa = PBXGroup; children = ( @@ -873,6 +890,7 @@ files = ( E45E4FDB22515D87004B537F /* Brewfile in Resources */, E42A8F3B22176D6400A13ED9 /* LICENSE.md in Resources */, + E453825323FA0186007F6BFC /* VolumeControlView.xib in Resources */, E45E4FDA22515D87004B537F /* CHANGELOG.md in Resources */, E43B67AB22909793007DCF55 /* AlbumDetailView.xib in Resources */, E489E3A522B9D31800CA8CBD /* DraggedSongView.xib in Resources */, @@ -979,6 +997,7 @@ E419E2872249B96600216A8C /* Song.swift in Sources */, E451E36B22BD214D008BE9B2 /* DraggedSongType.swift in Sources */, E4BBD2F323357C0700702C16 /* ArtistListState.swift in Sources */, + E453825223FA0186007F6BFC /* VolumeControlView.swift in Sources */, E44051A0227BB0AB0090CD6F /* UIState.swift in Sources */, E4FF718E2276010E00D4C412 /* PreferencesState.swift in Sources */, E439109822640213002982E9 /* SongNotifierService.swift in Sources */, @@ -997,6 +1016,7 @@ E47E2FD122205C4600F747E6 /* MainSplitViewController.swift in Sources */, E4B5AE7E22F4C49600CCEC65 /* MPDServerDelegate.swift in Sources */, E4B11BB8227538FA0075461B /* CurrentCoverArtView.swift in Sources */, + E453825523FA347C007F6BFC /* MPDClient+Mixer.swift in Sources */, E4E8CC9A22075D370024217A /* MPDSong.swift in Sources */, E41EA46C221636AF0068EF46 /* GeneralPrefsViewController.swift in Sources */, E4E8CC902204EC7F0024217A /* Delegate.swift in Sources */, diff --git a/Persephone/Assets.xcassets/speakerDisabled.imageset/Contents.json b/Persephone/Assets.xcassets/speakerDisabled.imageset/Contents.json new file mode 100644 index 0000000..0219751 --- /dev/null +++ b/Persephone/Assets.xcassets/speakerDisabled.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "speakerDisabled.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "speakerDisabled@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Persephone/Assets.xcassets/speakerDisabled.imageset/speakerDisabled.png b/Persephone/Assets.xcassets/speakerDisabled.imageset/speakerDisabled.png new file mode 100644 index 0000000..00fc024 Binary files /dev/null and b/Persephone/Assets.xcassets/speakerDisabled.imageset/speakerDisabled.png differ diff --git a/Persephone/Assets.xcassets/speakerDisabled.imageset/speakerDisabled@2x.png b/Persephone/Assets.xcassets/speakerDisabled.imageset/speakerDisabled@2x.png new file mode 100644 index 0000000..7c16890 Binary files /dev/null and b/Persephone/Assets.xcassets/speakerDisabled.imageset/speakerDisabled@2x.png differ diff --git a/Persephone/Assets.xcassets/speakerHigh.imageset/Contents.json b/Persephone/Assets.xcassets/speakerHigh.imageset/Contents.json new file mode 100644 index 0000000..73b0a79 --- /dev/null +++ b/Persephone/Assets.xcassets/speakerHigh.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "speakerHigh.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "speakerHigh@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Persephone/Assets.xcassets/speakerHigh.imageset/speakerHigh.png b/Persephone/Assets.xcassets/speakerHigh.imageset/speakerHigh.png new file mode 100644 index 0000000..e3b6870 Binary files /dev/null and b/Persephone/Assets.xcassets/speakerHigh.imageset/speakerHigh.png differ diff --git a/Persephone/Assets.xcassets/speakerHigh.imageset/speakerHigh@2x.png b/Persephone/Assets.xcassets/speakerHigh.imageset/speakerHigh@2x.png new file mode 100644 index 0000000..b0a07da Binary files /dev/null and b/Persephone/Assets.xcassets/speakerHigh.imageset/speakerHigh@2x.png differ diff --git a/Persephone/Assets.xcassets/speakerLow.imageset/Contents.json b/Persephone/Assets.xcassets/speakerLow.imageset/Contents.json new file mode 100644 index 0000000..c885e73 --- /dev/null +++ b/Persephone/Assets.xcassets/speakerLow.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "speakerLow.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "speakerLow@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Persephone/Assets.xcassets/speakerLow.imageset/speakerLow.png b/Persephone/Assets.xcassets/speakerLow.imageset/speakerLow.png new file mode 100644 index 0000000..864f84e Binary files /dev/null and b/Persephone/Assets.xcassets/speakerLow.imageset/speakerLow.png differ diff --git a/Persephone/Assets.xcassets/speakerLow.imageset/speakerLow@2x.png b/Persephone/Assets.xcassets/speakerLow.imageset/speakerLow@2x.png new file mode 100644 index 0000000..15a3c37 Binary files /dev/null and b/Persephone/Assets.xcassets/speakerLow.imageset/speakerLow@2x.png differ diff --git a/Persephone/Assets.xcassets/speakerMid.imageset/Contents.json b/Persephone/Assets.xcassets/speakerMid.imageset/Contents.json new file mode 100644 index 0000000..9befac5 --- /dev/null +++ b/Persephone/Assets.xcassets/speakerMid.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "speakerMid.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "speakerMid@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Persephone/Assets.xcassets/speakerMid.imageset/speakerMid.png b/Persephone/Assets.xcassets/speakerMid.imageset/speakerMid.png new file mode 100644 index 0000000..03d7958 Binary files /dev/null and b/Persephone/Assets.xcassets/speakerMid.imageset/speakerMid.png differ diff --git a/Persephone/Assets.xcassets/speakerMid.imageset/speakerMid@2x.png b/Persephone/Assets.xcassets/speakerMid.imageset/speakerMid@2x.png new file mode 100644 index 0000000..7486a86 Binary files /dev/null and b/Persephone/Assets.xcassets/speakerMid.imageset/speakerMid@2x.png differ diff --git a/Persephone/Assets.xcassets/speakerOff.imageset/Contents.json b/Persephone/Assets.xcassets/speakerOff.imageset/Contents.json new file mode 100644 index 0000000..bf6fb82 --- /dev/null +++ b/Persephone/Assets.xcassets/speakerOff.imageset/Contents.json @@ -0,0 +1,25 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "speakerOff.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "speakerOff@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template" + } +} \ No newline at end of file diff --git a/Persephone/Assets.xcassets/speakerOff.imageset/speakerOff.png b/Persephone/Assets.xcassets/speakerOff.imageset/speakerOff.png new file mode 100644 index 0000000..f1206d6 Binary files /dev/null and b/Persephone/Assets.xcassets/speakerOff.imageset/speakerOff.png differ diff --git a/Persephone/Assets.xcassets/speakerOff.imageset/speakerOff@2x.png b/Persephone/Assets.xcassets/speakerOff.imageset/speakerOff@2x.png new file mode 100644 index 0000000..a34c293 Binary files /dev/null and b/Persephone/Assets.xcassets/speakerOff.imageset/speakerOff@2x.png differ diff --git a/Persephone/Components/Shared/Extensions/NSImage.swift b/Persephone/Components/Shared/Extensions/NSImage.swift index cb336cd..7fa03d4 100644 --- a/Persephone/Components/Shared/Extensions/NSImage.swift +++ b/Persephone/Components/Shared/Extensions/NSImage.swift @@ -15,4 +15,10 @@ extension NSImage { static let queuePauseIcon = NSImage(named: "queuePauseButton") static let defaultCoverArt = NSImage(named: "defaultCoverArt") + + static let speakerDisabled = NSImage(named: "speakerDisabled") + static let speakerOff = NSImage(named: "speakerOff") + static let speakerLow = NSImage(named: "speakerLow") + static let speakerMid = NSImage(named: "speakerMid") + static let speakerHigh = NSImage(named: "speakerHigh") } diff --git a/Persephone/Components/VolumeControl/VolumeControlView.swift b/Persephone/Components/VolumeControl/VolumeControlView.swift new file mode 100644 index 0000000..1c6ed12 --- /dev/null +++ b/Persephone/Components/VolumeControl/VolumeControlView.swift @@ -0,0 +1,45 @@ + // +// VolumeControlView.swift +// Persephone +// +// Created by Daniel Barber on 2/16/20. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import AppKit +import ReSwift + +class VolumeControlView: NSViewController { + static let shared = VolumeControlView() + static let popover = NSPopover() + + var currentVolume: Int = 0 + + override func viewDidLoad() { + super.viewDidLoad() + + App.store.subscribe(self) { + $0.select { $0.playerState } + } + } + + @IBAction func volumeSliderAction(_ sender: NSSlider) { + let newVolume = sender.integerValue + + if newVolume != currentVolume { + App.mpdClient.setVolume(to: newVolume) + currentVolume = newVolume + } + } + + @IBOutlet var volumeSlider: NSSlider! +} + +extension VolumeControlView: StoreSubscriber { + typealias StoreSubscriberStateType = PlayerState + + func newState(state: StoreSubscriberStateType) { + volumeSlider.integerValue = state.volume + currentVolume = state.volume + } +} diff --git a/Persephone/Components/VolumeControl/VolumeControlView.xib b/Persephone/Components/VolumeControl/VolumeControlView.xib new file mode 100644 index 0000000..e34fb9e --- /dev/null +++ b/Persephone/Components/VolumeControl/VolumeControlView.xib @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Persephone/Components/Window/Base.lproj/Main.storyboard b/Persephone/Components/Window/Base.lproj/Main.storyboard index c6a8ed9..13285c6 100644 --- a/Persephone/Components/Window/Base.lproj/Main.storyboard +++ b/Persephone/Components/Window/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -208,7 +208,7 @@ - + @@ -230,7 +230,7 @@ - + @@ -257,7 +257,7 @@ - + @@ -277,9 +277,9 @@ + @@ -329,6 +343,8 @@ + + @@ -345,6 +361,7 @@ + @@ -409,7 +426,7 @@ - + @@ -439,7 +456,7 @@ - + @@ -449,7 +466,7 @@ - + @@ -482,7 +499,7 @@ - + @@ -547,7 +564,7 @@ - + @@ -558,7 +575,7 @@ - + @@ -569,7 +586,7 @@ - + @@ -624,7 +641,7 @@ - + @@ -669,7 +686,7 @@ - + @@ -690,7 +707,7 @@ - + @@ -717,7 +734,7 @@ - + @@ -734,7 +751,7 @@ - + @@ -883,6 +900,7 @@ + diff --git a/Persephone/Components/Window/WindowController.swift b/Persephone/Components/Window/WindowController.swift index 0b3e5d9..499db98 100644 --- a/Persephone/Components/Window/WindowController.swift +++ b/Persephone/Components/Window/WindowController.swift @@ -27,6 +27,8 @@ class WindowController: NSWindowController { @IBOutlet var shuffleState: NSButton! @IBOutlet var repeatState: NSButton! + @IBOutlet var volumeState: NSButton! + @IBOutlet weak var searchQuery: NSSearchField! override func windowDidLoad() { @@ -120,6 +122,25 @@ class WindowController: NSWindowController { trackRemaining.stringValue = time.formattedTime } + + func setVolumeControlIcon(_ state: PlayerState) { + volumeState.isEnabled = state.volume != -1 + + switch state.volume { + case -1: + volumeState.image = .speakerDisabled + case 0..<5: + volumeState.image = .speakerOff + case 5..<40: + volumeState.image = .speakerLow + case 40..<70: + volumeState.image = .speakerMid + case 70...100: + volumeState.image = .speakerHigh + default: + break + } + } @objc func willDisconnect() { DispatchQueue.main.async { @@ -176,6 +197,16 @@ class WindowController: NSWindowController { @IBAction func handleSearchQuery(_ sender: NSSearchField) { App.store.dispatch(SetSearchQuery(searchQuery: sender.stringValue)) } + + @IBAction func showVolumeControl(_ sender: NSButton) { + VolumeControlView.popover.contentViewController = VolumeControlView.shared + VolumeControlView.popover.behavior = .transient + VolumeControlView.popover.show( + relativeTo: sender.bounds, + of: sender, + preferredEdge: .maxY + ) + } } extension WindowController: NSWindowDelegate { @@ -201,6 +232,7 @@ extension WindowController: StoreSubscriber { self.setShuffleRepeatState(state.playerState) self.setTrackProgressControls(state.playerState) self.setDatabaseUpdatingIndicator(state.uiState) + self.setVolumeControlIcon(state.playerState) } } } diff --git a/Persephone/MPDClient/Extensions/MPDClient+Command.swift b/Persephone/MPDClient/Extensions/MPDClient+Command.swift index f394737..0358974 100644 --- a/Persephone/MPDClient/Extensions/MPDClient+Command.swift +++ b/Persephone/MPDClient/Extensions/MPDClient+Command.swift @@ -46,6 +46,11 @@ extension MPDClient { guard let repeatState = userData["repeatState"] as? Bool else { return } sendRepeatState(repeatState: repeatState) + + case .setVolume: + guard let volume = userData["volume"] as? Int + else { return } + sendSetVolume(to: volume) // Database commands case .updateDatabase: diff --git a/Persephone/MPDClient/Extensions/MPDClient+Idle.swift b/Persephone/MPDClient/Extensions/MPDClient+Idle.swift index 5a78886..ee9f28f 100644 --- a/Persephone/MPDClient/Extensions/MPDClient+Idle.swift +++ b/Persephone/MPDClient/Extensions/MPDClient+Idle.swift @@ -64,7 +64,9 @@ extension MPDClient { self.delegate?.didUpdateQueuePos(mpdClient: self, song: status.song) } } - if mpdIdle.contains(.player) || mpdIdle.contains(.options) { + if mpdIdle.contains(.player) || + mpdIdle.contains(.options) || + mpdIdle.contains(.mixer) { self.fetchStatus() if let status = self.status { diff --git a/Persephone/MPDClient/Extensions/MPDClient+Mixer.swift b/Persephone/MPDClient/Extensions/MPDClient+Mixer.swift new file mode 100644 index 0000000..18d65bf --- /dev/null +++ b/Persephone/MPDClient/Extensions/MPDClient+Mixer.swift @@ -0,0 +1,24 @@ +// +// MPDClient+Mixer.swift +// Persephone +// +// Created by Daniel Barber on 2/16/20. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import Foundation +import mpdclient + +extension MPDClient { + func setVolume(to volume: Int) { + enqueueCommand( + command: .setVolume, + priority: .high, + userData: ["volume": volume] + ) + } + + func sendSetVolume(to volume: Int) { + mpd_run_set_volume(connection, UInt32(volume)) + } +} diff --git a/Persephone/MPDClient/Models/MPDCommand.swift b/Persephone/MPDClient/Models/MPDCommand.swift index 21a1a9c..906019b 100644 --- a/Persephone/MPDClient/Models/MPDCommand.swift +++ b/Persephone/MPDClient/Models/MPDCommand.swift @@ -22,6 +22,8 @@ extension MPDClient { case setShuffleState case setRepeatState + + case setVolume // Database commands case updateDatabase diff --git a/Persephone/MPDClient/Models/MPDStatus.swift b/Persephone/MPDClient/Models/MPDStatus.swift index 095b8b5..e3009ce 100644 --- a/Persephone/MPDClient/Models/MPDStatus.swift +++ b/Persephone/MPDClient/Models/MPDStatus.swift @@ -57,6 +57,10 @@ extension MPDClient { var repeatState: Bool { return mpd_status_get_repeat(status) } + + var volume: Int { + return Int(mpd_status_get_volume(status)) + } var updating: Bool { let updating = mpd_status_get_update_id(status) diff --git a/Persephone/State/Actions/PlayerActions.swift b/Persephone/State/Actions/PlayerActions.swift index 77d4f94..a879506 100644 --- a/Persephone/State/Actions/PlayerActions.swift +++ b/Persephone/State/Actions/PlayerActions.swift @@ -20,3 +20,7 @@ struct UpdateElapsedTimeAction: Action { struct UpdateStatusAction: Action { var status: MPDClient.MPDStatus } + +struct UpdateVolumeAction: Action { + var volume: Int +} diff --git a/Persephone/State/PlayerState.swift b/Persephone/State/PlayerState.swift index 176bea2..e576430 100644 --- a/Persephone/State/PlayerState.swift +++ b/Persephone/State/PlayerState.swift @@ -16,6 +16,8 @@ struct PlayerState: StateType { var state: MPDClient.MPDStatus.State? var shuffleState: Bool = false var repeatState: Bool = false + + var volume: Int = 0 var totalTime: UInt? var elapsedTimeMs: UInt? @@ -23,10 +25,11 @@ struct PlayerState: StateType { extension PlayerState: Equatable { static func == (lhs: PlayerState, rhs: PlayerState) -> Bool { - return (lhs.state == rhs.state) && - (lhs.totalTime == rhs.totalTime) && - (lhs.elapsedTimeMs == rhs.elapsedTimeMs) && - (lhs.shuffleState == rhs.shuffleState) && - (lhs.repeatState == rhs.repeatState) + return lhs.state == rhs.state && + lhs.totalTime == rhs.totalTime && + lhs.elapsedTimeMs == rhs.elapsedTimeMs && + lhs.shuffleState == rhs.shuffleState && + lhs.repeatState == rhs.repeatState && + lhs.volume == rhs.volume } } diff --git a/Persephone/State/Reducers/PlayerReducer.swift b/Persephone/State/Reducers/PlayerReducer.swift index 30f64bc..2e168c8 100644 --- a/Persephone/State/Reducers/PlayerReducer.swift +++ b/Persephone/State/Reducers/PlayerReducer.swift @@ -20,6 +20,7 @@ func playerReducer(action: Action, state: PlayerState?) -> PlayerState { state.elapsedTimeMs = action.status.elapsedTimeMs state.shuffleState = action.status.shuffleState state.repeatState = action.status.repeatState + state.volume = action.status.volume if state.state == .playing { App.trackTimer.start(elapsedTimeMs: state.elapsedTimeMs) diff --git a/Resources/export/speakerDisabled.pdf b/Resources/export/speakerDisabled.pdf new file mode 100644 index 0000000..81ae909 Binary files /dev/null and b/Resources/export/speakerDisabled.pdf differ diff --git a/Resources/export/speakerDisabled.png b/Resources/export/speakerDisabled.png new file mode 100644 index 0000000..00fc024 Binary files /dev/null and b/Resources/export/speakerDisabled.png differ diff --git a/Resources/export/speakerDisabled@2x.png b/Resources/export/speakerDisabled@2x.png new file mode 100644 index 0000000..7c16890 Binary files /dev/null and b/Resources/export/speakerDisabled@2x.png differ diff --git a/Resources/export/speakerHigh.pdf b/Resources/export/speakerHigh.pdf new file mode 100644 index 0000000..08ac5f1 Binary files /dev/null and b/Resources/export/speakerHigh.pdf differ diff --git a/Resources/export/speakerHigh.png b/Resources/export/speakerHigh.png new file mode 100644 index 0000000..e3b6870 Binary files /dev/null and b/Resources/export/speakerHigh.png differ diff --git a/Resources/export/speakerHigh@2x.png b/Resources/export/speakerHigh@2x.png new file mode 100644 index 0000000..b0a07da Binary files /dev/null and b/Resources/export/speakerHigh@2x.png differ diff --git a/Resources/export/speakerLow.pdf b/Resources/export/speakerLow.pdf new file mode 100644 index 0000000..69fc7a0 Binary files /dev/null and b/Resources/export/speakerLow.pdf differ diff --git a/Resources/export/speakerLow.png b/Resources/export/speakerLow.png new file mode 100644 index 0000000..864f84e Binary files /dev/null and b/Resources/export/speakerLow.png differ diff --git a/Resources/export/speakerLow@2x.png b/Resources/export/speakerLow@2x.png new file mode 100644 index 0000000..15a3c37 Binary files /dev/null and b/Resources/export/speakerLow@2x.png differ diff --git a/Resources/export/speakerMid.pdf b/Resources/export/speakerMid.pdf new file mode 100644 index 0000000..2553fe5 Binary files /dev/null and b/Resources/export/speakerMid.pdf differ diff --git a/Resources/export/speakerMid.png b/Resources/export/speakerMid.png new file mode 100644 index 0000000..03d7958 Binary files /dev/null and b/Resources/export/speakerMid.png differ diff --git a/Resources/export/speakerMid@2x.png b/Resources/export/speakerMid@2x.png new file mode 100644 index 0000000..7486a86 Binary files /dev/null and b/Resources/export/speakerMid@2x.png differ diff --git a/Resources/export/speakerOff.pdf b/Resources/export/speakerOff.pdf new file mode 100644 index 0000000..a258eea Binary files /dev/null and b/Resources/export/speakerOff.pdf differ diff --git a/Resources/export/speakerOff.png b/Resources/export/speakerOff.png new file mode 100644 index 0000000..f1206d6 Binary files /dev/null and b/Resources/export/speakerOff.png differ diff --git a/Resources/export/speakerOff@2x.png b/Resources/export/speakerOff@2x.png new file mode 100644 index 0000000..a34c293 Binary files /dev/null and b/Resources/export/speakerOff@2x.png differ diff --git a/Resources/icons.sketch b/Resources/icons.sketch index a7732b4..3ac177b 100644 Binary files a/Resources/icons.sketch and b/Resources/icons.sketch differ