Skip to content
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 32 commits into from
Feb 8, 2017
Merged
Show file tree
Hide file tree
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 Feb 7, 2017
c86472f
Update VideoQueueTableViewCell
glennrfisher Feb 7, 2017
1d4a66e
Add play icon to assets
glennrfisher Feb 7, 2017
3e3e377
Update cellFor(queueTableView:at:)
glennrfisher Feb 7, 2017
afb2c6d
Set background color of content view
glennrfisher Feb 7, 2017
cbff1ee
Change separator color for queue table view
glennrfisher Feb 7, 2017
9b7eade
Improve comments
glennrfisher Feb 7, 2017
d731628
Hide separator for current video
glennrfisher Feb 7, 2017
e0423dc
Change number property from Int? to String?
glennrfisher Feb 7, 2017
dfc30e0
Make current video editable
glennrfisher Feb 7, 2017
31db63a
Set selection style to none
glennrfisher Feb 7, 2017
b246743
Update highlighted color
glennrfisher Feb 7, 2017
053169e
Highlight background of current video when editing
glennrfisher Feb 7, 2017
e5b9265
Start counting videos from 1 instead of 0
glennrfisher Feb 7, 2017
4530d29
Swap highlighting when a new video is selected
glennrfisher Feb 8, 2017
c789879
Swap highlight when video ends
glennrfisher Feb 8, 2017
a9e3b20
Update comments and formatting
glennrfisher Feb 8, 2017
70f2bef
Reset background color and separator when no longer the current video
glennrfisher Feb 8, 2017
38bbcc9
Hide separator of previous video
glennrfisher Feb 8, 2017
e2eb49d
Code cleanup
glennrfisher Feb 8, 2017
4946533
Update row numbering after moving a video
glennrfisher Feb 8, 2017
b1e321d
Reload rows to update video numbers
glennrfisher Feb 8, 2017
ee2507d
Remove row numbering for now
glennrfisher Feb 8, 2017
a495f49
Scroll to current video when showing the queue
glennrfisher Feb 8, 2017
63b3f78
Add helper function to highlight/unhighlight
glennrfisher Feb 8, 2017
736bbc3
Set previous video when loading cells
glennrfisher Feb 8, 2017
c12b799
Add support for deleting the current video
glennrfisher Feb 8, 2017
aa15744
Code cleanup — use switch instead of if/else
glennrfisher Feb 8, 2017
76aa0be
Remove ability to delete the current video
glennrfisher Feb 8, 2017
2e4fab3
Remove video cell numbers and play icon
glennrfisher Feb 8, 2017
8a2af98
Update guard statements
glennrfisher Feb 8, 2017
bfc71e3
Merge remote-tracking branch 'origin/develop' into video-queue
glennrfisher Feb 8, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 not shown.
180 changes: 113 additions & 67 deletions iOS/Stormtrooper/Stormtrooper/Controllers/StreamViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -654,70 +699,60 @@ extension StreamViewController: UITableViewDelegate, UITableViewDataSource {
if isKeyboardShowing {
visualEffectView.isHidden = false
dismissView.isHidden = false
}
else {
} else {
Copy link
Member

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

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 }
Copy link
Member

Choose a reason for hiding this comment

The 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
}
}
Expand All @@ -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 }
Copy link
Member

Choose a reason for hiding this comment

The 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 {
Expand Down Expand Up @@ -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
}
}
Expand Down Expand Up @@ -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:
Expand All @@ -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 {
Expand Down
8 changes: 6 additions & 2 deletions iOS/Stormtrooper/Stormtrooper/Storyboards/Stream.storyboard
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
Expand All @@ -15,6 +15,9 @@
<array key="OpenSans-Semibold.ttf">
<string>OpenSans-Semibold</string>
</array>
<array key="WorkSans-Medium.ttf">
<string>WorkSans-Medium</string>
</array>
<array key="WorkSans-SemiBold.ttf">
<string>WorkSans-SemiBold</string>
</array>
Expand Down Expand Up @@ -211,12 +214,13 @@
<tableView clipsSubviews="YES" tag="1" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" rowHeight="89" sectionHeaderHeight="1" sectionFooterHeight="1" translatesAutoresizingMaskIntoConstraints="NO" id="iC4-5G-MpH">
<rect key="frame" x="0.0" y="42" width="375" height="247"/>
<color key="backgroundColor" red="0.15686274510000001" green="0.14117647059999999" blue="0.14117647059999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<color key="separatorColor" red="0.34901960784313724" green="0.34509803921568627" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<connections>
<outlet property="dataSource" destination="BYZ-38-t0r" id="2Ly-0p-jhB"/>
<outlet property="delegate" destination="BYZ-38-t0r" id="kd1-Sm-0Z4"/>
</connections>
</tableView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="UP NEXT" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zJg-2p-vtP">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="QUEUE" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="zJg-2p-vtP">
<rect key="frame" x="16" y="8" width="160" height="18"/>
<constraints>
<constraint firstAttribute="height" constant="18" id="euG-Od-hWs"/>
Expand Down
Loading