Merge lp:~rockstar/ubuntuone-ios-music/swipe-download into lp:ubuntuone-ios-music
- swipe-download
- Merge into trunk
Proposed by
Paul Hummer
Status: | Merged |
---|---|
Approved by: | Zachery Bir |
Approved revision: | 241 |
Merged at revision: | 225 |
Proposed branch: | lp:~rockstar/ubuntuone-ios-music/swipe-download |
Merge into: | lp:ubuntuone-ios-music |
Diff against target: |
908 lines (+422/-196) 12 files modified
U1Music.xcodeproj/project.pbxproj (+36/-0) categories/UIImage+RoundedCorner.m (+3/-0) controls/PlaylistEditSongUITableViewCell.m (+0/-2) controls/SongUITableView.h (+35/-0) controls/SongUITableView.m (+178/-0) controls/SongUITableViewCell.h (+4/-15) controls/SongUITableViewCell.m (+5/-68) controls/UOPullGestureRecognizer.h (+20/-0) controls/UOPullGestureRecognizer.m (+77/-0) view_controllers/AlbumViewController.h (+2/-2) view_controllers/AlbumViewController.m (+60/-94) view_controllers/PlaylistEditAlbumViewController.m (+2/-15) |
To merge this branch: | bzr merge lp:~rockstar/ubuntuone-ios-music/swipe-download |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Zachery Bir | Approve | ||
Review via email: mp+116403@code.launchpad.net |
Commit message
Add swipe gesture to the SongUITableViewCell
Description of the change
This branch adds the ability to swipe to the right to download or clear the cache of a song. It moves all the logic from SongUIViewCell to a SongUIView.
The one thing from the design that I did not add is the removal of the three dots as handles. I disagree with design, and would like to continue that discussion before I completed remove them.
To post a comment you must log in.
Revision history for this message
Zachery Bir (urbanape) : | # |
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'U1Music.xcodeproj/project.pbxproj' |
2 | --- U1Music.xcodeproj/project.pbxproj 2012-06-28 02:52:49 +0000 |
3 | +++ U1Music.xcodeproj/project.pbxproj 2012-07-24 05:24:19 +0000 |
4 | @@ -10,6 +10,14 @@ |
5 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; |
6 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; |
7 | 2892E4100DC94CBA00A64D0F /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */; }; |
8 | + 523B3CDE15B4C42F004394F4 /* SongUITableView.m in Sources */ = {isa = PBXBuildFile; fileRef = 523B3CDD15B4C42F004394F4 /* SongUITableView.m */; }; |
9 | + 523B3CE215B5D64F004394F4 /* grabber.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CE015B5D64F004394F4 /* grabber.png */; }; |
10 | + 523B3CE315B5D64F004394F4 /* grabber@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CE115B5D64F004394F4 /* grabber@2x.png */; }; |
11 | + 523B3CE615B5D814004394F4 /* UOPullGestureRecognizer.m in Sources */ = {isa = PBXBuildFile; fileRef = 523B3CE515B5D814004394F4 /* UOPullGestureRecognizer.m */; }; |
12 | + 523B3CF915B73BA0004394F4 /* download-grey.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CF515B73BA0004394F4 /* download-grey.png */; }; |
13 | + 523B3CFA15B73BA0004394F4 /* download-grey@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CF615B73BA0004394F4 /* download-grey@2x.png */; }; |
14 | + 523B3CFB15B73BA0004394F4 /* download.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CF715B73BA0004394F4 /* download.png */; }; |
15 | + 523B3CFC15B73BA0004394F4 /* download@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 523B3CF815B73BA0004394F4 /* download@2x.png */; }; |
16 | 5305C2061157F4F800BC78F0 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 5305C2051157F4F800BC78F0 /* Default.png */; }; |
17 | 536D620B1144495400DFCE56 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 536D620A1144495400DFCE56 /* SystemConfiguration.framework */; }; |
18 | 537DE2D9113F008C00875852 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537DE2D8113F008C00875852 /* CoreFoundation.framework */; }; |
19 | @@ -211,6 +219,16 @@ |
20 | 1D6058910D05DD3D006BFB54 /* U1 Music.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "U1 Music.app"; sourceTree = BUILT_PRODUCTS_DIR; }; |
21 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; |
22 | 2892E40F0DC94CBA00A64D0F /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; |
23 | + 523B3CDC15B4C42F004394F4 /* SongUITableView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SongUITableView.h; sourceTree = "<group>"; }; |
24 | + 523B3CDD15B4C42F004394F4 /* SongUITableView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SongUITableView.m; sourceTree = "<group>"; }; |
25 | + 523B3CE015B5D64F004394F4 /* grabber.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = grabber.png; sourceTree = "<group>"; }; |
26 | + 523B3CE115B5D64F004394F4 /* grabber@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "grabber@2x.png"; sourceTree = "<group>"; }; |
27 | + 523B3CE415B5D814004394F4 /* UOPullGestureRecognizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UOPullGestureRecognizer.h; sourceTree = "<group>"; }; |
28 | + 523B3CE515B5D814004394F4 /* UOPullGestureRecognizer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UOPullGestureRecognizer.m; sourceTree = "<group>"; }; |
29 | + 523B3CF515B73BA0004394F4 /* download-grey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "download-grey.png"; sourceTree = "<group>"; }; |
30 | + 523B3CF615B73BA0004394F4 /* download-grey@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "download-grey@2x.png"; sourceTree = "<group>"; }; |
31 | + 523B3CF715B73BA0004394F4 /* download.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = download.png; sourceTree = "<group>"; }; |
32 | + 523B3CF815B73BA0004394F4 /* download@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "download@2x.png"; sourceTree = "<group>"; }; |
33 | 5305C2051157F4F800BC78F0 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; }; |
34 | 536D620A1144495400DFCE56 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; |
35 | 537DE2D8113F008C00875852 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; |
36 | @@ -798,6 +816,8 @@ |
37 | 9674C2C413A7DC01004509E4 /* UORadialProgressControl.m */, |
38 | 91BE401A138E8D3A00D44D68 /* RIButtonItem.h */, |
39 | 91BE401B138E8D3A00D44D68 /* RIButtonItem.m */, |
40 | + 523B3CDC15B4C42F004394F4 /* SongUITableView.h */, |
41 | + 523B3CDD15B4C42F004394F4 /* SongUITableView.m */, |
42 | 93F3345D1247FA97006C6707 /* SongUITableViewCell.h */, |
43 | 93F3345E1247FA97006C6707 /* SongUITableViewCell.m */, |
44 | 919376F1135CC1CF0030B7BD /* PlaylistEditSongUITableViewCell.h */, |
45 | @@ -814,6 +834,8 @@ |
46 | 91C8CCAE14B7883600A0E311 /* ArtistUITableViewCell.m */, |
47 | 91D3A17014BE12FE003D4FC0 /* PlaylistUITableViewCell.h */, |
48 | 91D3A17114BE12FE003D4FC0 /* PlaylistUITableViewCell.m */, |
49 | + 523B3CE415B5D814004394F4 /* UOPullGestureRecognizer.h */, |
50 | + 523B3CE515B5D814004394F4 /* UOPullGestureRecognizer.m */, |
51 | ); |
52 | name = Controls; |
53 | path = controls; |
54 | @@ -951,6 +973,12 @@ |
55 | 93FA42A6124DC1350080DF62 /* Images */ = { |
56 | isa = PBXGroup; |
57 | children = ( |
58 | + 523B3CF515B73BA0004394F4 /* download-grey.png */, |
59 | + 523B3CF615B73BA0004394F4 /* download-grey@2x.png */, |
60 | + 523B3CF715B73BA0004394F4 /* download.png */, |
61 | + 523B3CF815B73BA0004394F4 /* download@2x.png */, |
62 | + 523B3CE015B5D64F004394F4 /* grabber.png */, |
63 | + 523B3CE115B5D64F004394F4 /* grabber@2x.png */, |
64 | 9149D9C9159BEC3D009AE771 /* default-album-art-120.png */, |
65 | 9149D9CB159BEC3D009AE771 /* default-album-art-120@2x.png */, |
66 | 9149D9CA159BEC3D009AE771 /* default-album-art-200.png */, |
67 | @@ -1257,6 +1285,12 @@ |
68 | 9149D9D2159BEC3D009AE771 /* default-album-art-200@2x.png in Resources */, |
69 | 9149D9D3159BEC3D009AE771 /* default-album-art-640.png in Resources */, |
70 | 9149D9D4159BEC3D009AE771 /* default-album-art-640@2x.png in Resources */, |
71 | + 523B3CE215B5D64F004394F4 /* grabber.png in Resources */, |
72 | + 523B3CE315B5D64F004394F4 /* grabber@2x.png in Resources */, |
73 | + 523B3CF915B73BA0004394F4 /* download-grey.png in Resources */, |
74 | + 523B3CFA15B73BA0004394F4 /* download-grey@2x.png in Resources */, |
75 | + 523B3CFB15B73BA0004394F4 /* download.png in Resources */, |
76 | + 523B3CFC15B73BA0004394F4 /* download@2x.png in Resources */, |
77 | ); |
78 | runOnlyForDeploymentPostprocessing = 0; |
79 | }; |
80 | @@ -1405,6 +1439,8 @@ |
81 | 960E4B3514E58844002AAB79 /* U1CachedFile.m in Sources */, |
82 | 960E4B3814E5884B002AAB79 /* _U1CachedFile.m in Sources */, |
83 | 91F2653014EACFCC0027232B /* U1MigrationViewController.m in Sources */, |
84 | + 523B3CDE15B4C42F004394F4 /* SongUITableView.m in Sources */, |
85 | + 523B3CE615B5D814004394F4 /* UOPullGestureRecognizer.m in Sources */, |
86 | ); |
87 | runOnlyForDeploymentPostprocessing = 0; |
88 | }; |
89 | |
90 | === modified file 'categories/UIImage+RoundedCorner.m' |
91 | --- categories/UIImage+RoundedCorner.m 2011-04-14 18:53:36 +0000 |
92 | +++ categories/UIImage+RoundedCorner.m 2012-07-24 05:24:19 +0000 |
93 | @@ -55,6 +55,8 @@ |
94 | #pragma mark - |
95 | #pragma mark Private helper methods |
96 | |
97 | +#pragma clang diagnostic push |
98 | +#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" |
99 | // Adds a rectangular path to the given context and rounds its corners by the given extents |
100 | // Original author: Björn Sållarp. Used with permission. See: http://blog.sallarp.com/iphone-uiimage-round-corners/ |
101 | - (void)addRoundedRectToPath:(CGRect)rect context:(CGContextRef)context ovalWidth:(CGFloat)ovalWidth ovalHeight:(CGFloat)ovalHeight { |
102 | @@ -75,5 +77,6 @@ |
103 | CGContextClosePath(context); |
104 | CGContextRestoreGState(context); |
105 | } |
106 | +#pragma clang diagnostic pop |
107 | |
108 | @end |
109 | \ No newline at end of file |
110 | |
111 | === modified file 'controls/PlaylistEditSongUITableViewCell.m' |
112 | --- controls/PlaylistEditSongUITableViewCell.m 2011-04-19 01:48:10 +0000 |
113 | +++ controls/PlaylistEditSongUITableViewCell.m 2012-07-24 05:24:19 +0000 |
114 | @@ -25,7 +25,5 @@ |
115 | - (void)layoutSubviews |
116 | { |
117 | [super layoutSubviews]; |
118 | - self.durationLabel.frame = CGRectMake(252, 0, 68, self.frame.size.height); |
119 | - self.durationLabel.textAlignment = UITextAlignmentLeft; |
120 | } |
121 | @end |
122 | |
123 | === added file 'controls/SongUITableView.h' |
124 | --- controls/SongUITableView.h 1970-01-01 00:00:00 +0000 |
125 | +++ controls/SongUITableView.h 2012-07-24 05:24:19 +0000 |
126 | @@ -0,0 +1,35 @@ |
127 | +// |
128 | +// SongUITableView.h |
129 | +// U1Music |
130 | +// |
131 | +// Created by Paul Hummer on 7/16/12. |
132 | +// Copyright (c) 2012 Canonical. All rights reserved. |
133 | +// |
134 | + |
135 | +#import <UIKit/UIKit.h> |
136 | + |
137 | +@class SongUITableView; |
138 | + |
139 | +@protocol SongUITableViewDelegate <NSObject> |
140 | +- (void)viewDidBeginTouchGesture:(SongUITableView*)view; |
141 | +- (void)viewDidEndPullRightGesture:(SongUITableView *)view; |
142 | +@end |
143 | + |
144 | +@interface SongUITableView : UIView { |
145 | + UIImageView *actionIconView; |
146 | + UIView *bottomView; |
147 | + UIView *progressView; |
148 | + UIView *topView; |
149 | +} |
150 | +@property (nonatomic) BOOL cancelled; |
151 | +@property (nonatomic) BOOL downloading; |
152 | +@property (nonatomic) BOOL downloaded; |
153 | +@property (assign) IBOutlet id <SongUITableViewDelegate> delegate; |
154 | + |
155 | +@property (nonatomic,retain) UILabel *songNameLabel; |
156 | +@property(nonatomic,retain) UIImageView *nowPlaying; |
157 | + |
158 | +-(void)setCached:(BOOL)cached; |
159 | +-(void)closeBottomView; |
160 | + |
161 | +@end |
162 | |
163 | === added file 'controls/SongUITableView.m' |
164 | --- controls/SongUITableView.m 1970-01-01 00:00:00 +0000 |
165 | +++ controls/SongUITableView.m 2012-07-24 05:24:19 +0000 |
166 | @@ -0,0 +1,178 @@ |
167 | +// |
168 | +// SongUITableView.m |
169 | +// U1Music |
170 | +// |
171 | +// Created by Paul Hummer on 7/16/12. |
172 | +// Copyright (c) 2012 Canonical. All rights reserved. |
173 | +// |
174 | + |
175 | +#import "SongUITableView.h" |
176 | +#import "UOPullGestureRecognizer.h" |
177 | + |
178 | +@implementation SongUITableView |
179 | + |
180 | +@synthesize cancelled; |
181 | +@synthesize delegate; |
182 | +@synthesize downloaded; |
183 | +@synthesize downloading; |
184 | + |
185 | +@synthesize songNameLabel; |
186 | +@synthesize nowPlaying; |
187 | + |
188 | +- (id)initWithFrame:(CGRect)frame |
189 | +{ |
190 | + self = [super initWithFrame:frame]; |
191 | + if (self) { |
192 | + /* XXX: rockstar - This is a hack, as it seems that the subviews aren't ready by the time configureCell hits them. I think some restructuring might help here, but until then, this works. |
193 | + */ |
194 | + [self layoutSubviews]; |
195 | + } |
196 | + return self; |
197 | +} |
198 | + |
199 | +- (void)closeBottomView { |
200 | + [UIView animateWithDuration:0.333 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ |
201 | + CGRect frame = UIEdgeInsetsInsetRect(bottomView.bounds, UIEdgeInsetsMake(0, 12, 0, 0)); |
202 | + topView.frame = frame; |
203 | + } completion:^(BOOL finished) { |
204 | + }]; |
205 | +} |
206 | + |
207 | +- (void)layoutSubviews { |
208 | + [super layoutSubviews]; |
209 | + |
210 | + if (bottomView == nil) { |
211 | + bottomView = [[UIView alloc] initWithFrame:self.bounds]; |
212 | + bottomView.backgroundColor = [UIColor orangeColor]; |
213 | + [self addSubview:bottomView]; |
214 | + |
215 | + //Currently this isn't really a progress view as much as it is a cache indicator. |
216 | + progressView = [[UIView alloc] init]; |
217 | + progressView.backgroundColor = [UIColor whiteColor]; |
218 | + [bottomView addSubview:progressView]; |
219 | + |
220 | + actionIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"download-grey"]]; |
221 | + actionIconView.highlightedImage = [UIImage imageNamed:@"download"]; |
222 | + actionIconView.frame = CGRectMake(24, (CGRectGetHeight(self.bounds) - 28.f) / 2.f, 28, 28); |
223 | + [bottomView addSubview:actionIconView]; |
224 | + } |
225 | + |
226 | + if (topView == nil) { |
227 | + CGRect frame = UIEdgeInsetsInsetRect(bottomView.bounds, UIEdgeInsetsMake(0, 12, 0, 0)); |
228 | + topView = [[UIView alloc] initWithFrame:frame]; |
229 | + topView.backgroundColor = [UIColor whiteColor]; |
230 | + [bottomView addSubview:topView]; |
231 | + |
232 | + |
233 | + UIImageView *handleView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"grabber"]]; |
234 | + handleView.frame = CGRectMake(0, (CGRectGetHeight(self.bounds) - 52.f) / 2.f, 22, 52); |
235 | + [topView addSubview:handleView]; |
236 | + |
237 | + songNameLabel = [[UILabel alloc] initWithFrame:UIEdgeInsetsInsetRect(topView.bounds, UIEdgeInsetsMake(0, 27, 0, 0))]; |
238 | + [topView addSubview:songNameLabel]; |
239 | + |
240 | + nowPlaying = [[UIImageView alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.bounds) - 52.f, (CGRectGetHeight(self.bounds) - 48.f) / 2.f, 22, 52)]; |
241 | + nowPlaying.image = [UIImage imageNamed:@"speaker"]; |
242 | + nowPlaying.backgroundColor = [UIColor clearColor]; |
243 | + nowPlaying.contentMode = UIViewContentModeCenter; |
244 | + nowPlaying.hidden = YES; |
245 | + [topView addSubview:nowPlaying]; |
246 | + |
247 | + UOPullGestureRecognizer *pullRight = [[UOPullGestureRecognizer alloc] initWithTarget:self action:@selector(pullRight:)]; |
248 | + [topView addGestureRecognizer:pullRight]; |
249 | + [pullRight setDirection:UISwipeGestureRecognizerDirectionRight]; |
250 | + [pullRight setActionThreshold:52.f]; |
251 | + [pullRight setActivationRegion:CGRectMake(0, (CGRectGetHeight(self.bounds) - 52.f) / 2.f, 64, 52)]; |
252 | + [pullRight setFiresActionOnThresholdReached:NO]; |
253 | + } |
254 | +} |
255 | + |
256 | +- (void)pullRight:(UOPullGestureRecognizer*)pan { |
257 | + CGPoint offset = [pan translationInView:pan.view]; |
258 | + |
259 | + switch (pan.state) { |
260 | + case UIGestureRecognizerStateBegan: |
261 | + [self.delegate viewDidBeginTouchGesture:self]; |
262 | + break; |
263 | + case UIGestureRecognizerStateChanged: |
264 | + [UIView beginAnimations:nil context:NULL]; |
265 | + [UIView setAnimationBeginsFromCurrentState:YES]; |
266 | + [UIView setAnimationsEnabled:NO]; |
267 | + |
268 | + CGRect frameRect = topView.frame; |
269 | + CGFloat myOffset = MAX(0, MIN(offset.x, pan.actionThreshold)); |
270 | + frameRect.origin.x = myOffset + 12.f; |
271 | + |
272 | + if (myOffset >= pan.actionThreshold) { |
273 | + [UIView animateWithDuration:0.333 animations:^{ |
274 | + actionIconView.highlighted = YES; |
275 | + }]; |
276 | + } else { |
277 | + [UIView animateWithDuration:0.333 animations:^{ |
278 | + actionIconView.highlighted = NO; |
279 | + }]; |
280 | + } |
281 | + |
282 | + topView.frame = frameRect; |
283 | + [UIView commitAnimations]; |
284 | + [UIView setAnimationsEnabled:YES]; |
285 | + break; |
286 | + case UIGestureRecognizerStateEnded: |
287 | + cancelled = downloading; |
288 | + downloading = !downloading; |
289 | + [self.delegate viewDidEndPullRightGesture:self]; |
290 | + [self closeBottomView]; |
291 | + break; |
292 | + case UIGestureRecognizerStateCancelled: |
293 | + [UIView animateWithDuration:0.333 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{ |
294 | + CGRect frame = UIEdgeInsetsInsetRect(bottomView.bounds, UIEdgeInsetsMake(0, 12, 0, 0)); |
295 | + topView.frame = frame; |
296 | + } completion:^(BOOL finished) { |
297 | + // change the icon to whatever its new state should be |
298 | + if (downloading) |
299 | + { |
300 | + actionIconView.image = [UIImage imageNamed:@"cancel-grey"]; |
301 | + actionIconView.highlightedImage = [UIImage imageNamed:@"cancel"]; |
302 | + } |
303 | + else if (downloaded) |
304 | + { |
305 | + actionIconView.image = [UIImage imageNamed:@"trash-grey"]; |
306 | + actionIconView.highlightedImage = [UIImage imageNamed:@"trash"]; |
307 | + } |
308 | + else |
309 | + { |
310 | + actionIconView.image = [UIImage imageNamed:@"download-grey"]; |
311 | + actionIconView.highlightedImage = [UIImage imageNamed:@"download"]; |
312 | + } |
313 | + actionIconView.highlighted = NO; |
314 | + }]; |
315 | + |
316 | + [UIView animateWithDuration:0.333 animations:^{ |
317 | + bottomView.backgroundColor = [UIColor orangeColor]; |
318 | + }]; |
319 | + break; |
320 | + default: |
321 | + break; |
322 | + } |
323 | +} |
324 | + |
325 | +-(void)setCached:(BOOL)cached { |
326 | + CGRect frame; |
327 | + if (cached) { |
328 | + frame = CGRectMake(0, CGRectGetMaxY(self.bounds), 12, CGRectGetHeight(self.bounds)); |
329 | + } else { |
330 | + frame = CGRectMake(0, 0, 12, CGRectGetHeight(self.bounds)); |
331 | + } |
332 | + progressView.frame = frame; |
333 | +} |
334 | + |
335 | +/* |
336 | +// Only override drawRect: if you perform custom drawing. |
337 | +// An empty implementation adversely affects performance during animation. |
338 | +- (void)drawRect:(CGRect)rect |
339 | +{ |
340 | + // Drawing code |
341 | +} |
342 | +*/ |
343 | + |
344 | +@end |
345 | |
346 | === modified file 'controls/SongUITableViewCell.h' |
347 | --- controls/SongUITableViewCell.h 2011-05-27 18:22:51 +0000 |
348 | +++ controls/SongUITableViewCell.h 2012-07-24 05:24:19 +0000 |
349 | @@ -29,22 +29,11 @@ |
350 | // DAMAGE. |
351 | |
352 | #import <UIKit/UIKit.h> |
353 | +#import "SongUITableView.h" |
354 | |
355 | @interface SongUITableViewCell : UITableViewCell { |
356 | - UIButton *cacheButton; |
357 | - UIActivityIndicatorView *spinner; |
358 | - UILabel *songNameLabel; |
359 | - BOOL evenRow; |
360 | - UIView *coloredView; |
361 | - UILabel *positionLabel; |
362 | - UILabel *durationLabel; |
363 | - UIImageView *nowPlaying; |
364 | + SongUITableView *songUITableView; |
365 | } |
366 | -@property(nonatomic,retain) UIButton *cacheButton; |
367 | -@property(nonatomic,retain) UIActivityIndicatorView *spinner; |
368 | -@property(nonatomic,assign) BOOL evenRow; |
369 | -@property(nonatomic,retain) UIImageView *nowPlaying; |
370 | -@property(nonatomic,retain) UILabel *songNameLabel; |
371 | -@property(nonatomic,retain) UILabel *positionLabel; |
372 | -@property(nonatomic,retain) UILabel *durationLabel; |
373 | +@property (nonatomic, retain) SongUITableView *songUITableView; |
374 | + |
375 | @end |
376 | |
377 | === modified file 'controls/SongUITableViewCell.m' |
378 | --- controls/SongUITableViewCell.m 2011-06-07 09:20:03 +0000 |
379 | +++ controls/SongUITableViewCell.m 2012-07-24 05:24:19 +0000 |
380 | @@ -34,50 +34,14 @@ |
381 | |
382 | @implementation SongUITableViewCell |
383 | |
384 | -@synthesize cacheButton, spinner, songNameLabel, positionLabel, durationLabel, nowPlaying, evenRow; |
385 | +//@synthesize spinner, songNameLabel, positionLabel, durationLabel, nowPlaying, evenRow; |
386 | +@synthesize songUITableView; |
387 | |
388 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier |
389 | { |
390 | - if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) |
391 | - { |
392 | - self.evenRow = YES; |
393 | - |
394 | - coloredView = [[UIView alloc] initWithFrame:self.frame]; |
395 | - coloredView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; |
396 | - [self.contentView addSubview:coloredView]; |
397 | - |
398 | - // XXX: This is added first so that it sits behind the cacheButton. This isn't optimal. Something better would be to delegate taps on the spinner to the cacheButton, regardless of its front-to-back ordering in the subviews. |
399 | - spinner = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray] retain]; |
400 | - spinner.hidesWhenStopped = YES; |
401 | - [coloredView addSubview:spinner]; |
402 | - |
403 | - cacheButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain]; |
404 | - [cacheButton setImage:[UIImage imageNamed:@"uncached"] forState:UIControlStateNormal]; |
405 | - [coloredView addSubview:self.cacheButton]; |
406 | + if ((self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])) { |
407 | |
408 | - songNameLabel = [[UILabel alloc] init]; |
409 | - songNameLabel.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]]; |
410 | - [coloredView addSubview:self.songNameLabel]; |
411 | - |
412 | - positionLabel = [[UILabel alloc] init]; |
413 | - positionLabel.text = @"1"; |
414 | - positionLabel.textAlignment = UITextAlignmentCenter; |
415 | - positionLabel.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]]; |
416 | - [coloredView addSubview:positionLabel]; |
417 | - |
418 | - durationLabel = [[UILabel alloc] init]; |
419 | - durationLabel.text = @"0:00"; |
420 | - durationLabel.textAlignment = UITextAlignmentCenter; |
421 | - durationLabel.font = [UIFont boldSystemFontOfSize:[UIFont systemFontSize]]; |
422 | - [coloredView addSubview:durationLabel]; |
423 | - |
424 | - nowPlaying = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 13, 12)]; |
425 | - nowPlaying.image = [UIImage imageNamed:@"speaker"]; |
426 | - nowPlaying.backgroundColor = [UIColor clearColor]; |
427 | - nowPlaying.contentMode = UIViewContentModeCenter; |
428 | - [coloredView addSubview:nowPlaying]; |
429 | - |
430 | - self.textLabel.hidden = YES; |
431 | + songUITableView = [[SongUITableView alloc] initWithFrame:self.frame]; |
432 | } |
433 | |
434 | return self; |
435 | @@ -86,38 +50,11 @@ |
436 | - (void)layoutSubviews |
437 | { |
438 | [super layoutSubviews]; |
439 | - self.positionLabel.frame = CGRectMake(0, 0, 35, self.frame.size.height); |
440 | - self.songNameLabel.frame = CGRectMake(37, 0, 164, self.frame.size.height); |
441 | - self.nowPlaying.frame = CGRectMake(203, 0, 13, self.frame.size.height); |
442 | - self.durationLabel.frame = CGRectMake(218, 0, 48, self.frame.size.height); |
443 | - self.cacheButton.frame = CGRectMake(268, 0, 44, self.frame.size.height); |
444 | - self.spinner.frame = CGRectMake(282, 14, 16, 16); |
445 | - |
446 | - if (self.evenRow) |
447 | - { |
448 | - coloredView.backgroundColor = [UIColor whiteColor]; |
449 | - self.backgroundColor = [UIColor whiteColor]; |
450 | - self.songNameLabel.backgroundColor = [UIColor whiteColor]; |
451 | - self.positionLabel.backgroundColor = [UIColor whiteColor]; |
452 | - self.durationLabel.backgroundColor = [UIColor whiteColor]; |
453 | - } |
454 | - else |
455 | - { |
456 | - coloredView.backgroundColor = [UIColor colorWithRed:0.9529f green:0.9529f blue:0.9529f alpha:1.0f]; |
457 | - self.backgroundColor = [UIColor colorWithRed:0.9529f green:0.9529f blue:0.9529f alpha:1.0f]; |
458 | - self.songNameLabel.backgroundColor = [UIColor colorWithRed:0.9529f green:0.9529f blue:0.9529f alpha:1.0f]; |
459 | - self.positionLabel.backgroundColor = [UIColor colorWithRed:0.9529f green:0.9529f blue:0.9529f alpha:1.0f]; |
460 | - self.durationLabel.backgroundColor = [UIColor colorWithRed:0.9529f green:0.9529f blue:0.9529f alpha:1.0f]; |
461 | - } |
462 | + [self.contentView addSubview:songUITableView]; |
463 | } |
464 | |
465 | - (void)dealloc |
466 | { |
467 | - [cacheButton release]; |
468 | - [spinner release]; |
469 | - [durationLabel release]; |
470 | - [songNameLabel release]; |
471 | - [positionLabel release]; |
472 | [super dealloc]; |
473 | } |
474 | |
475 | |
476 | === added file 'controls/UOPullGestureRecognizer.h' |
477 | --- controls/UOPullGestureRecognizer.h 1970-01-01 00:00:00 +0000 |
478 | +++ controls/UOPullGestureRecognizer.h 2012-07-24 05:24:19 +0000 |
479 | @@ -0,0 +1,20 @@ |
480 | +// |
481 | +// UOPullGestureRecognizer.h |
482 | +// U1Music |
483 | +// |
484 | +// Created by Paul Hummer on 7/17/12. |
485 | +// Copyright (c) 2012 Canonical. All rights reserved. |
486 | +// |
487 | + |
488 | +#import <UIKit/UIKit.h> |
489 | + |
490 | +@interface UOPullGestureRecognizer : UIPanGestureRecognizer { |
491 | + CGPoint inceptionPoint; |
492 | +} |
493 | +@property UISwipeGestureRecognizerDirection direction; |
494 | +@property BOOL firesActionOnThresholdReached; |
495 | +@property CGFloat actionThreshold; |
496 | +@property CGRect activationRegion; |
497 | + |
498 | +//@property(nonatomic,readwrite) UIGestureRecognizerState state; |
499 | +@end |
500 | |
501 | === added file 'controls/UOPullGestureRecognizer.m' |
502 | --- controls/UOPullGestureRecognizer.m 1970-01-01 00:00:00 +0000 |
503 | +++ controls/UOPullGestureRecognizer.m 2012-07-24 05:24:19 +0000 |
504 | @@ -0,0 +1,77 @@ |
505 | +// |
506 | +// UOPullGestureRecognizer.m |
507 | +// U1Music |
508 | +// |
509 | +// Created by Paul Hummer on 7/17/12. |
510 | +// Copyright (c) 2012 Canonical. All rights reserved. |
511 | +// |
512 | + |
513 | +#import <UIKit/UIGestureRecognizerSubclass.h> |
514 | +#import "UOPullGestureRecognizer.h" |
515 | + |
516 | +@implementation UOPullGestureRecognizer |
517 | +@synthesize direction; |
518 | +@synthesize firesActionOnThresholdReached; |
519 | +@synthesize actionThreshold; |
520 | +@synthesize activationRegion; |
521 | + |
522 | +- (id)initWithTarget:(id)target action:(SEL)action { |
523 | + self = [super initWithTarget:target action:action]; |
524 | + if (self != nil) { |
525 | + actionThreshold = 64.f; |
526 | + } |
527 | + return self; |
528 | +} |
529 | + |
530 | +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { |
531 | + NSParameterAssert([touches count] == 1); |
532 | + |
533 | + CGPoint touchPoint = [[touches anyObject] locationInView:self.view]; |
534 | + if (!CGRectEqualToRect(activationRegion, CGRectZero)) { |
535 | + if (!CGRectContainsPoint(activationRegion, touchPoint)) { |
536 | + self.state = UIGestureRecognizerStateCancelled; |
537 | + return; |
538 | + } |
539 | + } |
540 | + |
541 | + [super touchesBegan:touches withEvent:event]; |
542 | + inceptionPoint = [[touches anyObject] locationInView:nil]; |
543 | +} |
544 | + |
545 | +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { |
546 | + for (UITouch *touch in touches) { |
547 | + CGPoint currentPoint = [touch locationInView:nil]; |
548 | + CGFloat offset = currentPoint.x - inceptionPoint.x; |
549 | + if ((offset < 0 && direction == UISwipeGestureRecognizerDirectionRight) || |
550 | + (offset > 0 && direction == UISwipeGestureRecognizerDirectionLeft)) { |
551 | + /* Pull cancelled */ |
552 | + self.state = UIGestureRecognizerStateCancelled; |
553 | + return; |
554 | + } |
555 | + |
556 | + if (fabs(offset) > actionThreshold && self.firesActionOnThresholdReached) { |
557 | + /* Pull completed */ |
558 | + self.state = UIGestureRecognizerStateEnded; |
559 | + } |
560 | + } |
561 | + [super touchesMoved:touches withEvent:event]; |
562 | +} |
563 | + |
564 | +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { |
565 | + // still passed the activation threshold? |
566 | + |
567 | + CGPoint currentPoint = [[touches anyObject] locationInView:nil]; |
568 | + CGFloat offset = currentPoint.x - inceptionPoint.x; |
569 | + |
570 | + if (fabs(offset) > actionThreshold && !self.firesActionOnThresholdReached) { |
571 | + NSLog(@"DO THE THING!"); |
572 | + [super touchesEnded:touches withEvent:event]; |
573 | + } |
574 | + else |
575 | + { |
576 | + self.state = UIGestureRecognizerStateCancelled; |
577 | + } |
578 | +} |
579 | + |
580 | + |
581 | +@end |
582 | |
583 | === added file 'images/download-grey.png' |
584 | Binary files images/download-grey.png 1970-01-01 00:00:00 +0000 and images/download-grey.png 2012-07-24 05:24:19 +0000 differ |
585 | === added file 'images/download-grey@2x.png' |
586 | Binary files images/download-grey@2x.png 1970-01-01 00:00:00 +0000 and images/download-grey@2x.png 2012-07-24 05:24:19 +0000 differ |
587 | === added file 'images/download.png' |
588 | Binary files images/download.png 1970-01-01 00:00:00 +0000 and images/download.png 2012-07-24 05:24:19 +0000 differ |
589 | === added file 'images/download@2x.png' |
590 | Binary files images/download@2x.png 1970-01-01 00:00:00 +0000 and images/download@2x.png 2012-07-24 05:24:19 +0000 differ |
591 | === added file 'images/grabber.png' |
592 | Binary files images/grabber.png 1970-01-01 00:00:00 +0000 and images/grabber.png 2012-07-24 05:24:19 +0000 differ |
593 | === added file 'images/grabber@2x.png' |
594 | Binary files images/grabber@2x.png 1970-01-01 00:00:00 +0000 and images/grabber@2x.png 2012-07-24 05:24:19 +0000 differ |
595 | === modified file 'view_controllers/AlbumViewController.h' |
596 | --- view_controllers/AlbumViewController.h 2011-06-07 09:20:03 +0000 |
597 | +++ view_controllers/AlbumViewController.h 2012-07-24 05:24:19 +0000 |
598 | @@ -18,12 +18,13 @@ |
599 | // along with this program. If not, see <http://www.gnu.org/licenses/>. |
600 | |
601 | #import <UIKit/UIKit.h> |
602 | +#import "SongUITableView.h" |
603 | #import "SubsonicTableViewController.h" |
604 | #import "AlbumArtLoader.h" |
605 | |
606 | @class Artist, Album; |
607 | |
608 | -@interface AlbumViewController : SubsonicTableViewController <AlbumArtLoaderDelegate> |
609 | +@interface AlbumViewController : SubsonicTableViewController <AlbumArtLoaderDelegate,SongUITableViewDelegate> |
610 | { |
611 | AlbumArtLoader *loader; |
612 | UIView *headerView; |
613 | @@ -38,7 +39,6 @@ |
614 | @property(nonatomic,retain) NSMutableArray *songs; |
615 | @property(nonatomic,retain) NSString *artist; |
616 | @property(nonatomic,retain) Album *album; |
617 | -@property(nonatomic,retain) UIButton *cacheButton; |
618 | |
619 | extern NSString * const NOTIF_downloadComplete; |
620 | extern NSString * const NOTIF_removeCachedContent; |
621 | |
622 | === modified file 'view_controllers/AlbumViewController.m' |
623 | --- view_controllers/AlbumViewController.m 2012-06-22 17:56:56 +0000 |
624 | +++ view_controllers/AlbumViewController.m 2012-07-24 05:24:19 +0000 |
625 | @@ -23,6 +23,7 @@ |
626 | #import "AlbumParser.h" |
627 | #import "Album.h" |
628 | #import "Song.h" |
629 | +#import "SongUITableView.h" |
630 | #import "SongUITableViewCell.h" |
631 | #import "NSDate+Extras.h" |
632 | #import "StreamingPlayer.h" |
633 | @@ -41,7 +42,7 @@ |
634 | @end |
635 | |
636 | @implementation AlbumViewController |
637 | -@synthesize artist, album, songs, cacheButton; |
638 | +@synthesize artist, album, songs; |
639 | |
640 | - (id)initWithStyle:(UITableViewStyle)aStyle |
641 | { |
642 | @@ -83,7 +84,8 @@ |
643 | @synchronized(self.songs) |
644 | { |
645 | [self.songs removeAllObjects]; |
646 | - [PerThreadManagedObjectContext() refreshObject:self.album mergeChanges:YES]; //force the album to reload its set of songs from the persistent store. |
647 | + //force the album to reload its set of songs from the persistent store. |
648 | + [PerThreadManagedObjectContext() refreshObject:self.album mergeChanges:YES]; |
649 | [self.songs addObjectsFromArray:[self.album.songs allObjects]]; |
650 | [self.songs sortUsingSelector:@selector(compare:)]; |
651 | } |
652 | @@ -135,11 +137,15 @@ |
653 | if (nil == cell) |
654 | { |
655 | cell = [[[SongUITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SongCellIdentifier] autorelease]; |
656 | + cell.songUITableView.delegate = self; |
657 | } |
658 | [self configureCell:cell forSongAtIndexPath:indexPath]; |
659 | return cell; |
660 | } |
661 | |
662 | +- (void)viewDidBeginTouchGesture:(SongUITableView*)view { |
663 | + // Stub for when we have a middle view. |
664 | +} |
665 | |
666 | #pragma mark - |
667 | #pragma mark Table view delegate |
668 | @@ -209,82 +215,14 @@ |
669 | } |
670 | } |
671 | |
672 | -@end |
673 | - |
674 | -@implementation AlbumViewController (Private) |
675 | - |
676 | -- (void)configureCell:(SongUITableViewCell*)cell forSongAtIndexPath:(NSIndexPath*)indexPath |
677 | -{ |
678 | - Song *song = [self.songs objectAtIndex:indexPath.row]; |
679 | - |
680 | - // explicitly re-set the default state of the button/spinner |
681 | - [cell.cacheButton setImage:(canCache ? [UIImage imageNamed:@"uncached"] : [UIImage imageNamed:@"uncached-disabled"]) forState:UIControlStateNormal]; |
682 | - [cell.spinner stopAnimating]; |
683 | - |
684 | - cell.cacheButton.tag = indexPath.row; |
685 | - [cell.cacheButton addTarget:self action:@selector(toggleCacheForSong:) forControlEvents:UIControlEventTouchUpInside]; |
686 | - |
687 | - U1CacheFileManager *cacheFileManager = [U1CacheFileManager sharedCacheFileManager]; |
688 | - BOOL offline = NO; |
689 | - NSString *cachedPath = [cacheFileManager cachedPathForFileId:song.idPath offline:&offline]; |
690 | - |
691 | - if ([[Downloader sharedDownloader] isDownloading:song.idPath] && offline) |
692 | - { |
693 | - [cell.spinner startAnimating]; |
694 | - } |
695 | - else if (offline) |
696 | - { |
697 | - [cell.cacheButton setImage:[UIImage imageNamed:@"cached"] forState:UIControlStateNormal]; |
698 | - } |
699 | - |
700 | - cell.songNameLabel.text = song.title; |
701 | - |
702 | - cell.positionLabel.text = [NSString stringWithFormat:@"%@", [song.track intValue] > 0 ? [song.track stringValue] : @""]; |
703 | - |
704 | - if (song.duration && [song.duration intValue] > 0) |
705 | - { |
706 | - cell.durationLabel.text = [NSDate stringFromDuration:song.duration]; |
707 | - } |
708 | - else |
709 | - { |
710 | - cell.durationLabel.text = @""; |
711 | - } |
712 | - |
713 | - if ([StreamingPlayer sharedStreamingPlayer].currentSong && [song.songId isEqual:[StreamingPlayer sharedStreamingPlayer].currentSong.songId]) |
714 | - { |
715 | - cell.nowPlaying.hidden = NO; |
716 | - } |
717 | - else |
718 | - { |
719 | - cell.nowPlaying.hidden = YES; |
720 | - } |
721 | - |
722 | - [cell.cacheButton setHidden:!canStream]; |
723 | - |
724 | - cell.evenRow = (0 == indexPath.row % 2); |
725 | - if (cachedPath == nil && !canStream) |
726 | - { |
727 | - cell.songNameLabel.textColor = [UIColor lightGrayColor]; |
728 | - cell.positionLabel.textColor = [UIColor lightGrayColor]; |
729 | - cell.durationLabel.textColor = [UIColor lightGrayColor]; |
730 | - } |
731 | - else |
732 | - { |
733 | - cell.songNameLabel.textColor = [UIColor blackColor]; |
734 | - cell.positionLabel.textColor = [UIColor blackColor]; |
735 | - cell.durationLabel.textColor = [UIColor blackColor]; |
736 | - } |
737 | -} |
738 | - |
739 | -- (void)toggleCacheForSong:(id)sender |
740 | -{ |
741 | +-(void)viewDidEndPullRightGesture:(SongUITableView *)view { |
742 | // This is a binary toggle, and right now, we don't bother trying to cancel a download in progress. |
743 | - int row = [(UIButton *)sender tag]; |
744 | - |
745 | + int row = [(UIButton *)view tag]; |
746 | + |
747 | NSIndexPath *songPath = [NSIndexPath indexPathForRow:row inSection:0]; |
748 | SongUITableViewCell *cell = (SongUITableViewCell *)[self.tableView cellForRowAtIndexPath:songPath]; |
749 | Song *song = [self.songs objectAtIndex:row]; |
750 | - |
751 | + |
752 | if (![[Downloader sharedDownloader] isDownloading:song.idPath]) |
753 | // If we're downloading at all, don't do anything. |
754 | { |
755 | @@ -295,26 +233,22 @@ |
756 | { |
757 | [cacheFileManager toggleOfflineStatusForFileId:song.idPath]; |
758 | |
759 | - [cell.spinner stopAnimating]; |
760 | [[NSNotificationCenter defaultCenter] postNotificationName:NOTIF_removeCachedContent object:nil]; |
761 | - [cell.cacheButton setImage:[UIImage imageNamed:@"uncached"] forState:UIControlStateNormal]; |
762 | + [cell.songUITableView setCached:NO]; |
763 | } |
764 | else if (cachedPath && !offline) |
765 | { |
766 | [cacheFileManager toggleOfflineStatusForFileId:song.idPath]; |
767 | - [cell.spinner stopAnimating]; |
768 | - [cell.cacheButton setImage:[UIImage imageNamed:@"cached"] forState:UIControlStateNormal]; |
769 | + [cell.songUITableView setCached:YES]; |
770 | } |
771 | else |
772 | { |
773 | if (canCache) |
774 | { |
775 | - [cell.spinner startAnimating]; |
776 | [[Downloader sharedDownloader] downloadFile:[[Subsonic sharedSubsonic] getStreamingURLForSongId:song.songId] withName:song.idPath forOffline:YES completionBlock:^(NSString *path) { |
777 | dispatch_async(dispatch_get_main_queue(), ^(void) { |
778 | SongUITableViewCell *cell = (SongUITableViewCell *)[self.tableView cellForRowAtIndexPath:songPath]; |
779 | - [cell.spinner stopAnimating]; |
780 | - [cell.cacheButton setImage:[UIImage imageNamed:@"cached"] forState:UIControlStateNormal]; |
781 | + [cell.songUITableView setCached:YES]; |
782 | }); |
783 | }]; |
784 | } |
785 | @@ -325,14 +259,14 @@ |
786 | { |
787 | RIButtonItem *cancelButton = [RIButtonItem item]; |
788 | cancelButton.label = NSLocalizedString(@"Remind Me", @""); |
789 | - |
790 | + |
791 | RIButtonItem *dismissButton = [RIButtonItem item]; |
792 | dismissButton.label = NSLocalizedString(@"Dismiss", @""); |
793 | dismissButton.action = ^ |
794 | { |
795 | [defaults setBool:YES forKey:@"acknowledged-no-cache-on-3g"]; |
796 | }; |
797 | - |
798 | + |
799 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Downloading Disabled", @"") |
800 | message:NSLocalizedString(@"Downloading songs for offline use can only be done on WiFi networks.", @"") |
801 | cancelButtonItem:cancelButton otherButtonItems:dismissButton, nil]; |
802 | @@ -344,6 +278,49 @@ |
803 | } |
804 | } |
805 | |
806 | +@end |
807 | + |
808 | +@implementation AlbumViewController (Private) |
809 | + |
810 | +-(void)toggleCacheForSong:(id)sender { |
811 | + |
812 | +} |
813 | + |
814 | +- (void)configureCell:(SongUITableViewCell*)cell forSongAtIndexPath:(NSIndexPath*)indexPath |
815 | +{ |
816 | + Song *song = [self.songs objectAtIndex:indexPath.row]; |
817 | + |
818 | + [cell.songUITableView setCached:NO]; |
819 | + cell.songUITableView.nowPlaying.hidden = YES; |
820 | + cell.songUITableView.songNameLabel.text = @""; |
821 | + |
822 | + cell.songUITableView.tag = indexPath.row; |
823 | + |
824 | + U1CacheFileManager *cacheFileManager = [U1CacheFileManager sharedCacheFileManager]; |
825 | + BOOL offline = NO; |
826 | + NSString *cachedPath = [cacheFileManager cachedPathForFileId:song.idPath offline:&offline]; |
827 | + |
828 | + if ([[Downloader sharedDownloader] isDownloading:song.idPath] && offline) { |
829 | + /* TODO: We need to implement the progress bar */ |
830 | + } else if (offline) { |
831 | + [cell.songUITableView setCached:YES]; |
832 | + } |
833 | + |
834 | + cell.songUITableView.songNameLabel.text = song.title; |
835 | + |
836 | + if ([StreamingPlayer sharedStreamingPlayer].currentSong && [song.songId isEqual:[StreamingPlayer sharedStreamingPlayer].currentSong.songId]) { |
837 | + cell.songUITableView.nowPlaying.hidden = NO; |
838 | + } else { |
839 | + cell.songUITableView.nowPlaying.hidden = YES; |
840 | + } |
841 | + |
842 | + if (cachedPath == nil && !canStream) { |
843 | + cell.songUITableView.songNameLabel.textColor = [UIColor lightGrayColor]; |
844 | + } else { |
845 | + cell.songUITableView.songNameLabel.textColor = [UIColor blackColor]; |
846 | + } |
847 | +} |
848 | + |
849 | - (void)toggleCacheForAlbum:(id)sender |
850 | { |
851 | |
852 | @@ -393,16 +370,6 @@ |
853 | [headerView addSubview:albumLabel]; |
854 | |
855 | albumLabel.text = self.album.title; |
856 | - |
857 | - /* Not yet |
858 | - cacheButton = [UIButton buttonWithType:UIButtonTypeCustom]; |
859 | - cacheButton.frame = CGRectMake(268, 76, 44, 44); |
860 | - // If none of the songs are cached, it should use uncached.png |
861 | - // If some of the songs are cached, it should use partiallycached.png |
862 | - // If all of the songs are cachced, it should use cached.png |
863 | - [cacheButton setImage:[UIImage imageNamed:@"uncached"] forState:UIControlStateNormal]; |
864 | - [headerView addSubview:cacheButton]; |
865 | - */ |
866 | |
867 | self.tableView.tableHeaderView = headerView; |
868 | |
869 | @@ -415,5 +382,4 @@ |
870 | [self.tableView.tableFooterView addSubview:bigFooterView]; |
871 | [bigFooterView release]; |
872 | } |
873 | - |
874 | @end |
875 | |
876 | === modified file 'view_controllers/PlaylistEditAlbumViewController.m' |
877 | --- view_controllers/PlaylistEditAlbumViewController.m 2011-06-23 13:54:49 +0000 |
878 | +++ view_controllers/PlaylistEditAlbumViewController.m 2012-07-24 05:24:19 +0000 |
879 | @@ -67,28 +67,15 @@ |
880 | |
881 | Song *song = [self.songs objectAtIndex:indexPath.row]; |
882 | |
883 | - cell.songNameLabel.text = song.title; |
884 | + cell.songUITableView.songNameLabel.text = song.title; |
885 | |
886 | - cell.positionLabel.text = [NSString stringWithFormat:@"%@", [song.track intValue] > 0 ? [song.track stringValue] : @""]; |
887 | - |
888 | - if (song.duration && [song.duration intValue] > 0) |
889 | - { |
890 | - cell.durationLabel.text = [NSDate stringFromDuration:song.duration]; |
891 | - } |
892 | - else |
893 | - { |
894 | - cell.durationLabel.text = @""; |
895 | - } |
896 | - |
897 | - cell.nowPlaying.hidden = YES; |
898 | + cell.songUITableView.nowPlaying.hidden = YES; |
899 | |
900 | if ([self.originator.playlist.songs containsObject:song]) |
901 | { |
902 | cell.accessoryType = UITableViewCellAccessoryCheckmark; |
903 | } |
904 | |
905 | - cell.evenRow = (0 == indexPath.row % 2); |
906 | - |
907 | return cell; |
908 | } |
909 |