-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update design of video queue #282
Merged
Merged
Changes from 28 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
58f980f
Change “UP NEXT” to “QUEUE”
glennrfisher c86472f
Update VideoQueueTableViewCell
glennrfisher 1d4a66e
Add play icon to assets
glennrfisher 3e3e377
Update cellFor(queueTableView:at:)
glennrfisher afb2c6d
Set background color of content view
glennrfisher cbff1ee
Change separator color for queue table view
glennrfisher 9b7eade
Improve comments
glennrfisher d731628
Hide separator for current video
glennrfisher e0423dc
Change number property from Int? to String?
glennrfisher dfc30e0
Make current video editable
glennrfisher 31db63a
Set selection style to none
glennrfisher b246743
Update highlighted color
glennrfisher 053169e
Highlight background of current video when editing
glennrfisher e5b9265
Start counting videos from 1 instead of 0
glennrfisher 4530d29
Swap highlighting when a new video is selected
glennrfisher c789879
Swap highlight when video ends
glennrfisher a9e3b20
Update comments and formatting
glennrfisher 70f2bef
Reset background color and separator when no longer the current video
glennrfisher 38bbcc9
Hide separator of previous video
glennrfisher e2eb49d
Code cleanup
glennrfisher 4946533
Update row numbering after moving a video
glennrfisher b1e321d
Reload rows to update video numbers
glennrfisher ee2507d
Remove row numbering for now
glennrfisher a495f49
Scroll to current video when showing the queue
glennrfisher 63b3f78
Add helper function to highlight/unhighlight
glennrfisher 736bbc3
Set previous video when loading cells
glennrfisher c12b799
Add support for deleting the current video
glennrfisher aa15744
Code cleanup — use switch instead of if/else
glennrfisher 76aa0be
Remove ability to delete the current video
glennrfisher 2e4fab3
Remove video cell numbers and play icon
glennrfisher 8a2af98
Update guard statements
glennrfisher bfc71e3
Merge remote-tracking branch 'origin/develop' into video-queue
glennrfisher File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
iOS/Stormtrooper/Stormtrooper/Assets.xcassets/playing.imageset/Contents.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
"images" : [ | ||
{ | ||
"idiom" : "universal", | ||
"filename" : "path.pdf" | ||
} | ||
], | ||
"info" : { | ||
"author" : "zeplin", | ||
"version" : "1" | ||
} | ||
} |
Binary file added
BIN
+3.8 KB
iOS/Stormtrooper/Stormtrooper/Assets.xcassets/playing.imageset/path.pdf
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -398,6 +398,10 @@ class StreamViewController: UIViewController { | |
self.headerArrowImageView.transform = CGAffineTransform(rotationAngle: CGFloat.pi) | ||
}, completion: { complete in | ||
self.queueView.isHidden = false | ||
if let currentVideoIndex = self.viewModel.currentVideoIndex { | ||
let currentVideoIndexPath = IndexPath(row: currentVideoIndex, section: 0) | ||
self.queueTableView.scrollToRow(at: currentVideoIndexPath, at: .top, animated: true) | ||
} | ||
}) | ||
} | ||
else { | ||
|
@@ -535,7 +539,50 @@ class StreamViewController: UIViewController { | |
} | ||
} | ||
} | ||
|
||
|
||
fileprivate func setHighlightForVideo(at row: Int, highlighted: Bool) { | ||
// update the previous video (i.e. whether to hide its separator) | ||
let previousIndexPath = IndexPath(row: row-1, section: 0) | ||
let previousVideoCell = queueTableView.cellForRow(at: previousIndexPath) as? VideoQueueTableViewCell | ||
previousVideoCell?.isPreviousVideo = highlighted | ||
|
||
// update the current video (i.e. whether to highlight it) | ||
let indexPath = IndexPath(row: row, section: 0) | ||
let videoCell = queueTableView.cellForRow(at: indexPath) as? VideoQueueTableViewCell | ||
videoCell?.isCurrentVideo = highlighted | ||
} | ||
|
||
fileprivate func deleteVideo(at indexPath: IndexPath) { | ||
guard let currentVideoIndex = viewModel.currentVideoIndex else { return } | ||
let previousIndexPath = IndexPath(row: indexPath.row - 1, section: 0) | ||
let nextIndexPath = IndexPath(row: indexPath.row + 1, section: 0) | ||
|
||
// deleted the previous video | ||
if indexPath.row == currentVideoIndex - 1 { | ||
let previousCell = queueTableView.cellForRow(at: previousIndexPath) | ||
let previousVideoCell = previousCell as? VideoQueueTableViewCell | ||
previousVideoCell?.isPreviousVideo = true | ||
} | ||
|
||
// deleted the current video | ||
if indexPath.row == currentVideoIndex { | ||
guard let videoQueue = viewModel.videoQueue else { return } | ||
setHighlightForVideo(at: nextIndexPath.row, highlighted: true) | ||
viewModel.currentVideoIndex = nextIndexPath.row | ||
let nextVideoId = videoQueue[nextIndexPath.row].id | ||
playerView.cueVideo(byId: nextVideoId, startSeconds: 0, suggestedQuality: .default) | ||
playerView.playVideo() | ||
} | ||
|
||
// remove deleted video from queue and view model | ||
queueTableView.beginUpdates() | ||
queueTableView.deleteRows(at: [indexPath], with: .automatic) | ||
viewModel.videoQueue?.remove(at: indexPath.row) | ||
if currentVideoIndex > indexPath.row { | ||
viewModel.currentVideoIndex = currentVideoIndex - 1 | ||
} | ||
queueTableView.endUpdates() | ||
} | ||
} | ||
|
||
extension StreamViewController: StreamViewModelDelegate { | ||
|
@@ -633,13 +680,11 @@ extension StreamViewController: StreamViewModelDelegate { | |
|
||
extension StreamViewController: UITableViewDelegate, UITableViewDataSource { | ||
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { | ||
if tableView.tag == chatTableTag { | ||
return cellFor(chatTableView: tableView, at: indexPath) | ||
switch tableView.tag { | ||
case chatTableTag: return cellFor(chatTableView: tableView, at: indexPath) | ||
case queueTableTag: return cellFor(queueTableView: tableView, at: indexPath) | ||
default: return UITableViewCell() | ||
} | ||
else if tableView.tag == queueTableTag { | ||
return cellFor(queueTableView: tableView, at: indexPath) | ||
} | ||
return UITableViewCell() | ||
} | ||
|
||
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { | ||
|
@@ -654,70 +699,60 @@ extension StreamViewController: UITableViewDelegate, UITableViewDataSource { | |
if isKeyboardShowing { | ||
visualEffectView.isHidden = false | ||
dismissView.isHidden = false | ||
} | ||
else { | ||
} else { | ||
visualEffectView.isHidden = true | ||
dismissView.isHidden = true | ||
} | ||
} | ||
|
||
func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { | ||
if tableView.tag == chatTableTag { | ||
return false | ||
} else if tableView.tag == queueTableTag { | ||
return indexPath.row != viewModel.currentVideoIndex | ||
} else { | ||
return false | ||
switch tableView.tag { | ||
case chatTableTag: return false | ||
case queueTableTag: return true | ||
default: return false | ||
} | ||
} | ||
|
||
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { | ||
if editingStyle == .delete, indexPath.row != viewModel.currentVideoIndex { | ||
tableView.beginUpdates() | ||
viewModel.videoQueue?.remove(at: indexPath.row) | ||
tableView.deleteRows(at: [indexPath], with: .automatic) | ||
if viewModel.currentVideoIndex ?? 0 > indexPath.row { | ||
viewModel.currentVideoIndex = (viewModel.currentVideoIndex ?? 0) - 1 | ||
} | ||
tableView.endUpdates() | ||
switch editingStyle { | ||
case .delete: deleteVideo(at: indexPath) | ||
default: break | ||
} | ||
} | ||
|
||
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { | ||
if tableView.tag == chatTableTag { | ||
return viewModel.messages.count //TODO: limit this to 50 or whatever performance allows | ||
} | ||
else if tableView.tag == queueTableTag { | ||
return viewModel.videoQueue?.count ?? 0 | ||
switch tableView.tag { | ||
case chatTableTag: return viewModel.messages.count | ||
case queueTableTag: return viewModel.videoQueue?.count ?? 0 | ||
default: return 0 | ||
} | ||
return 0 | ||
} | ||
|
||
func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool { | ||
if tableView.tag == queueTableTag { | ||
return true | ||
switch tableView.tag { | ||
case chatTableTag: return false | ||
case queueTableTag: return true | ||
default: return false | ||
} | ||
return false | ||
} | ||
|
||
func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) { | ||
guard let currentVideoIndex = viewModel.currentVideoIndex, let video = viewModel.videoQueue?.remove(at: sourceIndexPath.row) else { | ||
return | ||
} | ||
guard let currentVideoIndex = viewModel.currentVideoIndex else { return } | ||
guard let video = viewModel.videoQueue?.remove(at: sourceIndexPath.row) else { return } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can combine with above guard statement and use line breaks. |
||
viewModel.videoQueue?.insert(video, at: destinationIndexPath.row) | ||
|
||
// update the view model's current video index | ||
if sourceIndexPath.row == currentVideoIndex { | ||
// moved the current video | ||
viewModel.currentVideoIndex = destinationIndexPath.row | ||
} | ||
else if destinationIndexPath.row == currentVideoIndex { | ||
} else if destinationIndexPath.row == currentVideoIndex { | ||
// moved a video to the current video's index | ||
viewModel.currentVideoIndex = destinationIndexPath.row + (sourceIndexPath.row > destinationIndexPath.row ? 1 : -1) | ||
} | ||
// left-to-right | ||
else if sourceIndexPath.row < currentVideoIndex, currentVideoIndex < destinationIndexPath.row { | ||
} else if sourceIndexPath.row < currentVideoIndex, currentVideoIndex < destinationIndexPath.row { | ||
// moved a video from the left-side of the current video to the right-side | ||
viewModel.currentVideoIndex = currentVideoIndex - 1 | ||
} | ||
|
||
// right-to-left | ||
else if sourceIndexPath.row > currentVideoIndex, currentVideoIndex > destinationIndexPath.row { | ||
} else if sourceIndexPath.row > currentVideoIndex, currentVideoIndex > destinationIndexPath.row { | ||
// moved a video from the right-side of the current video to the left-side | ||
viewModel.currentVideoIndex = currentVideoIndex + 1 | ||
} | ||
} | ||
|
@@ -727,11 +762,13 @@ extension StreamViewController: UITableViewDelegate, UITableViewDataSource { | |
} | ||
|
||
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { | ||
if viewModel.currentVideoIndex != indexPath.row { | ||
viewModel.currentVideoIndex = indexPath.row | ||
playerView.cueVideo(byId: viewModel.videoQueue?[indexPath.row].id ?? "", startSeconds: 0, suggestedQuality: .default) | ||
playerView.playVideo() | ||
} | ||
guard viewModel.currentVideoIndex != indexPath.row else { return } | ||
guard let currentVideoIndex = viewModel.currentVideoIndex else { return } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
setHighlightForVideo(at: currentVideoIndex, highlighted: false) | ||
setHighlightForVideo(at: indexPath.row, highlighted: true) | ||
viewModel.currentVideoIndex = indexPath.row | ||
playerView.cueVideo(byId: viewModel.videoQueue?[indexPath.row].id ?? "", startSeconds: 0, suggestedQuality: .default) | ||
playerView.playVideo() | ||
} | ||
|
||
private func cellFor(chatTableView tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell { | ||
|
@@ -774,22 +811,23 @@ extension StreamViewController: UITableViewDelegate, UITableViewDataSource { | |
} | ||
|
||
private func cellFor(queueTableView tableView: UITableView, at indexPath: IndexPath) -> UITableViewCell { | ||
guard | ||
let cell = tableView.dequeueReusableCell(withIdentifier: "queueCell") as? VideoQueueTableViewCell, | ||
let video = viewModel.videoQueue?[indexPath.row] else { | ||
return UITableViewCell() | ||
guard let cell = tableView.dequeueReusableCell(withIdentifier: "queueCell") as? VideoQueueTableViewCell, | ||
let video = viewModel.videoQueue?[indexPath.row], | ||
let currentVideoIndex = viewModel.currentVideoIndex else { | ||
return UITableViewCell() | ||
} | ||
cell.titleLabel.text = video.title | ||
cell.channelTitleLabel.text = video.channelTitle | ||
|
||
cell.number = "\(indexPath.row + 1)" | ||
cell.title = video.title | ||
cell.channel = video.channelTitle | ||
cell.isPreviousVideo = (currentVideoIndex-1 == indexPath.row) | ||
cell.isCurrentVideo = (currentVideoIndex == indexPath.row) | ||
|
||
YouTubeDataManager.sharedInstance.getThumbnailForVideo(with: video.mediumThumbnailURL) {error, image in | ||
if let image = image { | ||
cell.thumbnailImageView.image = image | ||
} | ||
} | ||
if indexPath.row == viewModel.currentVideoIndex { | ||
cell.isSelected = true | ||
guard let image = image else { return } | ||
cell.thumbnail = image | ||
} | ||
cell.selectionStyle = .none | ||
|
||
return cell | ||
} | ||
} | ||
|
@@ -856,11 +894,8 @@ extension StreamViewController: YTPlayerViewDelegate { | |
} | ||
break | ||
case .ended: | ||
if viewModel.isHost, let queue = viewModel.videoQueue, var queueIndex = viewModel.currentVideoIndex { | ||
queueIndex = queueIndex < queue.count - 1 ? queueIndex + 1 : 0 | ||
playerView.cueVideo(byId: queue[queueIndex].id, startSeconds: 0, suggestedQuality: .default) | ||
viewModel.currentVideoIndex = queueIndex | ||
playerView.playVideo() | ||
if viewModel.isHost { | ||
playNextVideo() | ||
} | ||
break | ||
case .queued: | ||
|
@@ -872,6 +907,17 @@ extension StreamViewController: YTPlayerViewDelegate { | |
} | ||
} | ||
|
||
private func playNextVideo() { | ||
guard let videoQueue = viewModel.videoQueue else { return } | ||
guard let currentVideoIndex = viewModel.currentVideoIndex else { return } | ||
let nextVideoIndex = currentVideoIndex < videoQueue.count-1 ? currentVideoIndex+1 : 0 | ||
setHighlightForVideo(at: currentVideoIndex, highlighted: false) | ||
setHighlightForVideo(at: nextVideoIndex, highlighted: true) | ||
viewModel.currentVideoIndex = nextVideoIndex | ||
let nextVideoId = videoQueue[nextVideoIndex].id | ||
playerView.cueVideo(byId: nextVideoId, startSeconds: 0, suggestedQuality: .default) | ||
playerView.playVideo() | ||
} | ||
} | ||
|
||
extension StreamViewController: UITextFieldDelegate { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
haha surprised this hasn't come up before. I've always put it on a different line for spacing but I can see why some people prefer same line