Add now playing bar
@ -8,6 +8,8 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
38BAC36B249CB1A7004BAEA4 /* AlbumDetailSongTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 38BAC36A249CB1A6004BAEA4 /* AlbumDetailSongTitleView.swift */; };
|
||||
E403E63E246F4C3900200F58 /* NowPlayingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E403E63C246F4C3900200F58 /* NowPlayingViewController.swift */; };
|
||||
E403E63F246F4C3900200F58 /* NowPlayingViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = E403E63D246F4C3900200F58 /* NowPlayingViewController.xib */; };
|
||||
E407861C2110CE6E006887B1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E407861B2110CE6E006887B1 /* AppDelegate.swift */; };
|
||||
E40786202110CE70006887B1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E407861F2110CE70006887B1 /* Assets.xcassets */; };
|
||||
E40786232110CE70006887B1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E40786212110CE70006887B1 /* Main.storyboard */; };
|
||||
@ -320,6 +322,9 @@
|
||||
E4F2EFEE24076A2700198159 /* ServerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F2EFED24076A2700198159 /* ServerState.swift */; };
|
||||
E4F2EFF024076B0900198159 /* ServerActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F2EFEF24076B0900198159 /* ServerActions.swift */; };
|
||||
E4F2EFF224076B5E00198159 /* ServerReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F2EFF124076B5E00198159 /* ServerReducer.swift */; };
|
||||
E4F365D224942CC7006A8C4A /* NowPlayingTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F365D024942C6A006A8C4A /* NowPlayingTabBarController.swift */; };
|
||||
E4F365D4249432C0006A8C4A /* NowPlayingTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F365D3249432C0006A8C4A /* NowPlayingTabBar.swift */; };
|
||||
E4F365D6249C4CDC006A8C4A /* UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F365D5249C4CDC006A8C4A /* UIImage.swift */; };
|
||||
E4F6B460221E119B00ACF42A /* QueueDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F6B45F221E119B00ACF42A /* QueueDataSource.swift */; };
|
||||
E4F6B463221E125900ACF42A /* QueueItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F6B462221E125900ACF42A /* QueueItem.swift */; };
|
||||
E4F6B467221E233200ACF42A /* AlbumDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F6B466221E233200ACF42A /* AlbumDataSource.swift */; };
|
||||
@ -394,6 +399,8 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
38BAC36A249CB1A6004BAEA4 /* AlbumDetailSongTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailSongTitleView.swift; sourceTree = "<group>"; };
|
||||
E403E63C246F4C3900200F58 /* NowPlayingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NowPlayingViewController.swift; sourceTree = "<group>"; };
|
||||
E403E63D246F4C3900200F58 /* NowPlayingViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = NowPlayingViewController.xib; sourceTree = "<group>"; };
|
||||
E40786182110CE6E006887B1 /* Persephone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Persephone.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E407861B2110CE6E006887B1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
E407861F2110CE70006887B1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
@ -683,6 +690,9 @@
|
||||
E4F2EFED24076A2700198159 /* ServerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerState.swift; sourceTree = "<group>"; };
|
||||
E4F2EFEF24076B0900198159 /* ServerActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerActions.swift; sourceTree = "<group>"; };
|
||||
E4F2EFF124076B5E00198159 /* ServerReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerReducer.swift; sourceTree = "<group>"; };
|
||||
E4F365D024942C6A006A8C4A /* NowPlayingTabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NowPlayingTabBarController.swift; sourceTree = "<group>"; };
|
||||
E4F365D3249432C0006A8C4A /* NowPlayingTabBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NowPlayingTabBar.swift; sourceTree = "<group>"; };
|
||||
E4F365D5249C4CDC006A8C4A /* UIImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIImage.swift; sourceTree = "<group>"; };
|
||||
E4F6B45F221E119B00ACF42A /* QueueDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueDataSource.swift; sourceTree = "<group>"; };
|
||||
E4F6B462221E125900ACF42A /* QueueItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueItem.swift; sourceTree = "<group>"; };
|
||||
E4F6B466221E233200ACF42A /* AlbumDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDataSource.swift; sourceTree = "<group>"; };
|
||||
@ -914,6 +924,7 @@
|
||||
E41222062431425400473C1D /* Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4D4FAE6246F4B1B00CD02AF /* Now Playing */,
|
||||
E41222252431538700473C1D /* Shared */,
|
||||
E41222072431425400473C1D /* Browser */,
|
||||
);
|
||||
@ -954,6 +965,7 @@
|
||||
E4928E0A2218D62A001D4BEA /* CGColor.swift */,
|
||||
E41222272431539800473C1D /* CGSize.swift */,
|
||||
E4C51F09243428B60093FB31 /* UIFont.swift */,
|
||||
E4F365D5249C4CDC006A8C4A /* UIImage.swift */,
|
||||
);
|
||||
path = Extensions;
|
||||
sourceTree = "<group>";
|
||||
@ -1418,6 +1430,17 @@
|
||||
path = Protocols;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4D4FAE6246F4B1B00CD02AF /* Now Playing */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E403E63C246F4C3900200F58 /* NowPlayingViewController.swift */,
|
||||
E403E63D246F4C3900200F58 /* NowPlayingViewController.xib */,
|
||||
E4F365D024942C6A006A8C4A /* NowPlayingTabBarController.swift */,
|
||||
E4F365D3249432C0006A8C4A /* NowPlayingTabBar.swift */,
|
||||
);
|
||||
path = "Now Playing";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E4E13C2C2350D8CB00092A6E /* Layouts */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@ -1698,6 +1721,7 @@
|
||||
E480590F2426D73600362CF3 /* configure.py in Resources */,
|
||||
E48058292426D73500362CF3 /* version.h.in in Resources */,
|
||||
E48059152426D73600362CF3 /* build.sh in Resources */,
|
||||
E403E63F246F4C3900200F58 /* NowPlayingViewController.xib in Resources */,
|
||||
E48059132426D73600362CF3 /* win32.txt in Resources */,
|
||||
E48059C12426D73600362CF3 /* libmpdclient.vapi in Resources */,
|
||||
E41222162431425400473C1D /* Assets.xcassets in Resources */,
|
||||
@ -1962,7 +1986,9 @@
|
||||
E480512C24255BDF00362CF3 /* MPDCommand.swift in Sources */,
|
||||
E48059F52426D73600362CF3 /* search.c in Sources */,
|
||||
E4805A1F2426D73600362CF3 /* idle.c in Sources */,
|
||||
E4F365D224942CC7006A8C4A /* NowPlayingTabBarController.swift in Sources */,
|
||||
E41222182431425400473C1D /* AlbumItemCell.swift in Sources */,
|
||||
E4F365D4249432C0006A8C4A /* NowPlayingTabBar.swift in Sources */,
|
||||
E480511724255BAF00362CF3 /* MPDServer.swift in Sources */,
|
||||
E48059C32426D73600362CF3 /* directory.c in Sources */,
|
||||
E480514A24255E7D00362CF3 /* PlayerActions.swift in Sources */,
|
||||
@ -1982,9 +2008,11 @@
|
||||
E4B3B3672432DF1B007E25D2 /* AlbumSongListViewController.swift in Sources */,
|
||||
E480514524255E7700362CF3 /* PreferencesReducer.swift in Sources */,
|
||||
E41222292431555100473C1D /* CGColor.swift in Sources */,
|
||||
E4F365D6249C4CDC006A8C4A /* UIImage.swift in Sources */,
|
||||
E480511F24255BDB00362CF3 /* MPDClient+Album.swift in Sources */,
|
||||
E4805A0B2426D73600362CF3 /* sync.c in Sources */,
|
||||
E4805A052426D73600362CF3 /* connection.c in Sources */,
|
||||
E403E63E246F4C3900200F58 /* NowPlayingViewController.swift in Sources */,
|
||||
E480512324255BDB00362CF3 /* MPDClient+Database.swift in Sources */,
|
||||
E41222302432B0A300473C1D /* AlbumTracksDataSource.swift in Sources */,
|
||||
E48059ED2426D73600362CF3 /* stats.c in Sources */,
|
||||
|
||||
BIN
Resources/export/nextTrackButtonLarge.png
Normal file
|
After Width: | Height: | Size: 394 B |
BIN
Resources/export/nextTrackButtonLarge@2x.png
Normal file
|
After Width: | Height: | Size: 667 B |
BIN
Resources/export/nextTrackButtonLarge@3x.png
Normal file
|
After Width: | Height: | Size: 981 B |
BIN
Resources/export/nextTrackButtonLargeiOS.pdf
Normal file
BIN
Resources/export/nextTrackButtonLargeiOS.png
Normal file
|
After Width: | Height: | Size: 461 B |
BIN
Resources/export/nextTrackButtonLargeiOS@2x.png
Normal file
|
After Width: | Height: | Size: 822 B |
BIN
Resources/export/nextTrackButtonLargeiOS@3x.png
Normal file
|
After Width: | Height: | Size: 1.2 KiB |
BIN
Resources/export/pauseButtonLargeiOS.pdf
Normal file
BIN
Resources/export/pauseButtonLargeiOS.png
Normal file
|
After Width: | Height: | Size: 226 B |
BIN
Resources/export/pauseButtonLargeiOS@2x.png
Normal file
|
After Width: | Height: | Size: 342 B |
BIN
Resources/export/pauseButtonLargeiOS@3x.png
Normal file
|
After Width: | Height: | Size: 437 B |
|
Before Width: | Height: | Size: 295 B After Width: | Height: | Size: 363 B |
|
Before Width: | Height: | Size: 516 B After Width: | Height: | Size: 584 B |
BIN
Resources/export/playButtonLarge@3x.png
Normal file
|
After Width: | Height: | Size: 847 B |
BIN
Resources/export/playButtonLargeiOS.pdf
Normal file
BIN
Resources/export/playButtonLargeiOS.png
Normal file
|
After Width: | Height: | Size: 475 B |
BIN
Resources/export/playButtonLargeiOS@2x.png
Normal file
|
After Width: | Height: | Size: 751 B |
BIN
Resources/export/playButtonLargeiOS@3x.png
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
15
iOS/Assets.xcassets/nextTrackButtonLarge.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "nextTrackButtonLargeiOS.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
BIN
iOS/Assets.xcassets/nextTrackButtonLarge.imageset/nextTrackButtonLargeiOS.pdf
vendored
Normal file
15
iOS/Assets.xcassets/pauseButtonLarge.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "pauseButtonLargeiOS.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
BIN
iOS/Assets.xcassets/pauseButtonLarge.imageset/pauseButtonLargeiOS.pdf
vendored
Normal file
@ -1,7 +1,7 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "playButtonLarge.pdf",
|
||||
"filename" : "playButtonLargeiOS.pdf",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
||||
BIN
iOS/Assets.xcassets/playButtonLarge.imageset/playButtonLargeiOS.pdf
vendored
Normal file
@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="K6U-7P-Keb">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="K6U-7P-Keb">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16086"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="collection view cell content view" minToolsVersion="11.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
@ -78,7 +79,7 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1815.9420289855075" y="138.61607142857142"/>
|
||||
<point key="canvasLocation" x="1381" y="-165"/>
|
||||
</scene>
|
||||
<!--Album Song List View Controller-->
|
||||
<scene sceneID="oMo-KI-W9n">
|
||||
@ -93,8 +94,11 @@
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="523"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Album Title" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EZF-hY-Nqr">
|
||||
<rect key="frame" x="20" y="29" width="374" height="23"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Album Title" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="EZF-hY-Nqr">
|
||||
<rect key="frame" x="20" y="20" width="374" height="23"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="23" id="D8E-TS-um3"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="19"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@ -134,8 +138,8 @@
|
||||
<action selector="addAlbumToQueueAction:" destination="PiR-R2-zGX" eventType="touchUpInside" id="OHR-k8-Cob"/>
|
||||
</connections>
|
||||
</button>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Metadata" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LH5-iT-vfZ">
|
||||
<rect key="frame" x="20" y="55" width="374" height="21"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Metadata" lineBreakMode="wordWrap" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="LH5-iT-vfZ">
|
||||
<rect key="frame" x="20" y="45" width="374" height="23"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
@ -265,25 +269,42 @@
|
||||
</tableViewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="WIp-Eo-GAy" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="2673.913043478261" y="138.61607142857142"/>
|
||||
<point key="canvasLocation" x="2151" y="-165"/>
|
||||
</scene>
|
||||
<!--Tab Bar Controller-->
|
||||
<!--Now Playing Tab Bar Controller-->
|
||||
<scene sceneID="MfI-fd-cqh">
|
||||
<objects>
|
||||
<tabBarController automaticallyAdjustsScrollViewInsets="NO" id="K6U-7P-Keb" sceneMemberID="viewController">
|
||||
<tabBarController automaticallyAdjustsScrollViewInsets="NO" id="K6U-7P-Keb" customClass="NowPlayingTabBarController" customModule="Persephone" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<toolbarItems/>
|
||||
<tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="7Nx-g8-JPS">
|
||||
<tabBar key="tabBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="7Nx-g8-JPS" customClass="NowPlayingTabBar" customModule="Persephone" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1000" height="1000"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
</tabBar>
|
||||
<connections>
|
||||
<segue destination="9Vi-iO-P5G" kind="relationship" relationship="viewControllers" id="d6O-R2-Xvc"/>
|
||||
<segue destination="wfA-ep-C20" kind="relationship" relationship="viewControllers" id="qDm-CR-1GB"/>
|
||||
</connections>
|
||||
</tabBarController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="knf-OK-U9P" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="131.8840579710145" y="138.61607142857142"/>
|
||||
<point key="canvasLocation" x="-412" y="139"/>
|
||||
</scene>
|
||||
<!--Settings-->
|
||||
<scene sceneID="ngZ-Fa-mx2">
|
||||
<objects>
|
||||
<viewController id="wfA-ep-C20" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="Pe3-sm-fGd">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<viewLayoutGuide key="safeArea" id="vPj-fW-HyF"/>
|
||||
</view>
|
||||
<tabBarItem key="tabBarItem" title="Settings" image="gear" catalog="system" id="Acw-to-Efe"/>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="zAY-QV-a8t" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="583" y="549"/>
|
||||
</scene>
|
||||
<!--Albums-->
|
||||
<scene sceneID="fsq-t8-GDw">
|
||||
@ -302,11 +323,12 @@
|
||||
</navigationController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Hvo-yX-dBI" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="905.79710144927549" y="138.61607142857142"/>
|
||||
<point key="canvasLocation" x="580" y="-165"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="defaultCoverArt" width="128" height="128"/>
|
||||
<image name="gear" catalog="system" width="128" height="119"/>
|
||||
<image name="playButtonLarge" width="22" height="22"/>
|
||||
<image name="plus" catalog="system" width="128" height="113"/>
|
||||
<image name="square.grid.2x2.fill" catalog="system" width="128" height="114"/>
|
||||
|
||||
@ -15,7 +15,7 @@ class AlbumItemCell: UICollectionViewCell {
|
||||
override func didMoveToSuperview() {
|
||||
albumCoverView.layer.backgroundColor = UIColor.black.cgColor
|
||||
albumCoverView.layer.cornerRadius = 4
|
||||
albumCoverView.layer.borderWidth = 0.5
|
||||
albumCoverView.layer.borderWidth = 1 / traitCollection.displayScale
|
||||
albumCoverView.layer.masksToBounds = true
|
||||
setAppearance()
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ class AlbumSongListViewController: UITableViewController {
|
||||
|
||||
albumCoverView.layer.backgroundColor = UIColor.black.cgColor
|
||||
albumCoverView.layer.cornerRadius = 4
|
||||
albumCoverView.layer.borderWidth = 0.5
|
||||
albumCoverView.layer.borderWidth = 1 / traitCollection.displayScale
|
||||
albumCoverView.layer.masksToBounds = true
|
||||
|
||||
playAlbumButton.layer.cornerRadius = 8
|
||||
@ -116,6 +116,8 @@ class AlbumSongListViewController: UITableViewController {
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
|
||||
setAppearance()
|
||||
}
|
||||
|
||||
47
iOS/Components/Now Playing/NowPlayingTabBar.swift
Normal file
@ -0,0 +1,47 @@
|
||||
//
|
||||
// NowPlayingTabBar.swift
|
||||
// Persephone-iOS
|
||||
//
|
||||
// Created by Dan Barber on 2020-6-12.
|
||||
// Copyright © 2020 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class NowPlayingControlBackground: UIControl {
|
||||
// override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override func cancelTracking(with event: UIEvent?) {
|
||||
//
|
||||
// }
|
||||
//
|
||||
// override func endTracking(_ touch: UITouch?, with event: UIEvent?) {
|
||||
//
|
||||
// // if touch is inside your control
|
||||
// sendActions(for: .touchUpInside)
|
||||
// }
|
||||
}
|
||||
|
||||
class NowPlayingTabBar: UITabBar {
|
||||
static let barHeight: CGFloat = 56
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
let bounds = CGRect(x: 0, y: 0, width: 1, height: 1)
|
||||
NowPlayingTabBar.appearance().shadowImage = UIGraphicsImageRenderer(bounds: bounds).image { context in
|
||||
UIColor.systemRed.setFill()
|
||||
context.fill(bounds)
|
||||
}
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
for case let control as UIControl in subviews {
|
||||
control.frame.origin.y += Self.barHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
40
iOS/Components/Now Playing/NowPlayingTabBarController.swift
Normal file
@ -0,0 +1,40 @@
|
||||
//
|
||||
// NowPlayingTabBarController.swift
|
||||
// Persephone
|
||||
//
|
||||
// Created by Dan Barber on 2020-6-12.
|
||||
// Copyright © 2020 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class NowPlayingTabBarController: UITabBarController {
|
||||
private var barHeight: NSLayoutConstraint!
|
||||
let nowPlayingViewController = NowPlayingViewController()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
addChild(nowPlayingViewController)
|
||||
let subview = nowPlayingViewController.view!
|
||||
tabBar.superview?.addSubview(subview)
|
||||
tabBar.clipsToBounds = false
|
||||
subview.translatesAutoresizingMaskIntoConstraints = false
|
||||
barHeight = subview.heightAnchor.constraint(equalToConstant: 0)
|
||||
NSLayoutConstraint.activate([
|
||||
subview.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
||||
subview.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
||||
subview.topAnchor.constraint(equalTo: tabBar.topAnchor),
|
||||
barHeight,
|
||||
])
|
||||
nowPlayingViewController.didMove(toParent: self)
|
||||
|
||||
additionalSafeAreaInsets.bottom = NowPlayingTabBar.barHeight
|
||||
}
|
||||
|
||||
override func preferredContentSizeDidChange(forChildContentContainer container: UIContentContainer) {
|
||||
super.preferredContentSizeDidChange(forChildContentContainer: container)
|
||||
|
||||
barHeight.constant = container.preferredContentSize.height
|
||||
}
|
||||
}
|
||||
133
iOS/Components/Now Playing/NowPlayingViewController.swift
Normal file
@ -0,0 +1,133 @@
|
||||
//
|
||||
// NowPlayingViewController.swift
|
||||
// Persephone-iOS
|
||||
//
|
||||
// Created by Dan Barber on 2020-5-15.
|
||||
// Copyright © 2020 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import ReSwift
|
||||
import Kingfisher
|
||||
|
||||
class NowPlayingViewController: UIViewController {
|
||||
@IBOutlet var separatorHeight: NSLayoutConstraint!
|
||||
@IBOutlet var playPauseButton: UIButton!
|
||||
@IBOutlet var nextButton: UIButton!
|
||||
@IBOutlet var songTitle: UILabel!
|
||||
@IBOutlet var albumCoverView: UIImageView!
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
separatorHeight.constant = 1 / traitCollection.displayScale
|
||||
|
||||
App.store.subscribe(self) {
|
||||
$0.select { $0.playerState }
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(didConnect), name: .didConnect, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(willDisconnect), name: .willDisconnect, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(didReloadAlbumArt), name: .didReloadAlbumArt, object: nil)
|
||||
|
||||
albumCoverView.layer.backgroundColor = UIColor.black.cgColor
|
||||
albumCoverView.layer.cornerRadius = 4
|
||||
albumCoverView.layer.borderWidth = 1 / traitCollection.displayScale
|
||||
albumCoverView.layer.masksToBounds = true
|
||||
|
||||
setAppearance()
|
||||
}
|
||||
|
||||
override func didMove(toParent parent: UIViewController?) {
|
||||
super.didMove(toParent: parent)
|
||||
|
||||
preferredContentSize.height = NowPlayingTabBar.barHeight
|
||||
}
|
||||
|
||||
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
||||
super.traitCollectionDidChange(previousTraitCollection)
|
||||
|
||||
separatorHeight.constant = 1 / traitCollection.displayScale
|
||||
|
||||
if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
|
||||
setAppearance()
|
||||
}
|
||||
}
|
||||
|
||||
func setAppearance() {
|
||||
let darkMode = traitCollection.userInterfaceStyle == .dark
|
||||
|
||||
albumCoverView.layer.borderColor = darkMode ? CGColor.albumBorderColorDark : CGColor.albumBorderColorLight
|
||||
}
|
||||
|
||||
@objc func didConnect() {
|
||||
App.mpdClient.fetchQueue()
|
||||
}
|
||||
|
||||
@objc func willDisconnect() {
|
||||
DispatchQueue.main.async {
|
||||
App.store.dispatch(UpdateQueuePosAction(queuePos: -1))
|
||||
App.store.dispatch(UpdateQueueAction(queue: []))
|
||||
}
|
||||
}
|
||||
|
||||
@objc func didReloadAlbumArt() {
|
||||
// NO-OP
|
||||
}
|
||||
|
||||
func setTransportControlState(_ state: PlayerState) {
|
||||
guard let state = state.state else { return }
|
||||
|
||||
playPauseButton.isEnabled = state.isOneOf([.playing, .paused, .stopped])
|
||||
nextButton.isEnabled = state.isOneOf([.playing, .paused])
|
||||
|
||||
if state.isOneOf([.paused, .stopped, .unknown]) {
|
||||
playPauseButton.setImage(.playIconLarge, for: .normal)
|
||||
} else {
|
||||
playPauseButton.setImage(.pauseIconLarge, for: .normal)
|
||||
}
|
||||
}
|
||||
|
||||
func setSong(_ song: Song?) {
|
||||
guard let song = song else {
|
||||
self.songTitle.text = "Not Playing"
|
||||
self.albumCoverView.image = .defaultCoverArt
|
||||
return
|
||||
}
|
||||
|
||||
songTitle.text = song.title
|
||||
|
||||
let provider = MPDAlbumArtImageDataProvider(
|
||||
songUri: song.mpdSong.uriString,
|
||||
cacheKey: song.album.hash
|
||||
)
|
||||
|
||||
albumCoverView.kf.setImage(
|
||||
with: .provider(provider),
|
||||
placeholder: UIImage.defaultCoverArt,
|
||||
options: [
|
||||
.processor(DownsamplingImageProcessor(size: .queueSongCoverSize)),
|
||||
.scaleFactor(traitCollection.displayScale),
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
@IBAction func playPauseButtonAction(_ sender: Any) {
|
||||
App.mpdClient.playPause()
|
||||
}
|
||||
|
||||
@IBAction func nextButtonAction(_ sender: Any) {
|
||||
App.mpdClient.nextTrack()
|
||||
}
|
||||
}
|
||||
|
||||
extension NowPlayingViewController: StoreSubscriber {
|
||||
typealias StoreSubscriberStateType = PlayerState
|
||||
|
||||
func newState(state: PlayerState) {
|
||||
DispatchQueue.main.async {
|
||||
self.setTransportControlState(state)
|
||||
self.setSong(state.currentSong)
|
||||
}
|
||||
}
|
||||
}
|
||||
105
iOS/Components/Now Playing/NowPlayingViewController.xib
Normal file
@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="Stack View standard spacing" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="NowPlayingViewController" customModule="Persephone" customModuleProvider="target">
|
||||
<connections>
|
||||
<outlet property="albumCoverView" destination="6Cn-Qu-3ab" id="w0j-pd-zrj"/>
|
||||
<outlet property="nextButton" destination="k9u-Hf-Cp0" id="bs9-R1-q5h"/>
|
||||
<outlet property="playPauseButton" destination="aJD-nr-kHS" id="6sM-tz-FHK"/>
|
||||
<outlet property="separatorHeight" destination="chi-7m-8Ds" id="Ex2-Wm-ygG"/>
|
||||
<outlet property="songTitle" destination="4nQ-FU-7Ub" id="eGu-nR-CuK"/>
|
||||
<outlet property="view" destination="fma-vB-sY1" id="5BF-fd-Kur"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" id="fma-vB-sY1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="335" height="64"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" spacingType="standard" translatesAutoresizingMaskIntoConstraints="NO" id="9j9-AN-ijy">
|
||||
<rect key="frame" x="0.0" y="0.0" width="335" height="63"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="defaultCoverArt" translatesAutoresizingMaskIntoConstraints="NO" id="6Cn-Qu-3ab">
|
||||
<rect key="frame" x="20" y="8" width="47" height="47"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" secondItem="6Cn-Qu-3ab" secondAttribute="height" multiplier="1:1" id="I6V-Kn-Cwa"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Tik-7x-PaQ">
|
||||
<rect key="frame" x="75" y="8" width="0.0" height="47"/>
|
||||
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" id="DuG-NI-0Bp"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="249" verticalHuggingPriority="251" text="Not Playing" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="4nQ-FU-7Ub">
|
||||
<rect key="frame" x="83" y="8" width="152" height="47"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<button opaque="NO" contentMode="center" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aJD-nr-kHS">
|
||||
<rect key="frame" x="243" y="8" width="32" height="47"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="4Un-9M-vOk"/>
|
||||
</constraints>
|
||||
<color key="tintColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<state key="normal" image="playButtonLarge">
|
||||
<color key="titleColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="playPauseButtonAction:" destination="-1" eventType="touchUpInside" id="a3n-1h-p00"/>
|
||||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="center" enabled="NO" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="k9u-Hf-Cp0">
|
||||
<rect key="frame" x="283" y="8" width="32" height="47"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="fy0-Z2-OSg"/>
|
||||
</constraints>
|
||||
<color key="tintColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<state key="normal" image="nextTrackButtonLarge">
|
||||
<color key="titleColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="nextButtonAction:" destination="-1" eventType="touchUpInside" id="3Ke-PH-ud9"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<directionalEdgeInsets key="directionalLayoutMargins" top="8" leading="20" bottom="8" trailing="20"/>
|
||||
<viewLayoutGuide key="safeArea" id="Xfd-VS-LUl"/>
|
||||
</stackView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="2EO-qL-ast">
|
||||
<rect key="frame" x="0.0" y="63" width="335" height="1"/>
|
||||
<color key="backgroundColor" systemColor="separatorColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="chi-7m-8Ds"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstItem="9j9-AN-ijy" firstAttribute="top" secondItem="fma-vB-sY1" secondAttribute="top" id="Bpq-6d-BwN"/>
|
||||
<constraint firstItem="9j9-AN-ijy" firstAttribute="leading" secondItem="fma-vB-sY1" secondAttribute="leading" id="aG7-qp-jXe"/>
|
||||
<constraint firstAttribute="trailing" secondItem="9j9-AN-ijy" secondAttribute="trailing" id="cCF-6v-1x0"/>
|
||||
<constraint firstAttribute="trailing" secondItem="2EO-qL-ast" secondAttribute="trailing" id="dp6-XJ-FaI"/>
|
||||
<constraint firstItem="2EO-qL-ast" firstAttribute="top" secondItem="9j9-AN-ijy" secondAttribute="bottom" id="k9V-5A-Xt0"/>
|
||||
<constraint firstItem="2EO-qL-ast" firstAttribute="leading" secondItem="fma-vB-sY1" secondAttribute="leading" id="ueX-jc-IqH"/>
|
||||
<constraint firstAttribute="bottom" secondItem="2EO-qL-ast" secondAttribute="bottom" id="zCc-Cc-PPh"/>
|
||||
</constraints>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<point key="canvasLocation" x="-512.31884057971024" y="-32.142857142857139"/>
|
||||
</view>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="defaultCoverArt" width="128" height="128"/>
|
||||
<image name="nextTrackButtonLarge" width="28" height="28"/>
|
||||
<image name="playButtonLarge" width="22" height="22"/>
|
||||
</resources>
|
||||
</document>
|
||||
15
iOS/Components/Shared/Extensions/UIImage.swift
Normal file
@ -0,0 +1,15 @@
|
||||
//
|
||||
// UIImage.swift
|
||||
// Persephone-iOS
|
||||
//
|
||||
// Created by Dan Barber on 2020-6-18.
|
||||
// Copyright © 2020 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
extension UIImage {
|
||||
static let defaultCoverArt = UIImage(named: "defaultCoverArt")
|
||||
static let playIconLarge = UIImage(named: "playButtonLarge")
|
||||
static let pauseIconLarge = UIImage(named: "pauseButtonLarge")
|
||||
}
|
||||