mirror of
https://github.com/yattee/yattee.git
synced 2025-12-14 12:08:15 +00:00
Compare commits
6 Commits
v1.2-beta.
...
v1.2-beta.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f7fc2369e3 | ||
|
|
82ea8733ec | ||
|
|
1f495562fc | ||
|
|
37b99c59e1 | ||
|
|
7f9b53bd1f | ||
|
|
941e6a909d |
@@ -10,8 +10,8 @@ extension Color {
|
|||||||
static let secondaryBackground = Color(UIColor.secondarySystemBackground)
|
static let secondaryBackground = Color(UIColor.secondarySystemBackground)
|
||||||
static let tertiaryBackground = Color(UIColor.tertiarySystemBackground)
|
static let tertiaryBackground = Color(UIColor.tertiarySystemBackground)
|
||||||
#else
|
#else
|
||||||
static let background = Color.black
|
static func background(scheme: ColorScheme) -> Color {
|
||||||
static let secondaryBackground = Color.black
|
scheme == .dark ? .black : .init(white: 0.8)
|
||||||
static let tertiaryBackground = Color.black
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ final class InvidiousAPI: Service, ObservableObject, VideosAPI {
|
|||||||
self.account = account
|
self.account = account
|
||||||
|
|
||||||
validInstance = false
|
validInstance = false
|
||||||
signedIn = false
|
signedIn = !account.anonymous
|
||||||
|
|
||||||
configure()
|
configure()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,10 +72,12 @@ final class PipedAPI: Service, ObservableObject, VideosAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
configureTransformer(pathPattern("comments/*")) { (content: Entity<JSON>) -> CommentsPage in
|
configureTransformer(pathPattern("comments/*")) { (content: Entity<JSON>) -> CommentsPage in
|
||||||
let comments = content.json.dictionaryValue["comments"]?.arrayValue.map { PipedAPI.extractComment(from: $0)! } ?? []
|
let details = content.json.dictionaryValue
|
||||||
let nextPage = content.json.dictionaryValue["nextpage"]?.stringValue
|
let comments = details["comments"]?.arrayValue.map { PipedAPI.extractComment(from: $0)! } ?? []
|
||||||
|
let nextPage = details["nextpage"]?.stringValue
|
||||||
|
let disabled = details["disabled"]?.boolValue ?? false
|
||||||
|
|
||||||
return CommentsPage(comments: comments, nextPage: nextPage)
|
return CommentsPage(comments: comments, nextPage: nextPage, disabled: disabled)
|
||||||
}
|
}
|
||||||
|
|
||||||
if account.token.isNil {
|
if account.token.isNil {
|
||||||
|
|||||||
@@ -4,18 +4,29 @@ import SwiftyJSON
|
|||||||
|
|
||||||
final class CommentsModel: ObservableObject {
|
final class CommentsModel: ObservableObject {
|
||||||
@Published var all = [Comment]()
|
@Published var all = [Comment]()
|
||||||
@Published var replies = [Comment]()
|
|
||||||
|
|
||||||
@Published var nextPage: String?
|
@Published var nextPage: String?
|
||||||
@Published var firstPage = true
|
@Published var firstPage = true
|
||||||
|
|
||||||
@Published var loaded = false
|
@Published var loaded = true
|
||||||
|
@Published var disabled = false
|
||||||
|
|
||||||
|
@Published var replies = [Comment]()
|
||||||
|
@Published var repliesLoaded = false
|
||||||
|
|
||||||
var accounts: AccountsModel!
|
var accounts: AccountsModel!
|
||||||
var player: PlayerModel!
|
var player: PlayerModel!
|
||||||
|
|
||||||
|
var instance: Instance? {
|
||||||
|
InstancesModel.find(Defaults[.commentsInstanceID])
|
||||||
|
}
|
||||||
|
|
||||||
|
var api: VideosAPI? {
|
||||||
|
instance.isNil ? nil : PipedAPI(account: instance!.anonymousAccount)
|
||||||
|
}
|
||||||
|
|
||||||
static var enabled: Bool {
|
static var enabled: Bool {
|
||||||
!Defaults[.commentsInstanceID].isNil
|
!Defaults[.commentsInstanceID].isNil && !Defaults[.commentsInstanceID]!.isEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextPageAvailable: Bool {
|
var nextPageAvailable: Bool {
|
||||||
@@ -27,23 +38,23 @@ final class CommentsModel: ObservableObject {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
loaded = false
|
reset()
|
||||||
clear()
|
|
||||||
|
|
||||||
guard let instance = InstancesModel.find(Defaults[.commentsInstanceID]),
|
guard !instance.isNil,
|
||||||
!player.currentVideo.isNil
|
!(player?.currentVideo.isNil ?? true)
|
||||||
else {
|
else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
firstPage = page.isNil || page!.isEmpty
|
firstPage = page.isNil || page!.isEmpty
|
||||||
|
|
||||||
PipedAPI(account: instance.anonymousAccount).comments(player.currentVideo!.videoID, page: page)?
|
api?.comments(player.currentVideo!.videoID, page: page)?
|
||||||
.load()
|
.load()
|
||||||
.onSuccess { [weak self] response in
|
.onSuccess { [weak self] response in
|
||||||
if let page: CommentsPage = response.typedContent() {
|
if let page: CommentsPage = response.typedContent() {
|
||||||
self?.all = page.comments
|
self?.all = page.comments
|
||||||
self?.nextPage = page.nextPage
|
self?.nextPage = page.nextPage
|
||||||
|
self?.disabled = page.disabled
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onCompletion { [weak self] _ in
|
.onCompletion { [weak self] _ in
|
||||||
@@ -61,19 +72,27 @@ final class CommentsModel: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
replies = []
|
replies = []
|
||||||
|
repliesLoaded = false
|
||||||
|
|
||||||
accounts.api.comments(player.currentVideo!.videoID, page: page)?.load().onSuccess { response in
|
api?.comments(player.currentVideo!.videoID, page: page)?
|
||||||
|
.load()
|
||||||
|
.onSuccess { [weak self] response in
|
||||||
if let page: CommentsPage = response.typedContent() {
|
if let page: CommentsPage = response.typedContent() {
|
||||||
self.replies = page.comments
|
self?.replies = page.comments
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.onCompletion { [weak self] _ in
|
||||||
|
self?.repliesLoaded = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func clear() {
|
func reset() {
|
||||||
all = []
|
all = []
|
||||||
replies = []
|
disabled = false
|
||||||
firstPage = true
|
firstPage = true
|
||||||
nextPage = nil
|
nextPage = nil
|
||||||
loaded = false
|
loaded = false
|
||||||
|
replies = []
|
||||||
|
repliesLoaded = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,5 @@ import Foundation
|
|||||||
struct CommentsPage {
|
struct CommentsPage {
|
||||||
var comments = [Comment]()
|
var comments = [Comment]()
|
||||||
var nextPage: String?
|
var nextPage: String?
|
||||||
|
var disabled = false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -481,10 +481,9 @@ final class PlayerModel: ObservableObject {
|
|||||||
|
|
||||||
fileprivate func updateNowPlayingInfo() {
|
fileprivate func updateNowPlayingInfo() {
|
||||||
let duration: Int? = currentItem.video.live ? nil : Int(currentItem.videoDuration ?? 0)
|
let duration: Int? = currentItem.video.live ? nil : Int(currentItem.videoDuration ?? 0)
|
||||||
let nowPlayingInfo: [String: AnyObject] = [
|
var nowPlayingInfo: [String: AnyObject] = [
|
||||||
MPMediaItemPropertyTitle: currentItem.video.title as AnyObject,
|
MPMediaItemPropertyTitle: currentItem.video.title as AnyObject,
|
||||||
MPMediaItemPropertyArtist: currentItem.video.author as AnyObject,
|
MPMediaItemPropertyArtist: currentItem.video.author as AnyObject,
|
||||||
MPMediaItemPropertyArtwork: currentArtwork as AnyObject,
|
|
||||||
MPMediaItemPropertyPlaybackDuration: duration as AnyObject,
|
MPMediaItemPropertyPlaybackDuration: duration as AnyObject,
|
||||||
MPNowPlayingInfoPropertyIsLiveStream: currentItem.video.live as AnyObject,
|
MPNowPlayingInfoPropertyIsLiveStream: currentItem.video.live as AnyObject,
|
||||||
MPNowPlayingInfoPropertyElapsedPlaybackTime: player.currentTime().seconds as AnyObject,
|
MPNowPlayingInfoPropertyElapsedPlaybackTime: player.currentTime().seconds as AnyObject,
|
||||||
@@ -492,6 +491,10 @@ final class PlayerModel: ObservableObject {
|
|||||||
MPMediaItemPropertyMediaType: MPMediaType.anyVideo.rawValue as AnyObject
|
MPMediaItemPropertyMediaType: MPMediaType.anyVideo.rawValue as AnyObject
|
||||||
]
|
]
|
||||||
|
|
||||||
|
if !currentArtwork.isNil {
|
||||||
|
nowPlayingInfo[MPMediaItemPropertyArtwork] = currentArtwork as AnyObject
|
||||||
|
}
|
||||||
|
|
||||||
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
|
MPNowPlayingInfoCenter.default().nowPlayingInfo = nowPlayingInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ extension PlayerModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func playItem(_ item: PlayerQueueItem, video: Video? = nil, at time: TimeInterval? = nil) {
|
func playItem(_ item: PlayerQueueItem, video: Video? = nil, at time: TimeInterval? = nil) {
|
||||||
comments.clear()
|
comments.reset()
|
||||||
currentItem = item
|
currentItem = item
|
||||||
|
|
||||||
if !time.isNil {
|
if !time.isNil {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ struct CommentView: View {
|
|||||||
|
|
||||||
Spacer()
|
Spacer()
|
||||||
|
|
||||||
VStack(spacing: 5) {
|
VStack(alignment: .trailing, spacing: 8) {
|
||||||
likes
|
likes
|
||||||
statusIcons
|
statusIcons
|
||||||
}
|
}
|
||||||
@@ -65,8 +65,15 @@ struct CommentView: View {
|
|||||||
commentText
|
commentText
|
||||||
|
|
||||||
if comment.hasReplies {
|
if comment.hasReplies {
|
||||||
|
HStack(spacing: repliesButtonStackSpacing) {
|
||||||
repliesButton
|
repliesButton
|
||||||
|
|
||||||
|
ProgressView()
|
||||||
|
.scaleEffect(progressViewScale, anchor: .center)
|
||||||
|
.opacity(repliesID == comment.id && !comments.repliesLoaded ? 1 : 0)
|
||||||
|
.frame(maxHeight: 0)
|
||||||
|
}
|
||||||
|
|
||||||
if comment.id == repliesID {
|
if comment.id == repliesID {
|
||||||
repliesList
|
repliesList
|
||||||
}
|
}
|
||||||
@@ -148,16 +155,15 @@ struct CommentView: View {
|
|||||||
comments.loadReplies(page: comment.repliesPage!)
|
comments.loadReplies(page: comment.repliesPage!)
|
||||||
} label: {
|
} label: {
|
||||||
HStack(spacing: 5) {
|
HStack(spacing: 5) {
|
||||||
Image(systemName: self.repliesID == comment.id ? "arrow.turn.left.up" : "arrow.turn.right.down")
|
Image(systemName: repliesID == comment.id ? "arrow.turn.left.up" : "arrow.turn.right.down")
|
||||||
Text("Replies")
|
Text("Replies")
|
||||||
}
|
}
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
.padding(10)
|
.padding(10)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
.padding(.top, 2)
|
.padding(.vertical, 2)
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
.padding(.leading, 5)
|
.padding(.leading, 5)
|
||||||
#else
|
#else
|
||||||
@@ -165,6 +171,24 @@ struct CommentView: View {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var repliesButtonStackSpacing: Double {
|
||||||
|
#if os(tvOS)
|
||||||
|
24
|
||||||
|
#elseif os(iOS)
|
||||||
|
4
|
||||||
|
#else
|
||||||
|
2
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private var progressViewScale: Double {
|
||||||
|
#if os(macOS)
|
||||||
|
0.4
|
||||||
|
#else
|
||||||
|
0.8
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
private var repliesList: some View {
|
private var repliesList: some View {
|
||||||
Group {
|
Group {
|
||||||
let last = comments.replies.last
|
let last = comments.replies.last
|
||||||
@@ -179,8 +203,8 @@ struct CommentView: View {
|
|||||||
.padding(.vertical, 5)
|
.padding(.vertical, 5)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.padding(.leading, 22)
|
|
||||||
}
|
}
|
||||||
|
.padding(.leading, 22)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var commentText: some View {
|
private var commentText: some View {
|
||||||
@@ -219,3 +243,13 @@ struct CommentView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CommentView_Previews: PreviewProvider {
|
||||||
|
static var fixture: Comment {
|
||||||
|
Comment.fixture
|
||||||
|
}
|
||||||
|
|
||||||
|
static var previews: some View {
|
||||||
|
CommentView(comment: fixture, repliesID: .constant(fixture.id))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,6 +7,16 @@ struct CommentsView: View {
|
|||||||
@EnvironmentObject<PlayerModel> private var player
|
@EnvironmentObject<PlayerModel> private var player
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
Group {
|
||||||
|
if comments.disabled {
|
||||||
|
Text("Comments are disabled for this video")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
} else if comments.loaded && comments.all.isEmpty {
|
||||||
|
Text("No comments")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
} else if !comments.loaded {
|
||||||
|
progressView
|
||||||
|
} else {
|
||||||
ScrollView(.vertical, showsIndicators: false) {
|
ScrollView(.vertical, showsIndicators: false) {
|
||||||
VStack(alignment: .leading) {
|
VStack(alignment: .leading) {
|
||||||
let last = comments.all.last
|
let last = comments.all.last
|
||||||
@@ -22,6 +32,7 @@ struct CommentsView: View {
|
|||||||
HStack {
|
HStack {
|
||||||
if comments.nextPageAvailable {
|
if comments.nextPageAvailable {
|
||||||
Button {
|
Button {
|
||||||
|
repliesID = nil
|
||||||
comments.loadNextPage()
|
comments.loadNextPage()
|
||||||
} label: {
|
} label: {
|
||||||
Label("Show more", systemImage: "arrow.turn.down.right")
|
Label("Show more", systemImage: "arrow.turn.down.right")
|
||||||
@@ -30,6 +41,7 @@ struct CommentsView: View {
|
|||||||
|
|
||||||
if !comments.firstPage {
|
if !comments.firstPage {
|
||||||
Button {
|
Button {
|
||||||
|
repliesID = nil
|
||||||
comments.load(page: nil)
|
comments.load(page: nil)
|
||||||
} label: {
|
} label: {
|
||||||
Label("Show first", systemImage: "arrow.turn.down.left")
|
Label("Show first", systemImage: "arrow.turn.down.left")
|
||||||
@@ -37,11 +49,31 @@ struct CommentsView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.buttonStyle(.plain)
|
.buttonStyle(.plain)
|
||||||
.padding(.vertical, 5)
|
.padding(.vertical, 8)
|
||||||
.foregroundColor(.secondary)
|
.foregroundColor(.secondary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.padding(.horizontal)
|
.padding(.horizontal)
|
||||||
|
.onAppear {
|
||||||
|
if !comments.loaded {
|
||||||
|
comments.load()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var progressView: some View {
|
||||||
|
VStack {
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
HStack {
|
||||||
|
Spacer()
|
||||||
|
ProgressView()
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ struct VideoDetails: View {
|
|||||||
player.closeCurrentItem()
|
player.closeCurrentItem()
|
||||||
if !sidebarQueue {
|
if !sidebarQueue {
|
||||||
currentPage = .queue
|
currentPage = .queue
|
||||||
|
} else {
|
||||||
|
currentPage = .info
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Label("Close Video", systemImage: "xmark.circle")
|
Label("Close Video", systemImage: "xmark.circle")
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ struct AddToPlaylistView: View {
|
|||||||
|
|
||||||
@State private var selectedPlaylistID: Playlist.ID = ""
|
@State private var selectedPlaylistID: Playlist.ID = ""
|
||||||
|
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
@Environment(\.presentationMode) private var presentationMode
|
@Environment(\.presentationMode) private var presentationMode
|
||||||
@EnvironmentObject<PlaylistsModel> private var model
|
@EnvironmentObject<PlaylistsModel> private var model
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ struct AddToPlaylistView: View {
|
|||||||
.padding(.vertical)
|
.padding(.vertical)
|
||||||
#elseif os(tvOS)
|
#elseif os(tvOS)
|
||||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
||||||
.background(Color.tertiaryBackground)
|
.background(Color.background(scheme: colorScheme))
|
||||||
#else
|
#else
|
||||||
.padding(.vertical)
|
.padding(.vertical)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ struct PlaylistFormView: View {
|
|||||||
@State private var valid = false
|
@State private var valid = false
|
||||||
@State private var showingDeleteConfirmation = false
|
@State private var showingDeleteConfirmation = false
|
||||||
|
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
@Environment(\.presentationMode) private var presentationMode
|
@Environment(\.presentationMode) private var presentationMode
|
||||||
|
|
||||||
@EnvironmentObject<AccountsModel> private var accounts
|
@EnvironmentObject<AccountsModel> private var accounts
|
||||||
@@ -77,7 +78,7 @@ struct PlaylistFormView: View {
|
|||||||
.frame(maxWidth: 1000)
|
.frame(maxWidth: 1000)
|
||||||
}
|
}
|
||||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
||||||
.background(Color.tertiaryBackground)
|
.background(Color.background(scheme: colorScheme))
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
.onChange(of: name) { _ in validate() }
|
.onChange(of: name) { _ in validate() }
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ struct AccountForm: View {
|
|||||||
@State private var validationError: String?
|
@State private var validationError: String?
|
||||||
@State private var validationDebounce = Debounce()
|
@State private var validationDebounce = Debounce()
|
||||||
|
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
@Environment(\.presentationMode) private var presentationMode
|
@Environment(\.presentationMode) private var presentationMode
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -30,7 +31,7 @@ struct AccountForm: View {
|
|||||||
.padding(.vertical)
|
.padding(.vertical)
|
||||||
#elseif os(tvOS)
|
#elseif os(tvOS)
|
||||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
||||||
.background(Color.tertiaryBackground)
|
.background(Color.background(scheme: colorScheme))
|
||||||
#else
|
#else
|
||||||
.frame(width: 400, height: 145)
|
.frame(width: 400, height: 145)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ struct InstanceForm: View {
|
|||||||
@State private var validationError: String?
|
@State private var validationError: String?
|
||||||
@State private var validationDebounce = Debounce()
|
@State private var validationDebounce = Debounce()
|
||||||
|
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
@Environment(\.presentationMode) private var presentationMode
|
@Environment(\.presentationMode) private var presentationMode
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
@@ -32,7 +33,7 @@ struct InstanceForm: View {
|
|||||||
.padding(.vertical)
|
.padding(.vertical)
|
||||||
#elseif os(tvOS)
|
#elseif os(tvOS)
|
||||||
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
|
||||||
.background(Color.tertiaryBackground)
|
.background(Color.background(scheme: colorScheme))
|
||||||
#else
|
#else
|
||||||
.frame(width: 400, height: 190)
|
.frame(width: 400, height: 190)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ struct ServicesSettings: View {
|
|||||||
|
|
||||||
private var commentsInstancePicker: some View {
|
private var commentsInstancePicker: some View {
|
||||||
Picker("Comments", selection: $commentsInstanceID) {
|
Picker("Comments", selection: $commentsInstanceID) {
|
||||||
Text("Disabled").tag(String?.none)
|
Text("Disabled").tag(Optional(""))
|
||||||
|
|
||||||
ForEach(InstancesModel.all.filter { $0.app.supportsComments }) { instance in
|
ForEach(InstancesModel.all.filter { $0.app.supportsComments }) { instance in
|
||||||
Text(instance.description).tag(Optional(instance.id))
|
Text(instance.description).tag(Optional(instance.id))
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ struct SettingsView: View {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@Environment(\.presentationMode) private var presentationMode
|
@Environment(\.presentationMode) private var presentationMode
|
||||||
#endif
|
#endif
|
||||||
@@ -102,7 +104,7 @@ struct SettingsView: View {
|
|||||||
InstanceForm(savedInstanceID: $savedFormInstanceID)
|
InstanceForm(savedInstanceID: $savedFormInstanceID)
|
||||||
}
|
}
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
.background(Color.black)
|
.background(Color.background(scheme: colorScheme))
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ struct ChannelPlaylistView: View {
|
|||||||
|
|
||||||
@StateObject private var store = Store<ChannelPlaylist>()
|
@StateObject private var store = Store<ChannelPlaylist>()
|
||||||
|
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@Environment(\.inNavigationView) private var inNavigationView
|
@Environment(\.inNavigationView) private var inNavigationView
|
||||||
#endif
|
#endif
|
||||||
@@ -83,7 +85,7 @@ struct ChannelPlaylistView: View {
|
|||||||
.navigationTitle(playlist.title)
|
.navigationTitle(playlist.title)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
.background(Color.tertiaryBackground)
|
.background(Color.background(scheme: colorScheme))
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ struct ChannelVideosView: View {
|
|||||||
|
|
||||||
@StateObject private var store = Store<Channel>()
|
@StateObject private var store = Store<Channel>()
|
||||||
|
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
@Environment(\.presentationMode) private var presentationMode
|
@Environment(\.presentationMode) private var presentationMode
|
||||||
@Environment(\.inNavigationView) private var inNavigationView
|
@Environment(\.inNavigationView) private var inNavigationView
|
||||||
|
|
||||||
@@ -105,8 +106,6 @@ struct ChannelVideosView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
.background(Color.tertiaryBackground)
|
|
||||||
#endif
|
#endif
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
.sheet(isPresented: $presentingShareSheet) {
|
.sheet(isPresented: $presentingShareSheet) {
|
||||||
@@ -126,6 +125,9 @@ struct ChannelVideosView: View {
|
|||||||
return Group {
|
return Group {
|
||||||
if #available(macOS 12.0, *) {
|
if #available(macOS 12.0, *) {
|
||||||
content
|
content
|
||||||
|
#if os(tvOS)
|
||||||
|
.background(Color.background(scheme: colorScheme))
|
||||||
|
#endif
|
||||||
#if !os(iOS)
|
#if !os(iOS)
|
||||||
.focusScope(focusNamespace)
|
.focusScope(focusNamespace)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -25,13 +25,19 @@ struct DetailBadge: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct DefaultStyleModifier: ViewModifier {
|
struct DefaultStyleModifier: ViewModifier {
|
||||||
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
|
if #available(iOS 15.0, macOS 12.0, tvOS 15.0, *) {
|
||||||
content
|
content
|
||||||
.background(.thinMaterial)
|
.background(.thinMaterial)
|
||||||
} else {
|
} else {
|
||||||
content
|
content
|
||||||
|
#if os(tvOS)
|
||||||
|
.background(Color.background(scheme: colorScheme))
|
||||||
|
#else
|
||||||
.background(Color.background.opacity(0.95))
|
.background(Color.background.opacity(0.95))
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,9 @@ struct PlayerControlsView<Content: View>: View {
|
|||||||
.background(Material.ultraThinMaterial)
|
.background(Material.ultraThinMaterial)
|
||||||
} else {
|
} else {
|
||||||
controls
|
controls
|
||||||
|
#if !os(tvOS)
|
||||||
.background(Color.tertiaryBackground)
|
.background(Color.tertiaryBackground)
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2277,7 +2277,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -2311,7 +2311,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
|
CODE_SIGN_ENTITLEMENTS = "Open in Yattee/Open in Yattee.entitlements";
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -2343,7 +2343,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
||||||
@@ -2375,7 +2375,7 @@
|
|||||||
buildSettings = {
|
buildSettings = {
|
||||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
INFOPLIST_FILE = "Open in Yattee/Info.plist";
|
||||||
@@ -2538,7 +2538,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -2569,7 +2569,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
@@ -2604,7 +2604,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_APP_SANDBOX = YES;
|
ENABLE_APP_SANDBOX = YES;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -2637,7 +2637,7 @@
|
|||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
COMBINE_HIDPI_IMAGES = YES;
|
COMBINE_HIDPI_IMAGES = YES;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_APP_SANDBOX = YES;
|
ENABLE_APP_SANDBOX = YES;
|
||||||
ENABLE_HARDENED_RUNTIME = YES;
|
ENABLE_HARDENED_RUNTIME = YES;
|
||||||
@@ -2768,7 +2768,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
@@ -2800,7 +2800,7 @@
|
|||||||
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
|
ASSETCATALOG_COMPILER_APPICON_NAME = "App Icon & Top Shelf Image";
|
||||||
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 7;
|
||||||
DEVELOPMENT_ASSET_PATHS = "";
|
DEVELOPMENT_ASSET_PATHS = "";
|
||||||
DEVELOPMENT_TEAM = "";
|
DEVELOPMENT_TEAM = "";
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
|
|||||||
Reference in New Issue
Block a user