yattee/Shared/Views/ShareButton.swift

148 lines
4.8 KiB
Swift
Raw Normal View History

2021-10-26 22:59:59 +00:00
import SwiftUI
2022-11-13 17:52:15 +00:00
struct ShareButton<LabelView: View>: View {
2021-10-26 22:59:59 +00:00
let contentItem: ContentItem
@ObservedObject private var accounts = AccountsModel.shared
private var navigation: NavigationModel { .shared }
@ObservedObject private var player = PlayerModel.shared
2021-11-02 19:40:49 +00:00
2022-11-13 17:52:15 +00:00
let label: LabelView?
init(
contentItem: ContentItem,
@ViewBuilder label: @escaping () -> LabelView? = {
Label("Share...", systemImage: "square.and.arrow.up")
}
) {
2021-11-02 19:40:49 +00:00
self.contentItem = contentItem
2022-11-13 17:52:15 +00:00
self.label = label()
2021-11-02 19:40:49 +00:00
}
2021-10-26 22:59:59 +00:00
2022-11-10 20:58:45 +00:00
@ViewBuilder var body: some View {
2022-12-09 00:15:19 +00:00
// TODO: this should work with other content item types
if let video = contentItem.video {
Menu {
if !video.localStreamIsFile {
if video.localStreamIsRemoteURL {
remoteURLAction
} else {
instanceActions
Divider()
if !accounts.isEmpty {
youtubeActions
}
2022-11-10 20:58:45 +00:00
}
}
} label: {
label
}
.menuStyle(.borderlessButton)
2024-02-26 13:12:11 +00:00
.help("Share")
#if os(macOS)
.frame(maxWidth: 60)
#endif
2021-11-02 19:40:49 +00:00
}
}
private var instanceActions: some View {
2021-10-28 17:14:55 +00:00
Group {
2022-08-23 21:14:13 +00:00
Button(labelForShareURL(accounts.app.name)) {
2022-12-21 17:13:41 +00:00
if let url = player.playerAPI(contentItem.video)?.shareURL(contentItem) {
2021-11-02 19:40:49 +00:00
shareAction(url)
2022-08-23 21:14:13 +00:00
} else {
navigation.presentAlert(
title: "Could not create share link",
message: "For custom locations you can configure Frontend URL in Locations settings"
)
2021-11-02 19:40:49 +00:00
}
2022-08-23 21:14:13 +00:00
}
2021-11-02 19:40:49 +00:00
2022-08-23 21:14:13 +00:00
if contentItemIsPlayerCurrentVideo {
Button(labelForShareURL(accounts.app.name, withTime: true)) {
2022-12-21 17:13:41 +00:00
if let video = player.videoForDisplay,
let api = player.playerAPI(video)
{
shareAction(
api.shareURL(
contentItem,
time: player.backend.currentTime
)!
)
}
2021-11-02 19:40:49 +00:00
}
}
}
}
private var youtubeActions: some View {
Group {
if let url = accounts.api.shareURL(contentItem, frontendHost: "www.youtube.com") {
Button(labelForShareURL("YouTube")) {
shareAction(url)
}
if contentItemIsPlayerCurrentVideo {
2021-11-02 19:40:49 +00:00
Button(labelForShareURL("YouTube", withTime: true)) {
shareAction(
accounts.api.shareURL(
contentItem,
frontendHost: "www.youtube.com",
2022-02-16 20:23:11 +00:00
time: player.backend.currentTime
2021-11-02 19:40:49 +00:00
)!
)
}
2021-10-28 17:14:55 +00:00
}
}
2021-10-26 22:59:59 +00:00
}
}
private var contentItemIsPlayerCurrentVideo: Bool {
2022-12-21 17:13:41 +00:00
contentItem.contentType == .video && contentItem.video?.videoID == player.videoForDisplay?.videoID
}
2022-11-10 20:58:45 +00:00
@ViewBuilder private var remoteURLAction: some View {
if let url = contentItem.video.localStream?.localURL {
Button(labelForShareURL()) {
shareAction(url)
}
}
}
2021-11-02 19:40:49 +00:00
private func shareAction(_ url: URL) {
#if os(macOS)
NSPasteboard.general.clearContents()
NSPasteboard.general.setString(url.absoluteString, forType: .string)
#else
2022-06-16 17:43:56 +00:00
player.pause()
navigation.shareURL = url
navigation.presentingShareSheet = true
2021-11-02 19:40:49 +00:00
#endif
}
2022-11-10 20:58:45 +00:00
private func labelForShareURL(_ app: String? = nil, withTime: Bool = false) -> String {
2022-09-04 15:28:30 +00:00
if withTime {
#if os(macOS)
2022-11-10 20:58:45 +00:00
return String(format: "Copy %@ link with time".localized(), app ?? "")
2022-09-04 15:28:30 +00:00
#else
2022-11-10 20:58:45 +00:00
return String(format: "Share %@ link with time".localized(), app ?? "")
2022-09-04 15:28:30 +00:00
#endif
} else {
#if os(macOS)
2022-11-10 20:58:45 +00:00
return String(format: "Copy%@link".localized(), app == nil ? " " : " \(app!) ")
2022-09-04 15:28:30 +00:00
#else
2022-11-10 20:58:45 +00:00
return String(format: "Share%@link".localized(), app == nil ? " " : " \(app!) ")
2022-09-04 15:28:30 +00:00
#endif
}
2021-10-26 22:59:59 +00:00
}
}
struct ShareButton_Previews: PreviewProvider {
static var previews: some View {
2021-11-02 19:40:49 +00:00
ShareButton(
contentItem: ContentItem(video: Video.fixture)
2021-11-02 19:40:49 +00:00
)
.injectFixtureEnvironmentObjects()
2021-10-26 22:59:59 +00:00
}
}