This repository has been archived by the owner on May 6, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 191
/
VideoTranscript.swift
119 lines (95 loc) · 4.27 KB
/
VideoTranscript.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//
// VideoTranscript.swift
// edX
//
// Created by Danial Zahid on 12/19/16.
// Copyright © 2016 edX. All rights reserved.
//
import UIKit
protocol VideoTranscriptDelegate: AnyObject {
func didSelectSubtitleAtInterval(time: TimeInterval)
}
class VideoTranscript: NSObject, UITableViewDelegate, UITableViewDataSource, ScrollableDelegateProvider {
typealias Environment = DataManagerProvider & OEXInterfaceProvider & ReachabilityProvider
weak var scrollableDelegate: ScrollableDelegate?
private var scrollByDragging = false
let transcriptTableView = UITableView(frame: CGRect.zero, style: .plain)
var transcripts = [TranscriptObject]()
let environment : Environment
weak var delegate : VideoTranscriptDelegate?
//Maintain the cell index highlighted currently
var highlightedIndex = 0
//Flag to toggle if tableview has been dragged in the last few seconds
var isTableDragged : Bool = false
//Timer to reset the isTableDragged flag so automatic scrolling can kick back in
var draggingTimer = Timer()
//Delay after which automatic scrolling should kick back in
let dragDelay : TimeInterval = 5.0
init(environment : Environment) {
self.environment = environment
super.init()
setupTable(tableView: transcriptTableView)
transcriptTableView.dataSource = self
transcriptTableView.delegate = self
}
private func setupTable(tableView: UITableView) {
tableView.register(VideoTranscriptTableViewCell.self, forCellReuseIdentifier: VideoTranscriptTableViewCell.cellIdentifier)
tableView.separatorColor = UIColor.clear
tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 44
tableView.isHidden = true
}
//MARK: - UITableview methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return transcripts.count
}
internal func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: VideoTranscriptTableViewCell.cellIdentifier) as! VideoTranscriptTableViewCell
cell.applyStandardSeparatorInsets()
cell.setTranscriptText(text: transcripts[indexPath.row].text.decodingHTMLEntities, highlighted: indexPath.row == highlightedIndex)
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
delegate?.didSelectSubtitleAtInterval(time: transcripts[indexPath.row].start)
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if scrollByDragging {
scrollableDelegate?.scrollViewDidScroll(scrollView: scrollView)
}
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
scrollByDragging = false
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
scrollByDragging = true
isTableDragged = true
draggingTimer.invalidate()
draggingTimer = Timer.scheduledTimer(timeInterval: dragDelay, target: self, selector: #selector(invalidateDragging), userInfo: nil, repeats: false)
}
func updateTranscript(transcript: [TranscriptObject]) {
if transcript.count > 0 {
transcripts = transcript
transcriptTableView.reloadData()
transcriptTableView.isHidden = false
}
}
func highlightSubtitle(for time: TimeInterval?) {
if let index = getTranscriptIndex(for: time), index != highlightedIndex{
highlightedIndex = index
transcriptTableView.reloadData()
if !isTableDragged {
transcriptTableView.scrollToRow(at: IndexPath(row: index, section: 0), at: UITableView.ScrollPosition.middle, animated: true)
}
}
}
func getTranscriptIndex(for time: TimeInterval?) -> Int? {
guard let time = time else {
return nil
}
return transcripts.firstIndex(where: { time >= $0.start && time <= $0.end })
}
@objc func invalidateDragging(){
isTableDragged = false
}
}