mirror of
https://github.com/yattee/yattee.git
synced 2024-12-22 13:33:42 +00:00
iOS: make timestamps in comments touchable
Timestamps in comments can now be touched and jump to the corresponding part in the video. Signed-off-by: Toni Förster <toni.foerster@gmail.com>
This commit is contained in:
parent
af75afa912
commit
7e346bf49c
@ -1,9 +1,13 @@
|
||||
#if os(iOS)
|
||||
import ActiveLabel
|
||||
#endif
|
||||
import SDWebImageSwiftUI
|
||||
import SwiftUI
|
||||
|
||||
struct CommentView: View {
|
||||
let comment: Comment
|
||||
@Binding var repliesID: Comment.ID?
|
||||
var availableWidth: CGFloat
|
||||
|
||||
@State private var subscribed = false
|
||||
|
||||
@ -204,7 +208,7 @@ struct CommentView: View {
|
||||
Group {
|
||||
let last = comments.replies.last
|
||||
ForEach(comments.replies) { comment in
|
||||
Self(comment: comment, repliesID: $repliesID)
|
||||
Self(comment: comment, repliesID: $repliesID, availableWidth: availableWidth)
|
||||
#if os(tvOS)
|
||||
.focusable()
|
||||
#endif
|
||||
@ -220,22 +224,25 @@ struct CommentView: View {
|
||||
|
||||
private var commentText: some View {
|
||||
Group {
|
||||
let text = Text(comment.text)
|
||||
#if os(macOS)
|
||||
.font(.system(size: 14))
|
||||
#elseif os(iOS)
|
||||
.font(.system(size: 15))
|
||||
#endif
|
||||
.lineSpacing(3)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
|
||||
let rawText = comment.text
|
||||
if #available(iOS 15.0, macOS 12.0, *) {
|
||||
text
|
||||
#if !os(tvOS)
|
||||
.textSelection(.enabled)
|
||||
#if os(iOS)
|
||||
ActiveLabelCommentRepresentable(
|
||||
text: rawText,
|
||||
availableWidth: availableWidth
|
||||
)
|
||||
#elseif os(macOS)
|
||||
Text(rawText)
|
||||
.font(.system(size: 14))
|
||||
.lineSpacing(3)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
.textSelection(.enabled)
|
||||
#endif
|
||||
} else {
|
||||
text
|
||||
Text(rawText)
|
||||
.font(.system(size: 15))
|
||||
.lineSpacing(3)
|
||||
.fixedSize(horizontal: false, vertical: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -248,13 +255,78 @@ struct CommentView: View {
|
||||
}
|
||||
}
|
||||
|
||||
#if os(iOS)
|
||||
struct ActiveLabelCommentRepresentable: UIViewRepresentable {
|
||||
var text: String
|
||||
var availableWidth: CGFloat
|
||||
|
||||
@State private var label = ActiveLabel()
|
||||
|
||||
@Environment(\.openURL) private var openURL
|
||||
|
||||
var player = PlayerModel.shared
|
||||
|
||||
func makeUIView(context _: Context) -> some UIView {
|
||||
customizeLabel()
|
||||
return label
|
||||
}
|
||||
|
||||
func updateUIView(_: UIViewType, context _: Context) {
|
||||
label.preferredMaxLayoutWidth = availableWidth
|
||||
}
|
||||
|
||||
func customizeLabel() {
|
||||
label.customize { label in
|
||||
label.enabledTypes = [.url, .timestamp]
|
||||
label.text = text
|
||||
label.font = .systemFont(ofSize: 15)
|
||||
label.lineSpacing = 3
|
||||
label.preferredMaxLayoutWidth = availableWidth
|
||||
label.URLColor = UIColor(Color.accentColor)
|
||||
label.timestampColor = UIColor(Color.accentColor)
|
||||
label.handleURLTap(urlTapHandler(_:))
|
||||
label.handleTimestampTap(timestampTapHandler(_:))
|
||||
label.numberOfLines = 0
|
||||
}
|
||||
}
|
||||
|
||||
private func urlTapHandler(_ url: URL) {
|
||||
var urlToOpen = url
|
||||
|
||||
if var components = URLComponents(url: url, resolvingAgainstBaseURL: false) {
|
||||
components.scheme = "yattee"
|
||||
if let yatteeURL = components.url {
|
||||
let parser = URLParser(url: urlToOpen, allowFileURLs: false)
|
||||
let destination = parser.destination
|
||||
if destination == .video,
|
||||
parser.videoID == player.currentVideo?.videoID,
|
||||
let time = parser.time
|
||||
{
|
||||
player.backend.seek(to: Double(time), seekType: .userInteracted)
|
||||
return
|
||||
}
|
||||
if destination != nil {
|
||||
urlToOpen = yatteeURL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
openURL(urlToOpen)
|
||||
}
|
||||
|
||||
private func timestampTapHandler(_ timestamp: Timestamp) {
|
||||
player.backend.seek(to: timestamp.timeInterval, seekType: .userInteracted)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
struct CommentView_Previews: PreviewProvider {
|
||||
static var fixture: Comment {
|
||||
Comment.fixture
|
||||
}
|
||||
|
||||
static var previews: some View {
|
||||
CommentView(comment: fixture, repliesID: .constant(fixture.id))
|
||||
CommentView(comment: fixture, repliesID: .constant(fixture.id), availableWidth: 375)
|
||||
.padding(5)
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ import SwiftUI
|
||||
|
||||
struct CommentsView: View {
|
||||
@State private var repliesID: Comment.ID?
|
||||
@State private var availableWidth = 0.0
|
||||
|
||||
@ObservedObject private var comments = CommentsModel.shared
|
||||
|
||||
@ -14,16 +15,21 @@ struct CommentsView: View {
|
||||
} else if !comments.loaded {
|
||||
PlaceholderProgressView()
|
||||
} else {
|
||||
let last = comments.all.last
|
||||
LazyVStack {
|
||||
ForEach(comments.all) { comment in
|
||||
CommentView(comment: comment, repliesID: $repliesID)
|
||||
CommentView(comment: comment, repliesID: $repliesID, availableWidth: availableWidth)
|
||||
.onAppear {
|
||||
comments.loadNextPageIfNeeded(current: comment)
|
||||
}
|
||||
.borderBottom(height: comment != last ? 0.5 : 0, color: Color("ControlsBorderColor"))
|
||||
.borderBottom(height: comment != comments.all.last ? 0.5 : 0, color: Color("ControlsBorderColor"))
|
||||
}
|
||||
}
|
||||
.background(GeometryReader { geometry in
|
||||
Color.clear
|
||||
.onAppear {
|
||||
self.availableWidth = Double(geometry.size.width)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
.padding(.horizontal)
|
||||
|
Loading…
Reference in New Issue
Block a user